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