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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1811 - (hide annotations)
Thu Sep 25 23:11:13 2008 UTC (10 years, 11 months ago) by ksteube
File MIME type: text/plain
File size: 9897 byte(s)
Copyright updated in all files

1 ksteube 1313
2     /*******************************************************
3 ksteube 1811 *
4     * Copyright (c) 2003-2008 by University of Queensland
5     * 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 1758 /*
44     { int i;
45     for (i=0; i< out->recv->numNeighbors; ++i)
46     printf("Coupler: %d receive %d data at %d from %d\n",send->mpi_info->rank,out->recv->offsetInShared[i+1]- out->recv->offsetInShared[i],
47     out->recv->offsetInShared[i],out->recv->neighbor[i]);
48     for (i=0; i< out->send->numNeighbors; ++i)
49     printf("Coupler: %d send %d data at %d to %d\n",send->mpi_info->rank,out->send->offsetInShared[i+1]- out->send->offsetInShared[i],
50     out->send->offsetInShared[i],out->send->neighbor[i]);
51     }
52     */
53 gross 1552 }
54     if (Paso_noError()) {
55     return out;
56     } else {
57     Paso_Connector_free(out);
58     return NULL;
59     }
60     }
61 ksteube 1313
62 gross 1552 /* returns a reference to Connector */
63 ksteube 1313
64 gross 1552 Paso_Connector* Paso_Connector_getReference(Paso_Connector* in) {
65     if (in!=NULL) {
66     ++(in->reference_counter);
67     }
68     return in;
69     }
70    
71     /* deallocates a Connector: */
72 ksteube 1313
73 gross 1552 void Paso_Connector_free(Paso_Connector* in) {
74     if (in!=NULL) {
75     in->reference_counter--;
76     if (in->reference_counter<=0) {
77     Paso_SharedComponents_free(in->send);
78     Paso_SharedComponents_free(in->recv);
79     Paso_MPIInfo_free(in->mpi_info);
80 gross 1563 MEMFREE(in);
81 gross 1552 #ifdef Paso_TRACE
82     printf("Paso_Coupler_dealloc: system matrix pattern as been deallocated.\n");
83     #endif
84     }
85     }
86     }
87 ksteube 1313
88 gross 1552 Paso_Connector* Paso_Connector_copy(Paso_Connector* in) {
89     return Paso_Connector_unroll(in,1);
90     }
91 ksteube 1313
92 gross 1552 Paso_Connector* Paso_Connector_unroll(Paso_Connector* in, index_t block_size) {
93     Paso_SharedComponents *new_send_shcomp=NULL, *new_recv_shcomp=NULL;
94     Paso_Connector *out=NULL;
95     if (Paso_noError()) {
96     if (block_size>1) {
97 gross 1562 new_send_shcomp=Paso_SharedComponents_alloc(in->send->local_length,
98     in->send->numNeighbors,
99 gross 1552 in->send->neighbor,
100     in->send->shared,
101     in->send->offsetInShared,
102     block_size,0,in->mpi_info);
103 ksteube 1313
104 gross 1562 new_recv_shcomp=Paso_SharedComponents_alloc(in->recv->local_length,
105     in->recv->numNeighbors,
106 gross 1552 in->recv->neighbor,
107     in->recv->shared,
108     in->recv->offsetInShared,
109     block_size,0,in->mpi_info);
110     } else {
111     new_send_shcomp=Paso_SharedComponents_getReference(in->send);
112     new_recv_shcomp=Paso_SharedComponents_getReference(in->recv);
113     }
114     if (Paso_noError()) out=Paso_Connector_alloc(new_send_shcomp,new_recv_shcomp);
115     }
116     Paso_SharedComponents_free(new_send_shcomp);
117     Paso_SharedComponents_free(new_recv_shcomp);
118     if (Paso_noError()) {
119     return out;
120     } else {
121     Paso_Connector_free(out);
122     return NULL;
123     }
124     }
125     /*************************************************************
126     *
127     * allocates a Connector
128     *
129     **************************************************************/
130 ksteube 1313
131 gross 1552 Paso_Coupler* Paso_Coupler_alloc(Paso_Connector* connector, dim_t block_size)
132 ksteube 1313 {
133 gross 1552 Paso_MPIInfo *mpi_info = connector->mpi_info;
134 ksteube 1313 Paso_Coupler*out=NULL;
135     Paso_resetError();
136     out=MEMALLOC(1,Paso_Coupler);
137     if (!Paso_checkPtr(out)) {
138 gross 1562 out->data=NULL;
139 gross 1552 out->block_size=block_size;
140     out->connector=Paso_Connector_getReference(connector);
141 ksteube 1313 out->send_buffer=NULL;
142     out->recv_buffer=NULL;
143     out->mpi_requests=NULL;
144     out->mpi_stati=NULL;
145 gross 1552 out->mpi_info = Paso_MPIInfo_getReference(mpi_info);
146 ksteube 1313 out->reference_counter=1;
147    
148     #ifdef PASO_MPI
149 gross 1552 out->mpi_requests=MEMALLOC(connector->send->numNeighbors+connector->recv->numNeighbors,MPI_Request);
150     out->mpi_stati=MEMALLOC(connector->send->numNeighbors+connector->recv->numNeighbors,MPI_Status);
151 ksteube 1313 Paso_checkPtr(out->mpi_requests);
152     Paso_checkPtr(out->mpi_stati);
153     #endif
154 gross 1552 if (mpi_info->size>1) {
155     out->send_buffer=MEMALLOC(connector->send->numSharedComponents * block_size,double);
156     out->recv_buffer=MEMALLOC(connector->recv->numSharedComponents * block_size,double);
157     Paso_checkPtr(out->send_buffer);
158     Paso_checkPtr(out->recv_buffer);
159     }
160 ksteube 1313 }
161     if (Paso_noError()) {
162     return out;
163     } else {
164     Paso_Coupler_free(out);
165     return NULL;
166     }
167     }
168    
169 gross 1552 /* returns a reference to Coupler */
170 ksteube 1313
171     Paso_Coupler* Paso_Coupler_getReference(Paso_Coupler* in) {
172     if (in!=NULL) {
173     ++(in->reference_counter);
174     }
175     return in;
176     }
177    
178     /* deallocates a Coupler: */
179    
180     void Paso_Coupler_free(Paso_Coupler* in) {
181     if (in!=NULL) {
182     in->reference_counter--;
183     if (in->reference_counter<=0) {
184 gross 1552 Paso_Connector_free(in->connector);
185 ksteube 1313 MEMFREE(in->send_buffer);
186     MEMFREE(in->recv_buffer);
187     MEMFREE(in->mpi_requests);
188     MEMFREE(in->mpi_stati);
189     Paso_MPIInfo_free(in->mpi_info);
190     MEMFREE(in);
191     #ifdef Paso_TRACE
192     printf("Paso_Coupler_dealloc: system matrix pattern as been deallocated.\n");
193     #endif
194     }
195     }
196     }
197    
198    
199 gross 1639 void Paso_Coupler_startCollect(Paso_Coupler* coupler,const double* in)
200 ksteube 1313 {
201     Paso_MPIInfo *mpi_info = coupler->mpi_info;
202     dim_t block_size=coupler->block_size;
203     size_t block_size_size=block_size*sizeof(double);
204 phornby 1628 dim_t i;
205 gross 1639 coupler->data=(double*) in;
206 ksteube 1313 if ( mpi_info->size>1) {
207     /* start reveiving input */
208     {
209 gross 1552 for (i=0; i< coupler->connector->recv->numNeighbors; ++i) {
210 ksteube 1313 #ifdef PASO_MPI
211 gross 1552 MPI_Irecv(&(coupler->recv_buffer[coupler->connector->recv->offsetInShared[i] * block_size]),
212     (coupler->connector->recv->offsetInShared[i+1]- coupler->connector->recv->offsetInShared[i])*block_size,
213 ksteube 1313 MPI_DOUBLE,
214 gross 1552 coupler->connector->recv->neighbor[i],
215 gross 1553 mpi_info->msg_tag_counter+coupler->connector->recv->neighbor[i],
216 ksteube 1313 mpi_info->comm,
217     &(coupler->mpi_requests[i]));
218     #endif
219    
220     }
221     }
222     /* collect values into buffer */
223 gross 1758 if (block_size>1) {
224     #pragma omp parallel for private(i)
225     for (i=0; i < coupler->connector->send->numSharedComponents;++i) {
226     memcpy(&(coupler->send_buffer[(block_size)*i]),&(in[ block_size * coupler->connector->send->shared[i]]), block_size_size);
227     }
228     } else {
229     #pragma omp parallel for private(i)
230     for (i=0; i < coupler->connector->send->numSharedComponents;++i) coupler->send_buffer[i]=in[coupler->connector->send->shared[i]];
231 ksteube 1313 }
232     /* send buffer out */
233     {
234 gross 1552 for (i=0; i< coupler->connector->send->numNeighbors; ++i) {
235 ksteube 1313 #ifdef PASO_MPI
236 gross 1553 MPI_Issend(&(coupler->send_buffer[coupler->connector->send->offsetInShared[i] * block_size]),
237 gross 1552 (coupler->connector->send->offsetInShared[i+1]- coupler->connector->send->offsetInShared[i])*block_size,
238 ksteube 1313 MPI_DOUBLE,
239 gross 1552 coupler->connector->send->neighbor[i],
240 ksteube 1313 mpi_info->msg_tag_counter+mpi_info->rank,
241     mpi_info->comm,
242 gross 1553 &(coupler->mpi_requests[i+ coupler->connector->recv->numNeighbors]));
243 ksteube 1313 #endif
244     }
245     }
246 gross 1413 mpi_info->msg_tag_counter+=mpi_info->size;
247 ksteube 1313 }
248     }
249    
250     double* Paso_Coupler_finishCollect(Paso_Coupler* coupler)
251     {
252     Paso_MPIInfo *mpi_info = coupler->mpi_info;
253     if ( mpi_info->size>1) {
254     /* wait for receive */
255     #ifdef PASO_MPI
256 gross 1552 MPI_Waitall(coupler->connector->recv->numNeighbors+coupler->connector->send->numNeighbors,
257 ksteube 1313 coupler->mpi_requests,
258     coupler->mpi_stati);
259     #endif
260     }
261 gross 1758
262 ksteube 1313 return coupler->recv_buffer;
263     }
264 gross 1562 dim_t Paso_Coupler_getLocalLength(const Paso_Coupler* in) {
265     return in->connector->send->local_length;
266     }
267     void Paso_Coupler_copyAll(const Paso_Coupler* src, Paso_Coupler* target)
268     {
269     dim_t i;
270     #pragma omp parallel
271     {
272     #pragma omp for private(i)
273     for (i =0; i< src->connector->recv->numSharedComponents * src->block_size; ++i) {
274     target->recv_buffer[i]=src->recv_buffer[i];
275     }
276     #pragma omp for private(i)
277     for (i =0; i< Paso_Coupler_getLocalLength(src) * src->block_size; ++i) {
278     target->data[i]=src->data[i];
279     }
280     }
281     }

  ViewVC Help
Powered by ViewVC 1.1.26