ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/mpi_implementation/mpiSimulation.cpp
(Generate patch)

Comparing trunk/mdtools/mpi_implementation/mpiSimulation.cpp (file contents):
Revision 194 by chuckv, Wed Dec 4 21:19:38 2002 UTC vs.
Revision 253 by chuckv, Thu Jan 30 15:20:21 2003 UTC

# Line 5 | Line 5
5   #include "mpiSimulation.hpp"
6   #include "simError.h"
7  
8 + extern "C"{
9 +  void wrapsimparallelmod_( void (*wrapFunction)(void (*fSub)( mpiSimData*,
10 +                                                               int*, int*,
11 +                                                               int*)));
12 + }
13  
14 + void wrapSimParallel(void (*fSub)(mpiSimData*, int*, int*, int*));
15  
16 +
17 + mpiSimulation* mpiSim;
18 +
19   mpiSimulation::mpiSimulation(SimInfo* the_entryPlug)
20   {
21 <  entryPlug = the_entryPlug
21 >  entryPlug = the_entryPlug;
22 >  mpiPlug = new mpiSimData;
23 >  
24 >  mpiPlug->numberProcessors = MPI::COMM_WORLD.Get_size();
25 >  mpiPlug->myNode = worldRank;
26 >  
27 >  mpiSim = this;
28 >  wrapMe();
29  
14  numberProcessors = MPI::COMM_WORLD.Get_size();
15  myNode = worldRank;
16
17  // let the simulkation know were there.
18  entryPlug->mpiSim = this;
30   }
31  
32  
33   mpiSimulation::~mpiSimulation(){
34 +  
35 +  delete mpiPlug;
36 +  // perhaps we should let fortran know the party is over.
37 +  
38 + }
39  
40 <  // empty for now
40 > void mpiSimulation::wrapMe(){
41  
42 +  wrapsimparallelmod_( wrapSimParallel );
43   }
44  
45  
46 +
47 + int* mpiSimulation::divideLabor( void ){
48 +
49 +  int* globalIndex;
50 +
51 +  int nComponents;
52 +  MoleculeStamp** compStamps;
53 +  int* componentsNmol;
54 +
55 +  double numerator;
56 +  double denominator;
57 +  double precast;
58 +
59 +  int nTarget;
60 +  int molIndex, atomIndex, compIndex, compStart;
61 +  int done;
62 +  int nLocal, molLocal;
63 +  int i, index;
64 +  int smallDiff, bigDiff;
65 +
66 +  int testSum;
67 +
68 +  nComponents = entryPlug->nComponents;
69 +  compStamps = entryPlug->compStamps;
70 +  componentsNmol = entryPlug->componentsNmol;
71 +
72 +  mpiPlug->nAtomsGlobal = entryPlug->n_atoms;
73 +  mpiPlug->nBondsGlobal = entryPlug->n_bonds;
74 +  mpiPlug->nBendsGlobal = entryPlug->n_bends;
75 +  mpiPlug->nTorsionsGlobal = entryPlug->n_torsions;
76 +  mpiPlug->nSRIGlobal = entryPlug->n_SRI;
77 +  mpiPlug->nMolGlobal = entryPlug->n_mol;
78 +
79 +  numerator = (double) entryPlug->n_atoms;
80 +  denominator = (double) mpiPlug->numberProcessors;
81 +  precast = numerator / denominator;
82 +  nTarget = (int)( precast + 0.5 );
83 +  
84 +  molIndex = 0;
85 +  atomIndex = 0;
86 +  compIndex = 0;
87 +  compStart = 0;
88 +  for( i=0; i<(mpiPlug->numberProcessors-1); i++){
89 +    
90 +    done = 0;
91 +    nLocal = 0;
92 +    molLocal = 0;
93 +
94 +    if( i == mpiPlug->myNode ){
95 +      mpiPlug->myMolStart = molIndex;
96 +      mpiPlug->myAtomStart = atomIndex;
97 +    }
98 +    
99 +    while( !done ){
100 +      
101 +      if( (molIndex-compStart) >= componentsNmol[compIndex] ){
102 +        compStart = molIndex;
103 +        compIndex++;
104 +        continue;
105 +      }
106 +
107 +      nLocal += compStamps[compIndex]->getNAtoms();
108 +      atomIndex += compStamps[compIndex]->getNAtoms();
109 +      molIndex++;
110 +      molLocal++;
111 +      
112 +      if ( nLocal == nTarget ) done = 1;
113 +      
114 +      else if( nLocal < nTarget ){
115 +        smallDiff = nTarget - nLocal;
116 +      }
117 +      else if( nLocal > nTarget ){
118 +        bigDiff = nLocal - nTarget;
119 +        
120 +        if( bigDiff < smallDiff ) done = 1;
121 +        else{
122 +          molIndex--;
123 +          molLocal--;
124 +          atomIndex -= compStamps[compIndex]->getNAtoms();
125 +          nLocal -= compStamps[compIndex]->getNAtoms();
126 +          done = 1;
127 +        }
128 +      }
129 +    }
130 +    
131 +    if( i == mpiPlug->myNode ){
132 +      mpiPlug->myMolEnd = (molIndex - 1);
133 +      mpiPlug->myAtomEnd = (atomIndex - 1);
134 +      mpiPlug->myNlocal = nLocal;
135 +      mpiPlug->myMol = molLocal;
136 +    }
137 +    
138 +    numerator = (double)( entryPlug->n_atoms - atomIndex );
139 +    denominator = (double)( mpiPlug->numberProcessors - (i+1) );
140 +    precast = numerator / denominator;
141 +    nTarget = (int)( precast + 0.5 );
142 +  }
143 +  
144 +  if( mpiPlug->myNode == mpiPlug->numberProcessors-1 ){
145 +      mpiPlug->myMolStart = molIndex;
146 +      mpiPlug->myAtomStart = atomIndex;
147 +
148 +      nLocal = 0;
149 +      molLocal = 0;
150 +      while( compIndex < nComponents ){
151 +        
152 +        if( (molIndex-compStart) >= componentsNmol[compIndex] ){
153 +          compStart = molIndex;
154 +          compIndex++;
155 +          continue;
156 +        }
157 +
158 +        nLocal += compStamps[compIndex]->getNAtoms();
159 +        atomIndex += compStamps[compIndex]->getNAtoms();
160 +        molIndex++;
161 +        molLocal++;
162 +      }
163 +      
164 +      mpiPlug->myMolEnd = (molIndex - 1);
165 +      mpiPlug->myAtomEnd = (atomIndex - 1);
166 +      mpiPlug->myNlocal = nLocal;  
167 +      mpiPlug->myMol = molLocal;
168 +  }
169 +
170 +
171 +  MPI_Allreduce( &nLocal, &testSum, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
172 +  
173 +  if( mpiPlug->myNode == 0 ){
174 +    if( testSum != entryPlug->n_atoms ){
175 +      sprintf( painCave.errMsg,
176 +               "The summ of all nLocals, %d, did not equal the total number of atoms, %d.\n",
177 +               testSum, entryPlug->n_atoms );
178 +      painCave.isFatal = 1;
179 +      simError();
180 +    }
181 +  }
182 +
183 +  sprintf( checkPointMsg,
184 +           "Successfully divided the molecules among the processors.\n" );
185 +  MPIcheckPoint();
186 +
187 +  // lets create the identity array
188 +
189 +  globalIndex = new int[mpiPlug->myNlocal];
190 +  index = mpiPlug->myAtomStart;
191 +  for( i=0; i<mpiPlug->myNlocal; i++){
192 +    globalIndex[i] = index;
193 +    index++;
194 +  }
195 +
196 +  return globalIndex;
197 + }
198 +
199 +
200 + void wrapSimParallel(void (*fSub)(mpiSimData*, int*, int*, int*)){
201 +  
202 +  mpiSim->setInternal( fSub );
203 + }
204 +
205 +
206 + void mpiSimulation::mpiRefresh( void ){
207 +
208 +  int isError, i;
209 +  int *globalIndex = new int[mpiPlug->myNlocal];
210 +
211 +  for(i=0; i<mpiPlug->myNlocal; i++) globalIndex[i] = entryPlug->atoms[i]->getGlobalIndex();
212 +
213 +  
214 +  isError = 0;
215 +  setFsimParallel( mpiPlug, &(entryPlug->n_atoms), globalIndex, &isError );
216 +  if( isError ){
217 +
218 +    sprintf( painCave.errMsg,
219 +             "mpiRefresh errror: fortran didn't like something we gave it.\n" );
220 +    painCave.isFatal = 1;
221 +    simError();
222 +  }
223 +
224 +  delete[] globalIndex;
225 +
226 +  sprintf( checkPointMsg,
227 +           " mpiRefresh successful.\n" );
228 +  MPIcheckPoint();
229 + }
230 +  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines