00001 #include "fftlib.h"
00002 
00003 
00004 
00005 
00006 
00007 void
00008 NormalLineArray::doFirstFFT(int fftid, int direction)
00009 {
00010     LineFFTinfo &fftinfo = (infoVec[fftid]->info);
00011     int ptype = fftinfo.ptype;
00012     int pblock = fftinfo.pblock;
00013     complex *line = fftinfo.dataPtr;
00014     int sizeX = fftinfo.sizeX;
00015     int sizeZ = fftinfo.sizeZ;
00016     int *xsquare = fftinfo.xsquare;
00017     int *ysquare = fftinfo.ysquare;
00018     int *zsquare = fftinfo.zsquare;
00019 
00020 #ifdef HEAVYVERBOSE 
00021     {
00022     char fname[80];
00023     if(direction)
00024     snprintf(fname,80,"xline_%d.y%d.z%d.out", fftid,thisIndex.x, thisIndex.y);
00025     else
00026     snprintf(fname,80,"zline_%d.x%d.y%d.out", fftid,thisIndex.x, thisIndex.y);
00027       FILE *fp=fopen(fname,"w");
00028     for(int x = 0; x < sizeX*xsquare[0]*xsquare[1]; x++)
00029         fprintf(fp, "%d  %g %g\n", x, line[x].re, line[x].im);
00030     fclose(fp);
00031     }
00032 #endif
00033 
00034     if(direction && ptype==PencilType::XLINE)
00035     fftw(fwdplan, xsquare[0]*xsquare[1], (fftw_complex*)line, 1, sizeX, NULL, 0, 0); 
00036     else if(!direction && ptype==PencilType::ZLINE)
00037     fftw(bwdplan, zsquare[0]*zsquare[1], (fftw_complex*)line, 1, sizeZ, NULL, 0, 0);
00038     else
00039     CkAbort("Can't do this FFT\n");
00040 
00041     int x, y, z=0;
00042 #ifdef VERBOSE
00043     CkPrintf("First FFT done at [%d %d] [%d %d]\n", thisIndex.x, thisIndex.y,sizeX,sizeZ);
00044 #endif
00045     int baseX, ix, iy, iz;
00046     if(true) {
00047     if(direction)
00048     {
00049         int sendSquarethick = ysquare[1] <= xsquare[1] ? ysquare[1]:xsquare[1];
00050         int sendDataSize = ysquare[0]*xsquare[0] * sendSquarethick;
00051         int zpos = thisIndex.y;
00052         int index=0;
00053         complex *sendData = NULL;
00054 
00055         for(z = 0; z < xsquare[1]; z+=sendSquarethick){
00056         for(x = 0; x < sizeX; x+=ysquare[0]) {
00057             SendFFTMsg *msg = new(sendDataSize, sizeof(int)*8) SendFFTMsg;
00058             sendData = msg->data;
00059             msg->ypos = thisIndex.x; 
00060             msg->size = sendDataSize;
00061             msg->id = fftid;
00062             msg->direction = direction;
00063             msg->data = sendData;
00064             CkSetQueueing(msg, CK_QUEUEING_IFIFO);
00065 #ifdef _PRIOMSG_
00066             int prioNum =  (zpos+z) + x*sizeX;
00067             *(int*)CkPriorityPtr(msg) = prioNum; 
00068 #endif  
00069             index = 0;
00070             for(iz = z; iz < z+sendSquarethick; iz++)
00071             for(ix = x; ix < x+ysquare[0]; ix++)
00072                 for(y = 0; y < xsquare[0]; y++)
00073                 sendData[index++] = line[iz*sizeX*xsquare[0]+y*sizeX+ix];
00074         
00075 #ifdef VERBOSE  
00076             CkPrintf(" [%d %d] sending to YLINES [  %d %d] \n",  thisIndex.x, thisIndex.y, thisIndex.y, x);
00077 #endif  
00078             yProxy(zpos+z, x).doSecondFFT(msg);
00079         }
00080         
00081         }
00082     }
00083     else
00084     {
00085         int sendSquarewidth = ysquare[0]<=zsquare[0] ? ysquare[0]:zsquare[0];
00086         int sendDataSize = ysquare[1] * sendSquarewidth * zsquare[1];
00087         int xpos = thisIndex.x;
00088         int ypos = thisIndex.y;
00089         int index=0;
00090         complex *sendData = NULL;
00091 
00092         for(x = 0; x < zsquare[0]; x+=sendSquarewidth)
00093         for(z = 0; z < sizeZ; z+=ysquare[1]){
00094             SendFFTMsg *msg = new(sendDataSize, sizeof(int)*8) SendFFTMsg;
00095             sendData = msg->data;
00096             msg->ypos = thisIndex.y; 
00097             msg->size = sendDataSize;
00098             msg->id = fftid;
00099             msg->direction = direction;
00100             msg->data = sendData;
00101             CkSetQueueing(msg, CK_QUEUEING_IFIFO);
00102 #ifdef _PRIOMSG_
00103             int prioNum =  (z) + (x+xpos)*sizeX;
00104             *(int*)CkPriorityPtr(msg) = prioNum; 
00105 #endif  
00106             index = 0;
00107             for(iz = z; iz < z+ysquare[1]; iz++)
00108             for (ix = x; ix < x+sendSquarewidth; ix++) 
00109                 for(iy = 0; iy < zsquare[1]; iy++)
00110                 sendData[index++] = line[iz+ix*sizeZ+iy*sizeZ*zsquare[0]];
00111         
00112 #ifdef VERBOSE  
00113             CkPrintf(" [%d %d] sending   to YLINES [%d %d] \n",  thisIndex.x, thisIndex.y, z, thisIndex.x);
00114 #endif
00115             yProxy(z, xpos+x).doSecondFFT(msg);
00116         }
00117     }
00118     }
00119 }
00120 
00121 void
00122 NormalLineArray::doSecondFFT(int ypos, complex *val, int datasize, int fftid, int direction)
00123 {
00124     LineFFTinfo &fftinfo = (infoVec[fftid]->info);        
00125     int ptype = fftinfo.ptype;
00126     complex *line = fftinfo.dataPtr;
00127     int sizeY = fftinfo.sizeY;
00128     int *xsquare = fftinfo.xsquare;
00129     int *ysquare = fftinfo.ysquare;
00130     int *zsquare = fftinfo.zsquare;
00131     int expectSize = 0, expectMsg = 0;
00132     int x,y,z,baseY;
00133     int ix,iy,iz;
00134     if(direction){
00135     int sendSquarethick = ysquare[1]<=xsquare[1] ? ysquare[1]:xsquare[1];
00136     expectSize = ysquare[0]*xsquare[0] * sendSquarethick;
00137     expectMsg = sizeY/xsquare[0] * (ysquare[1]/sendSquarethick);
00138     CkAssert(datasize == expectSize);
00139     int idx = 0;
00140     for(z=0; z<sendSquarethick; z++)
00141         for(x=0; x<ysquare[0]; x++)
00142         for(y=0; y<xsquare[0]; y++)
00143             line[z*sizeY*ysquare[0]+x*sizeY+ypos+y] = val[idx++];
00144     }
00145     else {
00146     int sendSquarewidth = ysquare[0]<=zsquare[0] ? ysquare[0]:zsquare[0];
00147     expectSize = ysquare[1] * sendSquarewidth * zsquare[1];
00148     expectMsg = sizeY/zsquare[1] * (ysquare[0]/sendSquarewidth);
00149     CkAssert(datasize == expectSize);
00150     int idx=0;
00151     for(z=0; z<ysquare[1]; z++)
00152         for(x=0; x<sendSquarewidth; x++)
00153         for(y=0; y<zsquare[1]; y++)
00154             line[z*sizeY*ysquare[0]+x*sizeY+ypos+y] = val[idx++];
00155     }
00156     infoVec[fftid]->count++;
00157     if (infoVec[fftid]->count == expectMsg) {
00158     infoVec[fftid]->count = 0;
00159     int y;
00160 
00161 
00162     if(direction && ptype==PencilType::YLINE)
00163         fftw(fwdplan, ysquare[0]*ysquare[1], (fftw_complex*)line, 1, sizeY, NULL, 0, 0);
00164     else if(!direction && ptype==PencilType::YLINE)
00165         fftw(bwdplan, ysquare[0]*ysquare[1], (fftw_complex*)line, 1, sizeY, NULL, 0, 0);
00166     else
00167     CkAbort("Can't do this FFT\n");
00168 
00169 #ifdef HEAVYVERBOSE
00170     {
00171     char fname[80];
00172     snprintf(fname,80,"yline_%d.x%d.z%d.out", fftid, thisIndex.y, thisIndex.x);
00173       FILE *fp=fopen(fname,"w");
00174     for(int x = 0; x < sizeY*ysquare[0]*ysquare[1]; x++)
00175         fprintf(fp, "%d  %g %g\n", x, line[x].re, line[x].im);
00176     fclose(fp);
00177     }
00178 #endif
00179 
00180 #ifdef VERBOSE
00181     CkPrintf("Second FFT done at [%d %d]\n", thisIndex.x, thisIndex.y);
00182 #endif
00183         
00184     if(direction){
00185         int sendSquarewidth = ysquare[0]<=zsquare[0] ? ysquare[0]:zsquare[0];
00186         int sendDataSize = sendSquarewidth * ysquare[1] * zsquare[1];
00187         int xpos = thisIndex.y;
00188         int index=0;
00189         complex *sendData = NULL;
00190 
00191         for(x = 0; x < ysquare[0]; x+=sendSquarewidth)
00192         for(y = 0; y < sizeY; y+=zsquare[1]) {
00193             SendFFTMsg *msg = new(sendDataSize, sizeof(int)*8) SendFFTMsg;
00194             sendData = msg->data;
00195             msg->zpos = thisIndex.x; 
00196             msg->ypos = 0;
00197             msg->size = sendDataSize;
00198             msg->id = fftid;
00199             msg->direction = direction;
00200             msg->data = sendData;
00201             CkSetQueueing(msg, CK_QUEUEING_IFIFO);
00202 #ifdef _PRIOMSG_
00203             int prioNum =  (xpos+x) + y*sizeY;
00204             *(int*)CkPriorityPtr(msg) = prioNum; 
00205 #endif  
00206             index = 0;
00207             for(iy = y; iy < y+zsquare[1]; iy++)
00208             for(ix = x; ix < x+sendSquarewidth; ix++)
00209                 for(iz = 0; iz < ysquare[1]; iz++)
00210                 sendData[index++] = line[iz*sizeY*ysquare[0]+ix*sizeY+iy];
00211         
00212 #ifdef VERBOSE
00213             CkPrintf(" [%d %d] sending to ZLINES [  %d %d] \n",  thisIndex.x, thisIndex.y, thisIndex.y, y);
00214 #endif  
00215             (zProxy)(x+xpos, y).doThirdFFT(msg);
00216         }
00217     }
00218     else {
00219         int sendSquarethick = ysquare[1]<=xsquare[1] ? ysquare[1]:xsquare[1];
00220         int sendDataSize = ysquare[0]*xsquare[0] * sendSquarethick;
00221         int zpos = thisIndex.x;
00222         int index, ix, iy, iz;
00223         complex *sendData = NULL;
00224 
00225         for(z = 0; z < ysquare[1]; z+=sendSquarethick)
00226         for (y = 0; y < sizeY; y+=xsquare[0]) {
00227             SendFFTMsg *msg = new(sendDataSize, sizeof(int)*8) SendFFTMsg;
00228             sendData = msg->data;
00229             msg->zpos = 0;
00230             msg->ypos = thisIndex.y;
00231             msg->size = sendDataSize;
00232             msg->id = fftid;
00233             msg->direction = direction;
00234             msg->data = sendData;
00235             CkSetQueueing(msg, CK_QUEUEING_IFIFO);
00236 #ifdef _PRIOMSG_            
00237             int prioNum =  (y)*sizeY + (zpos+z);
00238             *(int*)CkPriorityPtr(msg) = prioNum; 
00239 #endif  
00240             index = 0;
00241             for(iz = z; iz < z+sendSquarethick; iz++)
00242             for(iy = y; iy < y+xsquare[0]; iy++)
00243                 for(x = 0; x < ysquare[0]; x++)
00244                 sendData[index++] = line[iz*sizeY*ysquare[0]+x*sizeY+iy];
00245 
00246 #ifdef VERBOSE
00247             CkPrintf(" [%d %d] sending to XLINES [%d %d]     \n",  thisIndex.x, thisIndex.y, y, zpos+z);
00248 #endif
00249             (xProxy)(y, zpos+z).doThirdFFT(msg);
00250         }
00251     }   
00252     }
00253 }
00254 
00255 void
00256 NormalLineArray::doThirdFFT(int zpos, int xpos, complex *val, int datasize, int fftid, int direction)
00257 {
00258     LineFFTinfo &fftinfo = (infoVec[fftid]->info);        
00259     int ptype = fftinfo.ptype;
00260     complex *line = fftinfo.dataPtr;
00261     int sizeX = fftinfo.sizeX;
00262     int sizeZ = fftinfo.sizeZ;
00263     int *xsquare = fftinfo.xsquare;
00264     int *ysquare = fftinfo.ysquare;
00265     int *zsquare = fftinfo.zsquare;
00266     int expectSize=0, expectMsg=0, offset=0, i; 
00267 
00268     int x,y,z,idx;
00269     if(direction){
00270     int sendSquarewidth = ysquare[0]<=zsquare[0] ? ysquare[0]:zsquare[0];
00271     expectSize = sendSquarewidth * ysquare[1] * zsquare[1];
00272     expectMsg = sizeZ/ysquare[1] * (zsquare[0]/sendSquarewidth);
00273     CkAssert(datasize == expectSize);
00274     idx=0;
00275     for(y=0; y<zsquare[1]; y++)
00276         for(x=0; x<sendSquarewidth; x++)
00277         for(z=0; z<ysquare[1]; z++)
00278             line[z+zpos+(x+xpos)*sizeZ+y*sizeZ*zsquare[0]] = val[idx++];
00279     }
00280     else{
00281     int sendSquarethick = ysquare[1]<=xsquare[1] ? ysquare[1]:xsquare[1];
00282     expectSize = ysquare[0]*xsquare[0] * sendSquarethick;
00283     expectMsg = sizeX/ysquare[0] * (xsquare[1]/sendSquarethick);
00284     CkAssert(datasize == expectSize);
00285     int idx=0;
00286     for(z=0; z<sendSquarethick; z++)
00287         for(y=0; y<xsquare[0]; y++)
00288         for(x=0; x<ysquare[0]; x++)
00289             line[(z+zpos)*sizeX*xsquare[0]+y*sizeX+xpos+x] = val[idx++];
00290     }
00291 
00292     infoVec[fftid]->count ++;
00293 
00294     if (infoVec[fftid]->count == expectMsg) {
00295     infoVec[fftid]->count = 0;
00296 
00297 
00298 #ifdef HEAVYVERBOSE
00299     {
00300     char fname[80];
00301     if(direction)
00302     snprintf(fname,80,"zline_%d.x%d.y%d.out", fftid, thisIndex.x, thisIndex.y);
00303     else
00304     snprintf(fname,80,"xline_%d.y%d.z%d.out", fftid, thisIndex.x, thisIndex.y);
00305       FILE *fp=fopen(fname,"w");
00306     for(int x = 0; x < sizeX*xsquare[0]*xsquare[1]; x++)
00307         fprintf(fp, "%g %g\n", line[x].re, line[x].im);
00308     fclose(fp);
00309     }
00310 #endif
00311 
00312 
00313     if(direction && ptype==PencilType::ZLINE)
00314         fftw(fwdplan, zsquare[0]*zsquare[1], (fftw_complex*)line, 1, sizeX, NULL, 0, 0);
00315     else if(!direction && ptype==PencilType::XLINE)
00316         fftw(bwdplan, xsquare[0]*xsquare[1], (fftw_complex*)line, 1, sizeX, NULL, 0, 0); 
00317     else
00318         CkAbort("Can't do this FFT\n");
00319 #ifdef VERBOSE
00320     CkPrintf("Third FFT done at [%d %d]\n", thisIndex.x, thisIndex.y);
00321 #endif
00322     doneFFT(fftid, direction);
00323 
00324     }
00325 }
00326 
00327 void 
00328 NormalLineArray::doSecondFFT(SendFFTMsg *msg){
00329     doSecondFFT(msg->ypos, msg->data, msg->size, msg->id, msg->direction);
00330     delete msg;
00331 }
00332 
00333 void 
00334 NormalLineArray::doThirdFFT(SendFFTMsg *msg){
00335     doThirdFFT(msg->zpos, msg->ypos, msg->data, msg->size, msg->id, msg->direction);
00336     delete msg;
00337 }
00338 
00339 void 
00340 NormalLineArray::doneFFT(int id, int direction){
00341 #ifdef VERBOSE
00342     CkPrintf("FFT finished \n");
00343 #endif
00344 }
00345 
00346 NormalLineArray::NormalLineArray (LineFFTinfo &info, CProxy_NormalLineArray _xProxy, CProxy_NormalLineArray _yProxy, CProxy_NormalLineArray _zProxy) {
00347 #ifdef VERBOSE
00348     CkPrintf("inserted line %d index[%d %d]\n", info.ptype, thisIndex.x, thisIndex.y);
00349 #endif
00350     setup(info, _xProxy, _yProxy, _zProxy);
00351 }
00352 
00353 void
00354 NormalLineArray::setup (LineFFTinfo &info, CProxy_NormalLineArray _xProxy, CProxy_NormalLineArray _yProxy, CProxy_NormalLineArray _zProxy) {
00355     xProxy = _xProxy;
00356     yProxy = _yProxy;
00357     zProxy = _zProxy;
00358     
00359     PencilArrayInfo *pencilinfo = new PencilArrayInfo();
00360     pencilinfo->info = info;
00361     pencilinfo->count = 0;
00362     infoVec.insert(infoVec.size(), pencilinfo);
00363     
00364     line = NULL;
00365     fwdplan = fftw_create_plan(info.sizeX, FFTW_FORWARD, FFTW_IN_PLACE);
00366     bwdplan = fftw_create_plan(info.sizeY, FFTW_BACKWARD, FFTW_IN_PLACE);
00367     id = -1;
00368 }