00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #ifndef _SPMDI_H_
00053 #define _SPMDI_H_
00054
00055
00056
00057 template <class T>
00058 int linearSize(const T& inputT)
00059 {
00060 return inputT.linearSize();
00061 }
00062
00063 template <class T>
00064 void linearIn(T& a_outputT, const void* const inBuf)
00065 {
00066 a_outputT.linearIn(inBuf);
00067 }
00068
00069 template <class T>
00070 void linearOut(void* const a_outBuf, const T& inputT)
00071 {
00072 inputT.linearOut(a_outBuf);
00073 }
00074
00075 #ifdef CH_MPI
00076
00077
00078
00079
00080 template <class T>
00081 inline void
00082 gather(Vector<T>& a_outVec, const T& a_input, int a_dest)
00083 {
00084 CH_assert (a_dest >= 0);
00085 CH_assert(a_dest < numProc());
00086
00087 int isize = linearSize(a_input);
00088
00089
00090 void* loclBuf = malloc(isize);
00091 if(loclBuf == NULL)
00092 MayDay::Error("out of memory in gather 1");
00093
00094
00095 linearOut(loclBuf, a_input);
00096
00097 int nProcess = numProc();
00098 int sendCount = 1;
00099 int recdCount = 1;
00100
00101
00102 int* vectSize = NULL;
00103 int* vectDisp = NULL;
00104 void* sendBuf = static_cast<void*>(&isize);
00105
00106 if(procID() == a_dest)
00107 {
00108 vectSize = new int[nProcess];
00109 vectDisp = new int[nProcess];
00110 }
00111
00112 int result1 = MPI_Gather(sendBuf, sendCount, MPI_INT,
00113 vectSize,recdCount, MPI_INT,
00114 a_dest, Chombo_MPI::comm);
00115
00116 if(result1 != MPI_SUCCESS)
00117 MayDay::Error("Gather<T> failed in MPI_Gather 1");
00118
00119
00120 void* recdBuf = NULL;
00121 if(procID() == a_dest)
00122 {
00123 int itotsize=0;
00124 for(int iproc = 0; iproc < nProcess; iproc++)
00125 {
00126 vectDisp[iproc] = itotsize;
00127 itotsize += vectSize[iproc];
00128 }
00129 recdBuf = malloc(itotsize);
00130 if(recdBuf == NULL)
00131 MayDay::Error("out of memory in gather 2");
00132 }
00133
00134
00135 int result2 = MPI_Gatherv(loclBuf, isize, MPI_BYTE,
00136 recdBuf, vectSize, vectDisp, MPI_BYTE,
00137 a_dest, Chombo_MPI::comm);
00138 if(result2 != MPI_SUCCESS)
00139 MayDay::Error("Gather<T> failed in MPI_Gather 2");
00140
00141 if(procID() == a_dest)
00142 {
00143
00144 int ioffset = 0;
00145 a_outVec.resize(nProcess);
00146
00147 char* arithPtr = (char*)recdBuf;
00148 for(int iproc = 0; iproc < nProcess; iproc++)
00149 {
00150 ioffset = vectDisp[iproc];
00151 char* thisProcBuf = arithPtr + ioffset;
00152 linearIn(a_outVec[iproc], thisProcBuf);
00153 }
00154
00155
00156 delete[] vectSize;
00157 delete[] vectDisp;
00158 free(recdBuf);
00159 }
00160
00161
00162 free(loclBuf);
00163 }
00164
00165
00166
00167
00168 template <class T>
00169 inline void
00170 broadcast(T& a_inAndOut, int a_src)
00171 {
00172 CH_assert (a_src >= 0);
00173 CH_assert(a_src < numProc());
00174 int isize;
00175 if(procID() == a_src)
00176 isize = linearSize(a_inAndOut);
00177
00178 MPI_Bcast(&isize, 1, MPI_INT, a_src, Chombo_MPI::comm);
00179
00180 void* broadBuf = malloc(isize);
00181
00182 if(broadBuf == NULL)
00183 MayDay::Error("out of memory in broadcast");
00184
00185
00186 if(procID() == a_src)
00187 linearOut(broadBuf, a_inAndOut);
00188
00189
00190 MPI_Bcast(broadBuf, isize, MPI_BYTE, a_src, Chombo_MPI::comm);
00191
00192
00193 if(procID() != a_src)
00194 linearIn(a_inAndOut, broadBuf);
00195
00196
00197 free(broadBuf);
00198 }
00199
00200
00201
00202
00203 inline void
00204 barrier(void)
00205 {
00206 MPI_Barrier(Chombo_MPI::comm);
00207 }
00208
00209 #else
00210
00211
00212
00213 template <class T>
00214 inline void
00215 gather(Vector<T>& a_outVec, const T& a_input, int a_dest)
00216 {
00217 a_outVec.resize(1);
00218 a_outVec[0] = a_input;
00219 }
00220
00221
00222
00223 template <class T>
00224 inline void
00225 broadcast(T& a_inAndOut, int a_src)
00226 {
00227
00228 }
00229
00230
00231
00232 inline void
00233 barrier(void)
00234 {
00235
00236 }
00237
00238 #endif //the mpi thing
00239
00240
00241
00242
00243
00244
00245 template <class T>
00246 void
00247 linearListIn(Vector<T>& a_outputT, const void* const a_inBuf)
00248 {
00249
00250 const int* const intBuf = (int*)a_inBuf;
00251 int vecsize = intBuf[0];
00252 Vector<int> vecOffset(vecsize);
00253
00254 for(int ivec = 0; ivec < vecsize; ivec++)
00255 {
00256 vecOffset[ivec] = intBuf[ivec+1];
00257 }
00258
00259
00260
00261
00262
00263
00264 a_outputT.resize(vecsize);
00265 const char* const charbuf = (char*)a_inBuf;
00266 for(int ivec = 0; ivec < vecsize; ivec++)
00267 {
00268 const char* const dataLoc = charbuf + vecOffset[ivec];
00269 linearIn(a_outputT[ivec], dataLoc);
00270 }
00271 }
00272
00273
00274 template <class T>
00275 void
00276 linearListOut(void* const a_outBuf, const Vector<T>& a_input)
00277 {
00278
00279 int* const intBuf = (int*)a_outBuf;
00280 intBuf[0] = a_input.size();
00281 int vecsize = intBuf[0];
00282 Vector<int> vecOffset(vecsize);
00283
00284
00285 int ioffset = (vecsize+1)*sizeof(int);
00286 for(int ivec = 0; ivec < vecsize; ivec++)
00287 {
00288 intBuf[ivec+1] = ioffset;
00289 vecOffset[ivec] = ioffset;
00290 ioffset += linearSize(a_input[ivec]);
00291 }
00292
00293
00294
00295
00296
00297 char* const charBuf = (char*)a_outBuf;
00298 for(int ivec = 0; ivec < vecsize; ivec++)
00299 {
00300 char* const dataLoc = charBuf + vecOffset[ivec];
00301 linearOut(dataLoc, a_input[ivec]);
00302 }
00303 }
00304
00305
00306 template <class T>
00307 int
00308 linearListSize(const Vector<T>& a_input)
00309 {
00310
00311
00312
00313 int itotsize = (a_input.size() + 1)*sizeof(int);
00314 for(int ivec = 0; ivec < a_input.size(); ivec++)
00315 {
00316 itotsize += linearSize(a_input[ivec]);
00317 }
00318 return itotsize;
00319 }
00320
00321 #endif