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
00038 int pe, i;
00039 for(i = 0, pe = 0; i < fftinfo.srcSize[0]; i += fftinfo.destPlanesPerSlab, pe++) {
00040 int ti;
00041 temp = sendData;
00042 for(ti = i; ti < i + fftinfo.destPlanesPerSlab; ti++)
00043 for(p = 0; p < fftinfo.srcPlanesPerSlab; p++) {
00044 memcpy(temp,
00045 dataPtr + p * planeSize + ti * lineSize,
00046 sizeof(complex) * lineSize);
00047 temp += lineSize;
00048 }
00049 ((CProxy_NormalSlabArray)destProxy)(pe).acceptDataForFFT(lineSize * fftinfo.srcPlanesPerSlab * fftinfo.destPlanesPerSlab, sendData, thisIndex, dst_id);
00050 }
00051
00052 delete [] sendData;
00053 }
00054
00055
00056
00057
00058 void
00059 NormalSlabArray::acceptDataForFFT(int numPoints, complex *points, int posn, int info_id)
00060 {
00061 NormalFFTinfo &fftinfo = (infoVec[info_id]->info);
00062
00063 CkAssert(fftinfo.transformType == COMPLEX_TO_COMPLEX);
00064
00065 complex *dataPtr = (complex*)fftinfo.dataPtr;
00066 int lineSize = fftinfo.destSize[1];
00067
00068 #if CAREFUL
00069 CkAssert(numPoints == fftinfo.srcPlanesPerSlab * fftinfo.destPlanesPerSlab * lineSize);
00070 #endif
00071
00072 infoVec[info_id]->count++;
00073 int planeSize = fftinfo.destSize[0] * fftinfo.destSize[1];
00074 int p;
00075 for (p = 0; p < fftinfo.destPlanesPerSlab; p++) {
00076 memcpy(dataPtr + posn * fftinfo.srcPlanesPerSlab * lineSize + p * planeSize,
00077 points,
00078 sizeof(complex) * lineSize * fftinfo.srcPlanesPerSlab);
00079 points += lineSize * fftinfo.srcPlanesPerSlab;
00080 }
00081 if (infoVec[info_id]->count == fftinfo.destSize[0] / fftinfo.srcPlanesPerSlab) {
00082 infoVec[info_id]->count = 0;
00083 CkAssert(fwd1DPlan != NULL);
00084 for(p = 0; p < fftinfo.destPlanesPerSlab; p++) {
00085 fftw(fwd1DPlan,
00086 lineSize,
00087 (fftw_complex*)dataPtr + p * planeSize,
00088 lineSize, 1,
00089 NULL, 0, 0);
00090 }
00091 doneFFT(info_id);
00092 }
00093 }
00094
00095
00096
00097
00098 void
00099 NormalSlabArray::doIFFT(int src_id, int dst_id)
00100 {
00101 NormalFFTinfo &fftinfo = (infoVec[src_id]->info);
00102
00103 CkAssert(fftinfo.transformType == COMPLEX_TO_COMPLEX);
00104
00105 complex *dataPtr = (complex*)fftinfo.dataPtr;
00106 int planeSize = fftinfo.destSize[0] * fftinfo.destSize[1];
00107 int lineSize = fftinfo.destSize[1];
00108
00109 CmiAssert(bwd2DPlan!=NULL);
00110 int p;
00111
00112 for(p = 0; p < fftinfo.destPlanesPerSlab; p++){
00113 fftwnd_one(bwd2DPlan,
00114 (fftw_complex*)dataPtr + p * planeSize,
00115 NULL);
00116 #if VERBOSE
00117 if(thisIndex==0 && src_id==0){
00118 for(int i=0;i<fftinfo.srcSize[1]*fftinfo.srcSize[0]; i++)
00119 CkPrintf("%d %g %g\n", i, dataPtr[p * planeSize+i].re, dataPtr[p * planeSize+i].im);
00120 }
00121 #endif
00122 }
00123
00124 complex *sendData = new complex[fftinfo.srcPlanesPerSlab * fftinfo.destPlanesPerSlab * lineSize];
00125 complex *temp;
00126 int i, pe;
00127 for (i = 0, pe = 0; i < fftinfo.destSize[0]; i += fftinfo.srcPlanesPerSlab, pe++) {
00128 int ti;
00129
00130 temp = sendData;
00131 for (ti = i; ti < i + fftinfo.srcPlanesPerSlab; ti++)
00132 for (p = 0; p < fftinfo.destPlanesPerSlab; p++) {
00133 memcpy(temp,
00134 dataPtr + p * planeSize + ti * lineSize,
00135 sizeof(complex) * lineSize);
00136 temp += lineSize;
00137 }
00138 ((CProxy_NormalSlabArray)srcProxy)(pe).acceptDataForIFFT(lineSize * fftinfo.destPlanesPerSlab * fftinfo.srcPlanesPerSlab, sendData, thisIndex, dst_id);
00139 }
00140
00141 delete [] sendData;
00142 }
00143
00144
00145 void
00146 NormalSlabArray::acceptDataForIFFT(int numPoints, complex *points, int posn, int info_id)
00147 {
00148 NormalFFTinfo &fftinfo = (infoVec[info_id]->info);
00149
00150 CkAssert(fftinfo.transformType == COMPLEX_TO_COMPLEX);
00151
00152 complex *dataPtr = (complex*)fftinfo.dataPtr;
00153 int planeSize = fftinfo.srcSize[0] * fftinfo.srcSize[1];
00154 int lineSize = fftinfo.srcSize[1];
00155 #if CAREFUL
00156 CkAssert(numPoints == fftinfo.srcPlanesPerSlab * fftinfo.destPlanesPerSlab * lineSize);
00157 #endif
00158
00159 infoVec[info_id]->count++;
00160 int p;
00161 for(p = 0; p < fftinfo.srcPlanesPerSlab; p++) {
00162 memcpy(dataPtr + p * planeSize + posn * lineSize * fftinfo.destPlanesPerSlab,
00163 points,
00164 sizeof(complex) * lineSize * fftinfo.destPlanesPerSlab);
00165 points += lineSize * fftinfo.destPlanesPerSlab;
00166 }
00167
00168 if (infoVec[info_id]->count == fftinfo.srcSize[0] / fftinfo.destPlanesPerSlab) {
00169 infoVec[info_id]->count = 0;
00170 CmiAssert(bwd1DPlan!=NULL);
00171 for(p = 0; p < fftinfo.srcPlanesPerSlab; p++) {
00172 fftw(bwd1DPlan,
00173 lineSize,
00174 (fftw_complex*)dataPtr + p * planeSize,
00175 lineSize, 1,
00176 NULL, 0, 0);
00177 }
00178
00179
00180 double factor = fftinfo.srcSize[0] * fftinfo.srcSize[1] * fftinfo.destSize[0];
00181 for(p = 0; p < fftinfo.srcPlanesPerSlab; p++) {
00182 complex *tempdataPtr = dataPtr + p * planeSize;
00183 for(int i = 0; i<fftinfo.destSize[0]*fftinfo.destSize[1]; i++){
00184 tempdataPtr[i].re /= factor;
00185 tempdataPtr[i].im /= factor;
00186 }
00187 }
00188
00189 doneIFFT(info_id);
00190 }
00191 }
00192
00193 void NormalSlabArray::createPlans(NormalFFTinfo &info)
00194 {
00195 if (info.isSrcSlab) {
00196 fwd2DPlan = fftw2d_create_plan(info.srcSize[0], info.srcSize[1], FFTW_FORWARD, FFTW_IN_PLACE);
00197 bwd1DPlan = fftw_create_plan(info.srcSize[0], FFTW_BACKWARD, FFTW_IN_PLACE);
00198 }
00199 else {
00200 bwd2DPlan = fftw2d_create_plan(info.destSize[0], info.destSize[1], FFTW_BACKWARD, FFTW_IN_PLACE);
00201 fwd1DPlan = fftw_create_plan(info.destSize[0], FFTW_FORWARD, FFTW_IN_PLACE);
00202 }
00203 }
00204
00205 void NormalSlabArray::setup(NormalFFTinfo &info,
00206 CProxy_NormalSlabArray src,
00207 CProxy_NormalSlabArray dest)
00208 {
00209 SlabArrayInfo *slabinfo = new SlabArrayInfo();
00210
00211 slabinfo->info = info;
00212 slabinfo->count = 0;
00213 infoVec.insert(infoVec.size(), slabinfo);
00214
00215 srcProxy = src;
00216 destProxy = dest;
00217
00218 if((info.isSrcSlab && fwd2DPlan==NULL) || (!info.isSrcSlab && bwd2DPlan==NULL))
00219 createPlans(info);
00220 }
00221
00222 NormalSlabArray::NormalSlabArray(NormalFFTinfo &info,
00223 CProxy_NormalSlabArray src,
00224 CProxy_NormalSlabArray dest) {
00225 setup(info, src, dest);
00226 }
00227
00228 NormalSlabArray::~NormalSlabArray()
00229 {
00230 if (fwd2DPlan)
00231 fftwnd_destroy_plan(fwd2DPlan);
00232 if (bwd2DPlan)
00233 fftwnd_destroy_plan(bwd2DPlan);
00234 if (fwd1DPlan)
00235 fftw_destroy_plan(fwd1DPlan);
00236 if (bwd1DPlan)
00237 fftw_destroy_plan(bwd1DPlan);
00238
00239 infoVec.removeAll();
00240 }
00241
00242
00243 void NormalSlabArray::pup(PUP::er &p)
00244 {
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 }
00266
00267
00268 #include "fftlib.def.h"