Zcpy Bcast Sender-side API: Add a ping_all benchmark
[charm.git] / examples / charm++ / zerocopy / entry_method_bcast_api / reg / ping_all / ping_all.C
1 #include <string.h> // for strlen, and strcmp
2 #include <charm++.h>
3
4 #include "ping_all.decl.h"
5
6 CProxy_main mainProxy;
7 int iterations;
8 size_t minSize, maxSize, smallIter, bigIter;
9
10 #define DEBUG(x) //x
11
12 class main : public CBase_main
13 {
14   int niter, counter;
15   char *buffer;
16   CProxy_LargeDataNodeGroup ngid;
17   double start_time, end_time, reg_time, zcpy_time;
18   CkCallback cb;
19   size_t size;
20   bool warmUp;
21
22 public:
23   main(CkMigrateMessage *m) {}
24   main(CkArgMsg* m)
25   {
26     if(m->argc == 5) {
27       minSize = atoi(m->argv[1])/2; // Start with a smaller size to run a warm up phase
28       maxSize = atoi(m->argv[2]);
29       smallIter = atoi(m->argv[3]);
30       bigIter = atoi(m->argv[4]);
31     } else if(m->argc == 1) {
32       // use defaults
33       minSize = 512; // Start with a smaller size to run a warm up phase before starting message size at 1024 bytes
34       maxSize = 1 << 13;
35       smallIter = 10;
36       bigIter = 100;
37     } else {
38       CkPrintf("Usage: ./ping_all <min size> <max size> <small message iter> <big message iter>\n");
39       CkExit(1);
40     }
41     delete m;
42     // Initialize
43     size = minSize;
44     niter = 0;
45     counter = 0;
46     mainProxy = thisProxy;
47     warmUp = true;
48     iterations = smallIter;
49
50     // Allocate a buffer to send
51     buffer = new char[maxSize];
52
53     // Create a nodegroup
54     ngid = CProxy_LargeDataNodeGroup::ckNew();
55
56     // Create a callback method to pass in the Zerocopy Bcast API call
57     int idx_zerocopySent = CkIndex_main::zerocopySent(NULL);
58     cb = CkCallback(idx_zerocopySent, thisProxy);
59
60     CkPrintf("Size (bytes) \t\tIterations\t\tRegular Bcast API (one-way us)\tZero Copy Bcast Send API (one-way us)\t\n");
61     CkStartQD(CkCallback(CkIndex_main::start(), mainProxy));
62   }
63
64   void start() {
65     if(size < minSize) {
66       // warmUp phase
67       start_time = CkWallTimer();
68       ngid.recv(buffer, size, niter, warmUp, iterations);
69     } else if(size <= maxSize) {
70       // regular experiment phase
71       start_time = CkWallTimer();
72       ngid.recv(buffer, size, niter, warmUp, iterations);
73     } else {
74       // completion phase
75       done();
76     }
77   }
78
79   // Invoked on main after a reduction by all the nodegroup elements
80   void regular_bcast_done() {
81     niter++; // An iteration of the Regular Bcast API is complete
82     if(niter == iterations) {
83       end_time = CkWallTimer();
84       reg_time = 1.0e6*(end_time - start_time)/iterations;
85       niter = 0;
86       start_time = CkWallTimer();
87       ngid.recv_zerocopy(CkSendBuffer(buffer, cb), size, niter, warmUp, iterations);
88     } else {
89       ngid.recv(buffer, size, niter, warmUp, iterations);
90     }
91   }
92
93   void zerocopySent(CkDataMsg *msg) {
94     zc_bcast_done();
95   }
96
97   void zc_bcast_done() {
98     counter++;
99     if(counter == 2) {
100       counter = 0;
101       niter++; // An iteration of the Zerocopy Bcast API is complete
102       if(niter == iterations) {
103         end_time = CkWallTimer();
104         zcpy_time = 1.0e6*(end_time - start_time)/iterations;
105         niter = 0;
106         if(warmUp == false) {
107             if(size < 1 << 24)
108               CkPrintf("%d\t\t\t%d\t\t\t%lf\t\t\t%lf\n", size, iterations, reg_time, zcpy_time);
109             else
110               CkPrintf("%d\t\t%d\t\t\t%lf\t\t\t%lf\n", size, iterations, reg_time, zcpy_time);
111         }
112         size = size << 1;
113         if(warmUp)
114           done();
115         else
116           mainProxy.start();
117       } else {
118         ngid.recv_zerocopy(CkSendBuffer(buffer, cb), size, niter, warmUp, iterations);
119       }
120     }
121   }
122
123   void done() {
124     if(warmUp) {
125       // warmUp phase complete
126       warmUp = false;
127       mainProxy.start();
128     } else {
129       // experiment complete
130       CkExit();
131     }
132   }
133 };
134
135
136 class LargeDataNodeGroup : public CBase_LargeDataNodeGroup
137 {
138   CkCallback regCb, zcCb;
139
140 public:
141   LargeDataNodeGroup() {
142     regCb = CkCallback(CkReductionTarget(main, regular_bcast_done), mainProxy);
143     zcCb = CkCallback(CkReductionTarget(main, zc_bcast_done), mainProxy);
144   }
145
146   void recv(char *msg, size_t size, int iter, bool warmUp, int iterations) {
147     contribute(regCb); // Nodegroup reduction to signal completion to the main chare
148   }
149
150   void recv_zerocopy(char *msg, size_t size, int iter, bool warmUp, int iterations) {
151     contribute(zcCb);
152   }
153 };
154
155
156 #include "ping_all.def.h"