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 ()

Detailed Description

Definition at line 108 of file fftlib.h.


Constructor & Destructor Documentation

OptPmeZPencil_SDAG_CODE OptPmeZPencil::OptPmeZPencil (  )  [inline]

Definition at line 111 of file fftlib.h.

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

OptPmeZPencil::OptPmeZPencil ( CkMigrateMessage *   )  [inline]

Definition at line 112 of file fftlib.h.

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


Member Function Documentation

void OptPmeZPencil::backward_fft (  ) 

Definition at line 639 of file fftlib.C.

References OptPmePencil< CBase_OptPmeZPencil >::data, PmeGrid::dim3, OptPmePencilInitMsgData::grid, OptPmePencil< CBase_OptPmeZPencil >::initdata, j, PmeGrid::K1, PmeGrid::K2, PmeGrid::K3, and OptPmePencil< CBase_OptPmeZPencil >::work.

00639                                  {
00640 #ifdef NAMD_FFTW
00641 #ifdef NAMD_FFTW_3
00642   fftwf_execute(backward_plan);
00643 #else
00644   rfftwnd_complex_to_real(backward_plan, nx*ny,
00645                           (fftw_complex *) data, 1, initdata.grid.dim3/2, work, 1, 0);
00646 #endif
00647 #endif
00648   
00649 #if CMK_BLUEGENEL
00650   CmiNetworkProgress();
00651 #endif
00652 
00653 #ifdef FFTCHECK
00654   int dim3 = initdata.grid.dim3;
00655   int K1 = initdata.grid.K1;
00656   int K2 = initdata.grid.K2;
00657   int K3 = initdata.grid.K3;
00658   float scale = 1. / (1. * K1 * K2 * K3);
00659   float maxerr = 0.;
00660   float maxstd = 0.;
00661   int mi, mj, mk;  mi = mj = mk = -1;
00662   float std_base = 100. * (thisIndex.x+1.) + 10. * (thisIndex.y+1.);
00663   const float *d = data;
00664   for ( int i=0; i<nx; ++i ) {
00665    for ( int j=0; j<ny; ++j, d += dim3 ) {
00666     for ( int k=0; k<K3; ++k ) {
00667       float std = 10. * (10. * (10. * std_base + i) + j) + k;
00668       float err = scale * d[k] - std;
00669       if ( fabsf(err) > fabsf(maxerr) ) {
00670         maxerr = err;
00671         maxstd = std;
00672         mi = i;  mj = j;  mk = k;
00673       }
00674     }
00675    }
00676   }
00677   CkPrintf("pencil %d %d max error %f at %d %d %d (should be %f)\n",
00678            thisIndex.x, thisIndex.y, maxerr, mi, mj, mk, maxstd);
00679 #endif
00680 }

void OptPmeZPencil::fft_init (  ) 

Definition at line 46 of file fftlib.C.

References PmeGrid::block1, PmeGrid::block2, OptPmePencil< CBase_OptPmeZPencil >::data, PmeGrid::dim3, fftw_plan_lock, OptPmePencilInitMsgData::grid, OptPmePencil< CBase_OptPmeZPencil >::handle, OptPmePencil< CBase_OptPmeZPencil >::initdata, PmeGrid::K1, PmeGrid::K2, PmeGrid::K3, OptPmePencil< CBase_OptPmeZPencil >::many_to_many_data, OptPmePencil< CBase_OptPmeZPencil >::many_to_many_nb, NAMD_die(), OptPmePencil< CBase_OptPmeZPencil >::order_init(), Node::simParameters, simParams, OptPmePencil< CBase_OptPmeZPencil >::work, and OptPmePencilInitMsgData::zBlocks.

00046                              {
00047   
00048   //printf ("Initialize zpencil [%d,%d], on pd %d\n", thisIndex.x, thisIndex.y, CkMyPe());
00049 
00050   CProxy_Node nd(CkpvAccess(BOCclass_group).node);
00051   Node *node = nd.ckLocalBranch();
00052   SimParameters *simParams = node->simParameters;
00053 
00054   int K1 = initdata.grid.K1;
00055   int K2 = initdata.grid.K2;
00056   int K3 = initdata.grid.K3;
00057   int dim3 = initdata.grid.dim3;
00058   int block1 = initdata.grid.block1;
00059   int block2 = initdata.grid.block2;
00060 
00061   nx = block1;
00062   if ( (thisIndex.x + 1) * block1 > K1 ) nx = K1 - thisIndex.x * block1;
00063   ny = block2;
00064   if ( (thisIndex.y + 1) * block2 > K2 ) ny = K2 - thisIndex.y * block2;
00065 
00066   data = new float[nx*ny*dim3];
00067   many_to_many_data = new float[nx*ny*dim3];
00068   many_to_many_nb = new int [initdata.zBlocks];
00069   work = new float[dim3];
00070 
00071   memset(data, 0, sizeof(float) * nx*ny*dim3);
00072   memset(many_to_many_data, 0, sizeof(float) * nx*ny*dim3);
00073 
00074   order_init(initdata.zBlocks);
00075 
00076 #ifdef NAMD_FFTW
00077   CmiLock(fftw_plan_lock);
00078 #ifdef NAMD_FFTW_3
00079   /* need array of sizes for the how many */
00080   int numLines=nx*ny;
00081   int planLineSizes[1];
00082   planLineSizes[0]=K3;
00083   CkAbort("what are we doing in here?");
00084   forward_plan = fftwf_plan_many_dft_r2c(1, planLineSizes, numLines,
00085                                      (float *) data, NULL, 1, 
00086                                          initdata.grid.dim3,
00087                                          (fftwf_complex *) data, NULL, 1, 0,
00088                                    ( simParams->FFTWEstimate ? FFTW_ESTIMATE 
00089                                      : FFTW_MEASURE ));
00090   backward_plan = fftwf_plan_many_dft_c2r(1, planLineSizes, numLines,
00091                                      (fftwf_complex *) data, NULL, 1, 
00092                                          initdata.grid.dim3/2,
00093                                      (float *) data, NULL, 1, 0,
00094                                    ( simParams->FFTWEstimate ? FFTW_ESTIMATE 
00095                                      : FFTW_MEASURE ));
00096 #else
00097 
00098   forward_plan = rfftwnd_create_plan_specific(1, &K3, FFTW_REAL_TO_COMPLEX,
00099         ( simParams->FFTWEstimate ? FFTW_ESTIMATE : FFTW_MEASURE )
00100         | FFTW_IN_PLACE | FFTW_USE_WISDOM, data, 1, work, 1);
00101   backward_plan = rfftwnd_create_plan_specific(1, &K3, FFTW_COMPLEX_TO_REAL,
00102         ( simParams->FFTWEstimate ? FFTW_ESTIMATE : FFTW_MEASURE )
00103         | FFTW_IN_PLACE | FFTW_USE_WISDOM, data, 1, work, 1);
00104 #endif
00105   CmiUnlock(fftw_plan_lock);
00106 #else
00107   NAMD_die("Sorry, FFTW must be compiled in to use PME.");
00108 #endif
00109 
00110   handle = CmiDirect_manytomany_allocate_handle();
00111 }

void OptPmeZPencil::forward_fft (  ) 

Definition at line 324 of file fftlib.C.

References OptPmePencil< CBase_OptPmeZPencil >::data, PmeGrid::dim3, OptPmePencilInitMsgData::grid, OptPmePencil< CBase_OptPmeZPencil >::initdata, j, PmeGrid::K3, and OptPmePencil< CBase_OptPmeZPencil >::work.

00324                                 {
00325 #ifdef FFTCHECK
00326   int dim3 = initdata.grid.dim3;
00327   int K3 = initdata.grid.K3;
00328   float std_base = 100. * (thisIndex.x+1.) + 10. * (thisIndex.y+1.);
00329   float *d = data;
00330   for ( int i=0; i<nx; ++i ) {
00331    for ( int j=0; j<ny; ++j, d += dim3 ) {
00332     for ( int k=0; k<dim3; ++k ) {
00333       d[k] = 10. * (10. * (10. * std_base + i) + j) + k;
00334     }
00335    }
00336   }
00337 #endif
00338 #ifdef NAMD_FFTW
00339 #ifdef NAMD_FFTW_3
00340   fftwf_execute(forward_plan);
00341 #else
00342   rfftwnd_real_to_complex(forward_plan, nx*ny,
00343                           data, 1, initdata.grid.dim3, (fftw_complex *) work, 1, 0);
00344 #endif
00345 #endif
00346 }

void OptPmeZPencil::many_to_many_recv_grid (  ) 

Definition at line 730 of file fftlib.C.

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

00730                                             {
00731   int dim3 = initdata.grid.dim3;  
00732   memset(data, 0, sizeof(float) * nx*ny*dim3);
00733   int K3 = initdata.grid.K3;
00734   int K3_1 = initdata.grid.K3 - 1;
00735   int k = 0;
00736   for (int idx = 0; idx < grid_msgs.size(); idx++) {
00737     int xstart = m2m_recv_grid[idx].xstart; 
00738     int xlen   = m2m_recv_grid[idx].xlen; 
00739     int ystart = m2m_recv_grid[idx].ystart; 
00740     int ylen   = m2m_recv_grid[idx].ylen; 
00741     int zstart = m2m_recv_grid[idx].zstart; 
00742     int zlen   = m2m_recv_grid[idx].zlen;   
00743     
00744     float *qmsg = m2m_recv_grid[idx].data;
00745     for ( int i=xstart; i<xstart+xlen; ++i ) {
00746       for ( int j=ystart; j<ystart+ylen; ++j) {
00747         float *d = data + (i * ny + j) * dim3;  
00748 
00749 #pragma disjoint (*qmsg, *d)
00750 #pragma unroll (4)
00751         for ( k=zstart; k<zstart+zlen; ++k ) {
00752           int kz = k;
00753           //if (kz >= K3) kz -= K3;
00754           kz = kz - ((unsigned)(K3_1 - kz)>>31)*K3;
00755           //assert (kz >= 0);
00756           //assert (kz <  K3);
00757           d[kz] += *(qmsg++);
00758         }
00759       }
00760     } 
00761   }
00762 }

void OptPmeZPencil::many_to_many_recv_untrans (  ) 

Definition at line 949 of file fftlib.C.

References PmeGrid::block3, OptPmePencil< CBase_OptPmeZPencil >::data, PmeGrid::dim3, OptPmePencilInitMsgData::grid, OptPmePencil< CBase_OptPmeZPencil >::initdata, j, OptPmePencil< CBase_OptPmeZPencil >::many_to_many_data, OptPmePencil< CBase_OptPmeZPencil >::many_to_many_nb, OptPmePencil< CBase_OptPmeZPencil >::single_pencil, and OptPmePencilInitMsgData::zBlocks.

00949                                               {  
00950   //printf ("%d, %d In recv untrans\n", thisIndex.x, thisIndex.y);                                                                             
00951   int block3 = initdata.grid.block3;
00952   int dim3 = initdata.grid.dim3;
00953   
00954   const float *md = many_to_many_data;
00955   if (single_pencil) {
00956     float *d = data;
00957     for (int kb = 0; kb < initdata.zBlocks; kb++ ) {
00958       d[2*kb]   = *(md++);
00959       d[2*kb+1] = *(md++);
00960     }
00961   }
00962   else {
00963     for (int kb = 0; kb < initdata.zBlocks; kb++ ) {
00964       int nz = many_to_many_nb[kb];
00965       float *d = data;
00966       for ( int i=0; i<nx; ++i ) {
00967         for ( int j=0; j<ny; ++j, d += dim3 ) {
00968           for ( int k=kb*block3; k<(kb*block3+nz); ++k ) {
00969             d[2*k] = *(md++);
00970             d[2*k+1] = *(md++);
00971           }
00972         }
00973       }
00974     }
00975   }
00976 }

void OptPmeZPencil::many_to_many_send_trans (  ) 

Definition at line 764 of file fftlib.C.

References PmeGrid::block3, OptPmePencil< CBase_OptPmeZPencil >::data, PmeGrid::dim3, OptPmePencilInitMsgData::grid, OptPmePencil< CBase_OptPmeZPencil >::handle, OptPmePencil< CBase_OptPmeZPencil >::initdata, j, OptPmePencil< CBase_OptPmeZPencil >::many_to_many_data, PHASE_YF, OptPmePencil< CBase_OptPmeZPencil >::single_pencil, and OptPmePencilInitMsgData::zBlocks.

00764                                             {
00765   int zBlocks = initdata.zBlocks;
00766   int block3 = initdata.grid.block3;
00767   int dim3 = initdata.grid.dim3;
00768 
00769   float *md = many_to_many_data;
00770   if (single_pencil) {
00771     const float *d = data;
00772     for ( int kb=0; kb<zBlocks; ++kb ) {
00773       *(md++) = d[2*kb];
00774       *(md++) = d[2*kb+1];
00775     }
00776   }
00777   else {
00778     int nz = block3;
00779     for ( int kb=0; kb<zBlocks; ++kb ) {
00780       nz = block3;
00781       if ( (kb+1)*block3 > dim3/2 ) nz = dim3/2 - kb*block3;
00782       
00783       const float *d = data;
00784       for ( int i=0; i<nx; ++i ) {
00785         for ( int j=0; j<ny; ++j, d += dim3 ) {
00786           for ( int k=kb*block3; k<(kb*block3+nz); ++k ) {
00787             *(md++) = d[2*k];
00788             *(md++) = d[2*k+1];
00789           }
00790         }
00791       }
00792     }
00793   }
00794 
00795   CmiDirect_manytomany_start (handle, PHASE_YF);
00796 }

void OptPmeZPencil::many_to_many_send_ungrid (  ) 

Definition at line 978 of file fftlib.C.

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

00978                                               {
00979   int dim3 = initdata.grid.dim3;
00980   int K3 = initdata.grid.K3;
00981   int K3_1 = initdata.grid.K3 - 1;
00982   int k = 0;
00983   for (int idx = 0; idx < grid_msgs.size(); idx++) {
00984     int xstart = m2m_recv_grid[idx].xstart; 
00985     int xlen   = m2m_recv_grid[idx].xlen; 
00986     int ystart = m2m_recv_grid[idx].ystart; 
00987     int ylen   = m2m_recv_grid[idx].ylen; 
00988     int zstart = m2m_recv_grid[idx].zstart; 
00989     int zlen   = m2m_recv_grid[idx].zlen;   
00990     
00991     float *qmsg = m2m_recv_grid[idx].data;
00992     for ( int i=xstart; i<xstart+xlen; ++i ) {
00993       for ( int j=ystart; j<ystart+ylen; ++j) {
00994         float *d = data + (i * ny + j) * dim3;  
00995 
00996 #pragma disjoint (*d, *qmsg)
00997 #pragma unroll (4)
00998         for ( k=zstart; k<zstart+zlen; ++k ) {
00999           int kz = k;
01000           //if (kz >= K3) kz -= K3;
01001           kz = kz - ((unsigned)(K3_1 - kz)>>31)*K3;
01002           //assert (kz >= 0);
01003           //assert (kz <  K3);
01004           *(qmsg++) = d[kz];
01005         }
01006       }
01007     } 
01008   }
01009   
01010   CmiDirect_manytomany_start (handle, PHASE_UG);
01011 }

void OptPmeZPencil::recv_grid ( const OptPmeGridMsg  ) 

Definition at line 262 of file fftlib.C.

References OptPmePencil< CBase_OptPmeZPencil >::_iter, PmeGrid::block1, PmeGrid::block2, OptPmePencil< CBase_OptPmeZPencil >::data, PmeGrid::dim3, OptPmePencilInitMsgData::grid, OptPmePencil< CBase_OptPmeZPencil >::imsg, OptPmePencil< CBase_OptPmeZPencil >::initdata, j, PmeGrid::K3, MANY_TO_MANY_SETUP, 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.

00262                                                       {
00263 
00264   int dim3 = initdata.grid.dim3;
00265   if ( imsg == 0 ) {
00266     memset(data, 0, sizeof(float) * nx*ny*dim3);
00267   }
00268 
00269   int xstart = msg->xstart - thisIndex.x * initdata.grid.block1;
00270   int ystart = msg->ystart - thisIndex.y * initdata.grid.block2;
00271   assert (xstart >= 0);
00272   assert (ystart >= 0);
00273   int xlen   = msg->xlen;
00274   int ylen   = msg->ylen;    
00275   assert (xstart + xlen <= nx);
00276   assert (ystart + ylen <= ny);
00277   
00278   float *qmsg = msg->qgrid;
00279   float *d = data;
00280   int zlen = msg->zlen;
00281   int zstart = msg->zstart;
00282   int zmax = zstart + zlen - 1;
00283   int k = 0;
00284 
00285   int K3 = initdata.grid.K3; 
00286   int K3_1 = initdata.grid.K3 - 1; 
00287   while (zstart < 0) {
00288     zstart += K3;
00289     zmax += K3;
00290   }
00291 
00292   for ( int i=xstart; i<xstart+xlen; ++i ) {
00293     for ( int j=ystart; j<ystart+ylen; ++j) {
00294       float *d = data + (i * ny + j) * dim3; 
00295       for ( k=zstart; k<=zmax; ++k ) {
00296         int kz = k;
00297         //if (kz >= K3) kz -= K3;
00298         kz = kz - ((unsigned)(K3_1 - kz)>>31)*K3;
00299         //assert (kz >= 0);
00300         //assert (kz <  K3);
00301         d[kz] += *(qmsg++);
00302       }
00303     }
00304   }
00305 
00306   if (_iter == MANY_TO_MANY_SETUP) {
00307     if (imsg == 0)
00308       m2m_recv_grid = new PatchGridElem [grid_msgs.size()];    
00309     
00310     m2m_recv_grid[imsg].xstart = xstart;
00311     m2m_recv_grid[imsg].xlen   = xlen;
00312     m2m_recv_grid[imsg].ystart = ystart;
00313     m2m_recv_grid[imsg].ylen   = ylen;
00314     m2m_recv_grid[imsg].zstart = zstart;
00315     m2m_recv_grid[imsg].zlen   = zlen;
00316     m2m_recv_grid[imsg].patchID = msg->patchID;
00317     
00318     if ( imsg == grid_msgs.size() - 1) 
00319         initialize_manytomany ();
00320   }
00321 }

void OptPmeZPencil::recv_untrans ( const OptPmeFFTMsg  ) 

Definition at line 618 of file fftlib.C.

References PmeGrid::block3, OptPmePencil< CBase_OptPmeZPencil >::data, PmeGrid::dim3, OptPmePencilInitMsgData::grid, OptPmePencil< CBase_OptPmeZPencil >::initdata, j, OptPmeFFTMsg::nx, OptPmeFFTMsg::qgrid, and OptPmeFFTMsg::sourceNode.

00618                                                         {
00619 
00620   //printf ("%d, %d In recv untrans\n", thisIndex.x, thisIndex.y);
00621 
00622   int block3 = initdata.grid.block3;
00623   int dim3 = initdata.grid.dim3;
00624   int kb = msg->sourceNode;
00625   int nz = msg->nx;
00626   const float *md = msg->qgrid;
00627   float *d = data;
00628   for ( int i=0; i<nx; ++i ) {
00629     for ( int j=0; j<ny; ++j, d += dim3 ) {
00630       for ( int k=kb*block3; k<(kb*block3+nz); ++k ) {
00631         d[2*k] = *(md++);
00632         d[2*k+1] = *(md++);
00633       }
00634     }
00635   }
00636 }

void OptPmeZPencil::send_trans (  ) 

Definition at line 348 of file fftlib.C.

References PmeGrid::block3, OptPmePencil< CBase_OptPmeZPencil >::data, PmeGrid::dim3, OptPmePencilInitMsgData::grid, OptPmePencil< CBase_OptPmeZPencil >::initdata, j, OptPmeFFTMsg::nx, PRIORITY_SIZE, OptPmeFFTMsg::qgrid, OptPmePencil< CBase_OptPmeZPencil >::send_order, OptPmeFFTMsg::sourceNode, OptPmePencilInitMsgData::yPencil, and OptPmePencilInitMsgData::zBlocks.

00348                                {
00349   int zBlocks = initdata.zBlocks;
00350   int block3 = initdata.grid.block3;
00351   int dim3 = initdata.grid.dim3;
00352 
00353   //int offset = 0;
00354   for ( int isend=0; isend<zBlocks; ++isend ) {
00355     int kb = send_order[isend];
00356     int nz = block3;
00357     if ( (kb+1)*block3 > dim3/2 ) nz = dim3/2 - kb*block3;
00358     //assert (nz > 0);
00359     OptPmeFFTMsg *msg = new (nx*ny*nz*2,PRIORITY_SIZE) OptPmeFFTMsg;
00360     msg->sourceNode = thisIndex.y;
00361     msg->nx = ny;
00362     float *md = msg->qgrid;
00363     const float *d = data;
00364     for ( int i=0; i<nx; ++i ) {
00365       for ( int j=0; j<ny; ++j, d += dim3 ) {
00366         for ( int k=kb*block3; k<(kb*block3+nz); ++k ) {
00367           *(md++) = d[2*k];
00368           *(md++) = d[2*k+1];
00369         }
00370       }
00371     }          
00372     //    printf ("%d, %d: Zpencil Sending trans to %d, %d\n", thisIndex.x, thisIndex.y, thisIndex.x, kb);
00373     initdata.yPencil(thisIndex.x,0,kb).recvTrans(msg);
00374   }
00375 }

void OptPmeZPencil::send_ungrid ( OptPmeGridMsg  ) 

Definition at line 682 of file fftlib.C.

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

00682                                                   {
00683   int pe = msg->sourceNode;
00684   msg->sourceNode = thisIndex.x * initdata.yBlocks + thisIndex.y;
00685 
00686   int dim3 = initdata.grid.dim3;
00687   int xstart = msg->xstart - thisIndex.x * initdata.grid.block1;
00688   int ystart = msg->ystart - thisIndex.y * initdata.grid.block2;
00689   assert (xstart >= 0);
00690   assert (ystart >= 0);
00691   int xlen   = msg->xlen;
00692   int ylen   = msg->ylen;
00693   assert (xstart + xlen <= nx);
00694   assert (ystart + ylen <= ny);
00695 
00696   float *qmsg = msg->qgrid;
00697   float *d = data;
00698   int zstart = msg->zstart;
00699   int zlen = msg->zlen;
00700   int zmax = zstart + zlen - 1;
00701   
00702   int K3_1 = initdata.grid.K3 - 1; 
00703   int K3 = initdata.grid.K3;
00704   if (zstart < 0) {
00705     zstart += K3;
00706     zmax += K3;
00707   }
00708   
00709   int k = 0;
00710   for ( int i=xstart; i<xstart+xlen; ++i ) {
00711     for ( int j=ystart; j<ystart+ylen; ++j) {
00712       float *d = data + (i * ny + j) * dim3;
00713       for ( k=zstart; k<=zmax; ++k ) {
00714         int kz = k;
00715         //if (kz >= K3) kz -= K3;
00716         kz = kz - ((unsigned)(K3_1 - kz)>>31)*K3;
00717         *(qmsg++) = d[kz];
00718       }
00719     }
00720   }
00721   
00722   initdata.pmeProxy[pe].recvUngrid(msg);
00723 }


The documentation for this class was generated from the following files:
Generated on Mon Sep 25 01:17:19 2017 for NAMD by  doxygen 1.4.7