Zerocopy Direct API: Do not change UNREG to REG mode after registration
[charm.git] / examples / charm++ / zerocopy / direct_api / prereg / get_put_pingpong / get_put_pingpong.C
blobcb61341f714104020e8f9353ff87bf1059dffc86
1 #include "simple_direct.decl.h"
2 #include <assert.h>
4 CProxy_main mainProxy;
5 class main : public CBase_main
7   CProxy_Ping1 arr1;
8   int count;
9 public:
10   main(CkMigrateMessage *m) {}
11   main(CkArgMsg *m)
12   {
13     if(CkNumPes()>2) {
14       CkPrintf("Run this program on 1 or 2 processors only.\n");
15       CkExit(1);
16     }
17     if(m->argc !=2 ) {
18       CkPrintf("Usage: ./simple_direct <array size>\n");
19       CkExit(1);
20     }
21     int size = atoi(m->argv[1]);
22     mainProxy = thisProxy;
23     delete m;
24     arr1 = CProxy_Ping1::ckNew(size, 2);
25     count = 0;
26     arr1[0].start();
27   };
29   void maindone(){
30     count++;
31     if(count == 2) {
32       CkPrintf("[%d][%d] Result validated! \n", CkMyPe(), CkMyNode());
33       CkExit();
34     }
35   };
38 template<class T>
39 void compareArray(T *&aArr, T *&bArr, int size){
40   for(int i=0; i<size; i++)
41     assert(aArr[i] == bArr[i]);
44 template<class T>
45 void assignValues(T *&arr, int size){
46   // Allocation through CkRdmaAlloc
47   arr = (T *)CkRdmaAlloc(size * sizeof(T));
48   for(int i=0; i<size; i++)
49      arr[i] = rand() % 100 + 1;
52 void assignCharValues(char *&arr, int size){
53   // Allocation through CkRdmaAlloc
54   arr = (char *)CkRdmaAlloc(size * sizeof(char));
55   for(int i=0; i<size; i++)
56      arr[i] = (char)(rand() % 125 + 1);
59 class Ping1 : public CBase_Ping1
61   int *iArr1, *iArr2;
62   char *cArr1, *cArr2;
63   double *dArr1, *dArr2;
64   int size;
65   int otherIndex, recvCbCounter, sendCbCounter;
66   CkCallback sendCb, recvCb;
67   CkNcpyBuffer otherDest1, otherDest2, otherDest3;
69 public:
70   Ping1(int size)
71   {
72     this->size = size;
74     // original arrays that contains data
75     assignValues(iArr1, size);
76     assignValues(dArr1, size);
77     assignCharValues(cArr1, size);
79     sendCb = CkCallback(CkIndex_Ping1::senderCallback(NULL), thisProxy[thisIndex]);
80     recvCb = CkCallback(CkIndex_Ping1::receiverCallback(NULL), thisProxy[thisIndex]);
82     otherIndex = (thisIndex + 1) % 2;
83     sendCbCounter = 0;
84     recvCbCounter = 0;
85   }
86   Ping1(CkMigrateMessage *m) {}
88   // Executed on Index 0
89   void start()
90   {
91     CkAssert(thisIndex == 0);
92     CkNcpyBuffer mySrc1(iArr1, size*sizeof(int), sendCb, CK_BUFFER_PREREG);
93     CkNcpyBuffer mySrc2(dArr1, size*sizeof(double), sendCb, CK_BUFFER_PREREG);
94     CkNcpyBuffer mySrc3(cArr1, size*sizeof(char), sendCb, CK_BUFFER_PREREG);
96     iArr2 = (int *)CkRdmaAlloc(size*sizeof(int));
97     dArr2 = (double *)CkRdmaAlloc(size*sizeof(double));
98     cArr2 = (char *)CkRdmaAlloc(size*sizeof(char));
100     CkNcpyBuffer myDest1(iArr2, size*sizeof(int), recvCb, CK_BUFFER_PREREG);
101     CkNcpyBuffer myDest2(dArr2, size*sizeof(double), recvCb, CK_BUFFER_PREREG);
102     CkNcpyBuffer myDest3(cArr2, size*sizeof(char), recvCb, CK_BUFFER_PREREG);
104     thisProxy[otherIndex].recvNcpyInfo(mySrc1, mySrc2, mySrc3, myDest1, myDest2, myDest3);
105   }
107   void senderCallback(CkDataMsg *m){
108     sendCbCounter++;
110     // Cast m->data as (CkNcpyBuffer *)
111     CkNcpyBuffer *src = (CkNcpyBuffer *)(m->data);
112     src->deregisterMem(); // in PREREG mode, actual de-registration is not performed
113     // the above API call is only for demonstration and testing
115     if(sendCbCounter == 3) {
116       if(thisIndex == 1){
117         CkRdmaFree(iArr1);
118         CkRdmaFree(dArr1);
119         CkRdmaFree(cArr1);
120         mainProxy.maindone();
121       }
122     }
123   }
125   void receiverCallback(CkDataMsg *m){
126     recvCbCounter++;
128     // Cast m->data as (CkNcpyBuffer *)
129     CkNcpyBuffer *dest = (CkNcpyBuffer *)(m->data);
130     dest->deregisterMem(); // in PREREG mode, actual de-registration is not performed
131     // the above API call is only for demonstration and testing
133     if(recvCbCounter == 3) {
135       if(thisIndex == 1){
136         CkPrintf("[%d][%d][%d] Get call completed\n", thisIndex, CkMyPe(), CkMyNode());
138         // Create a nocopy sources for me to Put from into destinations received
139         CkNcpyBuffer mySrc1(iArr1, sizeof(int)*size, sendCb, CK_BUFFER_PREREG);
140         CkNcpyBuffer mySrc2(dArr1, sizeof(double)*size, sendCb, CK_BUFFER_PREREG);
141         CkNcpyBuffer mySrc3(cArr1, sizeof(char)*size, sendCb, CK_BUFFER_PREREG);
143         // Index 1 Putting to 0
144         mySrc1.put(otherDest1);
145         mySrc2.put(otherDest2);
146         mySrc3.put(otherDest3);
148       } else {
149         CkPrintf("[%d][%d][%d] Put call completed\n", thisIndex, CkMyPe(), CkMyNode());
151         compareArray(iArr1, iArr2, size);
152         compareArray(dArr1, dArr2, size);
153         compareArray(cArr1, cArr2, size);
155         // All arrays can be deleted at this point. But they are not as the program is exiting.
156         mainProxy.maindone();
157       }
158     }
159   }
161   // Executed on Index 1
162   void recvNcpyInfo(CkNcpyBuffer src1, CkNcpyBuffer src2, CkNcpyBuffer src3, CkNcpyBuffer dest1, CkNcpyBuffer dest2, CkNcpyBuffer dest3)
163   {
164     CkAssert(thisIndex == 1);
165     otherDest1 = dest1;
166     otherDest2 = dest2;
167     otherDest3 = dest3;
169     // Create nocopy destinations for me to Get from sources received
170     CkNcpyBuffer myDest1(iArr1, size*sizeof(int), recvCb, CK_BUFFER_PREREG);
171     CkNcpyBuffer myDest2(dArr1, size*sizeof(double), recvCb, CK_BUFFER_PREREG);
172     CkNcpyBuffer myDest3(cArr1, size*sizeof(char), recvCb, CK_BUFFER_PREREG);
174     // Index 1 Getting from 0
175     myDest1.get(src1);
176     myDest2.get(src2);
177     myDest3.get(src3);
178   }
181 #include "simple_direct.def.h"