00001 #include "fftlib.h"
00002
00003
00004
00005
00006
00007 void
00008 NormalSlabArray::doFFT(int src_id, int dst_id)
00009 {
00010 NormalFFTinfo &fftinfo = (infoVec[src_id]->info);
00011
00012 CkAssert(fftinfo.transformType == COMPLEX_TO_COMPLEX);
00013
00014 complex *dataPtr = (complex*)fftinfo.dataPtr;
00015
00016 int planeSize = fftinfo.srcSize[0] * fftinfo.srcSize[1];
00017 int lineSize = fftinfo.srcSize[1];
00018
00019 CmiAssert(fwd2DPlan!=NULL);
00020
00021 int p;
00022 for(p = 0; p < fftinfo.srcPlanesPerSlab; p++){
00023 fftwnd_one(fwd2DPlan, (fftw_complex*)dataPtr + p * planeSize, NULL);
00024
00025 #if VERBOSE
00026 if(thisIndex==0 && src_id==0){
00027 for(int i=0;i<fftinfo.srcSize[1]*fftinfo.srcSize[0]; i++)
00028 CkPrintf("%d %g %g\n", i, dataPtr[p * planeSize+i].re, dataPtr[p * planeSize+i].im);
00029 }
00030 #endif
00031 }
00032
00033 complex *sendData = new complex[fftinfo.srcPlanesPerSlab * fftinfo.destPlanesPerSlab * lineSize];
00034 complex *temp;
00035
00036 CProxy_NormalSlabArray destProxy_com;
00037 ComlibInstanceHandle fftcommInstance = (infoVec[src_id]->fftcommInstance);
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 int pe, i;
00052 for(i = 0, pe = 0; i < fftinfo.srcSize[0]; i += fftinfo.destPlanesPerSlab, pe++) {
00053 int ti;
00054 temp = sendData;
00055 for(ti = i; ti < i + fftinfo.destPlanesPerSlab; ti++)
00056 for(p = 0; p < fftinfo.srcPlanesPerSlab; p++) {
00057 memcpy(temp,
00058 dataPtr + p * planeSize + ti * lineSize,
00059 sizeof(complex) * lineSize);
00060 temp += lineSize;
00061 }
00062 #if FFTLIB_USE_COMLIB
00063 if (fftuseCommlib)
00064 ((CProxy_NormalSlabArray)destProxy_com)(pe).acceptDataForFFT(lineSize * fftinfo.srcPlanesPerSlab * fftinfo.destPlanesPerSlab, sendData, thisIndex, dst_id);
00065 else
00066 ((CProxy_NormalSlabArray)destProxy)(pe).acceptDataForFFT(lineSize * fftinfo.srcPlanesPerSlab * fftinfo.destPlanesPerSlab, sendData, thisIndex, dst_id);
00067 #else
00068 ((CProxy_NormalSlabArray)destProxy)(pe).acceptDataForFFT(lineSize * fftinfo.srcPlanesPerSlab * fftinfo.destPlanesPerSlab, sendData, thisIndex, dst_id);
00069 #endif
00070
00071 }
00072
00073 #if FFTLIB_USE_COMLIB
00074 if (fftuseCommlib) {
00075
00076 fftcommInstance.endIteration();
00077 }
00078 #endif
00079 delete [] sendData;
00080 }
00081
00082
00083
00084
00085 void
00086 NormalSlabArray::acceptDataForFFT(int numPoints, complex *points, int posn, int info_id)
00087 {
00088 NormalFFTinfo &fftinfo = (infoVec[info_id]->info);
00089
00090 CkAssert(fftinfo.transformType == COMPLEX_TO_COMPLEX);
00091
00092 complex *dataPtr = (complex*)fftinfo.dataPtr;
00093 int lineSize = fftinfo.destSize[1];
00094
00095 #if CAREFUL
00096 CkAssert(numPoints == fftinfo.srcPlanesPerSlab * fftinfo.destPlanesPerSlab * lineSize);
00097 #endif
00098
00099 infoVec[info_id]->count++;
00100 int planeSize = fftinfo.destSize[0] * fftinfo.destSize[1];
00101 int p;
00102 for (p = 0; p < fftinfo.destPlanesPerSlab; p++) {
00103 memcpy(dataPtr + posn * fftinfo.srcPlanesPerSlab * lineSize + p * planeSize,
00104 points,
00105 sizeof(complex) * lineSize * fftinfo.srcPlanesPerSlab);
00106 points += lineSize * fftinfo.srcPlanesPerSlab;
00107 }
00108 if (infoVec[info_id]->count == fftinfo.destSize[0] / fftinfo.srcPlanesPerSlab) {
00109 infoVec[info_id]->count = 0;
00110 CkAssert(fwd1DPlan != NULL);
00111 for(p = 0; p < fftinfo.destPlanesPerSlab; p++) {
00112 fftw(fwd1DPlan,
00113 lineSize,
00114 (fftw_complex*)dataPtr + p * planeSize,
00115 lineSize, 1,
00116 NULL, 0, 0);
00117 #ifdef CMK_BLUEGENEL
00118 CmiNetworkProgress();
00119 #endif
00120 }
00121 doneFFT(info_id);
00122 }
00123 }
00124
00125
00126
00127
00128 void
00129 NormalSlabArray::doIFFT(int src_id, int dst_id)
00130 {
00131 NormalFFTinfo &fftinfo = (infoVec[src_id]->info);
00132
00133 CkAssert(fftinfo.transformType == COMPLEX_TO_COMPLEX);
00134
00135 complex *dataPtr = (complex*)fftinfo.dataPtr;
00136 int planeSize = fftinfo.destSize[0] * fftinfo.destSize[1];
00137 int lineSize = fftinfo.destSize[1];
00138
00139 CmiAssert(bwd2DPlan!=NULL);
00140 int p;
00141
00142 for(p = 0; p < fftinfo.destPlanesPerSlab; p++){
00143 fftwnd_one(bwd2DPlan,
00144 (fftw_complex*)dataPtr + p * planeSize,
00145 NULL);
00146 #if VERBOSE
00147 if(thisIndex==0 && src_id==0){
00148 for(int i=0;i<fftinfo.srcSize[1]*fftinfo.srcSize[0]; i++)
00149 CkPrintf("%d %g %g\n", i, dataPtr[p * planeSize+i].re, dataPtr[p * planeSize+i].im);
00150 }
00151 #endif
00152 }
00153
00154 #if FFTLIB_USE_COMLIB
00155 CProxy_NormalSlabArray srcProxy_com;
00156 ComlibInstanceHandle fftcommInstance = (infoVec[src_id]->fftcommInstance);
00157 if (fftuseCommlib) {
00158 if(fftinfo.isSrcSlab)
00159 srcProxy_com = (CProxy_NormalSlabArray)destProxy;
00160 else
00161 srcProxy_com = (CProxy_NormalSlabArray)srcProxy;
00162 ComlibAssociateProxy(&fftcommInstance, srcProxy_com);
00163
00164 fftcommInstance.beginIteration();
00165 }
00166 #endif
00167
00168 complex *sendData = new complex[fftinfo.srcPlanesPerSlab * fftinfo.destPlanesPerSlab * lineSize];
00169 complex *temp;
00170 int i, pe;
00171 for (i = 0, pe = 0; i < fftinfo.destSize[0]; i += fftinfo.srcPlanesPerSlab, pe++) {
00172 int ti;
00173
00174 temp = sendData;
00175 for (ti = i; ti < i + fftinfo.srcPlanesPerSlab; ti++)
00176 for (p = 0; p < fftinfo.destPlanesPerSlab; p++) {
00177 memcpy(temp,
00178 dataPtr + p * planeSize + ti * lineSize,
00179 sizeof(complex) * lineSize);
00180 temp += lineSize;
00181 }
00182 #if FFTLIB_USE_COMLIB
00183 if (fftuseCommlib)
00184 ((CProxy_NormalSlabArray)srcProxy_com)(pe).acceptDataForIFFT(lineSize * fftinfo.destPlanesPerSlab * fftinfo.srcPlanesPerSlab, sendData, thisIndex, dst_id);
00185 else
00186 ((CProxy_NormalSlabArray)srcProxy)(pe).acceptDataForIFFT(lineSize * fftinfo.destPlanesPerSlab * fftinfo.srcPlanesPerSlab, sendData, thisIndex, dst_id);
00187 #else
00188 ((CProxy_NormalSlabArray)srcProxy)(pe).acceptDataForIFFT(lineSize * fftinfo.destPlanesPerSlab * fftinfo.srcPlanesPerSlab, sendData, thisIndex, dst_id);
00189 #endif
00190 }
00191
00192
00193 #if FFTLIB_USE_COMLIB
00194 if (fftuseCommlib) {
00195
00196 fftcommInstance.endIteration();
00197 }
00198 #endif
00199
00200 delete [] sendData;
00201 }
00202
00203
00204 void
00205 NormalSlabArray::acceptDataForIFFT(int numPoints, complex *points, int posn, int info_id)
00206 {
00207 NormalFFTinfo &fftinfo = (infoVec[info_id]->info);
00208
00209 CkAssert(fftinfo.transformType == COMPLEX_TO_COMPLEX);
00210
00211 complex *dataPtr = (complex*)fftinfo.dataPtr;
00212 int planeSize = fftinfo.srcSize[0] * fftinfo.srcSize[1];
00213 int lineSize = fftinfo.srcSize[1];
00214 #if CAREFUL
00215 CkAssert(numPoints == fftinfo.srcPlanesPerSlab * fftinfo.destPlanesPerSlab * lineSize);
00216 #endif
00217
00218 infoVec[info_id]->count++;
00219 int p;
00220 for(p = 0; p < fftinfo.srcPlanesPerSlab; p++) {
00221 memcpy(dataPtr + p * planeSize + posn * lineSize * fftinfo.destPlanesPerSlab,
00222 points,
00223 sizeof(complex) * lineSize * fftinfo.destPlanesPerSlab);
00224 points += lineSize * fftinfo.destPlanesPerSlab;
00225 }
00226
00227 if (infoVec[info_id]->count == fftinfo.srcSize[0] / fftinfo.destPlanesPerSlab) {
00228 infoVec[info_id]->count = 0;
00229 CmiAssert(bwd1DPlan!=NULL);
00230 for(p = 0; p < fftinfo.srcPlanesPerSlab; p++) {
00231 fftw(bwd1DPlan,
00232 lineSize,
00233 (fftw_complex*)dataPtr + p * planeSize,
00234 lineSize, 1,
00235 NULL, 0, 0);
00236 #ifdef CMK_BLUEGENEL
00237 CmiNetworkProgress();
00238 #endif
00239
00240 }
00241
00242
00243 double factor = fftinfo.srcSize[0] * fftinfo.srcSize[1] * fftinfo.destSize[0];
00244 for(p = 0; p < fftinfo.srcPlanesPerSlab; p++) {
00245 complex *tempdataPtr = dataPtr + p * planeSize;
00246 for(int i = 0; i<fftinfo.destSize[0]*fftinfo.destSize[1]; i++){
00247 tempdataPtr[i].re /= factor;
00248 tempdataPtr[i].im /= factor;
00249 }
00250 }
00251
00252 doneIFFT(info_id);
00253 }
00254 }
00255
00256 void NormalSlabArray::createPlans(NormalFFTinfo &info)
00257 {
00258 if (info.isSrcSlab) {
00259 fwd2DPlan = fftw2d_create_plan(info.srcSize[0], info.srcSize[1], FFTW_FORWARD, FFTW_IN_PLACE);
00260 bwd1DPlan = fftw_create_plan(info.srcSize[0], FFTW_BACKWARD, FFTW_IN_PLACE);
00261 }
00262 else {
00263 bwd2DPlan = fftw2d_create_plan(info.destSize[0], info.destSize[1], FFTW_BACKWARD, FFTW_IN_PLACE);
00264 fwd1DPlan = fftw_create_plan(info.destSize[0], FFTW_FORWARD, FFTW_IN_PLACE);
00265 }
00266 }
00267
00268 void NormalSlabArray::setup(NormalFFTinfo &info,
00269 CProxy_NormalSlabArray src,
00270 CProxy_NormalSlabArray dest,
00271 bool _useCommlib, ComlibInstanceHandle inst)
00272 {
00273 SlabArrayInfo *slabinfo = new SlabArrayInfo();
00274
00275 slabinfo->info = info;
00276 slabinfo->count = 0;
00277 slabinfo->fftcommInstance = inst;
00278 infoVec.insert(infoVec.size(), slabinfo);
00279
00280 srcProxy = src;
00281 destProxy = dest;
00282
00283 if((info.isSrcSlab && fwd2DPlan==NULL) || (!info.isSrcSlab && bwd2DPlan==NULL))
00284 createPlans(info);
00285
00288 fftuseCommlib = false;
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 }
00302
00303 NormalSlabArray::NormalSlabArray(NormalFFTinfo &info,
00304 CProxy_NormalSlabArray src,
00305 CProxy_NormalSlabArray dest,
00306 bool useCommlib,
00307 ComlibInstanceHandle inst) {
00308 NormalSlabArray();
00309 setup(info, src, dest, useCommlib, inst);
00310 }
00311
00312 NormalSlabArray::~NormalSlabArray()
00313 {
00314 if (fwd2DPlan)
00315 fftwnd_destroy_plan(fwd2DPlan);
00316 if (bwd2DPlan)
00317 fftwnd_destroy_plan(bwd2DPlan);
00318 if (fwd1DPlan)
00319 fftw_destroy_plan(fwd1DPlan);
00320 if (bwd1DPlan)
00321 fftw_destroy_plan(bwd1DPlan);
00322
00323 infoVec.removeAll();
00324 }
00325
00326
00327 void NormalSlabArray::pup(PUP::er &p)
00328 {
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 p | fftuseCommlib;
00350
00351 }
00352
00353
00354 #include "fftlib.def.h"