/[escript]/trunk/finley/src/NodeFile_gather.c
ViewVC logotype

Annotation of /trunk/finley/src/NodeFile_gather.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1388 - (hide annotations)
Fri Jan 11 07:45:58 2008 UTC (11 years, 9 months ago) by trankine
File MIME type: text/plain
File size: 9120 byte(s)
And get the *(&(*&(* name right
1 jgs 150
2 ksteube 1312 /* $Id$ */
3    
4     /*******************************************************
5     *
6     * Copyright 2003-2007 by ACceSS MNRF
7     * Copyright 2007 by University of Queensland
8     *
9     * http://esscc.uq.edu.au
10     * Primary Business: Queensland, Australia
11     * Licensed under the Open Software License version 3.0
12     * http://www.opensource.org/licenses/osl-3.0.php
13     *
14     *******************************************************/
15    
16 jgs 82 /**************************************************************/
17    
18     /* Finley: Mesh: NodeFile */
19    
20 ksteube 1312 /* gathers the NodeFile out from the NodeFile in using the entries
21     /* in index[0:out->numNodes-1] which are between min_index and max_index (exclusive) */
22     /* the node index[i]
23 jgs 82
24     /**************************************************************/
25    
26     #include "NodeFile.h"
27    
28     /**************************************************************/
29    
30 ksteube 1312 void Finley_NodeFile_gatherEntries(dim_t n, index_t* index, index_t min_index, index_t max_index,
31     index_t* Id_out, index_t* Id_in,
32     index_t* Tag_out, index_t* Tag_in,
33     index_t* globalDegreesOfFreedom_out, index_t* globalDegreesOfFreedom_in,
34     dim_t numDim, double* Coordinates_out, double* Coordinates_in)
35     {
36 jgs 123 dim_t i,j;
37 ksteube 1312 register index_t k;
38     register const index_t range=max_index-min_index;
39     const size_t numDim_size=(size_t)numDim*sizeof(double);
40    
41     #pragma omp parallel for private(i,j,k) schedule(static)
42     for (i=0;i<n;i++) {
43     k=index[i]-min_index;
44     if ((k>=0) && (k <range)) {
45     Id_out[i]=Id_in[k];
46     Tag_out[i]=Tag_in[k];
47     globalDegreesOfFreedom_out[i]=globalDegreesOfFreedom_in[k];
48     memcpy(&(Coordinates_out[INDEX2(0,i,numDim)]), &(Coordinates_in[INDEX2(0,k,numDim)]), numDim_size);
49     }
50 jgs 82 }
51     }
52 ksteube 1312
53     void Finley_NodeFile_gather(index_t* index, Finley_NodeFile* in, Finley_NodeFile* out)
54     {
55     index_t min_id, max_id;
56     Finley_NodeFile_setGlobalIdRange(&min_id,&max_id,in);
57     Finley_NodeFile_gatherEntries(out->numNodes, index, min_id, max_id,
58     out->Id, in->Id,
59     out->Tag, in->Tag,
60     out->globalDegreesOfFreedom, in->globalDegreesOfFreedom,
61     out->numDim, out->Coordinates, in->Coordinates);
62     }
63    
64     void Finley_NodeFile_gather_global(index_t* index, Finley_NodeFile* in, Finley_NodeFile* out)
65     {
66     index_t min_id, max_id, undefined_node;
67     Paso_MPI_rank buffer_rank, dest, source, *distribution=NULL;
68     index_t *Id_buffer=NULL, *Tag_buffer=NULL, *globalDegreesOfFreedom_buffer=NULL;
69     double* Coordinates_buffer=NULL;
70     dim_t p, buffer_len,n;
71     char error_msg[100];
72     #ifdef PASO_MPI
73     MPI_Status status;
74     #endif
75    
76     /* get the global range of node ids */
77     Finley_NodeFile_setGlobalIdRange(&min_id,&max_id,in);
78     undefined_node=min_id-1;
79    
80     distribution=TMPMEMALLOC(in->MPIInfo->size+1, index_t);
81    
82     if ( !Finley_checkPtr(distribution) ) {
83     /* distribute the range of node ids */
84     buffer_len=Paso_MPIInfo_setDistribution(in->MPIInfo,min_id,max_id,distribution);
85     /* allocate buffers */
86     Id_buffer=TMPMEMALLOC(buffer_len,index_t);
87     Tag_buffer=TMPMEMALLOC(buffer_len,index_t);
88     globalDegreesOfFreedom_buffer=TMPMEMALLOC(buffer_len,index_t);
89     Coordinates_buffer=TMPMEMALLOC(buffer_len*out->numDim,double);
90     if (! (Finley_checkPtr(Id_buffer) || Finley_checkPtr(Tag_buffer) ||
91     Finley_checkPtr(globalDegreesOfFreedom_buffer) || Finley_checkPtr(Coordinates_buffer) ) ) {
92     /* fill Id_buffer by the undefined_node marker to check if nodes are defined */
93     #pragma omp parallel for private(n) schedule(static)
94     for (n=0;n<buffer_len;n++) Id_buffer[n]=undefined_node;
95    
96     /* fill the buffer by sending portions around in a circle */
97     dest=Paso_MPIInfo_mod(in->MPIInfo->size, in->MPIInfo->rank + 1);
98     source=Paso_MPIInfo_mod(in->MPIInfo->size, in->MPIInfo->rank - 1);
99     buffer_rank=in->MPIInfo->rank;
100     for (p=0; p< in->MPIInfo->size; ++p) {
101     if (p>0) { /* the initial send can be skipped */
102     #ifdef PASO_MPI
103     MPI_Sendrecv_replace(Id_buffer, buffer_len, MPI_INT,
104     dest, in->MPIInfo->msg_tag_counter, source, in->MPIInfo->msg_tag_counter,
105     in->MPIInfo->comm,&status);
106     MPI_Sendrecv_replace(Tag_buffer, buffer_len, MPI_INT,
107     dest, in->MPIInfo->msg_tag_counter+1, source, in->MPIInfo->msg_tag_counter+1,
108     in->MPIInfo->comm,&status);
109     MPI_Sendrecv_replace(globalDegreesOfFreedom_buffer, buffer_len, MPI_INT,
110     dest, in->MPIInfo->msg_tag_counter+2, source, in->MPIInfo->msg_tag_counter+2,
111     in->MPIInfo->comm,&status);
112     MPI_Sendrecv_replace(Coordinates_buffer, buffer_len*out->numDim, MPI_DOUBLE,
113     dest, in->MPIInfo->msg_tag_counter+3, source, in->MPIInfo->msg_tag_counter+3,
114     in->MPIInfo->comm,&status);
115     #endif
116     in->MPIInfo->msg_tag_counter+=4;
117     }
118     buffer_rank=Paso_MPIInfo_mod(in->MPIInfo->size, buffer_rank-1);
119     Finley_NodeFile_scatterEntries(in->numNodes, in->Id,
120     distribution[buffer_rank], distribution[buffer_rank+1],
121     Id_buffer, in->Id,
122     Tag_buffer, in->Tag,
123     globalDegreesOfFreedom_buffer, in->globalDegreesOfFreedom,
124     out->numDim, Coordinates_buffer, in->Coordinates);
125     }
126     /* now entries are collected from the buffer again by sending the entries around in a circle */
127     dest=Paso_MPIInfo_mod(in->MPIInfo->size, in->MPIInfo->rank + 1);
128     source=Paso_MPIInfo_mod(in->MPIInfo->size, in->MPIInfo->rank - 1);
129     buffer_rank=in->MPIInfo->rank;
130     for (p=0; p< in->MPIInfo->size; ++p) {
131     Finley_NodeFile_gatherEntries(out->numNodes, index,
132     distribution[buffer_rank], distribution[buffer_rank+1],
133     out->Id, Id_buffer,
134     out->Tag, Tag_buffer,
135     out->globalDegreesOfFreedom, globalDegreesOfFreedom_buffer,
136     out->numDim, out->Coordinates, Coordinates_buffer);
137     if (p<in->MPIInfo->size-1) { /* the last send can be skipped */
138     #ifdef PASO_MPI
139     MPI_Sendrecv_replace(Id_buffer, buffer_len, MPI_INT,
140     dest, in->MPIInfo->msg_tag_counter, source, in->MPIInfo->msg_tag_counter,
141     in->MPIInfo->comm,&status);
142     MPI_Sendrecv_replace(Tag_buffer, buffer_len, MPI_INT,
143     dest, in->MPIInfo->msg_tag_counter+1, source, in->MPIInfo->msg_tag_counter+1,
144     in->MPIInfo->comm,&status);
145     MPI_Sendrecv_replace(globalDegreesOfFreedom_buffer, buffer_len, MPI_INT,
146     dest, in->MPIInfo->msg_tag_counter+2, source, in->MPIInfo->msg_tag_counter+2,
147     in->MPIInfo->comm,&status);
148     MPI_Sendrecv_replace(Coordinates_buffer, buffer_len*out->numDim, MPI_DOUBLE,
149     dest, in->MPIInfo->msg_tag_counter+3, source, in->MPIInfo->msg_tag_counter+3,
150     in->MPIInfo->comm,&status);
151     #endif
152     in->MPIInfo->msg_tag_counter+=4;
153     }
154     buffer_rank=Paso_MPIInfo_mod(in->MPIInfo->size, buffer_rank-1);
155     }
156     /* check if all nodes are set: */
157     #pragma omp parallel for private(n) schedule(static)
158     for (n=0; n< out->numNodes; ++n) {
159     if (out->Id[n] == undefined_node ) {
160     sprintf(error_msg,"Finley_NodeFile_gather_global: Node id %d is referenced but is not defined.",out->Id[n]);
161     Finley_setError(VALUE_ERROR,error_msg);
162     }
163     }
164    
165     }
166     TMPMEMFREE(Id_buffer);
167     TMPMEMFREE(Tag_buffer);
168     TMPMEMFREE(globalDegreesOfFreedom_buffer);
169     TMPMEMFREE(Coordinates_buffer);
170     }
171     TMPMEMFREE(distribution);
172     /* make sure that the error is global */
173     Paso_MPIInfo_noError(in->MPIInfo);
174     }

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26