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 132 by chuckv, Wed Oct 9 22:56:09 2002 UTC vs.
Revision 253 by chuckv, Thu Jan 30 15:20:21 2003 UTC

# Line 1 | Line 1
1 + #include <cstdlib>
2 + #include <cstring>
3   #include <mpi.h>
2 #include <mpiSimulation.hpp>
4  
5 < mpiSimulation::mpiSimulation()
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 <  int mpi_error;
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  
30 <  MPI::Init();
30 > }
31  
32 <  numberProcessors = MPI::Comm::Get_size();
33 <  myNode = MPI::Comm::Get_rank();
34 <  MPI::Get_processor_name(processorName,&processorNameLen);
32 >
33 > mpiSimulation::~mpiSimulation(){
34 >  
35 >  delete mpiPlug;
36 >  // perhaps we should let fortran know the party is over.
37 >  
38   }
39  
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