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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1639 - (hide annotations)
Mon Jul 14 08:55:25 2008 UTC (11 years, 2 months ago) by gross
File MIME type: text/plain
File size: 9584 byte(s)


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

  ViewVC Help
Powered by ViewVC 1.1.26