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_