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