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