/[escript]/trunk/paso/src/Coupler.c
ViewVC logotype

Annotation of /trunk/paso/src/Coupler.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2548 - (hide annotations)
Mon Jul 20 06:20:06 2009 UTC (10 years, 3 months ago) by jfenwick
File MIME type: text/plain
File size: 9899 byte(s)
Updating copyright notices
1 ksteube 1313
2     /*******************************************************
3 ksteube 1811 *
4 jfenwick 2548 * Copyright (c) 2003-2009 by University of Queensland
5 ksteube 1811 * Earth Systems Science Computational Center (ESSCC)
6     * http://www.uq.edu.au/esscc
7     *
8     * Primary Business: Queensland, Australia
9     * Licensed under the Open Software License version 3.0
10     * http://www.opensource.org/licenses/osl-3.0.php
11     *
12     *******************************************************/
13 ksteube 1313
14 ksteube 1811
15 gross 1552 #include "Coupler.h"
16 ksteube 1313
17 gross 1552 /*************************************************************
18     *
19     * allocates a Connector
20     *
21     **************************************************************/
22 ksteube 1313
23 gross 1552 Paso_Connector* Paso_Connector_alloc(Paso_SharedComponents* send,
24     Paso_SharedComponents* recv)
25     {
26     Paso_Connector*out=NULL;
27     Paso_resetError();
28     out=MEMALLOC(1,Paso_Connector);
29     if ( send->mpi_info != recv->mpi_info ) {
30     Paso_setError(SYSTEM_ERROR,"Paso_Coupler_alloc: send and recv mpi communicator don't match.");
31     return NULL;
32     }
33 gross 1562 if ( send->local_length != recv->local_length ) {
34     Paso_setError(SYSTEM_ERROR,"Paso_Coupler_alloc: local length of send and recv Paso_SharedComponents must match.");
35     return NULL;
36     }
37    
38 gross 1552 if (!Paso_checkPtr(out)) {
39     out->send=Paso_SharedComponents_getReference(send);
40     out->recv= Paso_SharedComponents_getReference(recv);
41     out->mpi_info = Paso_MPIInfo_getReference(send->mpi_info);
42     out->reference_counter=1;
43 gross 2385
44 gross 1758 /*
45     { int i;
46     for (i=0; i< out->recv->numNeighbors; ++i)
47     printf("Coupler: %d receive %d data at %d from %d\n",send->mpi_info->rank,out->recv->offsetInShared[i+1]- out->recv->offsetInShared[i],
48     out->recv->offsetInShared[i],out->recv->neighbor[i]);
49     for (i=0; i< out->send->numNeighbors; ++i)
50     printf("Coupler: %d send %d data at %d to %d\n",send->mpi_info->rank,out->send->offsetInShared[i+1]- out->send->offsetInShared[i],
51     out->send->offsetInShared[i],out->send->neighbor[i]);
52     }
53     */
54 gross 2385
55 gross 1552 }
56     if (Paso_noError()) {
57     return out;
58     } else {
59     Paso_Connector_free(out);
60     return NULL;
61     }
62     }
63 ksteube 1313
64 gross 1552 /* returns a reference to Connector */
65 ksteube 1313
66 gross 1552 Paso_Connector* Paso_Connector_getReference(Paso_Connector* in) {
67     if (in!=NULL) {
68     ++(in->reference_counter);
69     }
70     return in;
71     }
72    
73     /* deallocates a Connector: */
74 ksteube 1313
75 gross 1552 void Paso_Connector_free(Paso_Connector* in) {
76     if (in!=NULL) {
77     in->reference_counter--;
78     if (in->reference_counter<=0) {
79     Paso_SharedComponents_free(in->send);
80     Paso_SharedComponents_free(in->recv);
81     Paso_MPIInfo_free(in->mpi_info);
82 gross 1563 MEMFREE(in);
83 gross 1552 #ifdef Paso_TRACE
84     printf("Paso_Coupler_dealloc: system matrix pattern as been deallocated.\n");
85     #endif
86     }
87     }
88     }
89 ksteube 1313
90 gross 1552 Paso_Connector* Paso_Connector_copy(Paso_Connector* in) {
91     return Paso_Connector_unroll(in,1);
92     }
93 ksteube 1313
94 gross 1552 Paso_Connector* Paso_Connector_unroll(Paso_Connector* in, index_t block_size) {
95     Paso_SharedComponents *new_send_shcomp=NULL, *new_recv_shcomp=NULL;
96     Paso_Connector *out=NULL;
97     if (Paso_noError()) {
98     if (block_size>1) {
99 gross 1562 new_send_shcomp=Paso_SharedComponents_alloc(in->send->local_length,
100     in->send->numNeighbors,
101 gross 1552 in->send->neighbor,
102     in->send->shared,
103     in->send->offsetInShared,
104     block_size,0,in->mpi_info);
105 ksteube 1313
106 gross 1562 new_recv_shcomp=Paso_SharedComponents_alloc(in->recv->local_length,
107     in->recv->numNeighbors,
108 gross 1552 in->recv->neighbor,
109     in->recv->shared,
110     in->recv->offsetInShared,
111     block_size,0,in->mpi_info);
112     } else {
113     new_send_shcomp=Paso_SharedComponents_getReference(in->send);
114     new_recv_shcomp=Paso_SharedComponents_getReference(in->recv);
115     }
116     if (Paso_noError()) out=Paso_Connector_alloc(new_send_shcomp,new_recv_shcomp);
117     }
118     Paso_SharedComponents_free(new_send_shcomp);
119     Paso_SharedComponents_free(new_recv_shcomp);
120     if (Paso_noError()) {
121     return out;
122     } else {
123     Paso_Connector_free(out);
124     return NULL;
125     }
126     }
127     /*************************************************************
128     *
129     * allocates a Connector
130     *
131     **************************************************************/
132 ksteube 1313
133 gross 1552 Paso_Coupler* Paso_Coupler_alloc(Paso_Connector* connector, dim_t block_size)
134 ksteube 1313 {
135 gross 1552 Paso_MPIInfo *mpi_info = connector->mpi_info;
136 ksteube 1313 Paso_Coupler*out=NULL;
137     Paso_resetError();
138     out=MEMALLOC(1,Paso_Coupler);
139     if (!Paso_checkPtr(out)) {
140 gross 1562 out->data=NULL;
141 gross 1552 out->block_size=block_size;
142     out->connector=Paso_Connector_getReference(connector);
143 ksteube 1313 out->send_buffer=NULL;
144     out->recv_buffer=NULL;
145     out->mpi_requests=NULL;
146     out->mpi_stati=NULL;
147 gross 1552 out->mpi_info = Paso_MPIInfo_getReference(mpi_info);
148 ksteube 1313 out->reference_counter=1;
149    
150     #ifdef PASO_MPI
151 gross 1552 out->mpi_requests=MEMALLOC(connector->send->numNeighbors+connector->recv->numNeighbors,MPI_Request);
152     out->mpi_stati=MEMALLOC(connector->send->numNeighbors+connector->recv->numNeighbors,MPI_Status);
153 ksteube 1313 Paso_checkPtr(out->mpi_requests);
154     Paso_checkPtr(out->mpi_stati);
155     #endif
156 gross 1552 if (mpi_info->size>1) {
157     out->send_buffer=MEMALLOC(connector->send->numSharedComponents * block_size,double);
158     out->recv_buffer=MEMALLOC(connector->recv->numSharedComponents * block_size,double);
159     Paso_checkPtr(out->send_buffer);
160     Paso_checkPtr(out->recv_buffer);
161     }
162 ksteube 1313 }
163     if (Paso_noError()) {
164     return out;
165     } else {
166     Paso_Coupler_free(out);
167     return NULL;
168     }
169     }
170    
171 gross 1552 /* returns a reference to Coupler */
172 ksteube 1313
173     Paso_Coupler* Paso_Coupler_getReference(Paso_Coupler* in) {
174     if (in!=NULL) {
175     ++(in->reference_counter);
176     }
177     return in;
178     }
179    
180     /* deallocates a Coupler: */
181    
182     void Paso_Coupler_free(Paso_Coupler* in) {
183     if (in!=NULL) {
184     in->reference_counter--;
185     if (in->reference_counter<=0) {
186 gross 1552 Paso_Connector_free(in->connector);
187 ksteube 1313 MEMFREE(in->send_buffer);
188     MEMFREE(in->recv_buffer);
189     MEMFREE(in->mpi_requests);
190     MEMFREE(in->mpi_stati);
191     Paso_MPIInfo_free(in->mpi_info);
192     MEMFREE(in);
193     #ifdef Paso_TRACE
194     printf("Paso_Coupler_dealloc: system matrix pattern as been deallocated.\n");
195     #endif
196     }
197     }
198     }
199    
200    
201 gross 1639 void Paso_Coupler_startCollect(Paso_Coupler* coupler,const double* in)
202 ksteube 1313 {
203     Paso_MPIInfo *mpi_info = coupler->mpi_info;
204     dim_t block_size=coupler->block_size;
205     size_t block_size_size=block_size*sizeof(double);
206 phornby 1628 dim_t i;
207 gross 1639 coupler->data=(double*) in;
208 ksteube 1313 if ( mpi_info->size>1) {
209     /* start reveiving input */
210     {
211 gross 1552 for (i=0; i< coupler->connector->recv->numNeighbors; ++i) {
212 ksteube 1313 #ifdef PASO_MPI
213 gross 1552 MPI_Irecv(&(coupler->recv_buffer[coupler->connector->recv->offsetInShared[i] * block_size]),
214     (coupler->connector->recv->offsetInShared[i+1]- coupler->connector->recv->offsetInShared[i])*block_size,
215 ksteube 1313 MPI_DOUBLE,
216 gross 1552 coupler->connector->recv->neighbor[i],
217 gross 1553 mpi_info->msg_tag_counter+coupler->connector->recv->neighbor[i],
218 ksteube 1313 mpi_info->comm,
219     &(coupler->mpi_requests[i]));
220     #endif
221    
222     }
223     }
224     /* collect values into buffer */
225 gross 1758 if (block_size>1) {
226     #pragma omp parallel for private(i)
227     for (i=0; i < coupler->connector->send->numSharedComponents;++i) {
228     memcpy(&(coupler->send_buffer[(block_size)*i]),&(in[ block_size * coupler->connector->send->shared[i]]), block_size_size);
229     }
230     } else {
231     #pragma omp parallel for private(i)
232     for (i=0; i < coupler->connector->send->numSharedComponents;++i) coupler->send_buffer[i]=in[coupler->connector->send->shared[i]];
233 ksteube 1313 }
234     /* send buffer out */
235     {
236 gross 1552 for (i=0; i< coupler->connector->send->numNeighbors; ++i) {
237 ksteube 1313 #ifdef PASO_MPI
238 gross 1553 MPI_Issend(&(coupler->send_buffer[coupler->connector->send->offsetInShared[i] * block_size]),
239 gross 1552 (coupler->connector->send->offsetInShared[i+1]- coupler->connector->send->offsetInShared[i])*block_size,
240 ksteube 1313 MPI_DOUBLE,
241 gross 1552 coupler->connector->send->neighbor[i],
242 ksteube 1313 mpi_info->msg_tag_counter+mpi_info->rank,
243     mpi_info->comm,
244 gross 1553 &(coupler->mpi_requests[i+ coupler->connector->recv->numNeighbors]));
245 ksteube 1313 #endif
246     }
247     }
248 gross 1413 mpi_info->msg_tag_counter+=mpi_info->size;
249 ksteube 1313 }
250     }
251    
252     double* Paso_Coupler_finishCollect(Paso_Coupler* coupler)
253     {
254     Paso_MPIInfo *mpi_info = coupler->mpi_info;
255     if ( mpi_info->size>1) {
256     /* wait for receive */
257     #ifdef PASO_MPI
258 gross 1552 MPI_Waitall(coupler->connector->recv->numNeighbors+coupler->connector->send->numNeighbors,
259 ksteube 1313 coupler->mpi_requests,
260     coupler->mpi_stati);
261     #endif
262     }
263 gross 1758
264 ksteube 1313 return coupler->recv_buffer;
265     }
266 gross 1562 dim_t Paso_Coupler_getLocalLength(const Paso_Coupler* in) {
267     return in->connector->send->local_length;
268     }
269     void Paso_Coupler_copyAll(const Paso_Coupler* src, Paso_Coupler* target)
270     {
271     dim_t i;
272     #pragma omp parallel
273     {
274     #pragma omp for private(i)
275     for (i =0; i< src->connector->recv->numSharedComponents * src->block_size; ++i) {
276     target->recv_buffer[i]=src->recv_buffer[i];
277     }
278     #pragma omp for private(i)
279     for (i =0; i< Paso_Coupler_getLocalLength(src) * src->block_size; ++i) {
280     target->data[i]=src->data[i];
281     }
282     }
283     }

  ViewVC Help
Powered by ViewVC 1.1.26