change the implementation of ARMCI_Malloc_local to also support migration. (using...
[charm.git] / src / libs / ck-libs / armci / armci_api.C
1 // APIs exposed in armci.h. These should be called from within the driver
2 // code "armciStart". Applications running the armci library MUST use
3 // the runtime option -memory isomalloc.
4
5 #include "armci_impl.h"
6
7 // API implementations
8
9 int armci_nproc;
10
11 // initialization api
12
13 // Bind the virtual processors in the armci library to TCharm's.
14 // This is called by the user's thread when it starts up.
15 CDECL int ARMCI_Init(void) {
16   TCHARM_API_TRACE("ARMCI_Init", "armci");
17   if (TCHARM_Element()==0) {
18     CkArrayID threadsAID;
19     int nChunks;
20     CkArrayOptions opts = TCHARM_Attach_start(&threadsAID, &nChunks);
21     CkArrayID aid = CProxy_ArmciVirtualProcessor::ckNew(threadsAID, opts);
22     CProxy_ArmciVirtualProcessor vpProxy = CProxy_ArmciVirtualProcessor(aid);
23   }
24   
25   ArmciVirtualProcessor *vp=(ArmciVirtualProcessor *)
26         TCharm::get()->semaGet(ARMCI_TCHARM_SEMAID);
27   return 0;
28 }
29
30 CDECL int ARMCI_Finalize(void) {
31   TCHARM_API_TRACE("ARMCI_Finalize", "armci");
32   TCHARM_Done();
33   return 0;
34 }
35
36 CDECL void ARMCI_Cleanup(void) {
37   TCHARM_API_TRACE("ARMCI_Cleanup", "armci");
38 }
39
40 CDECL void ARMCI_Error(char *message, int code) {
41   TCHARM_API_TRACE("ARMCI_Error", "armci");
42   ckerr << "armci error: " << message << " | code = " << code << endl;
43 }
44
45
46 CDECL int ARMCI_Procs(int *procs){
47   TCHARM_API_TRACE("ARMCI_Procs", "armci");
48   *procs = TCHARM_Num_elements();
49   return 0;
50 }
51 CDECL int ARMCI_Myid(int *myid){
52   TCHARM_API_TRACE("ARMCI_Myid", "armci");
53   *myid = TCHARM_Element();
54   return 0;
55 }
56
57 CDECL int ARMCI_GetV(
58                 armci_giov_t darr[], /* descriptor array */
59                 int len,              /* length of descriptor array */
60                 int proc              /* remote process(or) ID */
61                 ){
62   return 0;
63 }
64
65 CDECL int ARMCI_NbGetV(
66                 armci_giov_t *dsrc_arr,
67                 int arr_len,
68                 int proc,
69                 armci_hdl_t* handle
70                 ){
71   return 0;
72 }
73
74 CDECL int ARMCI_PutV(
75                 armci_giov_t darr[], /* descriptor array */
76                 int len,              /* length of descriptor array */
77                 int proc              /* remote process(or) ID */
78                 ){
79   return 0;
80 }
81
82 CDECL int ARMCI_NbPutV(
83                 armci_giov_t *dsrc_arr,
84                 int arr_len,
85                 int proc,
86                 armci_hdl_t* handle
87                  ){
88   return 0;
89 }
90
91 CDECL int ARMCI_AccV(
92                 int op,                /* operation code */
93                 void *scale,          /* scaling factor for accumulate */
94                 armci_giov_t darr[], /* descriptor array */
95                 int len,              /* length of descriptor array */
96                 int proc              /* remote process(or) ID */
97                 ){
98   return 0;
99 }
100         
101 CDECL int ARMCI_NbAccV(
102                 int datatype, 
103                 void *scale, 
104                 armci_giov_t *dsrc_arr, 
105                 int arr_len, 
106                 int proc, 
107                 armci_hdl_t* handle
108                 ){
109   return 0;
110 }
111
112 // src is local memory, dst is remote address
113 CDECL int ARMCI_Put(void *src, void *dst, int bytes, int proc) {
114   TCHARM_API_TRACE("ARMCI_Put", "armci");
115   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
116   vp->put(src, dst, bytes, proc);
117   return 0;
118 }
119
120 CDECL int ARMCI_NbPut(void *src, void* dst, int bytes, int proc, armci_hdl_t *handle){
121   TCHARM_API_TRACE("ARMCI_NbPut", "armci");
122   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
123   if (handle != NULL) {
124     *handle = vp->nbput(src, dst, bytes, proc);
125   } else {
126     vp->nbput_implicit(src, dst, bytes, proc);
127   }
128   return 0;
129 }
130
131 // src is remote memory addr, dst is local address
132 CDECL int ARMCI_Get(void *src, void *dst, int bytes, int proc) {
133   TCHARM_API_TRACE("ARMCI_Get", "armci");
134   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
135   vp->get(src, dst, bytes, proc);
136   return 0;
137 }
138
139 CDECL int ARMCI_NbGet(void *src, void* dst, int bytes, int proc, armci_hdl_t *handle){
140   TCHARM_API_TRACE("ARMCI_NbGet", "armci");
141   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
142   if (handle != NULL) {
143     *handle = vp->nbget(src, dst, bytes, proc);
144   } else {
145     vp->nbget_implicit(src, dst, bytes, proc);
146   }
147   return 0;
148 }
149
150 CDECL int ARMCI_Acc(int datatype, void *scale, void* src, void* dst, int bytes, int proc){
151   return 0;
152 }
153
154 CDECL int ARMCI_NbAcc(int datatype, void *scale, void* src, void* dst, int bytes, int proc, armci_hdl_t* handle) {
155   return 0;
156 }
157
158 // strided copy operations
159 CDECL int ARMCI_PutS(void *src_ptr, int src_stride_ar[], 
160                 void *dst_ptr, int dst_stride_ar[],
161                 int count[], int stride_levels, int proc) {
162   TCHARM_API_TRACE("ARMCI_PutS", "armci");
163   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
164   vp->puts(src_ptr, src_stride_ar, dst_ptr, dst_stride_ar, count, stride_levels, proc);
165   return 0;
166 }
167
168 CDECL int ARMCI_NbPutS(
169                  void *src_ptr,         /* ptr to 1st segment at source */
170                  int src_stride_ar[], /* array of strides at source  */
171                  void* dst_ptr,         /* ptr to 1st segment at dest */
172                  int dst_stride_ar[], /* array of strides at destination */
173                  int count[],           /* number of units at each stride  */
174                                           /* level count[0]=bytes  */
175                  int stride_levels,    /* number of stride levels */
176                  int proc,              /* remote process(or) ID  */
177                  armci_hdl_t *handle   /* pointer to descriptor associated */
178                                           /* with a particular non-blocking */
179                                             /* transfer. Passing NULL value */
180                                           /* makes this function do an */
181                                             /* implicit handle non-blocking */
182                                             /* transfer */
183                  ){
184   TCHARM_API_TRACE("ARMCI_NbPutS", "armci");
185   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
186   if (handle != NULL) {
187     *handle = vp->nbputs(src_ptr, src_stride_ar, dst_ptr, dst_stride_ar, 
188                          count, stride_levels, proc);
189   } else {
190     vp->nbputs_implicit(src_ptr, src_stride_ar, dst_ptr, dst_stride_ar,
191                         count, stride_levels, proc);
192   }
193   return 0;
194 }
195
196 CDECL int ARMCI_GetS(
197                 void *src_ptr,         /* pointer to 1st segment at source */
198                 int src_stride_ar[], /* array of strides at source */
199                 void* dst_ptr,         /* ptr to 1st segment at destination */
200                 int dst_stride_ar[], /* array of strides at destination */
201                 int count[],           /* number of units at each stride  */
202                                          /* level count[0]=bytes */
203                 int stride_levels,    /* number of stride levels */
204                 int proc                /* remote process(or) ID */
205                 ){
206   TCHARM_API_TRACE("ARMCI_GetS", "armci");
207   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
208   vp->gets(src_ptr, src_stride_ar, dst_ptr, dst_stride_ar, count, stride_levels, proc);
209   return 0;
210 }
211
212 CDECL int ARMCI_NbGetS(
213                 void *src_ptr,         /* pointer to 1st segment at source */
214                 int src_stride_ar[], /* array of strides at source */
215                 void* dst_ptr,         /* ptr to 1st segment at destination */
216                 int dst_stride_ar[], /* array of strides at destination */
217                 int count[],           /* number of units at each stride  */
218                                          /* level count[0]=bytes */
219                 int stride_levels,    /* number of stride levels */
220                 int proc,              /* remote process(or) ID  */
221                 armci_hdl_t *handle   /* pointer to descriptor associated */
222                                           /* with a particular non-blocking */
223                                             /* transfer. Passing NULL value */
224                                           /* makes this function do an */
225                                             /* implicit handle non-blocking */
226                                             /* transfer */
227                 ){
228   TCHARM_API_TRACE("ARMCI_NbGetS", "armci");
229   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
230   if (handle != NULL) {
231     *handle = vp->nbgets(src_ptr, src_stride_ar, dst_ptr, dst_stride_ar, 
232                          count, stride_levels, proc);
233   } else {
234     vp->nbgets_implicit(src_ptr, src_stride_ar, dst_ptr, dst_stride_ar,
235                         count, stride_levels, proc);
236   }
237   return 0;
238 }
239
240 CDECL int ARMCI_AccS(
241                 int  optype,           /* operation */
242                 void *scale,           /* scale factor x += scale*y */
243                 void *src_ptr,         /* pointer to 1st segment at source */
244                 int src_stride_arr[], /* array of strides at source */
245                 void* dst_ptr,         /* ptr to 1st segment at destination */
246                 int dst_stride_arr[], /* array of strides at destination */
247                 int count[],           /* number of units at each stride  */
248                                          /* level count[0]=bytes */
249                 int stride_levels,    /* number of stride levels */
250                 int proc                /* remote process(or) ID */
251                 ){
252   return 0;
253 }
254
255 CDECL int ARMCI_NbAccS(
256                 int  optype,           /* operation */
257                 void *scale,           /* scale factor x += scale*y */
258                 void *src_ptr,         /* pointer to 1st segment at source */
259                 int src_stride_arr[], /* array of strides at source */
260                 void* dst_ptr,         /* ptr to 1st segment at destination */
261                 int dst_stride_arr[], /* array of strides at destination */
262                 int count[],           /* number of units at each stride  */
263                                          /* level count[0]=bytes */
264                 int stride_levels,    /* number of stride levels */
265                 int proc,             /* remote process(or) ID  */
266                 armci_hdl_t *handle   /* pointer to descriptor associated */
267                                        /* with a particular non-blocking */
268                                        /* transfer. Passing NULL value */
269                                        /* makes this function do an */
270                                        /* implicit handle non-blocking */
271                                        /* transfer */
272                 ){
273   return 0;
274 }
275
276 CDECL int ARMCI_PutValueLong(long src, void* dst, int proc) { return 0; }
277 CDECL int ARMCI_PutValueInt(int src, void* dst, int proc) { return 0; }
278 CDECL int ARMCI_PutValueFloat(float src, void* dst, int proc) { return 0; }
279 CDECL int ARMCI_PutValueDouble(double src, void* dst, int proc) { return 0; }
280 CDECL int ARMCI_NbPutValueLong(long src, void* dst, int proc, armci_hdl_t* handle) { return 0; }
281 CDECL int ARMCI_NbPutValueInt(int src, void* dst, int proc, armci_hdl_t* handle) { return 0; }
282 CDECL int ARMCI_NbPutValueFloat(float src, void* dst, int proc, armci_hdl_t* handle) { return 0; }
283 CDECL int ARMCI_NbPutValueDouble(double src, void* dst, int proc, armci_hdl_t* handle) { return 0; }
284 CDECL long ARMCI_GetValueLong(void *src, int proc) { return 0; }
285 CDECL int ARMCI_GetValueInt(void *src, int proc) { return 0; }
286 CDECL float ARMCI_GetValueFloat(void *src, int proc) { return 0.0; }
287 CDECL double ARMCI_GetValueDouble(void *src, int proc) { return 0.0; }
288 CDECL long ARMCI_NbGetValueLong(void *src, int proc, armci_hdl_t* handle) { return 0; }
289 CDECL int ARMCI_NbGetValueInt(void *src, int proc, armci_hdl_t* handle) { return 0; }
290 CDECL float ARMCI_NbGetValueFloat(void *src, int proc, armci_hdl_t* handle) { return 0.0; }
291 CDECL double ARMCI_NbGetValueDouble(void *src, int proc, armci_hdl_t* handle) { return 0.0; }
292
293 // global completion operations
294 CDECL int ARMCI_Wait(armci_hdl_t *handle){
295   TCHARM_API_TRACE("ARMCI_Wait", "armci");
296   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
297   if (handle != NULL) {
298     vp->wait(*handle);
299   } else {
300     CmiAbort("ARMCI ERROR: Cannot pass NULL to ARMCI_Wait\n");
301   }
302   return 0;
303 }
304
305 CDECL int ARMCI_WaitProc(int proc){
306   TCHARM_API_TRACE("ARMCI_WaitProc", "armci");
307   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
308   vp->waitproc(proc);
309   return 0;
310 }
311
312 CDECL int ARMCI_WaitAll(){
313   TCHARM_API_TRACE("ARMCI_WaitAll", "armci");
314   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
315   vp->waitall();
316   return 0;
317 }
318
319 CDECL int ARMCI_Test(armci_hdl_t *handle){
320   TCHARM_API_TRACE("ARMCI_Test", "armci");
321   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
322   if(vp->test(*handle))
323     return 0;
324   else
325     return 1;
326 }
327
328 CDECL int ARMCI_Barrier(){
329   TCHARM_API_TRACE("ARMCI_Barrier", "armci");
330   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
331   vp->barrier();
332   return 0;
333 }
334
335 // these are no-ops because Put is blocking
336 CDECL int ARMCI_Fence(int proc) {
337   TCHARM_API_TRACE("ARMCI_Fence", "armci");
338   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
339   vp->fence(proc);
340   return 0;
341 }
342
343 CDECL int ARMCI_AllFence(void) {
344   TCHARM_API_TRACE("ARMCI_AllFence", "armci");
345   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
346   vp->allfence();
347   return 0;
348 }
349
350 // memory operations
351
352 // malloc is a collective operation. The user is expected to allocate
353 // and manage ptr_arr.
354 CDECL int ARMCI_Malloc(void *ptr_arr[], armci_size_t bytes) {
355   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
356 //  pointer ptr = malloc(bytes);
357   pointer ptr = vp->BlockMalloc(bytes);
358   // TCHARM_API_TRACE disables isomalloc, so malloc first.
359   TCHARM_API_TRACE("ARMCI_Malloc", "armci");
360   vp->requestAddresses(ptr, ptr_arr, bytes);
361   return 0;  
362 }
363
364 // CmiIsomalloc does not return a value and no indication is given about
365 // the success nor failure of the operation. Hence, it is assumed always
366 // that free works.
367 CDECL int ARMCI_Free(void *address) {
368   CmiIsomallocBlockListFree(address);
369 //  free(address);
370   TCHARM_API_TRACE("ARMCI_Free", "armci");
371   return 0;
372 }
373 CDECL void *ARMCI_Malloc_local(armci_size_t bytes){
374   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
375   pointer ptr = vp->BlockMalloc(bytes);
376   TCHARM_API_TRACE("ARMCI_Malloc_local", "armci");
377   //return malloc(bytes);
378   return ptr;
379 }
380
381 CDECL int ARMCI_Free_local(void *ptr){
382   CmiIsomallocBlockListFree(ptr);
383   TCHARM_API_TRACE("ARMCI_Free_local", "armci");
384   //free(ptr);
385   return 0;
386 }
387
388 CDECL void ARMCI_SET_AGGREGATE_HANDLE (armci_hdl_t* handle) { }
389 CDECL void ARMCI_UNSET_AGGREGATE_HANDLE (armci_hdl_t* handle) { }
390
391 CDECL int ARMCI_Rmw(int op, int *ploc, int *prem, int extra, int proc){
392   return 0;
393 }
394
395 CDECL int ARMCI_Create_mutexes(int num){
396   return 0;
397 }
398 CDECL int ARMCI_Destroy_mutexes(void){
399   return 0;
400 }
401 CDECL void ARMCI_Lock(int mutex, int proc){
402 }
403 CDECL void ARMCI_Unlock(int mutex, int proc){
404 }
405
406 CDECL int armci_notify(int proc){
407   TCHARM_API_TRACE("armci_notify", "armci");
408   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
409   vp->notify(proc);
410   return 0;
411 }
412
413 CDECL int armci_notify_wait(int proc, int *pval){
414   TCHARM_API_TRACE("armci_notify_wait", "armci");
415   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
416   vp->notify_wait(proc);
417   return 0;
418 }
419
420 /* ********************************* */
421 /* Collective Operations             */
422 CDECL void armci_msg_brdcst(void *buffer, int len, int root) {
423   armci_msg_bcast(buffer, len, root);
424 }
425
426 CDECL void armci_msg_bcast(void *buffer, int len, int root) {
427   TCHARM_API_TRACE("armci_msg_bcast", "armci");
428   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
429   vp->msgBcast(buffer, len, root);
430 }
431
432 // This does not look like an API actually used in ARMCI
433 CDECL void armci_msg_gop2(void *x, int n, int type, char *op) {
434 }
435
436 CDECL void armci_msg_igop(int *x, int n, char *op) {
437   TCHARM_API_TRACE("armci_msg_dgop", "armci");
438   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
439   vp->msgGop(x, n, op, ARMCI_INT);
440 }
441
442 CDECL void armci_msg_lgop(CmiInt8 *x, int n, char *op) {
443   TCHARM_API_TRACE("armci_msg_lgop", "armci");
444   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
445   vp->msgGop(x, n, op, ARMCI_LONG);
446 }
447
448 /*
449 CDECL void armci_msg_llgop(long long *x, int n, char *op) {
450   TCHARM_API_TRACE("armci_msg_llgop", "armci");
451   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
452   vp->msgGop(x, n, op, ARMCI_LONG_LONG);
453 }
454 */
455
456 CDECL void armci_msg_fgop(float *x, int n, char *op) {
457   TCHARM_API_TRACE("armci_msg_fgop", "armci");
458   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
459   vp->msgGop(x, n, op, ARMCI_FLOAT);
460 }
461
462 CDECL void armci_msg_dgop(double *x, int n, char *op) {
463   TCHARM_API_TRACE("armci_msg_dgop", "armci");
464   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
465   vp->msgGop(x, n, op, ARMCI_DOUBLE);
466 }
467
468 CDECL void armci_msg_barrier(void) {
469 }
470
471 CDECL void armci_msg_reduce(void *x, int n, char *op, int type) {
472 }
473
474 /* ******************************* */
475 /* System Configuration            */
476 CDECL int armci_domain_nprocs(armci_domain_t domain, int id) {
477   return -1;
478 }
479
480 CDECL int armci_domain_count(armci_domain_t domain) {
481   return -1;
482 }
483
484 CDECL int armci_domain_id(armci_domain_t domain, int glob_proc_id) {
485   return -1;
486 }
487
488 CDECL int armci_domain_glob_proc_id(armci_domain_t domain, int id, 
489                                     int loc_proc_id) {
490   return -1;
491 }
492
493 CDECL int armci_domain_my_id(armci_domain_t domain) {
494   return -1;
495 }
496
497 /* ********************************** */
498 /* Charm++ Runtime Support Extensions */
499
500 CDECL void ARMCI_Migrate(void){
501   TCHARM_API_TRACE("ARMCI_Migrate", "armci");
502   TCHARM_Migrate();
503 }
504 CDECL void ARMCI_Async_Migrate(void){
505   TCHARM_API_TRACE("ARMCI_Async_Migrate", "armci");
506   TCHARM_Async_Migrate();
507 }
508 CDECL void ARMCI_Checkpoint(char* dname){
509   TCHARM_API_TRACE("ARMCI_Checkpoint", "armci");
510   ARMCI_Barrier();
511   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
512   vp->startCheckpoint(dname);
513 }
514 CDECL void ARMCI_MemCheckpoint(void){
515   TCHARM_API_TRACE("ARMCI_MemCheckpoint", "armci");
516   ARMCI_Barrier();
517   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
518   vp->startCheckpoint("");
519 }
520