216e340b4ed30013ca7a5e16a72ffe3a442c6c7a
[charm.git] / example / hello.C
1 #include <stdio.h>
2 #include <assert.h>
3 #include <stdlib.h>
4 #include "hello.h"
5
6 #include "hello.decl.h"
7
8
9 CProxy_Main mainProxy;
10 CProxy_TestInstance allTestsProxy;
11 CProxy_FuncNodeHelper nodeHelperProxy;
12
13 int iteration;
14 int flag;// ith iteration
15 #define MODE 1
16 int threadNum;
17 int useNodeQueue;
18
19 #define THRESHOLD 100
20 extern "C" void doCalc(int first,int last, int & result, int paramNum, void * param);
21
22         void work(int start, int end, int &result){
23                 result=0;
24                 for(int i=start;i<=end;i++){
25                         result+=(int)(sqrt(1+cos(i*1.57)));
26                 }
27                 //return result;
28         }
29
30 extern "C" void doCalc(int first, int last, int &result, int paramNum, void * param) {
31         result=0;
32         double tstart = CmiWallTimer();
33         work(first, last, result);
34         tstart = CmiWallTimer() - tstart;
35     //printf("start=%d, end=%d, time: %f,result: %d on proc %d\n",first, last, tstart,result,CkMyPe());
36 }
37 /*mainchare*/
38
39
40 Main::Main(CkArgMsg* m) {
41         //number of elements
42         totalElems = 2;
43         flag=0;
44                 for(int i=0;i<4;i++){
45                         time[i]=0;
46
47                         chunck[i]=0;
48                 }
49         //process command line
50         if (m->argc >1 ) 
51                         processCommandLine(m->argc,m->argv);
52                 else 
53                         CkPrintf("usage -t(time) -c(chunk) -n(nodequeue) -a (num of tests) -p (thread)\n");
54         delete m;
55         /*choose mode and initialization
56          mode=0, use pthread;
57          mode=1, use NODEQUEUE;
58          mode=2, not use NODEQUEUE*/
59                         nodeHelperProxy = CProxy_FuncNodeHelper::ckNew(MODE,totalElems,threadNum);
60                         
61         if(MODE==0){
62                 
63                 FuncNodeHelper *nth = nodeHelperProxy[CkMyNode()].ckLocalBranch();
64                 nth->createThread();
65         }
66                 int result;
67                 wps=0;
68                 calTime=0.05;
69
70         mainProxy = thishandle;
71         nodesFinished = 0;
72         CkPrintf("useNodeQueue:%d\n",useNodeQueue);
73         CProxy_cyclicMap myMap = CProxy_cyclicMap::ckNew();
74         CkArrayOptions opts(totalElems);
75         opts.setMap(myMap);
76         allTestsProxy = CProxy_TestInstance::ckNew(opts);
77
78
79         //Start the computation
80         CkPrintf("Running Hello on %d processors for %d test elements\n",
81                  CkNumPes(),totalElems);
82
83         //serial version
84                 
85                 calibrated=-1;
86
87                 const double end_time = CmiWallTimer()+calTime;
88                 wps = 0;
89
90                 while(CmiWallTimer() < end_time) {
91                         work(0,100,result);
92                         wps+=100;
93                 }
94                 
95
96                 for(int i=0; i < 2; i++) {
97                         const double start_time = CmiWallTimer();
98                         work(0,(int)wps,result);
99                         const double end_time = CmiWallTimer();
100                         const double correction = calTime / (end_time-start_time);
101                         wps *= correction;
102                 }
103                 calibrated = (int)(wps/calTime);
104                 printf("calibrated 1: %d\n", calibrated);
105                 double starttime=CmiWallTimer();
106                 work(0,calibrated,result);
107                 double endtime = CmiWallTimer();
108                 printf("Serial time = %lf,result:%d\n",endtime-starttime,result);
109                 starttime=CmiWallTimer();
110                 work(0,calibrated/2500,result);
111                 endtime = CmiWallTimer();
112                 printf("Serial time for 400 micro second= %lf,result:%d\n",endtime-starttime,result);
113
114                 
115                 CmiSetCPUAffinity(0);
116                 
117                 //use node initialization
118                         
119                 CkStartQD(CkIndex_Main::doTests((CkQdMsg *)0), &thishandle);
120     };
121 void Main::done(void) {
122     nodesFinished++;
123     if (nodesFinished < totalElems){
124                 return;
125         }
126         else{
127                 flag++;
128                 nodesFinished=0;
129                 if(flag<iteration){
130                         
131                         for(int i=0;i<totalElems;i++){
132                                 //CkPrintf("time:%d\n",time[i]);
133                                 allTestsProxy[i].doTest(flag,(calibrated/(1e6/time[i])),chunck[i],time[i]);
134                         }
135                         return;
136                 }
137         }
138         CkPrintf("All done\n");
139         CkExit();
140 };
141     
142     void Main:: doTests(CkQdMsg *msg){
143
144                 delete msg;
145                 int wps=calibrated;
146                 for(int i=0;i<totalElems;i++){
147                         allTestsProxy[i].doTest(0,(wps/(1e6/time[i])),chunck[i],time[i]);
148                         //allTestsProxy[8].doTest(0,(wps/(1e6/time[0])),chunck[0],time[0]);
149                 }
150     };
151     
152     void Main::processCommandLine(int argc,char ** argv){
153                 int i;
154                 int j=0;
155                 int f=0;
156                 for(i=0;i<argc;i++){
157                         if(argv[i][0]=='-'){
158                                 switch(argv[i][1]){
159                                         case 't': time[j++]=atoi(argv[++i]);
160                                                           break;
161                                         case 'c': chunck[f++]=atoi(argv[++i]);
162                                                           break;
163                                         case 'n': iteration=atoi(argv[++i]);
164                                                           break;
165                                         case 'a': totalElems=atoi(argv[++i]);
166                                                           break;
167                                         case 'p': threadNum=atoi(argv[++i]);
168                                                           break;
169                                 }
170                         }
171                 }
172         }
173
174
175
176 int cmpDFunc(const void *a, const void *b){
177         double n1 = *(double *)a;
178         double n2 = *(double *)b;
179         if(n1<n2) return -1;
180         if(n1>n2) return 1;
181         return 0;
182 }
183
184 TestInstance::TestInstance() { 
185         CkPrintf("test case %d is created on proc %d node %d\n", thisIndex, CkMyPe(),CkMyNode());
186                 result=0;
187                 flag=0;
188         allTimes=(double *)malloc(sizeof(double)*iteration);
189         fflush(stdout);
190     }
191 void TestInstance::doTest(int flag,int wps,int chunck,int time){
192       //printf("On proc %d node %d, begin parallel execution for test case %d %dth iteration\n", CkMyPe(), CkMyNode(), thisIndex,flag);    
193         //CkPrintf("wps :%d, flag:%d\n",wps,flag); 
194                 timerec = CmiWallTimer();
195                  int result;
196                  if(chunck==0&&time<=THRESHOLD){
197                          work(0,wps,result);
198                          //printf("On proc %d node %d, Parallel time with %d helpers: %lf for test case %d, result: %d\n", CkMyPe(), CkMyNode(), 0,(CmiWallTimer()-timerec)*1e6, thisIndex,result);
199                          
200                  }
201                  else{
202
203                         FuncNodeHelper *nth = nodeHelperProxy[CkMyNode()].ckLocalBranch();
204                         unsigned int t;
205                         t=(int)(CmiWallTimer()*1000);
206                         result=nth->parallelizeFunc(doCalc,wps,t,thisIndex,chunck,time,0,NULL, 1,SMP_SUM);
207                         //printf("On proc %d node %d, Parallel time with %d helpers: %lf for test case %d, result: %d\n", CkMyPe(), CkMyNode(), nth->numHelpers,(CmiWallTimer()-timerec)*1e6, thisIndex,result);
208                         
209                  }
210                 allTimes[flag]=(CmiWallTimer()-timerec)*1e6;
211                 if(flag==iteration-1){
212                         qsort(allTimes,iteration,sizeof(double),cmpDFunc);
213                         double sumTimes=0.0;
214                         for(int i=0; i<iteration-3; i++) sumTimes += allTimes[i];
215                         CkPrintf("result:%d,avg iteration time: %.6f [%.6f, %.6f, %.6f] (us)\n",result, sumTimes/(iteration-3), allTimes[0], allTimes[iteration/2], allTimes[iteration-1]);
216                 }
217                 mainProxy.done();
218                   
219
220 }
221
222 #include "hello.def.h"
223