msgQ test: Adjust test parameters (num priorities, numiters)
[charm.git] / tests / charm++ / pmetest / patch.C
1
2 #include "patch.h"
3
4 ///
5 ///  \brief This entry function initializes the patch grid array. The
6 ///  grid array tells the patch which messages to send to which PME
7 ///  array elements. First the X,Y,Z bounds for in the charge grid is
8 ///  computed and then all the intersecting X Pencils are isolated.
9 ///  This function currently assumes each patch evenly divides the
10 ///  charge grid.
11 ///
12 void Patch::initialize (PatchInfo &info) {  
13   _info = info;
14   
15   int start_y, start_z, size_y, size_z;
16   
17   start_y = (_info.fftinfo.sizeY * _info.my_y) / _info.ny;
18   size_y  = (_info.fftinfo.sizeY + _info.ny - 1) /  _info.ny;
19   
20   start_z = (_info.fftinfo.sizeZ * _info.my_z) / _info.nz;
21   size_z  = (_info.fftinfo.sizeZ + _info.nz - 1) / _info.nz;
22
23   ///
24   /// \brief Since we have an interpolation grid with periodic boundry
25   /// conditions, we have to wrap some charges around
26   ///  
27   size_y += 2*INTERPOLATION_SIZE;
28   size_z += 2*INTERPOLATION_SIZE;   
29   start_y -= INTERPOLATION_SIZE;
30   start_z -= INTERPOLATION_SIZE;
31   
32   //number of x pencils along y and z dimensions
33   int nz_pblocks, ny_pblocks;
34   nz_pblocks = (_info.fftinfo.sizeY / _info.fftinfo.grainY);
35   ny_pblocks = (_info.fftinfo.sizeZ / _info.fftinfo.grainZ); 
36   
37   //Find all pencils that the patch will send messages to
38   int *pencilmap = new int [nz_pblocks * ny_pblocks];
39   memset (pencilmap, 0, (nz_pblocks * ny_pblocks) * sizeof(int));
40
41   int ngrid_msgs = 0;
42   int y = 0, z = 0;
43
44   int ywrap = ((INTERPOLATION_SIZE + _info.fftinfo.grainY -1) /
45                _info.fftinfo.grainY);
46   int zwrap = ((INTERPOLATION_SIZE + _info.fftinfo.grainZ -1) / 
47                _info.fftinfo.grainZ);
48
49 #if __TEST_PME_VERBOSE__
50   CkPrintf ("%d: In initialize (starty, startz, sizey, sizez)=(%d, %d, %d, %d)\n", 
51             CkMyPe(), start_y, start_z, size_y, size_z);
52   CkPrintf ("%d: In initialize (ywrap, zwrap) = (%d, %d)\n", CkMyPe(), 
53             ywrap, zwrap);
54   CkPrintf ("%d: In initialize (ny_pblocks, nz_pblocks) = (%d, %d)\n", 
55             CkMyPe(), ny_pblocks, nz_pblocks);
56 #endif
57
58   for (z = -zwrap; z < nz_pblocks + zwrap; z++) {
59     if ( (z * _info.fftinfo.grainZ >= start_z) &&
60          (z * _info.fftinfo.grainZ <= start_z + size_z))
61       for (y = -ywrap; y < ny_pblocks + ywrap; y++) 
62         if ( (y * _info.fftinfo.grainY >= start_y) &&
63              (y * _info.fftinfo.grainY <= start_y + size_y)) 
64           {
65             int rel_y = (y + ny_pblocks) % ny_pblocks;
66             int rel_z = (z + nz_pblocks) % nz_pblocks;
67             
68             int index = rel_z * ny_pblocks + rel_y;       
69             if (!pencilmap[index]) {
70               pencilmap[index] = 1;
71               ngrid_msgs ++;
72             }
73           }    
74   }
75   _nGridMsgs = ngrid_msgs;
76   
77   contribute (sizeof(int) * nz_pblocks * ny_pblocks, 
78               pencilmap, CkReduction::sum_int, _info.cb_start);
79   
80   _gridList = new LineFFTGrid [ngrid_msgs];
81   
82   CkCallback cb(CkIndex_Patch::receiveGrid(NULL), thisProxy[CkMyPe()]);
83   ngrid_msgs = 0;
84   for (z = -zwrap; z < nz_pblocks + zwrap; z++) {
85     if ( (z * _info.fftinfo.grainZ >= start_z) &&
86          (z * _info.fftinfo.grainZ <= start_z + size_z))
87       for (y = -ywrap; y < ny_pblocks + ywrap; y++) 
88         if ( (y * _info.fftinfo.grainY >= start_y) &&
89              (y * _info.fftinfo.grainY <= start_y + size_y)) 
90           {
91             int rel_y = (y + ny_pblocks) % ny_pblocks;
92             int rel_z = (z + nz_pblocks) % nz_pblocks;
93             
94             int index = rel_z * ny_pblocks + rel_y;       
95             if (pencilmap[index] == 1) {
96               pencilmap [index] --;
97               _gridList [ngrid_msgs].y0 = rel_y * _info.fftinfo.grainY;
98               _gridList [ngrid_msgs].z0 = rel_z * _info.fftinfo.grainZ;
99               _gridList [ngrid_msgs].ysize = _info.fftinfo.grainY;
100               _gridList [ngrid_msgs].zsize = _info.fftinfo.grainZ;
101               
102               _gridList [ngrid_msgs].idx_x = rel_y;
103               _gridList [ngrid_msgs].idx_y = rel_z;         
104               _gridList [ngrid_msgs].cb_done = cb;
105               
106               ngrid_msgs ++;
107             }
108           }    
109   }
110
111   CkAssert (ngrid_msgs == _nGridMsgs);
112
113   int start_x = 0, size_x = 0;
114
115   start_x = (_info.fftinfo.sizeX * _info.my_x) / _info.nx;
116   size_x  = (_info.fftinfo.sizeX + _info.nx - 1) /  _info.nx;
117
118   size_x += 2*INTERPOLATION_SIZE;
119   start_x -= INTERPOLATION_SIZE;
120
121   for (int count = 0; count < ngrid_msgs; count ++) {
122     _gridList [count].x0 = start_x;
123     _gridList [count].xsize = size_x;    
124   }
125
126   delete [] pencilmap;  
127 }
128
129
130 ///
131 ///  \brief Start the time step by sending grid messages to the Pencil
132 ///  FFT Chare Array elements. 
133 ///
134 void Patch :: startTimeStep () {
135
136   for (int count = 0; count < _nGridMsgs; count ++) {
137     int size = _gridList[count].xsize * 
138       _gridList[count].ysize * _gridList[count].zsize;
139     
140     LineFFTGridMsg *msg = new (size, sizeof(int) * 8) LineFFTGridMsg();
141     msg->grid = _gridList [count];
142     
143     for (int idx = 0; idx < size; idx ++)
144       msg->data[idx] = 2.0;
145     
146     _info.fftinfo.xProxy (_gridList[count].idx_x, _gridList[count].idx_y).
147       receiveGridMessage (msg);
148   }
149 }
150
151 ///
152 /// \brief Receive the fft'ed messages from Pencil FFT Chare array
153 /// elements
154 ///
155 void Patch :: receiveGrid (LineFFTGridMsg *msg) {
156
157   delete msg;
158   _nReceived ++;
159   
160   if (_nReceived == _nGridMsgs) {
161     _nReceived = 0;
162
163 #if __TEST_PME_VERBOSE__
164     CkPrintf ("%d: Finished Iteration %d, max iterations = %d, ngridmsgs=%d\n", 
165               CkMyPe(), _iteration, _info.niterations, _nGridMsgs);
166 #endif
167
168     _iteration ++;    
169     if (_iteration >= _info.niterations) {
170       int x = 0;
171       contribute (sizeof(int), &x, CkReduction::sum_int, _info.cb_done);
172       return;
173     }
174     
175     startTimeStep ();
176   }
177 };