00001 #ifndef _fftlib_h_
00002 #define _fftlib_h_
00003
00004 #include <charm++.h>
00005 #include "ckcomplex.h"
00006 #include "rfftw.h"
00007
00008 #define DEPRECATED(func) func
00009
00010 #define COMPLEX_TO_REAL -11
00011 #define REAL_TO_COMPLEX -12
00012 #define COMPLEX_TO_COMPLEX -13
00013 #define NULL_TO_NULL -14
00014
00015 #define MAX_FFTS 5
00016
00017 #warning "This Charm 3D FFT library is deprecated. Use the new CharmFFT instead: http://charm.cs.illinois.edu/manuals/html/libraries/4.html"
00018
00019 class NormalFFTinfo {
00020 public:
00021 NormalFFTinfo(int sDim[2], int dDim[2], int isSrc,
00022 void *dptr, int transType,
00023 int sPlanesPerSlab=1, int dPlanesPerSlab=1) {
00024 init(sDim, dDim, isSrc, dptr, transType, sPlanesPerSlab, dPlanesPerSlab);
00025 }
00026 NormalFFTinfo(NormalFFTinfo &info) {
00027 init(info.srcSize, info.destSize, info.isSrcSlab,
00028 info.dataPtr, info.transformType,
00029 info.srcPlanesPerSlab, info.destPlanesPerSlab);
00030 }
00031
00032 NormalFFTinfo(void) {dataPtr=NULL;}
00033
00034 int srcSize[2], destSize[2];
00035 bool isSrcSlab;
00036 int srcPlanesPerSlab, destPlanesPerSlab;
00037 void *dataPtr;
00038 int transformType;
00039
00040 void pup(PUP::er &p) {
00041 p(srcSize, 2);
00042 p(destSize, 2);
00043 p(isSrcSlab);
00044 p(srcPlanesPerSlab);
00045 p(destPlanesPerSlab);
00046 p|transformType;
00047 if (p.isUnpacking())
00048 dataPtr = NULL;
00049 }
00050
00051 private:
00052 void init( int sDim[2], int dDim[2], int isSrc,
00053 void *dptr, int transT,
00054 int sPlanesPerSlab, int dPlanesPerSlab) {
00055 if (sDim[1] != dDim[1])
00056 ckerr << "WARNING"
00057 << "This configuration of the source and destination "
00058 << "is not consistent, check the dimensions. The program is "
00059 << "likely to misbehave"
00060 << endl;
00061 isSrcSlab = isSrc;
00062 srcPlanesPerSlab = sPlanesPerSlab;
00063 destPlanesPerSlab = dPlanesPerSlab;
00064 dataPtr = dptr;
00065 transformType=transT;
00066 memcpy(srcSize, sDim, 2 * sizeof(int));
00067 memcpy(destSize, dDim, 2 * sizeof(int));
00068 }
00069 };
00070
00071 typedef struct _PencilType{
00072 const static int XLINE = 0;
00073 const static int YLINE = 1;
00074 const static int ZLINE = 2;
00075 }PencilType;
00076
00077 typedef struct _PencilBlock{
00078 const static int FLATBLOCK = 0;
00079 const static int SQUAREBLOCK = 1;
00080 }PencilBlock;
00081
00082
00083 class LineFFTinfo {
00084 public:
00085
00086 LineFFTinfo(int size[3], int _ptype, int _pblock, complex *dptr, int _xPencilsPerSlab=1, int _yPencilsPerSlab=1, int _zPencilsPerSlab=1) {
00087 init(size[0], size[1], size[2], _ptype, _pblock, dptr, _xPencilsPerSlab, _yPencilsPerSlab, _zPencilsPerSlab);
00088 }
00089 LineFFTinfo(LineFFTinfo &info) {
00090 init(info.sizeX, info.sizeY, info.sizeZ, info.ptype, info.pblock, (complex *) NULL, info.xPencilsPerSlab, info.yPencilsPerSlab, info.zPencilsPerSlab);
00091 }
00092 LineFFTinfo(void) {}
00093
00094
00095 void pup(PUP::er &p) {
00096 p|sizeX;
00097 p|sizeY;
00098 p|sizeZ;
00099 p(ptype);
00100 p(pblock);
00101 p(xPencilsPerSlab);
00102 p(yPencilsPerSlab);
00103 p(zPencilsPerSlab);
00104 p(xsquare, 2);
00105 p(ysquare, 2);
00106 p(zsquare, 2);
00107 if (p.isUnpacking())
00108 dataPtr = (complex *) NULL;
00109 }
00110 int sizeX, sizeY, sizeZ;
00111 int ptype;
00112 int pblock;
00113 int xPencilsPerSlab, yPencilsPerSlab, zPencilsPerSlab;
00114 int xsquare[2], ysquare[2], zsquare[2];
00115 complex *dataPtr;
00116 private:
00117 void init(int sizex, int sizey, int sizez, int _ptype, int _pblock, complex *dptr, int _xPencilsPerSlab, int _yPencilsPerSlab, int _zPencilsPerSlab) {
00118 if (sizex != sizey || sizey != sizez)
00119 ckerr << "WARNING"
00120 << "This configuration of the source and destination "
00121 << "is not consistent, check the dimensions. The program is "
00122 << "likely to misbehave"
00123 << endl;
00124 ptype = _ptype;
00125 pblock = _pblock;
00126 xPencilsPerSlab = _xPencilsPerSlab;
00127 yPencilsPerSlab = _yPencilsPerSlab;
00128 zPencilsPerSlab = _zPencilsPerSlab;
00129 dataPtr = dptr;
00130 sizeX = sizex;
00131 sizeY = sizey;
00132 sizeZ = sizez;
00133
00134 CkAssert((sizeX==sizeY) && (sizeX==sizeZ));
00135
00136 if(pblock == PencilBlock::SQUAREBLOCK){
00137 getSquaresize(xPencilsPerSlab, sizeX, xsquare);
00138 getSquaresize(yPencilsPerSlab, sizeX, ysquare);
00139 getSquaresize(zPencilsPerSlab, sizeX, zsquare);
00140
00141 CkAssert((xsquare[1]%ysquare[1]==0) || (ysquare[1]%xsquare[1]==0));
00142 CkAssert((zsquare[0]%ysquare[0]==0) || (ysquare[0]%zsquare[0]==0));
00143 }
00144 else {
00145 xsquare[0]=xPencilsPerSlab; xsquare[1]=1;
00146 ysquare[0]=yPencilsPerSlab; ysquare[1]=1;
00147 zsquare[0]=zPencilsPerSlab; zsquare[1]=1;
00148 CkAssert((yPencilsPerSlab%zPencilsPerSlab==0)
00149 || (zPencilsPerSlab%yPencilsPerSlab==0));
00150 }
00151 }
00152 void getSquaresize(int size, int planesize, int *square) {
00153 int squaresize = (int)sqrt((float)size);
00154 if(size==squaresize*squaresize){
00155 square[0]=squaresize;
00156 square[1]=squaresize;
00157 }
00158 else{
00159 while(squaresize>1 && ((size%squaresize!=0) ||
00160 ((size%squaresize==0)&&(planesize%squaresize!=0||planesize%(size/squaresize)!=0)))){
00161 squaresize--;
00162 }
00163 square[1]=squaresize;
00164 square[0]=size/squaresize;
00165 }
00166 CkAssert(size==square[0]*square[1]);
00167 }
00168 };
00169
00170 #include "fftlib.decl.h"
00171
00172 PUPmarshall(NormalFFTinfo)
00173 PUPmarshall(LineFFTinfo)
00174
00175
00176 typedef struct _SlabArrayInfo{
00177 int count;
00178 NormalFFTinfo info;
00179
00180
00181 }SlabArrayInfo;
00182
00183
00184
00185
00186
00187 class SlabArray: public CBase_SlabArray {
00188 public:
00189 SlabArray(CkMigrateMessage *m) {}
00190 SlabArray() {}
00191 virtual ~SlabArray() {}
00192
00193
00194 virtual void doneFFT(int id) {
00195 ckout << "NormalSlabArray finished FFT" << endl;
00196 CkExit();
00197 }
00198 virtual void doneIFFT(int id) {
00199 ckout << "NormalSlabArray finished IFFT" << endl;
00200 CkExit();
00201 }
00202
00203
00204 virtual void doFFT(int, int) = 0;
00205 virtual void doIFFT(int, int) = 0;
00206 protected:
00207 CProxy_SlabArray srcProxy, destProxy;
00208 CkVec<SlabArrayInfo*> infoVec;
00209 };
00210
00211
00212
00213
00214
00215 class NormalSlabArray: public CBase_NormalSlabArray {
00216 public:
00217 NormalSlabArray(CkMigrateMessage *m): CBase_NormalSlabArray(m) {CkPrintf("migrate constructor called\n");}
00218 NormalSlabArray() {
00219 #if VERBOSE
00220 CkPrintf("Empty constructor called\n");
00221 #endif
00222 fwd2DPlan = bwd2DPlan = (fftwnd_plan) NULL;
00223 fwd1DPlan = bwd1DPlan = (fftw_plan) NULL;
00224 }
00225
00226 NormalSlabArray(NormalFFTinfo &info,
00227 CProxy_NormalSlabArray src, CProxy_NormalSlabArray dest);
00228 ~NormalSlabArray();
00229
00230
00231 void acceptDataForFFT(int, complex *, int, int);
00232 void acceptDataForIFFT(int, complex *, int, int);
00233
00234 void doFFT(int src_id = 0, int dst_id = 0);
00235 void doIFFT(int src_id = 0, int dst_id = 0);
00236
00237 void pup(PUP::er &p);
00238
00239 void setup(NormalFFTinfo &info,
00240 CProxy_NormalSlabArray src, CProxy_NormalSlabArray dest);
00241 protected:
00242 fftwnd_plan fwd2DPlan, bwd2DPlan;
00243 fftw_plan fwd1DPlan, bwd1DPlan;
00244
00245 void createPlans(NormalFFTinfo &info);
00246 };
00247
00248 class NormalRealSlabArray: public CBase_NormalRealSlabArray {
00249 public:
00250 NormalRealSlabArray(CkMigrateMessage *m): CBase_NormalRealSlabArray(m) {}
00251 NormalRealSlabArray() {
00252 #if VERBOSE
00253 CkPrintf("Empty constructor called\n");
00254 #endif
00255 tempdataPtr = NULL;
00256 rfwd1DXPlan = rbwd1DXPlan = (rfftw_plan) NULL;
00257 fwd1DYPlan = bwd1DYPlan = (fftw_plan) NULL;
00258 fwd1DZPlan = bwd1DZPlan = (fftw_plan) NULL;
00259 rfwd2DXYPlan = rfwd2DXYPlan = (rfftwnd_plan)NULL;
00260 }
00261
00262 NormalRealSlabArray(NormalFFTinfo &info,
00263 CProxy_NormalRealSlabArray, CProxy_NormalRealSlabArray);
00264 ~NormalRealSlabArray();
00265
00266
00267 void acceptDataForFFT(int, complex *, int, int);
00268 void acceptDataForIFFT(int, complex *, int, int);
00269
00270 void doFFT(int src_id = 0, int dst_id = 0);
00271 void doIFFT(int src_id = 0, int dst_id = 0);
00272
00273 void pup(PUP::er &p);
00274
00275 void createPlans(NormalFFTinfo &info);
00276
00277 protected:
00278 rfftwnd_plan rfwd2DXYPlan, rbwd2DXYPlan;
00279 rfftw_plan rfwd1DXPlan, rbwd1DXPlan;
00280 fftw_plan fwd1DYPlan, bwd1DYPlan;
00281 fftw_plan fwd1DZPlan, bwd1DZPlan;
00282
00283 NormalFFTinfo *fftinfos[MAX_FFTS];
00284
00285 void setup(NormalFFTinfo &info,
00286 CProxy_NormalRealSlabArray, CProxy_NormalRealSlabArray);
00287
00288 private:
00289 complex *tempdataPtr;
00290 };
00291
00292 #if 0
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 class RunDescriptor {
00303 public:
00304 static const short X = 1;
00305 static const short Y = 2;
00306 static const short Z = 2;
00307
00308
00309 RunDescriptor(int x_, int y_, int z_, int l_, int i_ = 0) {x = x_; y = y_; z = z_; length = l_; inc = i_;}
00310 RunDescriptor(const RunDescriptor &rd) {x = rd.x; y = rd.y; z = rd.z; length = rd.length; inc = rd.inc;}
00311
00312
00313 void pup(PUP::er &p) {p|x; p|y; p|z; p|length; p(dir); p|inc;}
00314
00315
00316
00317 int offset(int i) const { return (inc > 0) ? i : -i; }
00318
00319
00320 int x, y, z;
00321 int length;
00322 short dir;
00323 int inc;
00324 };
00325
00326
00327
00328
00329 class SparseSlabArray: public CBase_SparseSlabArray {
00330 public:
00331 SparseSlabArray(CkMigrateMessage *m): SlabArray(m) {}
00332 SparseSlabArray(): SlabArray() {}
00333 SparseSlabArray(FFTinfo &info);
00334 ~SparseSlabArray();
00335
00336 virtual void getRuns(complex **runs, int *numRuns, int *numPoints) const {*runs = NULL; *numRuns = 0; *numPoints = 0;}
00337
00338 private:
00339 int count;
00340 fftwnd_plan fwd2DPlan, bwd2DPlan;
00341 fftw_plan fwd1DPlan, bwd1DPlan;
00342 FFTinfo info;
00343 int *nonZero;
00344 };
00345 #endif
00346
00347 typedef struct _PencilArrayInfo{
00348 int count;
00349 LineFFTinfo info;
00350 }PencilArrayInfo;
00351
00352 class SendFFTMsg: public CMessage_SendFFTMsg {
00353 public:
00354 int size;
00355 int id;
00356 int direction;
00357 int ypos;
00358 int zpos;
00359 complex *data;
00360 };
00361
00362
00363 class NormalLineArray : public CBase_NormalLineArray {
00364 public:
00365 NormalLineArray (CkMigrateMessage *m) {}
00366 NormalLineArray () {
00367 fwdplan = bwdplan =NULL;
00368 id = -1;
00369 line = NULL;
00370 }
00371 NormalLineArray (LineFFTinfo &info, CProxy_NormalLineArray _xProxy, CProxy_NormalLineArray _yProxy, CProxy_NormalLineArray _zProxy);
00372 ~NormalLineArray () {}
00373 void setup (LineFFTinfo &info, CProxy_NormalLineArray _xProxy, CProxy_NormalLineArray _yProxy, CProxy_NormalLineArray _zProxy);
00374 void doFirstFFT(int id, int direction);
00375 void doSecondFFT(int ypos, complex *val, int size, int id, int direction);
00376 void doThirdFFT(int zpos, int ypos, complex *val, int size, int id, int direction);
00377
00378 void doSecondFFT(SendFFTMsg *msg);
00379 void doThirdFFT(SendFFTMsg *msg);
00380
00381 void doFFT(int id, int direction) {doFirstFFT(id, direction);}
00382 virtual void doneFFT(int id, int direction);
00383 void setInstance(int id_) { id = id_;
00384 contribute(sizeof(int), &id_, CkReduction::sum_int);
00385 }
00386 protected:
00387 complex *line;
00388 fftw_plan fwdplan, bwdplan;
00389 int id;
00390
00391 CProxy_NormalLineArray xProxy, yProxy, zProxy;
00392 CkVec<PencilArrayInfo*> infoVec;
00393 };
00394
00395
00396 #define CAREFUL 1
00397
00398 #endif //_fftlib_h_