c5471209437ff2514696911dd58f4e44c19d8d6b
[charm.git] / examples / charm++ / PMEMimic / PMEMimic.C
1 #include <stdio.h>
2 #include "PMEMimic.decl.h"
3
4 /*readonly*/ CProxy_Main mainProxy;
5 /*readonly*/ 
6
7 int     N;
8 int     grid_x;
9 int     grid_y;
10 int     grid_z;
11 int     max_iter;
12 int     pes_per_node;
13
14 CProxy_PMEPencil pme_x;
15 CProxy_PMEPencil pme_y;
16 CProxy_PMEPencil pme_z;
17
18 class DataMsg : public CMessage_DataMsg
19 {
20 public:
21     int phrase;
22     char data[2048];
23
24 };
25
26 class PMEMap : public CkArrayMap 
27
28     int offset;
29 public: 
30     PMEMap(int off) { offset = off;} 
31     PMEMap(CkMigrateMessage *m){} 
32     int registerArray(CkArrayIndex& numElements,CkArrayID aid) { 
33         return 0; 
34     } 
35     int procNum(int /*arrayHdl*/,const CkArrayIndex &idx) { 
36         int penum;
37         int *index =  (int *)idx.data();
38         int obj_index =  index[0]*grid_x + index[1];
39         penum = obj_index * pes_per_node + offset;
40         return penum; 
41     } 
42 }; 
43
44
45 /*mainchare*/
46 class Main : public CBase_Main
47 {
48     double startTimer;
49     int done_pme, iteration;
50 public:
51
52     Main(CkArgMsg* m)
53     {
54         //Process command-line arguments
55  
56         grid_x = grid_y = grid_z = 10;
57         max_iter = 100;
58         pes_per_node = 3;
59         if(m->argc > 1)
60         {
61             pes_per_node = atoi(m->argv[1]);;
62             grid_x = grid_y = grid_z = atoi(m->argv[2]);
63             max_iter = atoi(m->argv[3]);
64         }
65         delete m;
66
67     //Start the computation
68       CkPrintf("Running PMEMimic on %d processors for %d elements\n",
69           CkNumPes(), grid_x);
70       mainProxy = thisProxy;
71
72       CProxy_PMEMap myMap_x=CProxy_PMEMap::ckNew(0); 
73       CkArrayOptions opts_x(grid_y, grid_z); 
74       opts_x.setMap(myMap_x);
75
76       CProxy_PMEMap myMap_y=CProxy_PMEMap::ckNew(1); 
77       CkArrayOptions opts_y(grid_x, grid_z); 
78       opts_y.setMap(myMap_y);
79
80       CProxy_PMEMap myMap_z=CProxy_PMEMap::ckNew(2); 
81       CkArrayOptions opts_z(grid_x, grid_y); 
82       opts_z.setMap(myMap_z);
83
84       pme_x = CProxy_PMEPencil::ckNew(opts_x);
85       pme_y = CProxy_PMEPencil::ckNew(opts_y);
86       pme_z = CProxy_PMEPencil::ckNew(opts_z);
87
88       done_pme=0;
89       startTimer = CmiWallTimer();
90       pme_x.start();
91     };
92
93     void done()
94     {
95         done_pme++;
96         if(done_pme == grid_x)
97         {
98             done_pme = 0;
99
100             CkPrintf("PME(%d, %d, %d) on %d PEs, %d iteration, avg time:%f\n", grid_x, grid_y, grid_z, CkNumPes(), max_iter, CmiWallTimer()-startTimer);
101             CkExit();
102         }
103     }
104 };
105
106 /*array [1D]*/
107 class PMEPencil : public CBase_PMEPencil
108 {
109     int recv_nums, iteration;
110 public:
111   PMEPencil()
112   {
113     recv_nums = 0;
114     iteration = 0;
115   }
116   PMEPencil(CkMigrateMessage *m) {}
117
118   void start()
119   {
120    //thisindex.x thisindex.y
121     // x (yz), y(x, z)
122     for(int x=0; x<grid_x; x++)
123     {
124       DataMsg *msg= new DataMsg;
125       msg->phrase = 1;
126       pme_y(x, thisIndex.y).recvTrans(msg);  
127     }
128   }
129   void recvTrans(DataMsg *msg_recv)
130   {
131     int expect_num, index;
132     recv_nums++;
133     expect_num = grid_x;
134     index = msg_recv->phrase;
135
136     if(recv_nums == expect_num)
137     {
138         if(index == 0  ) //x (y,z) to y(x,z)
139         {
140             iteration++;
141             if(iteration == max_iter)
142             {
143                 mainProxy.done();
144                 return;
145             }
146             for(int x=0; x<grid_x; x++)
147             {
148                 DataMsg *msg= new DataMsg;
149                 msg->phrase = msg_recv->phrase+1;
150                 pme_y(x, thisIndex.y).recvTrans(msg);  
151             }
152             CkPrintf("x==>y\n");
153         }else if(index == 1) //y(x,z) send to z(x,y)
154         {
155             for(int y=0; y<grid_y; y++)
156             {
157                 DataMsg *msg= new DataMsg;
158                 msg->phrase = msg_recv->phrase+1;
159                 pme_z(thisIndex.x, y).recvTrans(msg); 
160             }
161             CkPrintf("y==>z\n");
162         }else if(index == 2) //Z(x,y) send to y(x,z)
163         {
164             for(int z=0; z<grid_z; z++)
165             {
166                 DataMsg *msg= new DataMsg;
167                 msg->phrase = msg_recv->phrase+1;
168                 pme_z(thisIndex.x, z).recvTrans(msg); 
169             }
170             CkPrintf("z==>y\n");
171         } else if(index == 3) //y(x,z) to x(y,z)
172         {
173             for(int y=0; y<grid_y; y++)
174             {
175                 DataMsg *msg= new DataMsg;
176                 msg->phrase = 0;
177                 pme_z(y, thisIndex.y).recvTrans(msg); 
178             }
179             CkPrintf("y==>x\n");
180
181         }
182         recv_nums = 0;
183     }
184     delete msg_recv;
185   }
186 };
187
188
189 #include "PMEMimic.def.h"