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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1
2 /*******************************************************
3 *
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
14
15 #include "Coupler.h"
16
17 /*************************************************************
18 *
19 * allocates a Connector
20 *
21 **************************************************************/
22
23 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 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 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 /*
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 }
54 if (Paso_noError()) {
55 return out;
56 } else {
57 Paso_Connector_free(out);
58 return NULL;
59 }
60 }
61
62 /* returns a reference to Connector */
63
64 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
73 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 MEMFREE(in);
81 #ifdef Paso_TRACE
82 printf("Paso_Coupler_dealloc: system matrix pattern as been deallocated.\n");
83 #endif
84 }
85 }
86 }
87
88 Paso_Connector* Paso_Connector_copy(Paso_Connector* in) {
89 return Paso_Connector_unroll(in,1);
90 }
91
92 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 new_send_shcomp=Paso_SharedComponents_alloc(in->send->local_length,
98 in->send->numNeighbors,
99 in->send->neighbor,
100 in->send->shared,
101 in->send->offsetInShared,
102 block_size,0,in->mpi_info);
103
104 new_recv_shcomp=Paso_SharedComponents_alloc(in->recv->local_length,
105 in->recv->numNeighbors,
106 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
131 Paso_Coupler* Paso_Coupler_alloc(Paso_Connector* connector, dim_t block_size)
132 {
133 Paso_MPIInfo *mpi_info = connector->mpi_info;
134 Paso_Coupler*out=NULL;
135 Paso_resetError();
136 out=MEMALLOC(1,Paso_Coupler);
137 if (!Paso_checkPtr(out)) {
138 out->data=NULL;
139 out->block_size=block_size;
140 out->connector=Paso_Connector_getReference(connector);
141 out->send_buffer=NULL;
142 out->recv_buffer=NULL;
143 out->mpi_requests=NULL;
144 out->mpi_stati=NULL;
145 out->mpi_info = Paso_MPIInfo_getReference(mpi_info);
146 out->reference_counter=1;
147
148 #ifdef PASO_MPI
149 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 Paso_checkPtr(out->mpi_requests);
152 Paso_checkPtr(out->mpi_stati);
153 #endif
154 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 }
161 if (Paso_noError()) {
162 return out;
163 } else {
164 Paso_Coupler_free(out);
165 return NULL;
166 }
167 }
168
169 /* returns a reference to Coupler */
170
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 Paso_Connector_free(in->connector);
185 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 void Paso_Coupler_startCollect(Paso_Coupler* coupler,const double* in)
200 {
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 dim_t i;
205 coupler->data=(double*) in;
206 if ( mpi_info->size>1) {
207 /* start reveiving input */
208 {
209 for (i=0; i< coupler->connector->recv->numNeighbors; ++i) {
210 #ifdef PASO_MPI
211 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 MPI_DOUBLE,
214 coupler->connector->recv->neighbor[i],
215 mpi_info->msg_tag_counter+coupler->connector->recv->neighbor[i],
216 mpi_info->comm,
217 &(coupler->mpi_requests[i]));
218 #endif
219
220 }
221 }
222 /* collect values into buffer */
223 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 }
232 /* send buffer out */
233 {
234 for (i=0; i< coupler->connector->send->numNeighbors; ++i) {
235 #ifdef PASO_MPI
236 MPI_Issend(&(coupler->send_buffer[coupler->connector->send->offsetInShared[i] * block_size]),
237 (coupler->connector->send->offsetInShared[i+1]- coupler->connector->send->offsetInShared[i])*block_size,
238 MPI_DOUBLE,
239 coupler->connector->send->neighbor[i],
240 mpi_info->msg_tag_counter+mpi_info->rank,
241 mpi_info->comm,
242 &(coupler->mpi_requests[i+ coupler->connector->recv->numNeighbors]));
243 #endif
244 }
245 }
246 mpi_info->msg_tag_counter+=mpi_info->size;
247 }
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 MPI_Waitall(coupler->connector->recv->numNeighbors+coupler->connector->send->numNeighbors,
257 coupler->mpi_requests,
258 coupler->mpi_stati);
259 #endif
260 }
261
262 return coupler->recv_buffer;
263 }
264 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