Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

OptPmeZPencil Class Reference

#include <fftlib.h>

Inheritance diagram for OptPmeZPencil:

OptPmePencil< CBase_OptPmeZPencil > CBase_OptPmeZPencil List of all members.

Public Member Functions

OptPmeZPencil_SDAG_CODE OptPmeZPencil ()
 OptPmeZPencil (CkMigrateMessage *)
void fft_init ()
void recv_grid (const OptPmeGridMsg *)
void many_to_many_recv_grid ()
void forward_fft ()
void send_trans ()
void many_to_many_send_trans ()
void recv_untrans (const OptPmeFFTMsg *)
void many_to_many_recv_untrans ()
void backward_fft ()
void send_ungrid (OptPmeGridMsg *)
void many_to_many_send_ungrid ()

Constructor & Destructor Documentation

OptPmeZPencil_SDAG_CODE OptPmeZPencil::OptPmeZPencil  )  [inline]
 

Definition at line 109 of file fftlib.h.

00109 { __sdag_init(); setMigratable(false); }

OptPmeZPencil::OptPmeZPencil CkMigrateMessage *   )  [inline]
 

Definition at line 110 of file fftlib.h.

00110 { __sdag_init();  setMigratable (false); }


Member Function Documentation

void OptPmeZPencil::backward_fft  ) 
 

Definition at line 515 of file fftlib.C.

References PmeGrid::dim3, OptPmePencilInitMsgData::grid, j, PmeGrid::K1, PmeGrid::K2, and PmeGrid::K3.

00515                                  {
00516 #ifdef NAMD_FFTW
00517   rfftwnd_complex_to_real(backward_plan, nx*ny,
00518                           (fftw_complex *) data, 1, initdata.grid.dim3/2, work, 1, 0);
00519 #endif
00520   
00521 #if CMK_BLUEGENEL
00522   CmiNetworkProgress();
00523 #endif
00524 
00525 #ifdef FFTCHECK
00526   int dim3 = initdata.grid.dim3;
00527   int K1 = initdata.grid.K1;
00528   int K2 = initdata.grid.K2;
00529   int K3 = initdata.grid.K3;
00530   float scale = 1. / (1. * K1 * K2 * K3);
00531   float maxerr = 0.;
00532   float maxstd = 0.;
00533   int mi, mj, mk;  mi = mj = mk = -1;
00534   float std_base = 100. * (thisIndex.x+1.) + 10. * (thisIndex.y+1.);
00535   const float *d = data;
00536   for ( int i=0; i<nx; ++i ) {
00537    for ( int j=0; j<ny; ++j, d += dim3 ) {
00538     for ( int k=0; k<K3; ++k ) {
00539       float std = 10. * (10. * (10. * std_base + i) + j) + k;
00540       float err = scale * d[k] - std;
00541       if ( fabsf(err) > fabsf(maxerr) ) {
00542         maxerr = err;
00543         maxstd = std;
00544         mi = i;  mj = j;  mk = k;
00545       }
00546     }
00547    }
00548   }
00549   CkPrintf("pencil %d %d max error %f at %d %d %d (should be %f)\n",
00550            thisIndex.x, thisIndex.y, maxerr, mi, mj, mk, maxstd);
00551 #endif
00552 }

void OptPmeZPencil::fft_init  ) 
 

Definition at line 11 of file fftlib.C.

References PmeGrid::block1, PmeGrid::block2, PmeGrid::dim3, SimParameters::FFTWEstimate, OptPmePencilInitMsgData::grid, PmeGrid::K1, PmeGrid::K2, PmeGrid::K3, NAMD_die(), OptPmePencil< CBase_OptPmeZPencil >::order_init(), Node::simParameters, simParams, and OptPmePencilInitMsgData::zBlocks.

00011                              {
00012   
00013   //printf ("Initialize zpencil [%d,%d], on pd %d\n", thisIndex.x, thisIndex.y, CkMyPe());
00014 
00015   CProxy_Node nd(CkpvAccess(BOCclass_group).node);
00016   Node *node = nd.ckLocalBranch();
00017   SimParameters *simParams = node->simParameters;
00018 
00019   int K1 = initdata.grid.K1;
00020   int K2 = initdata.grid.K2;
00021   int K3 = initdata.grid.K3;
00022   int dim3 = initdata.grid.dim3;
00023   int block1 = initdata.grid.block1;
00024   int block2 = initdata.grid.block2;
00025 
00026   nx = block1;
00027   if ( (thisIndex.x + 1) * block1 > K1 ) nx = K1 - thisIndex.x * block1;
00028   ny = block2;
00029   if ( (thisIndex.y + 1) * block2 > K2 ) ny = K2 - thisIndex.y * block2;
00030 
00031   data = new float[nx*ny*dim3];
00032   many_to_many_data = new float[nx*ny*dim3];
00033   many_to_many_nb = new int [initdata.zBlocks];
00034   work = new float[dim3];
00035 
00036   memset(data, 0, sizeof(float) * nx*ny*dim3);
00037   memset(many_to_many_data, 0, sizeof(float) * nx*ny*dim3);
00038 
00039   order_init(initdata.zBlocks);
00040 
00041 #ifdef NAMD_FFTW
00042   CmiLock(fftw_plan_lock);
00043 
00044   forward_plan = rfftwnd_create_plan_specific(1, &K3, FFTW_REAL_TO_COMPLEX,
00045         ( simParams->FFTWEstimate ? FFTW_ESTIMATE : FFTW_MEASURE )
00046         | FFTW_IN_PLACE | FFTW_USE_WISDOM, data, 1, work, 1);
00047   backward_plan = rfftwnd_create_plan_specific(1, &K3, FFTW_COMPLEX_TO_REAL,
00048         ( simParams->FFTWEstimate ? FFTW_ESTIMATE : FFTW_MEASURE )
00049         | FFTW_IN_PLACE | FFTW_USE_WISDOM, data, 1, work, 1);
00050 
00051   CmiUnlock(fftw_plan_lock);
00052 #else
00053   NAMD_die("Sorry, FFTW must be compiled in to use PME.");
00054 #endif
00055 
00056   handle = NULL; 
00057 #if CHARM_VERSION > 60000
00058   handle = CmiDirect_manytomany_allocate_handle();
00059 #endif
00060 }

void OptPmeZPencil::forward_fft  ) 
 

Definition at line 239 of file fftlib.C.

References PmeGrid::dim3, OptPmePencilInitMsgData::grid, j, and PmeGrid::K3.

00239                                 {
00240 #ifdef FFTCHECK
00241   int dim3 = initdata.grid.dim3;
00242   int K3 = initdata.grid.K3;
00243   float std_base = 100. * (thisIndex.x+1.) + 10. * (thisIndex.y+1.);
00244   float *d = data;
00245   for ( int i=0; i<nx; ++i ) {
00246    for ( int j=0; j<ny; ++j, d += dim3 ) {
00247     for ( int k=0; k<dim3; ++k ) {
00248       d[k] = 10. * (10. * (10. * std_base + i) + j) + k;
00249     }
00250    }
00251   }
00252 #endif
00253 #ifdef NAMD_FFTW
00254   rfftwnd_real_to_complex(forward_plan, nx*ny,
00255                           data, 1, initdata.grid.dim3, (fftw_complex *) work, 1, 0);
00256 #endif
00257 }

void OptPmeZPencil::many_to_many_recv_grid  ) 
 

Definition at line 602 of file fftlib.C.

References PatchGridElem::data, PmeGrid::dim3, OptPmePencilInitMsgData::grid, j, PmeGrid::K3, ResizeArray< Elem >::size(), PatchGridElem::xlen, PatchGridElem::xstart, PatchGridElem::ylen, PatchGridElem::ystart, PatchGridElem::zlen, and PatchGridElem::zstart.

00602                                             {
00603   int dim3 = initdata.grid.dim3;  
00604   memset(data, 0, sizeof(float) * nx*ny*dim3);
00605   int K3 = initdata.grid.K3;
00606   int K3_1 = initdata.grid.K3 - 1;
00607   int k = 0;
00608   for (int idx = 0; idx < grid_msgs.size(); idx++) {
00609     int xstart = m2m_recv_grid[idx].xstart; 
00610     int xlen   = m2m_recv_grid[idx].xlen; 
00611     int ystart = m2m_recv_grid[idx].ystart; 
00612     int ylen   = m2m_recv_grid[idx].ylen; 
00613     int zstart = m2m_recv_grid[idx].zstart; 
00614     int zlen   = m2m_recv_grid[idx].zlen;   
00615     
00616     float *qmsg = m2m_recv_grid[idx].data;
00617     for ( int i=xstart; i<xstart+xlen; ++i ) {
00618       for ( int j=ystart; j<ystart+ylen; ++j) {
00619         float *d = data + (i * ny + j) * dim3;  
00620 
00621 #pragma disjoint (*qmsg, *d)
00622 #pragma unroll (4)
00623         for ( k=zstart; k<zstart+zlen; ++k ) {
00624           int kz = k;
00625           //if (kz >= K3) kz -= K3;
00626           kz = kz - ((unsigned)(K3_1 - kz)>>31)*K3;
00627           //assert (kz >= 0);
00628           //assert (kz <  K3);
00629           d[kz] += *(qmsg++);
00630         }
00631       }
00632     } 
00633   }
00634 }

void OptPmeZPencil::many_to_many_recv_untrans  ) 
 

Definition at line 774 of file fftlib.C.

References PmeGrid::block3, PmeGrid::dim3, OptPmePencilInitMsgData::grid, j, and OptPmePencilInitMsgData::zBlocks.

00774                                               {  
00775   //printf ("%d, %d In recv untrans\n", thisIndex.x, thisIndex.y);                                                                             
00776   int block3 = initdata.grid.block3;
00777   int dim3 = initdata.grid.dim3;
00778   
00779   const float *md = many_to_many_data;
00780   for (int kb = 0; kb < initdata.zBlocks; kb++ ) {
00781     int nz = many_to_many_nb[kb];
00782     float *d = data;
00783     for ( int i=0; i<nx; ++i ) {
00784       for ( int j=0; j<ny; ++j, d += dim3 ) {
00785         for ( int k=kb*block3; k<(kb*block3+nz); ++k ) {
00786           d[2*k] = *(md++);
00787           d[2*k+1] = *(md++);
00788         }
00789       }
00790     }
00791   }
00792 }

void OptPmeZPencil::many_to_many_send_trans  ) 
 

Definition at line 636 of file fftlib.C.

References PmeGrid::block3, PmeGrid::dim3, OptPmePencilInitMsgData::grid, j, PHASE_YF, and OptPmePencilInitMsgData::zBlocks.

00636                                             {
00637   int zBlocks = initdata.zBlocks;
00638   int block3 = initdata.grid.block3;
00639   int dim3 = initdata.grid.dim3;
00640 
00641   float *md = many_to_many_data;
00642   int nz = block3;
00643   for ( int kb=0; kb<zBlocks; ++kb ) {
00644     nz = block3;
00645     if ( (kb+1)*block3 > dim3/2 ) nz = dim3/2 - kb*block3;
00646     
00647     const float *d = data;
00648     for ( int i=0; i<nx; ++i ) {
00649       for ( int j=0; j<ny; ++j, d += dim3 ) {
00650         for ( int k=kb*block3; k<(kb*block3+nz); ++k ) {
00651           *(md++) = d[2*k];
00652           *(md++) = d[2*k+1];
00653         }
00654       }
00655     }
00656   }
00657   
00658 #if CHARM_VERSION > 60000
00659   CmiDirect_manytomany_start (handle, PHASE_YF);
00660 #endif
00661 }

void OptPmeZPencil::many_to_many_send_ungrid  ) 
 

Definition at line 794 of file fftlib.C.

References PatchGridElem::data, PmeGrid::dim3, OptPmePencilInitMsgData::grid, j, PmeGrid::K3, PHASE_UG, ResizeArray< Elem >::size(), PatchGridElem::xlen, PatchGridElem::xstart, PatchGridElem::ylen, PatchGridElem::ystart, PatchGridElem::zlen, and PatchGridElem::zstart.

00794                                               {
00795   int dim3 = initdata.grid.dim3;
00796   int K3 = initdata.grid.K3;
00797   int K3_1 = initdata.grid.K3 - 1;
00798   int k = 0;
00799   for (int idx = 0; idx < grid_msgs.size(); idx++) {
00800     int xstart = m2m_recv_grid[idx].xstart; 
00801     int xlen   = m2m_recv_grid[idx].xlen; 
00802     int ystart = m2m_recv_grid[idx].ystart; 
00803     int ylen   = m2m_recv_grid[idx].ylen; 
00804     int zstart = m2m_recv_grid[idx].zstart; 
00805     int zlen   = m2m_recv_grid[idx].zlen;   
00806     
00807     float *qmsg = m2m_recv_grid[idx].data;
00808     for ( int i=xstart; i<xstart+xlen; ++i ) {
00809       for ( int j=ystart; j<ystart+ylen; ++j) {
00810         float *d = data + (i * ny + j) * dim3;  
00811 
00812 #pragma disjoint (*d, *qmsg)
00813 #pragma unroll (4)
00814         for ( k=zstart; k<zstart+zlen; ++k ) {
00815           int kz = k;
00816           //if (kz >= K3) kz -= K3;
00817           kz = kz - ((unsigned)(K3_1 - kz)>>31)*K3;
00818           //assert (kz >= 0);
00819           //assert (kz <  K3);
00820           *(qmsg++) = d[kz];
00821         }
00822       }
00823     } 
00824   }
00825   
00826 #if CHARM_VERSION > 60000
00827   CmiDirect_manytomany_start (handle, PHASE_UG);
00828 #endif
00829 }

void OptPmeZPencil::recv_grid const OptPmeGridMsg  ) 
 

Definition at line 177 of file fftlib.C.

References PmeGrid::block1, PmeGrid::block2, PmeGrid::dim3, OptPmePencilInitMsgData::grid, j, PmeGrid::K3, OptPmeGridMsg::patchID, PatchGridElem::patchID, OptPmeGridMsg::qgrid, ResizeArray< Elem >::size(), PatchGridElem::xlen, OptPmeGridMsg::xlen, PatchGridElem::xstart, OptPmeGridMsg::xstart, PatchGridElem::ylen, OptPmeGridMsg::ylen, PatchGridElem::ystart, OptPmeGridMsg::ystart, PatchGridElem::zlen, OptPmeGridMsg::zlen, PatchGridElem::zstart, and OptPmeGridMsg::zstart.

00177                                                       {
00178 
00179   int dim3 = initdata.grid.dim3;
00180   if ( imsg == 0 ) {
00181     memset(data, 0, sizeof(float) * nx*ny*dim3);
00182   }
00183 
00184   int xstart = msg->xstart - thisIndex.x * initdata.grid.block1;
00185   int ystart = msg->ystart - thisIndex.y * initdata.grid.block2;
00186   assert (xstart >= 0);
00187   assert (ystart >= 0);
00188   int xlen   = msg->xlen;
00189   int ylen   = msg->ylen;    
00190   assert (xstart + xlen <= nx);
00191   assert (ystart + ylen <= ny);
00192   
00193   float *qmsg = msg->qgrid;
00194   float *d = data;
00195   int zlen = msg->zlen;
00196   int zstart = msg->zstart;
00197   int zmax = zstart + zlen - 1;
00198   int k = 0;
00199 
00200   int K3 = initdata.grid.K3; 
00201   int K3_1 = initdata.grid.K3 - 1; 
00202   while (zstart < 0) {
00203     zstart += K3;
00204     zmax += K3;
00205   }
00206 
00207   for ( int i=xstart; i<xstart+xlen; ++i ) {
00208     for ( int j=ystart; j<ystart+ylen; ++j) {
00209       float *d = data + (i * ny + j) * dim3; 
00210       for ( k=zstart; k<=zmax; ++k ) {
00211         int kz = k;
00212         //if (kz >= K3) kz -= K3;
00213         kz = kz - ((unsigned)(K3_1 - kz)>>31)*K3;
00214         //assert (kz >= 0);
00215         //assert (kz <  K3);
00216         d[kz] += *(qmsg++);
00217       }
00218     }
00219   }
00220 
00221   if (_iter == MANY_TO_MANY_SETUP) {
00222     if (imsg == 0)
00223       m2m_recv_grid = new PatchGridElem [grid_msgs.size()];    
00224     
00225     m2m_recv_grid[imsg].xstart = xstart;
00226     m2m_recv_grid[imsg].xlen   = xlen;
00227     m2m_recv_grid[imsg].ystart = ystart;
00228     m2m_recv_grid[imsg].ylen   = ylen;
00229     m2m_recv_grid[imsg].zstart = zstart;
00230     m2m_recv_grid[imsg].zlen   = zlen;
00231     m2m_recv_grid[imsg].patchID = msg->patchID;
00232     
00233     if ( imsg == grid_msgs.size() - 1) 
00234         initialize_manytomany ();
00235   }
00236 }

void OptPmeZPencil::recv_untrans const OptPmeFFTMsg  ) 
 

Definition at line 494 of file fftlib.C.

References PmeGrid::block3, PmeGrid::dim3, OptPmePencilInitMsgData::grid, j, OptPmeFFTMsg::nx, OptPmeFFTMsg::qgrid, and OptPmeFFTMsg::sourceNode.

00494                                                         {
00495 
00496   //printf ("%d, %d In recv untrans\n", thisIndex.x, thisIndex.y);
00497 
00498   int block3 = initdata.grid.block3;
00499   int dim3 = initdata.grid.dim3;
00500   int kb = msg->sourceNode;
00501   int nz = msg->nx;
00502   const float *md = msg->qgrid;
00503   float *d = data;
00504   for ( int i=0; i<nx; ++i ) {
00505     for ( int j=0; j<ny; ++j, d += dim3 ) {
00506       for ( int k=kb*block3; k<(kb*block3+nz); ++k ) {
00507         d[2*k] = *(md++);
00508         d[2*k+1] = *(md++);
00509       }
00510     }
00511   }
00512 }

void OptPmeZPencil::send_trans  ) 
 

Definition at line 259 of file fftlib.C.

References PmeGrid::block3, PmeGrid::dim3, OptPmePencilInitMsgData::grid, j, OptPmeFFTMsg::nx, OptPmeFFTMsg::qgrid, OptPmeFFTMsg::sourceNode, OptPmePencilInitMsgData::yPencil, and OptPmePencilInitMsgData::zBlocks.

00259                                {
00260   int zBlocks = initdata.zBlocks;
00261   int block3 = initdata.grid.block3;
00262   int dim3 = initdata.grid.dim3;
00263 
00264   //int offset = 0;
00265   for ( int isend=0; isend<zBlocks; ++isend ) {
00266     int kb = send_order[isend];
00267     int nz = block3;
00268     if ( (kb+1)*block3 > dim3/2 ) nz = dim3/2 - kb*block3;
00269     //assert (nz > 0);
00270     OptPmeFFTMsg *msg = new (nx*ny*nz*2,PRIORITY_SIZE) OptPmeFFTMsg;
00271     msg->sourceNode = thisIndex.y;
00272     msg->nx = ny;
00273     float *md = msg->qgrid;
00274     const float *d = data;
00275     for ( int i=0; i<nx; ++i ) {
00276       for ( int j=0; j<ny; ++j, d += dim3 ) {
00277         for ( int k=kb*block3; k<(kb*block3+nz); ++k ) {
00278           *(md++) = d[2*k];
00279           *(md++) = d[2*k+1];
00280         }
00281       }
00282     }
00283     
00284     //    printf ("%d, %d: Zpencil Sending trans to %d, %d\n", thisIndex.x, thisIndex.y, thisIndex.x, kb);
00285     initdata.yPencil(thisIndex.x,0,kb).recvTrans(msg);
00286   }
00287 }

void OptPmeZPencil::send_ungrid OptPmeGridMsg  ) 
 

Definition at line 554 of file fftlib.C.

References PmeGrid::block1, PmeGrid::block2, PmeGrid::dim3, OptPmePencilInitMsgData::grid, j, PmeGrid::K3, OptPmePencilInitMsgData::pmeProxy, OptPmeGridMsg::qgrid, OptPmeGridMsg::sourceNode, OptPmeGridMsg::xlen, OptPmeGridMsg::xstart, OptPmePencilInitMsgData::yBlocks, OptPmeGridMsg::ylen, OptPmeGridMsg::ystart, OptPmeGridMsg::zlen, and OptPmeGridMsg::zstart.

00554                                                   {
00555   int pe = msg->sourceNode;
00556   msg->sourceNode = thisIndex.x * initdata.yBlocks + thisIndex.y;
00557 
00558   int dim3 = initdata.grid.dim3;
00559   int xstart = msg->xstart - thisIndex.x * initdata.grid.block1;
00560   int ystart = msg->ystart - thisIndex.y * initdata.grid.block2;
00561   assert (xstart >= 0);
00562   assert (ystart >= 0);
00563   int xlen   = msg->xlen;
00564   int ylen   = msg->ylen;
00565   assert (xstart + xlen <= nx);
00566   assert (ystart + ylen <= ny);
00567 
00568   float *qmsg = msg->qgrid;
00569   float *d = data;
00570   int zstart = msg->zstart;
00571   int zlen = msg->zlen;
00572   int zmax = zstart + zlen - 1;
00573   
00574   int K3_1 = initdata.grid.K3 - 1; 
00575   int K3 = initdata.grid.K3;
00576   if (zstart < 0) {
00577     zstart += K3;
00578     zmax += K3;
00579   }
00580   
00581   int k = 0;
00582   for ( int i=xstart; i<xstart+xlen; ++i ) {
00583     for ( int j=ystart; j<ystart+ylen; ++j) {
00584       float *d = data + (i * ny + j) * dim3;
00585       for ( k=zstart; k<=zmax; ++k ) {
00586         int kz = k;
00587         //if (kz >= K3) kz -= K3;
00588         kz = kz - ((unsigned)(K3_1 - kz)>>31)*K3;
00589         *(qmsg++) = d[kz];
00590       }
00591     }
00592   }
00593   
00594   initdata.pmeProxy[pe].recvUngrid(msg);
00595 }


The documentation for this class was generated from the following files:
Generated on Sat Nov 7 04:07:55 2009 for NAMD by  doxygen 1.3.9.1