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