/[escript]/trunk/dudley/src/Mesh_optimizeDOFDistribution.c
ViewVC logotype

Diff of /trunk/dudley/src/Mesh_optimizeDOFDistribution.c

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

temp_trunk_copy/finley/src/Mesh_optimizeDOFDistribution.c revision 1384 by phornby, Fri Jan 11 02:29:38 2008 UTC branches/domexper/dudley/src/Mesh_optimizeDOFDistribution.c revision 3080 by jfenwick, Tue Aug 3 04:28:03 2010 UTC
# Line 1  Line 1 
1    
 /* $Id$ */  
   
2  /*******************************************************  /*******************************************************
3   *  *
4   *           Copyright 2003-2007 by ACceSS MNRF  * Copyright (c) 2003-2010 by University of Queensland
5   *       Copyright 2007 by University of Queensland  * Earth Systems Science Computational Center (ESSCC)
6   *  * http://www.uq.edu.au/esscc
7   *                http://esscc.uq.edu.au  *
8   *        Primary Business: Queensland, Australia  * Primary Business: Queensland, Australia
9   *  Licensed under the Open Software License version 3.0  * Licensed under the Open Software License version 3.0
10   *     http://www.opensource.org/licenses/osl-3.0.php  * http://www.opensource.org/licenses/osl-3.0.php
11   *  *
12   *******************************************************/  *******************************************************/
13    
14    
15  /**************************************************************/  /**************************************************************/
16    
# Line 26  Line 25 
25  #ifdef _OPENMP  #ifdef _OPENMP
26  #include <omp.h>  #include <omp.h>
27  #endif  #endif
28    #ifdef USE_PARMETIS
29    #include "parmetis.h"
30    #endif
31    
32    /**************************************************************
33       Check whether there is any node which has no vertex. In case
34       such node exists, we don't use parmetis since parmetis requires
35       that every node has at least 1 vertex (at line 129 of file
36       "xyzpart.c" in parmetis 3.1.1, variable "nvtxs" would be 0 if
37       any node has no vertex).
38     **************************************************************/
39    #ifdef USE_PARMETIS
40    int Check_Inputs_For_Parmetis(dim_t mpiSize, dim_t rank, dim_t *distribution, MPI_Comm *comm)
41    {
42      dim_t i, len;
43      int ret_val = 1;
44    
45      if (rank == 0){
46        for (i=0; i<mpiSize; i++){
47          len = distribution[i+1] - distribution[i];
48          if (len == 0){
49            ret_val = 0;
50            break;
51          }
52        }
53      }
54      MPI_Bcast(&ret_val, 1, MPI_INTEGER, 0, *comm);
55      if (ret_val == 0)
56        printf("INFO: Parmetis is not used since some nodes have no vertex!\n");
57      return ret_val;
58    }
59    #endif
60    
61    
62    
63  /**************************************************************/  /**************************************************************/
64    
# Line 40  void Finley_Mesh_optimizeDOFDistribution Line 73  void Finley_Mesh_optimizeDOFDistribution
73       Paso_MPI_rank myRank,dest,source,current_rank, rank;       Paso_MPI_rank myRank,dest,source,current_rank, rank;
74       Finley_IndexList* index_list=NULL;       Finley_IndexList* index_list=NULL;
75       float *xyz=NULL;       float *xyz=NULL;
76         int c;
77            
78       #ifdef PASO_MPI       #ifdef PASO_MPI
79       MPI_Status status;       MPI_Status status;
# Line 67  void Finley_Mesh_optimizeDOFDistribution Line 101  void Finley_Mesh_optimizeDOFDistribution
101       newGlobalDOFID=TMPMEMALLOC(len,index_t);       newGlobalDOFID=TMPMEMALLOC(len,index_t);
102       setNewDOFId=TMPMEMALLOC(in->Nodes->numNodes,bool_t);       setNewDOFId=TMPMEMALLOC(in->Nodes->numNodes,bool_t);
103       if (!(Finley_checkPtr(partition) || Finley_checkPtr(xyz) || Finley_checkPtr(partition_count) || Finley_checkPtr(partition_count) || Finley_checkPtr(newGlobalDOFID) || Finley_checkPtr(setNewDOFId))) {       if (!(Finley_checkPtr(partition) || Finley_checkPtr(xyz) || Finley_checkPtr(partition_count) || Finley_checkPtr(partition_count) || Finley_checkPtr(newGlobalDOFID) || Finley_checkPtr(setNewDOFId))) {
104             dim_t *recvbuf=TMPMEMALLOC(mpiSize*mpiSize,dim_t);
105    
106           /* set the coordinates: *?           /* set the coordinates: */
107           /* it is assumed that at least one node on this processor provides a coordinate */           /* it is assumed that at least one node on this processor provides a coordinate */
108           #pragma omp parallel for private(i,j,k)           #pragma omp parallel for private(i,j,k)
109           for (i=0;i<in->Nodes->numNodes;++i) {           for (i=0;i<in->Nodes->numNodes;++i) {
# Line 91  void Finley_Mesh_optimizeDOFDistribution Line 126  void Finley_Mesh_optimizeDOFDistribution
126                }                }
127            /* ksteube build CSR format */            /* ksteube build CSR format */
128                /*  insert contributions from element matrices into colums index index_list: */                /*  insert contributions from element matrices into colums index index_list: */
129                Finley_IndexList_insertElementsWithRowRange(index_list, myFirstVertex, myLastVertex,                Finley_IndexList_insertElementsWithRowRangeNoMainDiagonal(index_list, myFirstVertex, myLastVertex,
130                                                            in->Elements,in->Nodes->globalDegreesOfFreedom,                                                                          in->Elements,in->Nodes->globalDegreesOfFreedom,
131                                                            in->Nodes->globalDegreesOfFreedom);                                                                          in->Nodes->globalDegreesOfFreedom);
132                Finley_IndexList_insertElementsWithRowRange(index_list, myFirstVertex, myLastVertex,                Finley_IndexList_insertElementsWithRowRangeNoMainDiagonal(index_list, myFirstVertex, myLastVertex,
133                                                            in->FaceElements,in->Nodes->globalDegreesOfFreedom,                                                                          in->FaceElements,in->Nodes->globalDegreesOfFreedom,
134                                                            in->Nodes->globalDegreesOfFreedom);                                                                          in->Nodes->globalDegreesOfFreedom);
135                Finley_IndexList_insertElementsWithRowRange(index_list, myFirstVertex, myLastVertex,                Finley_IndexList_insertElementsWithRowRangeNoMainDiagonal(index_list, myFirstVertex, myLastVertex,
136                                                            in->ContactElements,in->Nodes->globalDegreesOfFreedom,                                                                          in->ContactElements,in->Nodes->globalDegreesOfFreedom,
137                                                            in->Nodes->globalDegreesOfFreedom);                                                                          in->Nodes->globalDegreesOfFreedom);
138                Finley_IndexList_insertElementsWithRowRange(index_list, myFirstVertex, myLastVertex,                Finley_IndexList_insertElementsWithRowRangeNoMainDiagonal(index_list, myFirstVertex, myLastVertex,
139                                                            in->Points,in->Nodes->globalDegreesOfFreedom,                                                                          in->Points,in->Nodes->globalDegreesOfFreedom,
140                                                            in->Nodes->globalDegreesOfFreedom);                                                                          in->Nodes->globalDegreesOfFreedom);
141             }             }
142                        
143             /* create the local matrix pattern */             /* create the local matrix pattern */
144             pattern=Finley_IndexList_createPattern(myNumVertices,index_list,0,globalNumVertices,0);             pattern=Finley_IndexList_createPattern(0,myNumVertices,index_list,0,globalNumVertices,0);
145    
146             /* clean up index list */             /* clean up index list */
147             if (index_list!=NULL) {             if (index_list!=NULL) {
# Line 116  void Finley_Mesh_optimizeDOFDistribution Line 151  void Finley_Mesh_optimizeDOFDistribution
151    
152             if (Finley_noError()) {             if (Finley_noError()) {
153    
154  /*  #ifdef USE_PARMETIS
155    
156              if (mpiSize>1 &&
157              Check_Inputs_For_Parmetis(mpiSize, myRank, distribution, &(in->MPIInfo->comm))>0 ) {
158             int i;
159             int wgtflag = 0;
160             int numflag = 0;   /* pattern->ptr is C style: starting from 0 instead of 1 */
161             int ncon = 1;
162             int edgecut;
163             int options[2];
164             float *tpwgts = TMPMEMALLOC(ncon*mpiSize,float);
165             float *ubvec = TMPMEMALLOC(ncon,float);
166             for (i=0; i<ncon*mpiSize; i++) tpwgts[i] = 1.0/(float)mpiSize;
167             for (i=0; i<ncon; i++) ubvec[i] = 1.05;
168             options[0] = 3;
169             options[1] = 15;
170                 ParMETIS_V3_PartGeomKway(distribution,
171                                              pattern->ptr,
172                                              pattern->index,
173                                              NULL,
174                                              NULL,
175                                              &wgtflag,
176                                              &numflag,
177                                              &dim,
178                                              xyz,
179                                              &ncon,
180                                              &mpiSize,
181                                              tpwgts,
182                                              ubvec,
183                                              options,
184                                              &edgecut,
185                                              partition,                /* new CPU ownership of elements */
186                                              &(in->MPIInfo->comm));
187             /* printf("ParMETIS number of edges cut by partitioning per processor: %d\n", edgecut/MAX(in->MPIInfo->size,1)); */
188                     TMPMEMFREE(ubvec);
189                     TMPMEMFREE(tpwgts);
190              } else {
191                     for (i=0;i<myNumVertices;++i) partition[i]=0;      /* CPU 0 owns it */
192              }
193    #else
194                  for (i=0;i<myNumVertices;++i) partition[i]=myRank;    /* CPU 0 owns it */
195    #endif
196    
         ParMETIS_V3_PartGeomKway(distribution,  
                                  pattern->ptr,  
                                  pattern->index,  
                                  idxtype *vwgt, +  
                                  idxtype *adjwgt, +  
                                  int *wgtflag, +  
                                  int *numflag, +  
                                  dim,  
                                  xyz,  
                                  int *ncon, +  
                                  mpiSize,  
                                  float *tpwgts, +  
                                  float *ubvec, +  
                                  int *options, +  
                                  int *edgecut, +  
                                  partition,  
                                  in->MPIInfo->comm);  
 */  
                for (i=0;i<myNumVertices;++i) partition[i]=myRank; /* remove */  
197             }             }
198    
199             Paso_Pattern_free(pattern);             Paso_Pattern_free(pattern);
# Line 156  void Finley_Mesh_optimizeDOFDistribution Line 213  void Finley_Mesh_optimizeDOFDistribution
213                 THREAD_MEMFREE(loc_partition_count);                 THREAD_MEMFREE(loc_partition_count);
214             }             }
215             #ifdef PASO_MPI             #ifdef PASO_MPI
216                MPI_Allreduce( new_distribution, partition_count, mpiSize, MPI_INT, MPI_SUM, in->MPIInfo->comm );            /* recvbuf will be the concatenation of each CPU's contribution to new_distribution */
217              MPI_Allgather(new_distribution, mpiSize, MPI_INT, recvbuf, mpiSize, MPI_INT, in->MPIInfo->comm);
218             #else             #else
219                 for (i=0;i<mpiSize;++i) partition_count[i]=new_distribution[i];                 for (i=0;i<mpiSize;++i) recvbuf[i]=new_distribution[i];
220             #endif             #endif
221             new_distribution[0]=0;             new_distribution[0]=0;
222             for (i=0;i<mpiSize;++i) {         for (rank=0; rank<mpiSize;rank++) {
223                 new_distribution[i+1]=new_distribution[i]+partition_count[i];            c=0;
224                 partition_count[i]=0;                for (i=0;i<myRank;++i) c+=recvbuf[rank+mpiSize*i];
225             }                for (i=0;i<myNumVertices;++i) {
226             for (i=0;i<myNumVertices;++i) {                   if (rank==partition[i]) {
227                rank=partition[i];                      newGlobalDOFID[i]=new_distribution[rank]+c;
228                newGlobalDOFID[i]=new_distribution[rank]+partition_count[rank];                      c++;
229                partition_count[rank]++;               }
230                  }
231                  for (i=myRank+1;i<mpiSize;++i) c+=recvbuf[rank+mpiSize*i];
232                  new_distribution[rank+1]=new_distribution[rank]+c;
233             }             }
234               TMPMEMFREE(recvbuf);
235    
236             /* now the overlap needs to be created by sending the partition around*/             /* now the overlap needs to be created by sending the partition around*/
237    
238             dest=Paso_MPIInfo_mod(mpiSize, myRank + 1);             dest=Paso_MPIInfo_mod(mpiSize, myRank + 1);
# Line 203  void Finley_Mesh_optimizeDOFDistribution Line 266  void Finley_Mesh_optimizeDOFDistribution
266                }                }
267             }             }
268             for (i=0;i<mpiSize+1;++i) distribution[i]=new_distribution[i];             for (i=0;i<mpiSize+1;++i) distribution[i]=new_distribution[i];
   
             
269           }           }
270           TMPMEMFREE(index_list);           TMPMEMFREE(index_list);
271       }       }

Legend:
Removed from v.1384  
changed lines
  Added in v.3080

  ViewVC Help
Powered by ViewVC 1.1.26