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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1387 - (hide annotations)
Fri Jan 11 07:45:26 2008 UTC (11 years, 9 months ago) by trankine
Original Path: temp/paso/src/Coupler.c
File MIME type: text/plain
File size: 7888 byte(s)
Restore the trunk that existed before the windows changes were committed to the (now moved to branches) old trunk.
1 ksteube 1313
2     /* $Id: Coupler.c 1306 2007-09-18 05:51:09Z ksteube $ */
3    
4     /*******************************************************
5     *
6     * Copyright 2003-2007 by ACceSS MNRF
7     * Copyright 2007 by University of Queensland
8     *
9     * http://esscc.uq.edu.au
10     * Primary Business: Queensland, Australia
11     * Licensed under the Open Software License version 3.0
12     * http://www.opensource.org/licenses/osl-3.0.php
13     *
14     *******************************************************/
15    
16     /**************************************************************/
17    
18     /* Paso: Coupler organizes the coupling with in a pattern/matrix */
19     /* across processors */
20    
21     /**************************************************************/
22    
23     /* Author: gross@access.edu.au */
24    
25     /**************************************************************/
26    
27     #include "Coupler.h"
28    
29     /**************************************************************/
30    
31     /* allocates a Coupler */
32    
33    
34     /**************************************************************/
35    
36    
37     Paso_Coupler* Paso_Coupler_alloc(Paso_SharedComponents* send,
38     Paso_SharedComponents* recv)
39     {
40     Paso_Coupler*out=NULL;
41     Paso_resetError();
42     out=MEMALLOC(1,Paso_Coupler);
43     if ( send->mpi_info != recv->mpi_info ) {
44     Paso_setError(SYSTEM_ERROR,"Paso_Coupler_alloc: send and recv mpi communicator don't match.");
45     return NULL;
46     }
47     if (!Paso_checkPtr(out)) {
48     out->send=Paso_SharedComponents_getReference(send);
49     out->send_buffer=NULL;
50     out->recv= Paso_SharedComponents_getReference(recv);
51     out->recv_buffer=NULL;
52     out->mpi_requests=NULL;
53     out->mpi_stati=NULL;
54     out->mpi_info = Paso_MPIInfo_getReference(send->mpi_info);
55     out->reference_counter=1;
56    
57     #ifdef PASO_MPI
58     out->mpi_requests=MEMALLOC(send->numNeighbors+recv->numNeighbors,MPI_Request);
59     out->mpi_stati=MEMALLOC(send->numNeighbors+recv->numNeighbors,MPI_Status);
60     Paso_checkPtr(out->mpi_requests);
61     Paso_checkPtr(out->mpi_stati);
62     #endif
63     }
64     if (Paso_noError()) {
65     return out;
66     } else {
67     Paso_Coupler_free(out);
68     return NULL;
69     }
70     }
71    
72     /* returns a reference to in */
73    
74     Paso_Coupler* Paso_Coupler_getReference(Paso_Coupler* in) {
75     if (in!=NULL) {
76     ++(in->reference_counter);
77     }
78     return in;
79     }
80    
81     /* deallocates a Coupler: */
82    
83     void Paso_Coupler_free(Paso_Coupler* in) {
84     if (in!=NULL) {
85     in->reference_counter--;
86     if (in->reference_counter<=0) {
87     Paso_SharedComponents_free(in->send);
88     MEMFREE(in->send_buffer);
89     Paso_SharedComponents_free(in->recv);
90     MEMFREE(in->recv_buffer);
91     MEMFREE(in->mpi_requests);
92     MEMFREE(in->mpi_stati);
93     Paso_MPIInfo_free(in->mpi_info);
94     MEMFREE(in);
95     #ifdef Paso_TRACE
96     printf("Paso_Coupler_dealloc: system matrix pattern as been deallocated.\n");
97     #endif
98     }
99     }
100     }
101    
102 gross 1362 bool_t Paso_Coupler_bufferIsAllocated(Paso_Coupler* coupler) {
103     return ( (coupler->send_buffer !=NULL) || (coupler->recv_buffer!=NULL) );
104     }
105 ksteube 1313
106     void Paso_Coupler_allocBuffer(Paso_Coupler* coupler,dim_t block_size)
107     {
108     Paso_MPIInfo *mpi_info = coupler->mpi_info;
109 gross 1362 if (Paso_Coupler_bufferIsAllocated(coupler)) {
110 ksteube 1313 Paso_setError(SYSTEM_ERROR,"Paso_Coupler_allocBuffer: coupler are still in use.");
111     return;
112     }
113     coupler->block_size=block_size;
114     if (coupler->mpi_info->size>1) {
115     coupler->send_buffer=MEMALLOC(coupler->send->numSharedComponents * coupler->block_size,double);
116     coupler->recv_buffer=MEMALLOC(coupler->recv->numSharedComponents * coupler->block_size,double);
117     if (Paso_checkPtr(coupler->send_buffer) || Paso_checkPtr(coupler->recv_buffer) ) {
118     TMPMEMFREE(coupler->send_buffer);
119     TMPMEMFREE(coupler->recv_buffer);
120     }
121     }
122     return;
123     }
124     void Paso_Coupler_freeBuffer(Paso_Coupler* coupler)
125     {
126    
127     if (coupler->mpi_info->size>1) {
128     MEMFREE(coupler->send_buffer);
129     MEMFREE(coupler->recv_buffer);
130     }
131     return;
132     }
133    
134     void Paso_Coupler_startCollect(Paso_Coupler* coupler, double* in)
135     {
136     Paso_MPIInfo *mpi_info = coupler->mpi_info;
137     dim_t block_size=coupler->block_size;
138     size_t block_size_size=block_size*sizeof(double);
139     dim_t i,j;
140     if ( mpi_info->size>1) {
141     /* start reveiving input */
142     #pragma omp master
143     {
144     for (i=0; i< coupler->recv->numNeighbors; ++i) {
145     #ifdef PASO_MPI
146     MPI_Irecv(&(coupler->recv_buffer[coupler->recv->offsetInShared[i] * block_size]),
147     (coupler->recv->offsetInShared[i+1]- coupler->recv->offsetInShared[i])*block_size,
148     MPI_DOUBLE,
149     coupler->recv->neighbor[i],
150     mpi_info->msg_tag_counter+coupler->recv->neighbor[i],
151     mpi_info->comm,
152     &(coupler->mpi_requests[i]));
153     #endif
154    
155     }
156     }
157     /* collect values into buffer */
158 gross 1374 #pragma omp parallel for private(i)
159 ksteube 1313 for (i=0; i < coupler->send->numSharedComponents;++i) {
160     memcpy(&(coupler->send_buffer[(block_size)*i]),&(in[ block_size * coupler->send->shared[i]]), block_size_size);
161     }
162     /* send buffer out */
163     #pragma omp master
164     {
165     for (i=0; i< coupler->send->numNeighbors; ++i) {
166     #ifdef PASO_MPI
167     MPI_Issend(&(coupler->send_buffer[coupler->send->offsetInShared[i] * block_size]),
168     (coupler->send->offsetInShared[i+1]- coupler->send->offsetInShared[i])*block_size,
169     MPI_DOUBLE,
170     coupler->send->neighbor[i],
171     mpi_info->msg_tag_counter+mpi_info->rank,
172     mpi_info->comm,
173     &(coupler->mpi_requests[i+ coupler->recv->numNeighbors]));
174     #endif
175     }
176     }
177     mpi_info->msg_tag_counter+mpi_info->size;
178     }
179     }
180    
181     double* Paso_Coupler_finishCollect(Paso_Coupler* coupler)
182     {
183     Paso_MPIInfo *mpi_info = coupler->mpi_info;
184     if ( mpi_info->size>1) {
185     /* wait for receive */
186     #pragma omp master
187     {
188     #ifdef PASO_MPI
189     MPI_Waitall(coupler->recv->numNeighbors+coupler->send->numNeighbors,
190     coupler->mpi_requests,
191     coupler->mpi_stati);
192     #endif
193     }
194     }
195     return coupler->recv_buffer;
196     }
197    
198     Paso_Coupler* Paso_Coupler_unroll(Paso_Coupler* in, index_t block_size) {
199     Paso_SharedComponents *new_send_shcomp=NULL, *new_recv_shcomp=NULL;
200     Paso_Coupler *out=NULL;
201     if (Paso_noError()) {
202     if (block_size>1) {
203     new_send_shcomp=Paso_SharedComponents_alloc(in->send->numNeighbors,
204     in->send->neighbor,
205     in->send->shared,
206     in->send->offsetInShared,
207     block_size,0,in->mpi_info);
208    
209     new_recv_shcomp=Paso_SharedComponents_alloc(in->recv->numNeighbors,
210     in->recv->neighbor,
211     in->recv->shared,
212     in->recv->offsetInShared,
213     block_size,0,in->mpi_info);
214     } else {
215     new_send_shcomp=Paso_SharedComponents_getReference(in->send);
216     new_recv_shcomp=Paso_SharedComponents_getReference(in->recv);
217     }
218     if (Paso_noError()) out=Paso_Coupler_alloc(new_send_shcomp,new_recv_shcomp);
219     }
220     Paso_SharedComponents_free(new_send_shcomp);
221     Paso_SharedComponents_free(new_recv_shcomp);
222     if (Paso_noError()) {
223     return out;
224     } else {
225     Paso_Coupler_free(out);
226     return NULL;
227     }
228    
229     }
230    

  ViewVC Help
Powered by ViewVC 1.1.26