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