ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/mpi_implementation/mpiSimulation.cpp
Revision: 245
Committed: Fri Jan 24 21:25:08 2003 UTC (21 years, 5 months ago) by mmeineke
File size: 4329 byte(s)
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 chuckv 195 i#include <cstdlib>
2 chuckv 194 #include <cstring>
3 chuckv 132 #include <mpi.h>
4 chuckv 122
5 chuckv 194 #include "mpiSimulation.hpp"
6     #include "simError.h"
7    
8 mmeineke 245 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 chuckv 215 mpiSimulation* mpiSim;
18 chuckv 194
19     mpiSimulation::mpiSimulation(SimInfo* the_entryPlug)
20 chuckv 122 {
21 chuckv 195 entryPlug = the_entryPlug;
22 chuckv 215 mpiPlug = new MpiSimData;
23 chuckv 195
24 chuckv 215 mpiPlug->numberProcessors = MPI::COMM_WORLD.Get_size();
25     mpiPlug->myNode = worldRank;
26 chuckv 195
27 mmeineke 245 mpiSim = this;
28     wrapMe();
29 chuckv 215
30 chuckv 122 }
31    
32    
33 chuckv 194 mpiSimulation::~mpiSimulation(){
34 chuckv 195
35 chuckv 215 delete mpiPlug;
36     // perhaps we should let fortran know the party is over.
37 chuckv 195
38 chuckv 194 }
39    
40 mmeineke 245 void mpiSimulation::wrapMe(){
41 chuckv 194
42 mmeineke 245 wrapsimparallelmod_( wrapSimParallel );
43     }
44    
45    
46    
47 mmeineke 200 void mpiSimulation::divideLabor( void ){
48    
49     int nComponents;
50     MoleculeStamp** compStamps;
51     int* componentsNmol;
52    
53 chuckv 195 double numerator;
54     double denominator;
55     double precast;
56    
57     int nTarget;
58     int molIndex, atomIndex, compIndex, compStart;
59     int done;
60 chuckv 196 int nLocal, molLocal;
61 chuckv 195 int i;
62     int smallDiff, bigDiff;
63    
64     int testSum;
65    
66 mmeineke 200 nComponents = entryPlug->nComponents;
67     compStamps = entryPlug->compStamps;
68     componentsNmol = entryPlug->componentsNmol;
69    
70 chuckv 215 mpiPlug->nAtomsGlobal = entryPlug->n_atoms;
71     mpiPlug->nBondsGlobal = entryPlug->n_bonds;
72     mpiPlug->nBendsGlobal = entryPlug->n_bends;
73     mpiPlug->nTorsionsGlobal = entryPlug->n_torsions;
74     mpiPlug->nSRIGlobal = entryPlug->n_SRI;
75     mpiPlug->nMolGlobal = entryPlug->n_nmol;
76 mmeineke 202
77 chuckv 195 numerator = (double) entryPlug->n_atoms;
78 chuckv 215 denominator = (double) mpiPlug->numberProcessors;
79 chuckv 195 precast = numerator / denominator;
80     nTarget = (int)( precast + 0.5 );
81    
82     molIndex = 0;
83     atomIndex = 0;
84     compIndex = 0;
85     compStart = 0;
86 chuckv 215 for( i=0; i<(mpiPlug->numberProcessors-1); i++){
87 chuckv 195
88     done = 0;
89     nLocal = 0;
90 chuckv 196 molLocal = 0;
91 chuckv 195
92 chuckv 215 if( i == mpiPlug->myNode ){
93     mpiPlug->myMolStart = molIndex;
94     mpiPlug->myAtomStart = atomIndex;
95 chuckv 195 }
96    
97     while( !done ){
98    
99     if( (molIndex-compStart) >= componentsNmol[compIndex] ){
100     compStart = molIndex;
101     compIndex++;
102     continue;
103     }
104    
105     nLocal += compStamps[compIndex]->getNAtoms();
106     atomIndex += compStamps[compIndex]->getNAtoms();
107     molIndex++;
108 chuckv 196 molLocal++;
109 chuckv 195
110     if ( nLocal == nTarget ) done = 1;
111    
112     else if( nLocal < nTarget ){
113     smallDiff = nTarget - nLocal;
114     }
115     else if( nLocal > nTarget ){
116     bigDiff = nLocal - nTarget;
117    
118     if( bigDiff < smallDiff ) done = 1;
119     else{
120     molIndex--;
121 chuckv 196 molLocal--;
122 chuckv 195 atomIndex -= compStamps[compIndex]->getNAtoms();
123     nLocal -= compStamps[compIndex]->getNAtoms();
124     done = 1;
125     }
126     }
127     }
128    
129 chuckv 215 if( i == mpiPlug->myNode ){
130     mpiPlug->myMolEnd = (molIndex - 1);
131     mpiPlug->myAtomEnd = (atomIndex - 1);
132     mpiPlug->myNlocal = nLocal;
133     mpiPlug->myMol = molLocal;
134 chuckv 195 }
135    
136     numerator = (double)( entryPlug->n_atoms - atomIndex );
137 chuckv 215 denominator = (double)( mpiPlug->numberProcessors - (i+1) );
138 chuckv 195 precast = numerator / denominator;
139     nTarget = (int)( precast + 0.5 );
140     }
141    
142 chuckv 215 if( mpiPlug->myNode == mpiPlug->numberProcessors-1 ){
143     mpiPlug->myMolStart = molIndex;
144     mpiPlug->myAtomStart = atomIndex;
145 chuckv 195
146     nLocal = 0;
147 chuckv 196 molLocal = 0;
148 chuckv 195 while( compIndex < nComponents ){
149    
150     if( (molIndex-compStart) >= componentsNmol[compIndex] ){
151     compStart = molIndex;
152     compIndex++;
153     continue;
154     }
155    
156     nLocal += compStamps[compIndex]->getNAtoms();
157     atomIndex += compStamps[compIndex]->getNAtoms();
158     molIndex++;
159 chuckv 196 molLocal++;
160 chuckv 195 }
161    
162 chuckv 215 mpiPlug->myMolEnd = (molIndex - 1);
163     mpiPlug->myAtomEnd = (atomIndex - 1);
164     mpiPlug->myNlocal = nLocal;
165     mpiPlug->myMol = molLocal;
166 chuckv 195 }
167    
168    
169 chuckv 215 MPI_Allreduce( &nLocal, &testSum, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
170 chuckv 195
171 chuckv 215 if( mpiPlug->myNode == 0 ){
172 chuckv 195 if( testSum != entryPlug->n_atoms ){
173     sprintf( painCave.errMsg,
174     "The summ of all nLocals, %d, did not equal the total number of atoms, %d.\n",
175     testSum, entryPlug->n_atoms );
176     painCave.isFatal = 1;
177     simError();
178     }
179     }
180    
181     sprintf( checkPointMsg,
182     "Successfully divided the molecules among the processors.\n" );
183     MPIcheckPoint();
184 chuckv 196
185     // lets create the identity array
186 chuckv 195 }
187 mmeineke 245
188    
189     void wrapSimParallel((void (*fSub)(mpiSimData*, int*, int*, int*))){
190    
191     mpiSim->setInternal( fSub );
192     }