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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26