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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1413 by gross, Sun Feb 10 08:45:37 2008 UTC revision 1552 by gross, Thu May 8 08:52:41 2008 UTC
# Line 1  Line 1 
   
1  /* $Id: Coupler.c 1306 2007-09-18 05:51:09Z ksteube $ */  /* $Id: Coupler.c 1306 2007-09-18 05:51:09Z ksteube $ */
2    
3  /*******************************************************  /*******************************************************
# Line 11  Line 10 
10   *  Licensed under the Open Software License version 3.0   *  Licensed under the Open Software License version 3.0
11   *     http://www.opensource.org/licenses/osl-3.0.php   *     http://www.opensource.org/licenses/osl-3.0.php
12   *   *
13   *******************************************************/   **************************************************************
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    
24  /* Paso: Coupler organizes the coupling with in a pattern/matrix   */  #include "Coupler.h"
 /*       across processors                                         */  
25    
26  /**************************************************************/  /*************************************************************
27     *
28  /* Author: gross@access.edu.au */   * allocates a Connector
29     *
30     **************************************************************/
31    
32  /**************************************************************/  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      if (!Paso_checkPtr(out)) {
43          out->send=Paso_SharedComponents_getReference(send);
44          out->recv= Paso_SharedComponents_getReference(recv);
45          out->mpi_info = Paso_MPIInfo_getReference(send->mpi_info);
46          out->reference_counter=1;
47      }
48      if (Paso_noError()) {
49         return out;
50      } else {
51         Paso_Connector_free(out);
52         return NULL;
53      }
54    }
55    
56  #include "Coupler.h"  /* returns a reference to Connector */
57    
58  /**************************************************************/  Paso_Connector* Paso_Connector_getReference(Paso_Connector* in) {
59         if (in!=NULL) {
60            ++(in->reference_counter);
61         }
62         return in;
63    }
64      
65    /* deallocates a Connector: */
66    
67  /* allocates a Coupler  */  void Paso_Connector_free(Paso_Connector* in) {
68      if (in!=NULL) {
69         in->reference_counter--;
70         if (in->reference_counter<=0) {
71            Paso_SharedComponents_free(in->send);
72            Paso_SharedComponents_free(in->recv);
73            Paso_MPIInfo_free(in->mpi_info);
74            #ifdef Paso_TRACE
75            printf("Paso_Coupler_dealloc: system matrix pattern as been deallocated.\n");
76            #endif
77         }
78       }
79    }
80    
81    Paso_Connector* Paso_Connector_copy(Paso_Connector* in) {
82      return Paso_Connector_unroll(in,1);
83    }
84    
85  /**************************************************************/  Paso_Connector* Paso_Connector_unroll(Paso_Connector* in, index_t block_size) {
86         Paso_SharedComponents *new_send_shcomp=NULL, *new_recv_shcomp=NULL;
87         Paso_Connector *out=NULL;
88         if (Paso_noError()) {
89            if (block_size>1) {
90                new_send_shcomp=Paso_SharedComponents_alloc(in->send->numNeighbors,
91                                                            in->send->neighbor,
92                                                            in->send->shared,
93                                                            in->send->offsetInShared,
94                                                            block_size,0,in->mpi_info);
95    
96                new_recv_shcomp=Paso_SharedComponents_alloc(in->recv->numNeighbors,
97                                                            in->recv->neighbor,
98                                                            in->recv->shared,
99                                                            in->recv->offsetInShared,
100                                                            block_size,0,in->mpi_info);
101            } else {
102                new_send_shcomp=Paso_SharedComponents_getReference(in->send);
103                new_recv_shcomp=Paso_SharedComponents_getReference(in->recv);
104            }
105            if (Paso_noError()) out=Paso_Connector_alloc(new_send_shcomp,new_recv_shcomp);
106         }
107         Paso_SharedComponents_free(new_send_shcomp);
108         Paso_SharedComponents_free(new_recv_shcomp);
109         if (Paso_noError()) {
110              return out;
111         } else {
112              Paso_Connector_free(out);
113              return NULL;
114         }
115    }
116    /*************************************************************
117     *
118     * allocates a Connector
119     *
120     **************************************************************/
121    
122  Paso_Coupler* Paso_Coupler_alloc(Paso_SharedComponents* send,  Paso_Coupler* Paso_Coupler_alloc(Paso_Connector* connector, dim_t block_size)
                                  Paso_SharedComponents* recv)  
123  {  {
124      Paso_MPIInfo *mpi_info = connector->mpi_info;  
125    Paso_Coupler*out=NULL;    Paso_Coupler*out=NULL;
126    Paso_resetError();    Paso_resetError();
127    out=MEMALLOC(1,Paso_Coupler);    out=MEMALLOC(1,Paso_Coupler);
   if ( send->mpi_info != recv->mpi_info ) {  
      Paso_setError(SYSTEM_ERROR,"Paso_Coupler_alloc: send and recv mpi communicator don't match.");  
      return NULL;  
   }  
128    if (!Paso_checkPtr(out)) {    if (!Paso_checkPtr(out)) {
129        out->send=Paso_SharedComponents_getReference(send);        out->block_size=block_size;
130          out->connector=Paso_Connector_getReference(connector);
131        out->send_buffer=NULL;        out->send_buffer=NULL;
       out->recv= Paso_SharedComponents_getReference(recv);  
132        out->recv_buffer=NULL;        out->recv_buffer=NULL;
133        out->mpi_requests=NULL;        out->mpi_requests=NULL;
134        out->mpi_stati=NULL;        out->mpi_stati=NULL;
135        out->mpi_info = Paso_MPIInfo_getReference(send->mpi_info);        out->mpi_info = Paso_MPIInfo_getReference(mpi_info);
136        out->reference_counter=1;        out->reference_counter=1;
137                
138        #ifdef PASO_MPI        #ifdef PASO_MPI
139           out->mpi_requests=MEMALLOC(send->numNeighbors+recv->numNeighbors,MPI_Request);           out->mpi_requests=MEMALLOC(connector->send->numNeighbors+connector->recv->numNeighbors,MPI_Request);
140           out->mpi_stati=MEMALLOC(send->numNeighbors+recv->numNeighbors,MPI_Status);           out->mpi_stati=MEMALLOC(connector->send->numNeighbors+connector->recv->numNeighbors,MPI_Status);
141           Paso_checkPtr(out->mpi_requests);           Paso_checkPtr(out->mpi_requests);
142           Paso_checkPtr(out->mpi_stati);           Paso_checkPtr(out->mpi_stati);
143        #endif        #endif
144          if (mpi_info->size>1) {
145            out->send_buffer=MEMALLOC(connector->send->numSharedComponents * block_size,double);
146            out->recv_buffer=MEMALLOC(connector->recv->numSharedComponents * block_size,double);
147            Paso_checkPtr(out->send_buffer);
148            Paso_checkPtr(out->recv_buffer);
149          }
150    }    }
151    if (Paso_noError()) {    if (Paso_noError()) {
152       return out;       return out;
# Line 69  Paso_Coupler* Paso_Coupler_alloc(Paso_Sh Line 156  Paso_Coupler* Paso_Coupler_alloc(Paso_Sh
156    }    }
157  }  }
158    
159  /* returns a reference to in */  /* returns a reference to Coupler */
160    
161  Paso_Coupler* Paso_Coupler_getReference(Paso_Coupler* in) {  Paso_Coupler* Paso_Coupler_getReference(Paso_Coupler* in) {
162       if (in!=NULL) {       if (in!=NULL) {
# Line 84  void Paso_Coupler_free(Paso_Coupler* in) Line 171  void Paso_Coupler_free(Paso_Coupler* in)
171    if (in!=NULL) {    if (in!=NULL) {
172       in->reference_counter--;       in->reference_counter--;
173       if (in->reference_counter<=0) {       if (in->reference_counter<=0) {
174          Paso_SharedComponents_free(in->send);          Paso_Connector_free(in->connector);
175          MEMFREE(in->send_buffer);          MEMFREE(in->send_buffer);
         Paso_SharedComponents_free(in->recv);  
176          MEMFREE(in->recv_buffer);          MEMFREE(in->recv_buffer);
177          MEMFREE(in->mpi_requests);          MEMFREE(in->mpi_requests);
178          MEMFREE(in->mpi_stati);          MEMFREE(in->mpi_stati);
# Line 99  void Paso_Coupler_free(Paso_Coupler* in) Line 185  void Paso_Coupler_free(Paso_Coupler* in)
185     }     }
186  }  }
187    
 bool_t Paso_Coupler_bufferIsAllocated(Paso_Coupler* coupler) {  
   return ( (coupler->send_buffer !=NULL) || (coupler->recv_buffer!=NULL) );  
 }  
   
 void Paso_Coupler_allocBuffer(Paso_Coupler* coupler,dim_t block_size)  
 {  
     Paso_MPIInfo *mpi_info = coupler->mpi_info;    
     if (Paso_Coupler_bufferIsAllocated(coupler))  {  
         Paso_setError(SYSTEM_ERROR,"Paso_Coupler_allocBuffer: coupler are still in use.");  
         return;  
     }  
     coupler->block_size=block_size;  
     if (coupler->mpi_info->size>1) {  
         coupler->send_buffer=MEMALLOC(coupler->send->numSharedComponents * coupler->block_size,double);  
         coupler->recv_buffer=MEMALLOC(coupler->recv->numSharedComponents * coupler->block_size,double);  
         if (Paso_checkPtr(coupler->send_buffer) || Paso_checkPtr(coupler->recv_buffer) ) {  
               TMPMEMFREE(coupler->send_buffer);  
               TMPMEMFREE(coupler->recv_buffer);  
         }  
     }  
     return;  
 }  
 void Paso_Coupler_freeBuffer(Paso_Coupler* coupler)  
 {  
   
   if (coupler->mpi_info->size>1) {  
      MEMFREE(coupler->send_buffer);  
      MEMFREE(coupler->recv_buffer);  
   }  
   return;  
 }  
188    
189  void Paso_Coupler_startCollect(Paso_Coupler* coupler,const double* in)  void Paso_Coupler_startCollect(Paso_Coupler* coupler,const double* in)
190  {  {
# Line 141  void Paso_Coupler_startCollect(Paso_Coup Line 196  void Paso_Coupler_startCollect(Paso_Coup
196       /* start reveiving input */       /* start reveiving input */
197       #pragma omp master       #pragma omp master
198       {       {
199          for (i=0; i< coupler->recv->numNeighbors; ++i) {          for (i=0; i< coupler->connector->recv->numNeighbors; ++i) {
200              #ifdef PASO_MPI              #ifdef PASO_MPI
201              MPI_Irecv(&(coupler->recv_buffer[coupler->recv->offsetInShared[i] *  block_size]),              MPI_Irecv(&(coupler->recv_buffer[coupler->connector->recv->offsetInShared[i] *  block_size]),
202                        (coupler->recv->offsetInShared[i+1]- coupler->recv->offsetInShared[i])*block_size,                        (coupler->connector->recv->offsetInShared[i+1]- coupler->connector->recv->offsetInShared[i])*block_size,
203                        MPI_DOUBLE,                        MPI_DOUBLE,
204                        coupler->recv->neighbor[i],                        coupler->connector->recv->neighbor[i],
205                        mpi_info->msg_tag_counter+coupler->recv->neighbor[i],                        mpi_info->msg_tag_counter+coupler->recv->neighbor[i],
206                        mpi_info->comm,                        mpi_info->comm,
207                        &(coupler->mpi_requests[i]));                        &(coupler->mpi_requests[i]));
# Line 156  void Paso_Coupler_startCollect(Paso_Coup Line 211  void Paso_Coupler_startCollect(Paso_Coup
211       }       }
212       /* collect values into buffer */       /* collect values into buffer */
213       #pragma omp parallel for private(i)       #pragma omp parallel for private(i)
214       for (i=0; i < coupler->send->numSharedComponents;++i) {       for (i=0; i < coupler->connector->send->numSharedComponents;++i) {
215          memcpy(&(coupler->send_buffer[(block_size)*i]),&(in[ block_size * coupler->send->shared[i]]), block_size_size);          memcpy(&(coupler->send_buffer[(block_size)*i]),&(in[ block_size * coupler->connector->send->shared[i]]), block_size_size);
216       }       }
217       /* send buffer out */       /* send buffer out */
218       #pragma omp master       #pragma omp master
219       {       {
220          for (i=0; i< coupler->send->numNeighbors; ++i) {          for (i=0; i< coupler->connector->send->numNeighbors; ++i) {
221               #ifdef PASO_MPI               #ifdef PASO_MPI
222               MPI_Issend(&(coupler->send_buffer[coupler->send->offsetInShared[i] *  block_size]),               MPI_Issend(&(coupler->send_buffer[coupler->send->offsetInShared[i] *  block_size]),
223                          (coupler->send->offsetInShared[i+1]- coupler->send->offsetInShared[i])*block_size,                          (coupler->connector->send->offsetInShared[i+1]- coupler->connector->send->offsetInShared[i])*block_size,
224                          MPI_DOUBLE,                          MPI_DOUBLE,
225                          coupler->send->neighbor[i],                          coupler->connector->send->neighbor[i],
226                          mpi_info->msg_tag_counter+mpi_info->rank,                          mpi_info->msg_tag_counter+mpi_info->rank,
227                          mpi_info->comm,                          mpi_info->comm,
228                          &(coupler->mpi_requests[i+ coupler->recv->numNeighbors]));                          &(coupler->mpi_requests[i+ coupler->recv->numNeighbors]));
# Line 186  double* Paso_Coupler_finishCollect(Paso_ Line 241  double* Paso_Coupler_finishCollect(Paso_
241       #pragma omp master       #pragma omp master
242       {       {
243          #ifdef PASO_MPI          #ifdef PASO_MPI
244          MPI_Waitall(coupler->recv->numNeighbors+coupler->send->numNeighbors,          MPI_Waitall(coupler->connector->recv->numNeighbors+coupler->connector->send->numNeighbors,
245                      coupler->mpi_requests,                      coupler->mpi_requests,
246                      coupler->mpi_stati);                      coupler->mpi_stati);
247          #endif          #endif
# Line 194  double* Paso_Coupler_finishCollect(Paso_ Line 249  double* Paso_Coupler_finishCollect(Paso_
249    }    }
250    return coupler->recv_buffer;    return coupler->recv_buffer;
251  }  }
   
 Paso_Coupler* Paso_Coupler_unroll(Paso_Coupler* in, index_t block_size) {  
      Paso_SharedComponents *new_send_shcomp=NULL, *new_recv_shcomp=NULL;  
      Paso_Coupler *out=NULL;  
      if (Paso_noError()) {  
         if (block_size>1) {  
             new_send_shcomp=Paso_SharedComponents_alloc(in->send->numNeighbors,  
                                                         in->send->neighbor,  
                                                         in->send->shared,  
                                                         in->send->offsetInShared,  
                                                         block_size,0,in->mpi_info);  
   
             new_recv_shcomp=Paso_SharedComponents_alloc(in->recv->numNeighbors,  
                                                         in->recv->neighbor,  
                                                         in->recv->shared,  
                                                         in->recv->offsetInShared,  
                                                         block_size,0,in->mpi_info);  
         } else {  
             new_send_shcomp=Paso_SharedComponents_getReference(in->send);  
             new_recv_shcomp=Paso_SharedComponents_getReference(in->recv);  
         }  
         if (Paso_noError()) out=Paso_Coupler_alloc(new_send_shcomp,new_recv_shcomp);  
      }  
      Paso_SharedComponents_free(new_send_shcomp);  
      Paso_SharedComponents_free(new_recv_shcomp);  
      if (Paso_noError()) {  
           return out;  
      } else {  
           Paso_Coupler_free(out);  
           return NULL;  
      }  
   
 }  
   

Legend:
Removed from v.1413  
changed lines
  Added in v.1552

  ViewVC Help
Powered by ViewVC 1.1.26