~ubuntu-branches/ubuntu/trusty/nwchem/trusty-proposed

« back to all changes in this revision

Viewing changes to src/tools/ga-5-2/armci/src-gemini/strided.c

  • Committer: Package Import Robot
  • Author(s): Michael Banck, Daniel Leidert, Andreas Tille, Michael Banck
  • Date: 2013-07-04 12:14:55 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20130704121455-5tvsx2qabor3nrui
Tags: 6.3-1
* New upstream release.
* Fixes anisotropic properties (Closes: #696361).
* New features include:
  + Multi-reference coupled cluster (MRCC) approaches
  + Hybrid DFT calculations with short-range HF 
  + New density-functionals including Minnesota (M08, M11) and HSE hybrid
    functionals
  + X-ray absorption spectroscopy (XAS) with TDDFT
  + Analytical gradients for the COSMO solvation model
  + Transition densities from TDDFT 
  + DFT+U and Electron-Transfer (ET) methods for plane wave calculations
  + Exploitation of space group symmetry in plane wave geometry optimizations
  + Local density of states (LDOS) collective variable added to Metadynamics
  + Various new XC functionals added for plane wave calculations, including
    hybrid and range-corrected ones
  + Electric field gradients with relativistic corrections 
  + Nudged Elastic Band optimization method
  + Updated basis sets and ECPs 

[ Daniel Leidert ]
* debian/watch: Fixed.

[ Andreas Tille ]
* debian/upstream: References

[ Michael Banck ]
* debian/upstream (Name): New field.
* debian/patches/02_makefile_flags.patch: Refreshed.
* debian/patches/06_statfs_kfreebsd.patch: Likewise.
* debian/patches/07_ga_target_force_linux.patch: Likewise.
* debian/patches/05_avoid_inline_assembler.patch: Removed, no longer needed.
* debian/patches/09_backported_6.1.1_fixes.patch: Likewise.
* debian/control (Build-Depends): Added gfortran-4.7 and gcc-4.7.
* debian/patches/10_force_gcc-4.7.patch: New patch, explicitly sets
  gfortran-4.7 and gcc-4.7, fixes test suite hang with gcc-4.8 (Closes:
  #701328, #713262).
* debian/testsuite: Added tests for COSMO analytical gradients and MRCC.
* debian/rules (MRCC_METHODS): New variable, required to enable MRCC methods.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#if HAVE_CONFIG_H
 
2
#   include "config.h"
 
3
#endif
 
4
 
 
5
#include "armcip.h"
 
6
#include "copy.h"
 
7
#include "acc.h"
 
8
#include "memlock.h"
 
9
#include <stdio.h>
 
10
#include <assert.h>
 
11
 
 
12
extern int cos_me;
 
13
 
 
14
#define DATA_SERVER_ 1
 
15
 
 
16
// by default use the ds remote gets
 
17
#define ORNL_USE_DS_FOR_REMOTE_GETS
 
18
 
 
19
#ifdef ORNL_USE_DS_FOR_REMOTE_GETS
 
20
#define DATA_SERVER_GET_ 1
 
21
#else
 
22
#define DATA_SERVER_GET_ 0
 
23
#endif
 
24
 
 
25
#define ARMCI_OP_2D(op, scale, proc, src, dst, bytes, count, src_stride, dst_stride,lockit)\
 
26
if(op == GET || op ==PUT)\
 
27
      armci_copy_2D(op, proc, src, dst, bytes, count, src_stride,dst_stride);\
 
28
else if(count==1) armci_acc_1D(op, scale, proc, src, dst, bytes,lockit);\
 
29
else\
 
30
      armci_acc_2D(op, scale, proc, src, dst, bytes, count, src_stride,dst_stride,lockit) 
 
31
 
 
32
/* macro supports run-time selection of request sending scheme */
 
33
#if defined(CLIENT_BUF_BYPASS)
 
34
#define CAN_REQUEST_DIRECTLY _armci_bypass
 
35
#else
 
36
#  if defined(HITACHI)
 
37
#    define CAN_REQUEST_DIRECTLY 0
 
38
#  else
 
39
#    define CAN_REQUEST_DIRECTLY 1
 
40
#  endif
 
41
#endif
 
42
 
 
43
#define PREPROCESS_STRIDED(tmp_count) {\
 
44
 tmp_count=0;\
 
45
 if(stride_levels) \
 
46
    for(;stride_levels;stride_levels--)if(count[stride_levels]>1)break;\
 
47
 if(stride_levels&&(count[0]==src_stride_arr[0]&&count[0]==dst_stride_arr[0])){\
 
48
      tmp_count=seg_count[1];\
 
49
      count = seg_count+1;\
 
50
      seg_count[1] = seg_count[0] * seg_count[1];\
 
51
      stride_levels --;\
 
52
      src_stride_arr ++;  dst_stride_arr++ ;\
 
53
 }\
 
54
}
 
55
#define POSTPROCESS_STRIDED(tmp_count) if(tmp_count)seg_count[1]=tmp_count
 
56
 
 
57
#define SERVER_PUT   1
 
58
#define SERVER_NBPUT 2
 
59
#define DIRECT_PUT   3
 
60
#define DIRECT_NBPUT 4
 
61
#define SERVER_GET   5
 
62
#define SERVER_NBGET 6
 
63
#define DIRECT_GET   7
 
64
#define DIRECT_NBGET 8
 
65
#define ONESIDED_PUT 9
 
66
#define ONESIDED_GET 10
 
67
 
 
68
 
 
69
#  define DO_FENCE(__proc,__prot)                               \
 
70
        if(__prot==SERVER_GET);                                 \
 
71
        else if(__prot==SERVER_PUT);                            \
 
72
        else if(__prot==DIRECT_GET || __prot==DIRECT_NBGET) {   \
 
73
          if(armci_prot_switch_fence[__proc]==SERVER_PUT)       \
 
74
            ARMCI_DoFence(__proc);                              \
 
75
        }                                                       \
 
76
        else if(__prot==DIRECT_PUT || __prot==DIRECT_NBPUT) {   \
 
77
          if(armci_prot_switch_fence[__proc]==SERVER_PUT)       \
 
78
            ARMCI_DoFence(__proc);                              \
 
79
        }                                                       \
 
80
        else if(__prot==ONESIDED_GET) {                         \
 
81
          if(armci_prot_switch_fence[__proc]==SERVER_PUT) {     \
 
82
            ARMCI_DoFence(__proc);                              \
 
83
          }                                                     \
 
84
        }                                                       \
 
85
        else if(__prot==ONESIDED_PUT);                          \
 
86
        else;                                                   \
 
87
        armci_prot_switch_fence[__proc]=__prot
 
88
 
 
89
#ifndef REGIONS_REQUIRE_MEMHDL 
 
90
#  define ARMCI_MEMHDL_T void
 
91
#endif
 
92
 
 
93
ARMCI_MEMHDL_T *mhloc=NULL,*mhrem=NULL; 
 
94
 
 
95
#ifdef REGIONS_REQUIRE_MEMHDL 
 
96
   int armci_region_both_found_hndl(void *loc, void *rem, int size, int node,
 
97
                 ARMCI_MEMHDL_T **loc_memhdl,ARMCI_MEMHDL_T **rem_memhdl);
 
98
#  define ARMCI_REGION_BOTH_FOUND(_s,_d,_b,_p) \
 
99
    armci_region_both_found_hndl((_s),(_d),(_b),(_p),&mhloc,&mhrem)
 
100
#else
 
101
#  define ARMCI_REGION_BOTH_FOUND(_s,_d,_b,_p) \
 
102
    armci_region_both_found((_s),(_d),(_b),(_p))
 
103
#endif
 
104
 
 
105
#ifdef HAS_RDMA_GET
 
106
        
 
107
#  ifdef REGIONS_REQUIRE_MEMHDL 
 
108
   void armci_client_direct_get(int p, void *src_buf, void *dst_buf, int len,
 
109
         void** cptr,int nbtag,ARMCI_MEMHDL_T *lochdl,ARMCI_MEMHDL_T *remhdl);
 
110
#  else
 
111
   void armci_client_direct_get(int p, void *src_buf, void *dst_buf, int len,
 
112
                    void** contextptr,int nbtag,void *mhdl,void *mhdl1);
 
113
#  endif
 
114
#  define ARMCI_NBREM_GET(_p,_s,_sst,_d,_dst,_cou,_lev,_hdl) \
 
115
    armci_client_direct_get((_p),(_s),(_d),(_cou)[0],&((_hdl)->cmpl_info),(_hdl)->tag,(void *)mhloc,(void *)mhrem); \
 
116
 
 
117
#  define ARMCI_REM_GET(_p,_s,_sst,_d,_dst,_cou,_lev,_hdl) \
 
118
    armci_client_direct_get((_p),(_s),(_d),(_cou)[0],NULL,0,(void *)mhloc,(void *)mhrem); \
 
119
 
 
120
#else
 
121
 
 
122
#  define ARMCI_REM_GET(_p,_s,_sst,_d,_dst,_cou,_lev,_hdl) \
 
123
    armci_rem_get((_p),(_s),(_sst),(_d),(_dst),(_cou),(_lev),(_hdl),(void *)mhloc,(void *)mhrem)
 
124
#  define ARMCI_NBREM_GET ARMCI_REM_GET
 
125
        
 
126
#endif
 
127
 
 
128
 extern int* armci_prot_switch_fence;
 
129
 extern int armci_prot_switch_preproc;
 
130
 extern int armci_prot_switch_preop;
 
131
 
 
132
        
 
133
int armci_iwork[MAX_STRIDE_LEVEL];
 
134
 
 
135
/*\ 2-dimensional array copy
 
136
\*/
 
137
static void armci_copy_2D(int op, int proc, void *src_ptr, void *dst_ptr, 
 
138
                          int bytes, int count, int src_stride, int dst_stride)
 
139
{
 
140
    int armci_th_idx = ARMCI_THREAD_IDX;
 
141
    
 
142
#ifdef LAPI2__
 
143
#  define COUNT 1
 
144
#else
 
145
#  define COUNT count
 
146
#endif
 
147
 
 
148
#ifdef __crayx1
 
149
    int shmem = 1;
 
150
#else
 
151
    int shmem = SAMECLUSNODE(proc);
 
152
#endif
 
153
    if(shmem) {
 
154
      /* data is in local/shared memory -- can use memcpy */
 
155
//    printf("%s: shmem==true; count==%d\n",Portals_ID(),count);
 
156
      if(count==1){
 
157
        armci_copy(src_ptr, dst_ptr, bytes); 
 
158
//      printf("%s: shmem==true; finished\n",Portals_ID(),count);
 
159
      }else {
 
160
        char *ps=(char*)src_ptr;
 
161
        char *pd=(char*)dst_ptr;
 
162
        int j;
 
163
        for (j = 0;  j < count;  j++){
 
164
          bcopy(ps,pd,bytes);
 
165
          ps += src_stride;
 
166
          pd += dst_stride;
 
167
        }
 
168
      }
 
169
    } else {
 
170
        
 
171
        /* data not in local/shared memory-access through global address space*/
 
172
        
 
173
        if(op==PUT){ 
 
174
 
 
175
         // printf("%s: pre UPDATE_FENCE_STATE\n",Portals_ID());
 
176
            UPDATE_FENCE_STATE(proc, PUT, COUNT);
 
177
         // printf("%s: post UPDATE_FENCE_STATE\n",Portals_ID());
 
178
#ifdef LAPI
 
179
            SET_COUNTER(ack_cntr[armci_th_idx],COUNT);
 
180
#endif
 
181
            if(count==1){
 
182
                armci_put(src_ptr, dst_ptr, bytes, proc);
 
183
            }else{
 
184
                armci_put2D(proc, bytes, count, src_ptr, src_stride,
 
185
                            dst_ptr, dst_stride);
 
186
            }
 
187
            
 
188
        }else{
 
189
            
 
190
#ifdef LAPI
 
191
            SET_COUNTER(get_cntr[armci_th_idx], COUNT);
 
192
#endif
 
193
            if(count==1){
 
194
                armci_get(src_ptr, dst_ptr, bytes, proc);
 
195
            }else{
 
196
                armci_get2D(proc, bytes, count, src_ptr, src_stride,
 
197
                            dst_ptr, dst_stride);
 
198
            }
 
199
        }
 
200
    }
 
201
}
 
202
 
 
203
 
 
204
#if (defined(CRAY) && !defined(__crayx1)) || defined(FUJITSU)
 
205
#ifdef CRAY
 
206
#  define DAXPY  SAXPY
 
207
#else
 
208
#  define DAXPY  daxpy_
 
209
#endif
 
210
 
 
211
static int ONE=1;
 
212
#define THRESH_ACC 32
 
213
 
 
214
static void daxpy_2d_(void* alpha, int *rows, int *cols, void *a, int *ald,
 
215
               void* b, int *bld)
 
216
{
 
217
   int c,r;   
 
218
   double *A = (double*)a;
 
219
   double *B = (double*)b;
 
220
   double Alpha = *(double*)alpha;
 
221
 
 
222
   if(*rows < THRESH_ACC)
 
223
      for(c=0;c<*cols;c++)
 
224
         for(r=0;r<*rows;r++)
 
225
           A[c* *ald+ r] += Alpha * B[c* *bld+r];
 
226
   else for(c=0;c<*cols;c++)
 
227
         DAXPY(rows, alpha, B + c* *bld, &ONE, A + c* *ald, &ONE);
 
228
}
 
229
#endif
 
230
 
 
231
 
 
232
void armci_acc_1D(int op, void *scale, int proc, void *src, void *dst, int bytes, int lockit)
 
233
{
 
234
int rows;
 
235
void (*func)(void*, void*, void*, int*);
 
236
    ARMCI_PR_DBG("enter",0);
 
237
      switch (op){
 
238
      case ARMCI_ACC_INT:
 
239
          rows = bytes/sizeof(int);
 
240
          func = I_ACCUMULATE_1D;
 
241
          break;
 
242
      case ARMCI_ACC_LNG:
 
243
          rows = bytes/sizeof(long);
 
244
          func = L_ACCUMULATE_1D;
 
245
          break;
 
246
      case ARMCI_ACC_DBL:
 
247
          rows = bytes/sizeof(double);
 
248
          func = D_ACCUMULATE_1D;
 
249
          break;
 
250
      case ARMCI_ACC_DCP:
 
251
          rows = bytes/(2*sizeof(double));
 
252
          func = Z_ACCUMULATE_1D;
 
253
          break;
 
254
      case ARMCI_ACC_CPL:
 
255
          rows = bytes/(2*sizeof(float));
 
256
          func = C_ACCUMULATE_1D;
 
257
          break;
 
258
      case ARMCI_ACC_FLT:
 
259
          rows = bytes/sizeof(float);
 
260
          func = F_ACCUMULATE_1D;
 
261
          break;
 
262
      default: armci_die("ARMCI accumulate: operation not supported",op);
 
263
          func = F_ACCUMULATE_1D; /*avoid compiler whining */
 
264
      }
 
265
 
 
266
 
 
267
      if(lockit){
 
268
          ARMCI_LOCKMEM(dst, bytes + (char*)dst, proc);
 
269
      }
 
270
      func(scale, dst, src, &rows);
 
271
      if(lockit)ARMCI_UNLOCKMEM(proc);
 
272
    ARMCI_PR_DBG("exit",0);
 
273
}
 
274
 
 
275
/*\ 2-dimensional accumulate
 
276
\*/
 
277
void armci_acc_2D(int op, void* scale, int proc, void *src_ptr, void *dst_ptr,
 
278
                  int bytes, int cols, int src_stride, int dst_stride, int lockit)
 
279
{
 
280
int   rows, lds, ldd, span;
 
281
void (*func)(void*, int*, int*, void*, int*, void*, int*);
 
282
 
 
283
    ARMCI_PR_DBG("enter",0);
 
284
 
 
285
/*
 
286
      if((long)src_ptr%ALIGN)armci_die("src not aligned",(long)src_ptr);
 
287
      if((long)dst_ptr%ALIGN)armci_die("src not aligned",(long)dst_ptr);
 
288
*/
 
289
 
 
290
      switch (op){
 
291
      case ARMCI_ACC_INT:
 
292
          rows = bytes/sizeof(int);
 
293
          ldd  = dst_stride/sizeof(int);
 
294
          lds  = src_stride/sizeof(int);
 
295
          func = I_ACCUMULATE_2D;
 
296
          break;
 
297
      case ARMCI_ACC_LNG:
 
298
          rows = bytes/sizeof(long);
 
299
          ldd  = dst_stride/sizeof(long);
 
300
          lds  = src_stride/sizeof(long);
 
301
          func = L_ACCUMULATE_2D;
 
302
          break;
 
303
      case ARMCI_ACC_DBL:
 
304
          rows = bytes/sizeof(double);
 
305
          ldd  = dst_stride/sizeof(double);
 
306
          lds  = src_stride/sizeof(double);
 
307
          func = D_ACCUMULATE_2D;
 
308
          break;
 
309
      case ARMCI_ACC_DCP:
 
310
          rows = bytes/(2*sizeof(double));
 
311
          ldd  = dst_stride/(2*sizeof(double));
 
312
          lds  = src_stride/(2*sizeof(double));
 
313
          func = Z_ACCUMULATE_2D;
 
314
          break;
 
315
      case ARMCI_ACC_CPL:
 
316
          rows = bytes/(2*sizeof(float));
 
317
          ldd  = dst_stride/(2*sizeof(float));
 
318
          lds  = src_stride/(2*sizeof(float));
 
319
          func = C_ACCUMULATE_2D;
 
320
          break;
 
321
      case ARMCI_ACC_FLT:
 
322
          rows = bytes/sizeof(float);
 
323
          ldd  = dst_stride/sizeof(float);
 
324
          lds  = src_stride/sizeof(float);
 
325
          func = F_ACCUMULATE_2D;
 
326
          break;
 
327
      case ARMCI_ACC_RA:
 
328
          rows = bytes/sizeof(long);
 
329
          ldd  = dst_stride/sizeof(long);
 
330
          lds  = src_stride/sizeof(long);
 
331
          func = RA_ACCUMULATE_2D_;
 
332
          break;
 
333
      default: armci_die("ARMCI accumulate: operation not supported",op);
 
334
          func = F_ACCUMULATE_2D; /*avoid compiler whining */
 
335
      }
 
336
 
 
337
             
 
338
      if(lockit){ 
 
339
          span = cols*dst_stride;
 
340
          ARMCI_LOCKMEM(dst_ptr, span + (char*)dst_ptr, proc);
 
341
      }
 
342
      func(scale, &rows, &cols, dst_ptr, &ldd, src_ptr, &lds);
 
343
      if(lockit)ARMCI_UNLOCKMEM(proc);
 
344
    ARMCI_PR_DBG("exit",0);
 
345
 
 
346
}
 
347
 
 
348
 
 
349
/*\ compute range of strided data AND lock it
 
350
\*/
 
351
static void 
 
352
armci_lockmem_patch(void* dst_ptr, int dst_stride_arr[], int count[], int stride_levels, int proc)
 
353
{
 
354
    long span = count[stride_levels];
 
355
    ARMCI_PR_DBG("enter",0);
 
356
    span *= dst_stride_arr[stride_levels-1];
 
357
 
 
358
    /* lock region of remote memory */
 
359
    ARMCI_LOCKMEM(dst_ptr, span + (char*)dst_ptr, proc);
 
360
    ARMCI_PR_DBG("exit",0);
 
361
}
 
362
 
 
363
 
 
364
/*\ strided accumulate on top of remote memory copy:
 
365
 *  copies remote data to local buffer, accumulates, puts it back 
 
366
 *  Note: if we are here then remote patch must fit in the ARMCI buffer
 
367
\*/
 
368
int armci_acc_copy_strided(int optype, void* scale, int proc,
 
369
                                  void* src_ptr, int src_stride_arr[],  
 
370
                                  void* dst_ptr, int dst_stride_arr[], 
 
371
                                  int count[], int stride_levels)
 
372
{
 
373
    void *buf_ptr = armci_internal_buffer;
 
374
    int  rc, i, *buf_stride_arr = armci_iwork;
 
375
    ARMCI_PR_DBG("enter",0);
 
376
    armci_lockmem_patch(dst_ptr,dst_stride_arr, count, stride_levels, proc);
 
377
 
 
378
    /* setup stride array for internal buffer */
 
379
    buf_stride_arr[0]=count[0];
 
380
    for(i=0; i< stride_levels; i++) {
 
381
         buf_stride_arr[i+1]= buf_stride_arr[i]*count[i+1];
 
382
    }
 
383
 
 
384
    /* get remote data to local buffer */
 
385
    rc = armci_op_strided(GET, scale, proc, dst_ptr, dst_stride_arr, buf_ptr, 
 
386
                          buf_stride_arr, count, stride_levels, 0,NULL);
 
387
 
 
388
    if(rc) { ARMCI_UNLOCKMEM(proc); return(rc); }
 
389
 
 
390
    /* call local accumulate with lockit=0 (we locked it already) and proc=me */
 
391
    rc = armci_op_strided(optype, scale, armci_me, src_ptr, src_stride_arr, 
 
392
                          buf_ptr,buf_stride_arr, count, stride_levels,0,NULL);
 
393
    if(rc) { ARMCI_UNLOCKMEM(proc); return(rc); }
 
394
 
 
395
    /* put data back from the buffer to remote location */
 
396
    rc = armci_op_strided(PUT, scale, proc, buf_ptr, buf_stride_arr, dst_ptr, 
 
397
                          dst_stride_arr, count, stride_levels,0,NULL);
 
398
 
 
399
    FENCE_NODE(proc); /* make sure put completes before unlocking */
 
400
    ARMCI_UNLOCKMEM(proc);    /* release memory lock */
 
401
    ARMCI_PR_DBG("exit",0);
 
402
 
 
403
    return(rc);
 
404
}
 
405
 
 
406
 
 
407
 
 
408
/*\ Strided  operation
 
409
\*/
 
410
int armci_op_strided(int op, void* scale, int proc,void *src_ptr, 
 
411
                     int src_stride_arr[], void* dst_ptr, int dst_stride_arr[], 
 
412
                     int count[], int stride_levels, int lockit,
 
413
                     armci_ihdl_t nb_handle)
 
414
{
 
415
char *src = (char*)src_ptr, *dst=(char*)dst_ptr;
 
416
int s2, s3, i,j, unlockit=0;
 
417
int total_of_2D;
 
418
int index[MAX_STRIDE_LEVEL], unit[MAX_STRIDE_LEVEL];
 
419
    ARMCI_PR_DBG("enter",op);
 
420
#   if defined(ACC_COPY)
 
421
      
 
422
#      ifdef ACC_SMP
 
423
         if(ARMCI_ACC(op) && !(SAMECLUSNODE(proc)) )
 
424
#      else
 
425
         if ( ARMCI_ACC(op) && proc!=armci_me)
 
426
#      endif
 
427
             /* copy remote data, accumulate, copy back*/
 
428
             return (armci_acc_copy_strided(op,scale, proc, src_ptr, src_stride_arr,
 
429
                                       dst_ptr, dst_stride_arr, count, stride_levels));
 
430
 
 
431
         else; /* do it directly through shared/local memory */
 
432
#   endif
 
433
 
 
434
 
 
435
      if(ARMCI_ACC(op) && (stride_levels>2) && lockit){
 
436
         /* we need one lock operation only - must be done outside 2d acc */
 
437
         armci_lockmem_patch(dst_ptr,dst_stride_arr, count, stride_levels, proc);
 
438
         unlockit=1;
 
439
         lockit =0;
 
440
      }
 
441
/*    if(proc!=armci_me) INTR_OFF;*/
 
442
    if(armci_me>=0 && !SAMECLUSNODE(proc)) {
 
443
       printf("%d network_strided not supported (in op_strided)\n",cos_me);
 
444
       abort();
 
445
     # if 0
 
446
       armci_network_strided(op,scale,proc,src_ptr,src_stride_arr,dst_ptr,
 
447
                         dst_stride_arr,count,stride_levels,nb_handle);
 
448
     # endif
 
449
    }
 
450
      else {
 
451
//     printf("%s in large switch stmt in op_strided (stride_levels=%d)\n",Portals_ID(),stride_levels);
 
452
    switch (stride_levels) {
 
453
      case 0: /* 1D copy */ 
 
454
 
 
455
          ARMCI_OP_2D(op, scale, proc, src_ptr, dst_ptr, count[0], 1, 
 
456
                      count[0], count[0], lockit); 
 
457
          
 
458
          break;
 
459
          
 
460
      case 1: /* 2D op */
 
461
          ARMCI_OP_2D(op, scale, proc, src_ptr, dst_ptr, count[0], count[1], 
 
462
                      src_stride_arr[0], dst_stride_arr[0], lockit);
 
463
          break;
 
464
 
 
465
      case 2: /* 3D op */
 
466
          for (s2= 0; s2  < count[2]; s2++){ /* 2D copy */
 
467
              ARMCI_OP_2D(op, scale, proc, src+s2*src_stride_arr[1], 
 
468
                          dst+s2*dst_stride_arr[1], count[0], count[1], 
 
469
                          src_stride_arr[0], dst_stride_arr[0], lockit );
 
470
          }
 
471
          break;
 
472
          
 
473
      case 3: /* 4D op */
 
474
          for(s3=0; s3< count[3]; s3++){
 
475
              src = (char*)src_ptr + src_stride_arr[2]*s3;
 
476
              dst = (char*)dst_ptr + dst_stride_arr[2]*s3;
 
477
              for (s2= 0; s2  < count[2]; s2++){ /* 3D copy */
 
478
                  ARMCI_OP_2D(op, scale, proc, src+s2*src_stride_arr[1],
 
479
                              dst+s2*dst_stride_arr[1],
 
480
                              count[0], count[1],src_stride_arr[0],
 
481
                              dst_stride_arr[0],lockit);
 
482
              }
 
483
          }
 
484
          break;
 
485
          
 
486
      default: /* N-dimensional */ 
 
487
      {
 
488
          /* stride_levels is not the same as ndim. it is ndim-1
 
489
           * For example a 10x10x10... array, suppose the datatype is byte
 
490
           * the stride_arr is 10, 10x10, 10x10x10 ....
 
491
           */
 
492
          index[2] = 0; unit[2] = 1; total_of_2D = count[2];
 
493
          for(j=3; j<=stride_levels; j++) {
 
494
              index[j] = 0; unit[j] = unit[j-1] * count[j-1];
 
495
              total_of_2D *= count[j];
 
496
          }
 
497
 
 
498
          for(i=0; i<total_of_2D; i++) {
 
499
              src = (char *)src_ptr; dst = (char *)dst_ptr;
 
500
              for(j=2; j<=stride_levels; j++) {
 
501
                  src += index[j] * src_stride_arr[j-1];
 
502
                  dst += index[j] * dst_stride_arr[j-1];
 
503
                  
 
504
                  if(((i+1) % unit[j]) == 0) index[j]++;
 
505
                  if(index[j] >= count[j]) index[j] = 0;
 
506
              }
 
507
              
 
508
              ARMCI_OP_2D(op, scale, proc, src, dst, count[0], count[1], 
 
509
                          src_stride_arr[0], dst_stride_arr[0], lockit);
 
510
          }
 
511
          
 
512
      }
 
513
    }
 
514
    } // ends else block
 
515
 
 
516
//  printf("%s after switch stmt; prior to fence/lock\n",Portals_ID());
 
517
 
 
518
    if(unlockit){
 
519
#      if defined(ACC_COPY)
 
520
          FENCE_NODE(proc); 
 
521
#      endif
 
522
       ARMCI_UNLOCKMEM(proc);    /* release memory lock */
 
523
    }
 
524
 
 
525
//  printf("%s after fence/lock; leaving op_strided\n",Portals_ID());
 
526
    ARMCI_PR_DBG("exit",op);
 
527
    return 0;
 
528
}
 
529
 
 
530
 
 
531
int PARMCI_PutS( void *src_ptr,        /* pointer to 1st segment at source*/ 
 
532
                int src_stride_arr[], /* array of strides at source */
 
533
                void* dst_ptr,        /* pointer to 1st segment at destination*/
 
534
                int dst_stride_arr[], /* array of strides at destination */
 
535
                int seg_count[],      /* number of segments at each stride 
 
536
                                         levels: count[0]=bytes*/
 
537
                int stride_levels,    /* number of stride levels */
 
538
                int proc              /* remote process(or) ID */
 
539
                )
 
540
{
 
541
int rc=0, direct=1;
 
542
int *count=seg_count, tmp_count=0;
 
543
 
 
544
    ARMCI_PR_DBG("enter",proc);
 
545
    if(src_ptr == NULL || dst_ptr == NULL) return FAIL;
 
546
    if(seg_count[0]<0)return FAIL3;
 
547
    if(stride_levels <0 || stride_levels > MAX_STRIDE_LEVEL) return FAIL4;
 
548
    if(proc<0)return FAIL5;
 
549
 
 
550
    ORDER(PUT,proc); /* ensure ordering */
 
551
    PREPROCESS_STRIDED(tmp_count);
 
552
 
 
553
#if DATA_SERVER_
 
554
    if(stride_levels) direct=SAMECLUSNODE(proc);
 
555
    direct=SAMECLUSNODE(proc);
 
556
#endif
 
557
 
 
558
    // printf("%s direct=%d, proc=%d\n",Portals_ID(),direct,proc);
 
559
 
 
560
    if(!direct){
 
561
 
 
562
     # ifdef CRAY_REGISTER_ARMCI_MALLOC
 
563
       if (stride_levels == 0 && armci_onesided_direct_put_enabled) 
 
564
       {
 
565
       // maybe move this to just before the operation happen of even after it happens
 
566
       // it's possible we may want to skip the ONESIDED_PUT and do a SERVER_PUT if we can't find the remote mdh
 
567
          DO_FENCE(proc,SERVER_PUT);
 
568
 
 
569
       // local variable within stride_level == 0 scope
 
570
          cos_desc_t *comm_desc = &__global_1sided_direct_comm_desc;
 
571
          onesided_hnd_t cp_hnd;
 
572
          cos_mdesc_t local_mdh, remote_mdh;
 
573
 
 
574
       // find remote mdh
 
575
          armci_onesided_search_remote_mdh_list(dst_ptr, proc, &remote_mdh);
 
576
 
 
577
       // register local memory -- this should use abhinav's dreg routines
 
578
          cpMemRegister(src_ptr, count[0], &local_mdh);
 
579
       // onesided_mem_register(cp_hnd, src_ptr, count[0], NULL, &local_mdh);
 
580
 
 
581
       // get the onesided v2.0 api handle for the compute process
 
582
          cpGetOnesidedHandle(&cp_hnd);
 
583
 
 
584
       // initialize onesided communication descriptor
 
585
          onesided_desc_init(cp_hnd, &local_mdh, &remote_mdh, 0, comm_desc);
 
586
 
 
587
       // initiate put
 
588
          onesided_put_nb(comm_desc);
 
589
 
 
590
       // complete put [locally]
 
591
          onesided_wait(comm_desc);
 
592
 
 
593
       // deregister memory -- if we were using the dreg routines, we would let the
 
594
       // dreg memory do this for us "on demand" = lazy mem deregisteration
 
595
          cpMemDeregister(&local_mdh);
 
596
       // onesided_mem_deregister(cp_hnd, &local_mdh);
 
597
 
 
598
       // issue a flushing get - does nothing to fix the fence problem
 
599
       /*
 
600
          static long flushaddr = 911;
 
601
          cpMemRegister(&flushaddr, sizeof(long), &local_mdh);
 
602
          onesided_desc_init(cp_hnd, &local_mdh, &remote_mdh, NULL, comm_desc);
 
603
          onesided_get_nb(comm_desc);
 
604
          onesided_wait(comm_desc);
 
605
          cpMemDeregister(&local_mdh);
 
606
        */
 
607
 
 
608
       // done!
 
609
          goto fn_exit;
 
610
       } 
 
611
       else
 
612
     # endif
 
613
       {
 
614
          DO_FENCE(proc,SERVER_PUT);
 
615
//     printf("%s calling pack_strided in PARMCI_PutS\n",Portals_ID());
 
616
          rc = armci_pack_strided(PUT, NULL, proc, src_ptr, src_stride_arr,dst_ptr,
 
617
                      dst_stride_arr, count, stride_levels, NULL, -1, -1, -1,NULL);
 
618
       }
 
619
    }
 
620
    else
 
621
    {
 
622
       if(!SAMECLUSNODE(proc))DO_FENCE(proc,DIRECT_PUT);
 
623
//     printf("%s calling op_strided in PARMCI_PutS\n",Portals_ID());
 
624
       rc = armci_op_strided( PUT, NULL, proc, src_ptr, src_stride_arr, 
 
625
                                 dst_ptr, dst_stride_arr,count,stride_levels, 
 
626
                                 0,NULL);
 
627
    }
 
628
    POSTPROCESS_STRIDED(tmp_count);
 
629
 
 
630
#ifdef ARMCI_PROFILE
 
631
    armci_profile_stop_strided(ARMCI_PROF_PUTS);
 
632
#endif
 
633
 
 
634
fn_exit:
 
635
    ARMCI_PR_DBG("exit",proc);
 
636
    if(rc) return FAIL6;
 
637
    else return 0;
 
638
 
 
639
}
 
640
 
 
641
 
 
642
int PARMCI_PutS_flag(
 
643
      void* src_ptr,        /* pointer to 1st segment at source */
 
644
      int src_stride_arr[], /* array of strides at source */
 
645
      void* dst_ptr,        /* pointer to 1st segment at destination */
 
646
      int dst_stride_arr[], /* array of strides at destination */
 
647
      int count[],          /* number of units at each stride level,
 
648
                               count[0] = #bytes */
 
649
      int stride_levels,    /* number of stride levels */
 
650
      int *flag,            /* pointer to remote flag */
 
651
      int val,              /* value to set flag upon completion of
 
652
                               data transfer */
 
653
      int proc              /* remote process(or) ID */
 
654
      )
 
655
{
 
656
  int bytes;
 
657
  /* Put local data on remote processor */
 
658
  PARMCI_PutS(src_ptr, src_stride_arr, dst_ptr, dst_stride_arr,
 
659
             count, stride_levels, proc);
 
660
 
 
661
  /* Send signal to remote processor that data transfer has
 
662
   * been completed. */
 
663
  bytes = sizeof(int);
 
664
  PARMCI_Put(&val, flag, bytes, proc);
 
665
  return 1;
 
666
}
 
667
 
 
668
 
 
669
int PARMCI_Put_flag(void *src, void* dst,int bytes,int *f,int v,int proc) {
 
670
  return  PARMCI_PutS_flag(src, NULL, dst, NULL, &bytes, 0, f, v, proc);
 
671
}
 
672
 
 
673
 
 
674
int PARMCI_PutS_flag_dir(void *src_ptr,   int src_stride_arr[],
 
675
            void* dst_ptr,   int dst_stride_arr[],
 
676
            int seg_count[], int stride_levels,
 
677
            int *flag, int val, int proc) {
 
678
  return PARMCI_PutS_flag(src_ptr, src_stride_arr,dst_ptr,dst_stride_arr,
 
679
             seg_count, stride_levels, flag, val, proc);
 
680
}
 
681
 
 
682
 
 
683
int PARMCI_GetS( void *src_ptr,         /* pointer to 1st segment at source*/ 
 
684
                int src_stride_arr[],   /* array of strides at source */
 
685
                void* dst_ptr,          /* 1st segment at destination*/
 
686
                int dst_stride_arr[],   /* array of strides at destination */
 
687
                int seg_count[],       /* number of segments at each stride 
 
688
                                           levels: count[0]=bytes*/
 
689
                int stride_levels,      /* number of stride levels */
 
690
                int proc                /* remote process(or) ID */
 
691
                )
 
692
{
 
693
        int rc,direct=1;
 
694
        int *count=seg_count, tmp_count=0;
 
695
        ARMCI_PR_DBG("enter",proc);
 
696
 
 
697
#ifdef ARMCI_ONESIDED_GETS_USES_NBGETS
 
698
        armci_hdl_t nb_handle;
 
699
        ARMCI_INIT_HANDLE(&nb_handle);
 
700
        PARMCI_NbGetS(src_ptr, src_stride_arr, dst_ptr, dst_stride_arr, seg_count, 
 
701
                      stride_levels, proc, &nb_handle);
 
702
        rc = PARMCI_Wait(&nb_handle);
 
703
#else
 
704
    if(src_ptr == NULL || dst_ptr == NULL) return FAIL;
 
705
    if(seg_count[0]<0)return FAIL3;
 
706
    if(stride_levels <0 || stride_levels > MAX_STRIDE_LEVEL) return FAIL4;
 
707
    if(proc<0||proc>=armci_nproc){printf("\n%d:%s:proc=%d",armci_me,__FUNCTION__,proc);fflush(stdout);return FAIL5;}
 
708
    
 
709
    ORDER(GET,proc); /* ensure ordering */
 
710
    PREPROCESS_STRIDED(tmp_count);
 
711
 
 
712
    direct=SAMECLUSNODE(proc);
 
713
 
 
714
 # ifdef CRAY_REGISTER_ARMCI_MALLOC
 
715
    if(!direct && armci_onesided_direct_get_enabled)
 
716
    {
 
717
 
 
718
       onesided_hnd_t cp_hnd;
 
719
       cpGetOnesidedHandle(&cp_hnd);
 
720
       cos_mdesc_t local_mdh, remote_mdh, *mdh = NULL;
 
721
       int node = armci_clus_id(proc);
 
722
 
 
723
       if(stride_levels == 0)
 
724
       {
 
725
 
 
726
       // if a strided put/acc is outstanding to proc, then we need to ensure that is completed
 
727
       // we allow the maximum possible overlap for strided puts/acc.  that means they are not fully blocking
 
728
       // calls.  they are however, guaranteed to be complete prior to another request being sent.
 
729
          DO_FENCE(proc,ONESIDED_GET);
 
730
 
 
731
       // local varaibles
 
732
          cos_desc_t *comm_desc = &__global_1sided_direct_get_comm_desc;
 
733
       // printf("[cp %d]: direct remote get - src=%p; dst=%p; tgt_rank=%d; tgt_node=%d\n",armci_me,src_ptr,dst_ptr,proc,node);
 
734
 
 
735
       // find remote mdh
 
736
          armci_onesided_search_remote_mdh_list(src_ptr, proc, &remote_mdh);
 
737
 
 
738
       // register local memory -- will use UDREG if ONESIDED_USE_UDREG is active
 
739
          cpMemRegister(dst_ptr, count[0], &local_mdh);
 
740
       // onesided_mem_register(cp_hnd, src_ptr, count[0], NULL, &local_mdh);
 
741
 
 
742
       // initialize onesided communication descriptor
 
743
          onesided_desc_init(cp_hnd, &local_mdh, &remote_mdh, 0, comm_desc);
 
744
 
 
745
       // initiate get
 
746
          onesided_get_nb(comm_desc);
 
747
 
 
748
       // complete put [locally]
 
749
          onesided_wait(comm_desc);
 
750
 
 
751
       // deregister memory -- if we were using the dreg routines, we would let the
 
752
       // dreg memory do this for us "on demand" = lazy mem deregisteration
 
753
          cpMemDeregister(&local_mdh);
 
754
       // onesided_mem_deregister(cp_hnd, &local_mdh);
 
755
 
 
756
       // done! 
 
757
          rc=0;
 
758
          goto fn_exit;
 
759
       }
 
760
       else 
 
761
       {
 
762
          DO_FENCE(proc,ONESIDED_GET);
 
763
 
 
764
          int i,j,id;
 
765
          long src_idx;   /* index offset of the current block position to src_ptr */
 
766
          long dst_idx;   /* index offset of the current block position to dst_ptr */
 
767
          int n1dim;      /* number of 1-dimensional blocks to xfer */
 
768
          int bvalue[MAX_STRIDE_LEVEL];
 
769
          int bunit[MAX_STRIDE_LEVEL];
 
770
          cos_desc_t cds[MAX_OUTSTANDING_ONESIDED_GETS];
 
771
          uint64_t src_addr, dst_addr;
 
772
 
 
773
          n1dim = 1;
 
774
          for(i=1; i<=stride_levels; i++) {
 
775
             n1dim *= count[i];
 
776
          }
 
777
 
 
778
          bvalue[0] = 0; bvalue[1] = 0; bunit[0] = 1; bunit[1] = 1;
 
779
          for(i=2; i<=stride_levels; i++)
 
780
          {
 
781
              bvalue[i] = 0;
 
782
              bunit[i] = bunit[i-1] * count[i-1];
 
783
          }
 
784
 
 
785
          for(i=0,id=0; i<n1dim; i++)
 
786
          {
 
787
              src_idx = 0;
 
788
              dst_idx = 0;
 
789
              for(j=1; j<=stride_levels; j++)
 
790
              {
 
791
                  src_idx += bvalue[j] * src_stride_arr[j-1];
 
792
                  dst_idx += bvalue[j] * dst_stride_arr[j-1];
 
793
                  if((i+1) % bunit[j] == 0) bvalue[j]++;
 
794
                  if(bvalue[j] > (count[j]-1)) bvalue[j] = 0;
 
795
              }
 
796
 
 
797
              src_addr = (uint64_t) ((char *) src_ptr + src_idx);
 
798
              dst_addr = (uint64_t) ((char *) dst_ptr + dst_idx);
 
799
 
 
800
              if(i >= MAX_OUTSTANDING_ONESIDED_GETS)
 
801
              {
 
802
                 if(id == MAX_OUTSTANDING_ONESIDED_GETS) id=0;
 
803
                 onesided_wait(&cds[id]);
 
804
                 cpMemDeregister(&cds[id].local_mdesc);
 
805
              }
 
806
 
 
807
              armci_onesided_search_remote_mdh_list((void*)src_addr, proc, &remote_mdh);
 
808
              cpMemRegister((void*)dst_addr, count[0], &local_mdh);
 
809
              onesided_desc_init(cp_hnd, &local_mdh, &remote_mdh, 0, &cds[id]);
 
810
              onesided_get_nb(&cds[id]);
 
811
              id++;
 
812
          }
 
813
 
 
814
          // finish up any outstanding requests
 
815
          int count = n1dim;
 
816
          if(MAX_OUTSTANDING_ONESIDED_GETS < n1dim) count = MAX_OUTSTANDING_ONESIDED_GETS;
 
817
          for(i=0; i<count; i++)
 
818
          {
 
819
             if(cds[i].state)
 
820
             {
 
821
                onesided_wait(&cds[i]);
 
822
                cpMemDeregister(&cds[i].local_mdesc);
 
823
             }
 
824
          }
 
825
 
 
826
       // done
 
827
          rc=0;
 
828
          goto fn_exit;
 
829
       }
 
830
    }     // end if(!direct && armci_onesided_direct_get_enabled)
 
831
  # endif // CRAY_REGISTER_ARMCI_MALLOC
 
832
 
 
833
    if(!direct) {
 
834
       DO_FENCE(proc,SERVER_GET);
 
835
       rc = armci_pack_strided(GET, NULL, proc, src_ptr, src_stride_arr,
 
836
                               dst_ptr,dst_stride_arr,count,stride_levels,
 
837
                               NULL,-1,-1,-1,NULL);
 
838
    } else {
 
839
       if(!SAMECLUSNODE(proc))DO_FENCE(proc,DIRECT_GET);
 
840
       rc = armci_op_strided(GET, NULL, proc, src_ptr, src_stride_arr, dst_ptr,
 
841
                             dst_stride_arr,count, stride_levels,0,NULL);
 
842
    }
 
843
 
 
844
    POSTPROCESS_STRIDED(tmp_count);
 
845
 
 
846
#ifdef ARMCI_PROFILE
 
847
    armci_profile_stop_strided(ARMCI_PROF_GETS);
 
848
#endif
 
849
#endif // ifdef/else ARMCI_ONESIDED_GETS_USES_NBGETS
 
850
 
 
851
fn_exit:
 
852
    ARMCI_PR_DBG("exit",proc);
 
853
    if(rc) return FAIL6;
 
854
    else return 0;
 
855
}
 
856
 
 
857
 
 
858
int PARMCI_AccS( int  optype,            /* operation */
 
859
                void *scale,            /* scale factor x += scale*y */
 
860
                void *src_ptr,          /* pointer to 1st segment at source*/ 
 
861
                int src_stride_arr[],   /* array of strides at source */
 
862
                void* dst_ptr,          /* 1st segment at destination*/
 
863
                int dst_stride_arr[],   /* array of strides at destination */
 
864
                int seg_count[],        /* number of segments at each stride 
 
865
                                           levels: count[0]=bytes*/
 
866
                int stride_levels,      /* number of stride levels */
 
867
                int proc                /* remote process(or) ID */
 
868
                )
 
869
{
 
870
int rc, direct=1;
 
871
int *count=seg_count, tmp_count=0;
 
872
 
 
873
    ARMCI_PR_DBG("enter",proc);
 
874
    if(src_ptr == NULL || dst_ptr == NULL) return FAIL;
 
875
    if(src_stride_arr == NULL || dst_stride_arr ==NULL) return FAIL2;
 
876
    if(count[0]<0)return FAIL3;
 
877
    if(stride_levels <0 || stride_levels > MAX_STRIDE_LEVEL) return FAIL4;
 
878
    if(proc<0)return FAIL5;
 
879
 
 
880
    ORDER(optype,proc); /* ensure ordering */
 
881
    PREPROCESS_STRIDED(tmp_count);
 
882
 
 
883
#if DATA_SERVER_
 
884
    direct=SAMECLUSNODE(proc);
 
885
#endif
 
886
 
 
887
#   if defined(ACC_COPY) && !defined(ACC_SMP)
 
888
       if(armci_me != proc) direct=0;
 
889
#   endif
 
890
    if(direct)
 
891
      rc = armci_op_strided(optype,scale, proc, src_ptr, src_stride_arr,dst_ptr,
 
892
                           dst_stride_arr, count, stride_levels,1,NULL);
 
893
    else{
 
894
      DO_FENCE(proc,SERVER_PUT);
 
895
      rc = armci_pack_strided(optype,scale,proc,src_ptr, src_stride_arr,dst_ptr,
 
896
                      dst_stride_arr,count,stride_levels,NULL,-1,-1,-1,NULL);
 
897
    }
 
898
    POSTPROCESS_STRIDED(tmp_count);
 
899
    ARMCI_PR_DBG("exit",proc);
 
900
    if(rc) return FAIL6;
 
901
    else return 0;
 
902
}
 
903
 
 
904
int PARMCI_Acc(int optype, void *scale, void *src, void* dst, int bytes, int proc) {
 
905
  int rc=0;
 
906
  rc = PARMCI_AccS(optype, scale, src, NULL, dst, NULL, &bytes, 0, proc);
 
907
  return rc;
 
908
}
 
909
 
 
910
/* 
 
911
   whatever original put and get functions were here have been
 
912
   replaced with the proper ones from the main armci branch.
 
913
   the old functions were entirely responsible for causing the
 
914
   test_vector_acc test to fail in test.x
 
915
*/
 
916
    
 
917
int PARMCI_Put(void *src, void* dst, int bytes, int proc) {
 
918
  int rc=0;
 
919
//ARMCI_PROFILE_START_STRIDED(&bytes, 0, proc, ARMCI_PROF_PUT);
 
920
  rc = PARMCI_PutS(src, NULL, dst, NULL, &bytes, 0, proc);
 
921
//ARMCI_PROFILE_STOP_STRIDED(ARMCI_PROF_PUT);
 
922
  assert(rc==0);
 
923
  return rc;
 
924
}
 
925
 
 
926
int PARMCI_Get(void *src, void* dst, int bytes, int proc) {
 
927
  int rc=0;
 
928
//ARMCI_PROFILE_START_STRIDED(&bytes, 0, proc, ARMCI_PROF_GET);
 
929
 
 
930
#ifdef __crayx1
 
931
  memcpy(dst,src,bytes);
 
932
#else
 
933
  rc = PARMCI_GetS(src, NULL, dst, NULL, &bytes, 0, proc);
 
934
#endif
 
935
//ARMCI_PROFILE_STOP_STRIDED(ARMCI_PROF_GET);
 
936
//dassert(1,rc==0);
 
937
  assert(rc==0);
 
938
  return rc;
 
939
}
 
940
 
 
941
#define PACK1D 1
 
942
 
 
943
#if PACK1D 
 
944
#  define armci_read_strided1  armci_read_strided
 
945
#  define armci_write_strided1 armci_write_strided
 
946
#else
 
947
#  define armci_read_strided2  armci_read_strided
 
948
#  define armci_write_strided2 armci_write_strided
 
949
#endif
 
950
 
 
951
void armci_write_strided1(void *ptr, int stride_levels, int stride_arr[],
 
952
                   int count[], char *buf)
 
953
{
 
954
    int i, j;
 
955
    long idx;    /* index offset of current block position to ptr */
 
956
    int n1dim;  /* number of 1 dim block */
 
957
    int bvalue[MAX_STRIDE_LEVEL], bunit[MAX_STRIDE_LEVEL];
 
958
    int bytes = count[0];
 
959
    ARMCI_PR_DBG("enter",stride_levels);
 
960
 
 
961
    /* number of n-element of the first dimension */
 
962
    n1dim = 1;
 
963
    for(i=1; i<=stride_levels; i++)
 
964
        n1dim *= count[i];
 
965
 
 
966
    /* calculate the destination indices */
 
967
    bvalue[0] = 0; bvalue[1] = 0; bunit[0] = 1; bunit[1] = 1;
 
968
    for(i=2; i<=stride_levels; i++) {
 
969
        bvalue[i] = 0;
 
970
        bunit[i] = bunit[i-1] * count[i-1];
 
971
    }
 
972
 
 
973
    for(i=0; i<n1dim; i++) {
 
974
        idx = 0;
 
975
        for(j=1; j<=stride_levels; j++) {
 
976
            idx += bvalue[j] * stride_arr[j-1];
 
977
            if((i+1) % bunit[j] == 0) bvalue[j]++;
 
978
            if(bvalue[j] > (count[j]-1)) bvalue[j] = 0;
 
979
        }
 
980
 
 
981
        armci_copy( ((char*)ptr)+idx, buf, bytes);
 
982
        buf += count[0];
 
983
    }
 
984
    ARMCI_PR_DBG("exit",stride_levels);
 
985
}
 
986
 
 
987
 
 
988
void armci_write_strided2(void *ptr, int stride_levels, int stride_arr[],
 
989
                          int count[], char *buf)
 
990
{                  
 
991
    int i, j;
 
992
    int total;   /* number of 2 dim block */
 
993
    int index[MAX_STRIDE_LEVEL], unit[MAX_STRIDE_LEVEL];
 
994
    ARMCI_PR_DBG("enter",stride_levels);
 
995
    
 
996
    if(stride_levels == 0){
 
997
       armci_copy( ptr, buf, count[0]);
 
998
    }else if (count[0]%ALIGN_SIZE || (unsigned long)ptr%ALIGN_SIZE ) 
 
999
              armci_write_strided1(ptr,stride_levels, stride_arr,count,buf);
 
1000
          else {
 
1001
             int rows, ld, idx, ldd;
 
1002
             char *src;
 
1003
             rows = count[0]/8;
 
1004
             ld   = stride_arr[0]/8;
 
1005
             switch(stride_levels){
 
1006
             case 1: 
 
1007
                     DCOPY21(&rows, count+1, ptr, &ld, buf, &idx);
 
1008
                     break;
 
1009
             case 2: 
 
1010
                     ldd = stride_arr[1]/stride_arr[0];
 
1011
                     DCOPY31(&rows, count+1, count+2, ptr, &ld, &ldd, buf,&idx);
 
1012
 
 
1013
                     break;
 
1014
             default: 
 
1015
                     index[2] = 0; unit[2] = 1; total = count[2];
 
1016
                     for(j=3; j<=stride_levels; j++) {
 
1017
                         index[j] = 0; unit[j] = unit[j-1] * count[j-1];
 
1018
                         total *= count[j];
 
1019
                     }
 
1020
                     for(i=0; i<total; i++) {
 
1021
                         src = (char *)ptr; 
 
1022
                         for(j=2; j<=stride_levels; j++) {
 
1023
                             src += index[j] * stride_arr[j-1];
 
1024
                             if(((i+1) % unit[j]) == 0) index[j]++;
 
1025
                             if(index[j] >= count[j]) index[j] = 0;
 
1026
                         }
 
1027
                         DCOPY21(&rows, count+1,src, &ld, buf, &idx); 
 
1028
                         buf = (char*) ((double*)buf + idx);
 
1029
                     }
 
1030
            } /*switch */
 
1031
         } /*else */
 
1032
    ARMCI_PR_DBG("exit",stride_levels);
 
1033
}
 
1034
 
 
1035
 
 
1036
void armci_read_strided1(void *ptr, int stride_levels, int stride_arr[],
 
1037
                        int count[], char *buf)
 
1038
{
 
1039
    int i, j;
 
1040
    long idx;    /* index offset of current block position to ptr */
 
1041
    int n1dim;  /* number of 1 dim block */
 
1042
    int bvalue[MAX_STRIDE_LEVEL], bunit[MAX_STRIDE_LEVEL];
 
1043
    int bytes = count[0];
 
1044
 
 
1045
    ARMCI_PR_DBG("enter",stride_levels);
 
1046
    /* number of n-element of the first dimension */
 
1047
    n1dim = 1;
 
1048
    for(i=1; i<=stride_levels; i++)
 
1049
        n1dim *= count[i];
 
1050
 
 
1051
    /* calculate the destination indices */
 
1052
    bvalue[0] = 0; bvalue[1] = 0; bunit[0] = 1; bunit[1] = 1;
 
1053
    for(i=2; i<=stride_levels; i++) {
 
1054
        bvalue[i] = 0;
 
1055
        bunit[i] = bunit[i-1] * count[i-1];
 
1056
    }
 
1057
 
 
1058
    for(i=0; i<n1dim; i++) {
 
1059
        idx = 0;
 
1060
        for(j=1; j<=stride_levels; j++) {
 
1061
            idx += bvalue[j] * stride_arr[j-1];
 
1062
            if((i+1) % bunit[j] == 0) bvalue[j]++;
 
1063
            if(bvalue[j] > (count[j]-1)) bvalue[j] = 0;
 
1064
        }
 
1065
 
 
1066
        armci_copy(buf, ((char*)ptr)+idx,bytes);
 
1067
        buf += count[0];
 
1068
    }
 
1069
    ARMCI_PR_DBG("exit",stride_levels);
 
1070
}
 
1071
 
 
1072
 
 
1073
void armci_read_strided2(void *ptr, int stride_levels, int stride_arr[],
 
1074
                         int count[], char *buf)
 
1075
{                  
 
1076
    int i, j;
 
1077
    int total;   /* number of 2 dim block */
 
1078
    int index[MAX_STRIDE_LEVEL], unit[MAX_STRIDE_LEVEL];
 
1079
   
 
1080
    ARMCI_PR_DBG("enter",stride_levels);
 
1081
    if(stride_levels == 0){
 
1082
       armci_copy( buf, ptr, count[0]);
 
1083
    }else if (count[0]%ALIGN_SIZE || (unsigned long)ptr%ALIGN_SIZE) 
 
1084
              armci_read_strided1(ptr,stride_levels, stride_arr,count,buf);
 
1085
          else {
 
1086
             int rows, ld, idx, ldd;
 
1087
             char *src;
 
1088
             rows = count[0]/8;
 
1089
             ld   = stride_arr[0]/8;
 
1090
             switch(stride_levels){
 
1091
             case 1: 
 
1092
                     DCOPY12(&rows, count+1, ptr, &ld, buf, &idx);
 
1093
                     break;
 
1094
             case 2:
 
1095
                     ldd = stride_arr[1]/stride_arr[0];   
 
1096
                     DCOPY13(&rows, count+1, count+2, ptr, &ld, &ldd, buf,&idx);
 
1097
                     break;
 
1098
             default:
 
1099
                     index[2] = 0; unit[2] = 1; total = count[2];
 
1100
                     for(j=3; j<=stride_levels; j++) {
 
1101
                         index[j] = 0; unit[j] = unit[j-1] * count[j-1];
 
1102
                         total *= count[j];
 
1103
                     }
 
1104
                     for(i=0; i<total; i++) {
 
1105
                         src = (char *)ptr; 
 
1106
                         for(j=2; j<=stride_levels; j++) {
 
1107
                             src += index[j] * stride_arr[j-1];
 
1108
                             if(((i+1) % unit[j]) == 0) index[j]++;
 
1109
                             if(index[j] >= count[j]) index[j] = 0;
 
1110
                         }
 
1111
                         DCOPY12(&rows, count+1,src, &ld, buf, &idx);
 
1112
                         buf = (char*) ((double*)buf + idx);
 
1113
                     }
 
1114
            } /*switch */
 
1115
         } /*else */
 
1116
    ARMCI_PR_DBG("exit",stride_levels);
 
1117
}
 
1118
 
 
1119
/*\Non-Blocking API
 
1120
\*/
 
1121
int PARMCI_NbPutS( void *src_ptr,        /* pointer to 1st segment at source*/ 
 
1122
                int src_stride_arr[], /* array of strides at source */
 
1123
                void* dst_ptr,        /* pointer to 1st segment at destination*/
 
1124
                int dst_stride_arr[], /* array of strides at destination */
 
1125
                int seg_count[],      /* number of segments at each stride 
 
1126
                                         levels: count[0]=bytes*/
 
1127
                int stride_levels,    /* number of stride levels */
 
1128
                int proc,             /* remote process(or) ID */
 
1129
                armci_hdl_t* usr_hdl  /* armci non-blocking call handle*/
 
1130
                )
 
1131
{
 
1132
armci_ihdl_t nb_handle = (armci_ihdl_t)usr_hdl;
 
1133
int *count=seg_count, tmp_count=0;
 
1134
int rc=0, direct=1;
 
1135
    ARMCI_PR_DBG("enter",proc);
 
1136
    if(src_ptr == NULL || dst_ptr == NULL) return FAIL;
 
1137
    if(count[0]<0)return FAIL3;
 
1138
    if(stride_levels <0 || stride_levels > MAX_STRIDE_LEVEL) return FAIL4;
 
1139
    if(proc<0)return FAIL5;
 
1140
 
 
1141
    PREPROCESS_STRIDED(tmp_count);
 
1142
 
 
1143
#if DATA_SERVER_
 
1144
    if(stride_levels)direct=SAMECLUSNODE(proc);
 
1145
    direct=SAMECLUSNODE(proc);
 
1146
#endif
 
1147
 
 
1148
    /* aggregate put */
 
1149
    if(nb_handle && nb_handle->agg_flag == SET) {
 
1150
      if(!direct){ 
 
1151
        rc= armci_agg_save_strided_descriptor(src_ptr, src_stride_arr, 
 
1152
                                                 dst_ptr, dst_stride_arr, 
 
1153
                                                 count, stride_levels, proc, 
 
1154
                                                 PUT, nb_handle);
 
1155
        POSTPROCESS_STRIDED(tmp_count);
 
1156
        return(rc);
 
1157
      }
 
1158
    } 
 
1159
    else {
 
1160
      UPDATE_FENCE_INFO(proc);
 
1161
      
 
1162
      /*set tag and op in the nb handle*/
 
1163
      if(nb_handle){
 
1164
        nb_handle->tag = GET_NEXT_NBTAG();
 
1165
        nb_handle->op  = PUT;
 
1166
        nb_handle->proc= proc;
 
1167
        nb_handle->bufid=NB_NONE;
 
1168
      }
 
1169
      else
 
1170
        nb_handle = armci_set_implicit_handle(PUT, proc);
 
1171
    }
 
1172
 
 
1173
    if(!direct){
 
1174
      DO_FENCE(proc,SERVER_NBPUT);
 
1175
      rc = armci_pack_strided(PUT, NULL, proc, src_ptr, src_stride_arr,dst_ptr,
 
1176
                  dst_stride_arr, count, stride_levels,NULL,-1,-1,-1,nb_handle);
 
1177
    }
 
1178
    else{
 
1179
      if(!SAMECLUSNODE(proc))DO_FENCE(proc,DIRECT_NBPUT);
 
1180
      rc = armci_op_strided( PUT, NULL, proc, src_ptr, src_stride_arr,
 
1181
                      dst_ptr,dst_stride_arr,count,stride_levels, 0,nb_handle);
 
1182
    }
 
1183
    
 
1184
    POSTPROCESS_STRIDED(tmp_count);
 
1185
    ARMCI_PR_DBG("exit",proc);
 
1186
    if(rc) return FAIL6;
 
1187
    else return 0;
 
1188
}
 
1189
 
 
1190
int PARMCI_NbGetS( void *src_ptr,       /* pointer to 1st segment at source*/ 
 
1191
                int src_stride_arr[],   /* array of strides at source */
 
1192
                void* dst_ptr,          /* 1st segment at destination*/
 
1193
                int dst_stride_arr[],   /* array of strides at destination */
 
1194
                int seg_count[],        /* number of segments at each stride 
 
1195
                                           levels: byte_count[0]=bytes*/
 
1196
                int stride_levels,      /* number of stride levels */
 
1197
                int proc,               /* remote process(or) ID */
 
1198
                armci_hdl_t* usr_hdl    /* armci non-blocking call handle*/
 
1199
                )
 
1200
{
 
1201
    int rc=0,direct=1;
 
1202
    int *count=seg_count, tmp_count=0;
 
1203
    armci_ihdl_t nb_handle = (armci_ihdl_t) usr_hdl;
 
1204
    ARMCI_PR_DBG("enter",proc);
 
1205
 
 
1206
    if(src_ptr == NULL || dst_ptr == NULL) return FAIL;
 
1207
    if(seg_count[0]<0) return FAIL3;
 
1208
    if(stride_levels<0 || stride_levels > MAX_STRIDE_LEVEL) return FAIL4;
 
1209
    if(proc<0 || proc>=armci_nproc) { 
 
1210
       printf("\n%d:%s:proc=%d",armci_me,__FUNCTION__,proc);
 
1211
       fflush(stdout);
 
1212
       return FAIL5;
 
1213
    }
 
1214
   
 
1215
    // ORDER(GET,proc); /* ensure ordering */
 
1216
    PREPROCESS_STRIDED(tmp_count);
 
1217
    direct = SAMECLUSNODE(proc); // direct ==> local on node operation
 
1218
 
 
1219
    if(nb_handle && nb_handle->agg_flag == SET) {
 
1220
      if(!direct){
 
1221
        rc= armci_agg_save_strided_descriptor(src_ptr, src_stride_arr,
 
1222
                                         dst_ptr, dst_stride_arr,
 
1223
                                         count, stride_levels, proc,
 
1224
                                         GET, nb_handle);
 
1225
        POSTPROCESS_STRIDED(tmp_count);
 
1226
        return(rc);
 
1227
      }
 
1228
    } else {
 
1229
      // ORDER(GET,proc); ensure ordering
 
1230
      // set tag and op in the nb handle
 
1231
      if(nb_handle) {
 
1232
        nb_handle->tag = GET_NEXT_NBTAG();
 
1233
        nb_handle->op  = GET;
 
1234
        nb_handle->proc= proc;
 
1235
        nb_handle->bufid=NB_NONE;
 
1236
      }
 
1237
      else
 
1238
        nb_handle = armci_set_implicit_handle(GET, proc);
 
1239
    }
 
1240
 
 
1241
    if(nb_handle) {
 
1242
       nb_handle->onesided_direct = 0;
 
1243
    }
 
1244
 
 
1245
  # ifdef CRAY_REGISTER_ARMCI_MALLOC
 
1246
    if(!direct && armci_onesided_direct_get_enabled)
 
1247
    {
 
1248
    // set up the non-blocking descriptor
 
1249
       nb_handle->onesided_direct = 1;
 
1250
       bzero(&nb_handle->comm_desc, MAX_OUTSTANDING_ONESIDED_GETS*sizeof(cos_desc_t));
 
1251
 
 
1252
       onesided_hnd_t cp_hnd;
 
1253
       cpGetOnesidedHandle(&cp_hnd);
 
1254
       cos_mdesc_t local_mdh, remote_mdh, *mdh = NULL;
 
1255
       int node = armci_clus_id(proc);
 
1256
 
 
1257
       if(stride_levels == 0)
 
1258
       {
 
1259
 
 
1260
       // if a strided put/acc is outstanding to proc, then we need to ensure that is completed
 
1261
       // we allow the maximum possible overlap for strided puts/acc.  that means they are not fully blocking
 
1262
       // calls.  they are however, guaranteed to be complete prior to another request being sent.
 
1263
          DO_FENCE(proc,ONESIDED_GET);
 
1264
 
 
1265
       // local varaibles
 
1266
          cos_desc_t *comm_desc = &nb_handle->comm_desc[0];
 
1267
       // printf("[cp %d]: direct remote get - src=%p; dst=%p; tgt_rank=%d; tgt_node=%d\n",armci_me,src_ptr,dst_ptr,proc,node);
 
1268
 
 
1269
       // find remote mdh
 
1270
          armci_onesided_search_remote_mdh_list(src_ptr, proc, &remote_mdh);
 
1271
 
 
1272
       // register local memory -- will use UDREG if ONESIDED_USE_UDREG is active
 
1273
          cpMemRegister(dst_ptr, count[0], &local_mdh);
 
1274
       // onesided_mem_register(cp_hnd, src_ptr, count[0], NULL, &local_mdh);
 
1275
 
 
1276
       // initialize onesided communication descriptor
 
1277
          onesided_desc_init(cp_hnd, &local_mdh, &remote_mdh, 0, comm_desc);
 
1278
 
 
1279
       // initiate get
 
1280
          onesided_get_nb(comm_desc);
 
1281
 
 
1282
       // done! 
 
1283
          rc=0;
 
1284
          goto fn_exit;
 
1285
       }
 
1286
       else 
 
1287
       {
 
1288
          DO_FENCE(proc,ONESIDED_GET);
 
1289
 
 
1290
          int i,j,id;
 
1291
          long src_idx;   /* index offset of the current block position to src_ptr */
 
1292
          long dst_idx;   /* index offset of the current block position to dst_ptr */
 
1293
          int n1dim;      /* number of 1-dimensional blocks to xfer */
 
1294
          int bunit[MAX_STRIDE_LEVEL];
 
1295
          int bvalue[MAX_STRIDE_LEVEL];
 
1296
          cos_desc_t *cds = nb_handle->comm_desc;
 
1297
          uint64_t src_addr, dst_addr;
 
1298
 
 
1299
          n1dim = 1;
 
1300
          for(i=1; i<=stride_levels; i++) {
 
1301
             n1dim *= count[i];
 
1302
          }
 
1303
 
 
1304
          bvalue[0] = 0; bvalue[1] = 0; bunit[0] = 1; bunit[1] = 1;
 
1305
          for(i=2; i<=stride_levels; i++)
 
1306
          {
 
1307
              bvalue[i] = 0;
 
1308
              bunit[i] = bunit[i-1] * count[i-1];
 
1309
          }
 
1310
 
 
1311
          for(i=0,id=0; i<n1dim; i++)
 
1312
          {
 
1313
              src_idx = 0;
 
1314
              dst_idx = 0;
 
1315
              for(j=1; j<=stride_levels; j++)
 
1316
              {
 
1317
                  src_idx += bvalue[j] * src_stride_arr[j-1];
 
1318
                  dst_idx += bvalue[j] * dst_stride_arr[j-1];
 
1319
                  if((i+1) % bunit[j] == 0) bvalue[j]++;
 
1320
                  if(bvalue[j] > (count[j]-1)) bvalue[j] = 0;
 
1321
              }
 
1322
 
 
1323
              src_addr = (uint64_t) ((char *) src_ptr + src_idx);
 
1324
              dst_addr = (uint64_t) ((char *) dst_ptr + dst_idx);
 
1325
/*
 
1326
              if(armci_me == 0) {
 
1327
                 printf("1dpass=%d of %d; src_idx=%d; dst_idx=%d; count[0]=%d\n",i,n1dim,src_idx, dst_idx,count[0]);
 
1328
              }
 
1329
*/
 
1330
              if(i >= MAX_OUTSTANDING_ONESIDED_GETS)
 
1331
              {
 
1332
                 if(id == MAX_OUTSTANDING_ONESIDED_GETS) id=0;
 
1333
                 onesided_wait(&cds[id]);
 
1334
                 cpMemDeregister(&cds[id].local_mdesc);
 
1335
              }
 
1336
 
 
1337
              armci_onesided_search_remote_mdh_list((void*)src_addr, proc, &remote_mdh);
 
1338
              cpMemRegister((void*)dst_addr, count[0], &local_mdh);
 
1339
              onesided_desc_init(cp_hnd, &local_mdh, &remote_mdh, 0, &cds[id]);
 
1340
              onesided_get_nb(&cds[id]);
 
1341
              id++;
 
1342
          }
 
1343
 
 
1344
       // done
 
1345
          rc=0;
 
1346
          goto fn_exit;
 
1347
       } 
 
1348
    }     // end if(!direct && armci_onesided_direct_get_enabled)
 
1349
  # endif // CRAY_REGISTER_ARMCI_MALLOC
 
1350
 
 
1351
    if(!direct) {
 
1352
       DO_FENCE(proc,SERVER_NBGET);
 
1353
       rc = armci_pack_strided(GET, NULL, proc, src_ptr, src_stride_arr,
 
1354
                               dst_ptr,dst_stride_arr,count,stride_levels,
 
1355
                               NULL,-1,-1,-1,nb_handle);
 
1356
    } else {
 
1357
       // DO_FENCE(proc,DIRECT_GET);
 
1358
       rc = armci_op_strided(GET, NULL, proc, src_ptr, src_stride_arr, dst_ptr,
 
1359
                             dst_stride_arr,count, stride_levels,0,nb_handle);
 
1360
    }
 
1361
 
 
1362
    POSTPROCESS_STRIDED(tmp_count);
 
1363
 
 
1364
fn_exit:
 
1365
#ifdef ARMCI_PROFILE
 
1366
    armci_profile_stop_strided(ARMCI_PROF_GETS);
 
1367
#endif
 
1368
    ARMCI_PR_DBG("exit",proc);
 
1369
    if(rc) return FAIL6;
 
1370
    else return 0;
 
1371
}
 
1372
 
 
1373
 
 
1374
int PARMCI_NbAccS( int  optype,            /* operation */
 
1375
                void *scale,            /* scale factor x += scale*y */
 
1376
                void *src_ptr,          /* pointer to 1st segment at source*/ 
 
1377
                int src_stride_arr[],   /* array of strides at source */
 
1378
                void* dst_ptr,          /* 1st segment at destination*/
 
1379
                int dst_stride_arr[],   /* array of strides at destination */
 
1380
                int seg_count[],        /* number of segments at each stride 
 
1381
                                           levels: count[0]=bytes*/
 
1382
                int stride_levels,      /* number of stride levels */
 
1383
                int proc,               /* remote process(or) ID */
 
1384
                armci_hdl_t* usr_hdl  /* armci non-blocking call handle*/
 
1385
                )
 
1386
{
 
1387
armci_ihdl_t nb_handle = (armci_ihdl_t)usr_hdl;
 
1388
int *count=seg_count, tmp_count=0;
 
1389
int rc, direct=1;
 
1390
 
 
1391
    ARMCI_PR_DBG("enter",proc);
 
1392
    if(src_ptr == NULL || dst_ptr == NULL) return FAIL;
 
1393
    if(src_stride_arr == NULL || dst_stride_arr ==NULL) return FAIL2;
 
1394
    if(count[0]<0)return FAIL3;
 
1395
    if(stride_levels <0 || stride_levels > MAX_STRIDE_LEVEL) return FAIL4;
 
1396
    if(proc<0)return FAIL5;
 
1397
 
 
1398
    UPDATE_FENCE_INFO(proc);
 
1399
    PREPROCESS_STRIDED(tmp_count);
 
1400
    
 
1401
#if DATA_SERVER_
 
1402
    direct=SAMECLUSNODE(proc);
 
1403
#endif
 
1404
 
 
1405
#   if defined(ACC_COPY) && !defined(ACC_SMP)
 
1406
       if(armci_me != proc) direct=0;
 
1407
#   endif
 
1408
 
 
1409
    /*set tag and op in the nb handle*/
 
1410
    if(nb_handle){
 
1411
      nb_handle->tag = GET_NEXT_NBTAG();
 
1412
      nb_handle->op  = optype;
 
1413
      nb_handle->proc= proc;
 
1414
      nb_handle->bufid=NB_NONE;
 
1415
    }
 
1416
    else
 
1417
      nb_handle = armci_set_implicit_handle(optype, proc);
 
1418
 
 
1419
 
 
1420
    if(direct){
 
1421
      rc = armci_op_strided(optype,scale, proc, src_ptr, src_stride_arr,dst_ptr,
 
1422
                            dst_stride_arr, count, stride_levels,1,NULL);
 
1423
    }
 
1424
    else{
 
1425
      DO_FENCE(proc,SERVER_NBPUT);
 
1426
      rc = armci_pack_strided(optype,scale,proc,src_ptr, src_stride_arr,dst_ptr,
 
1427
                    dst_stride_arr,count,stride_levels,NULL,-1,-1,-1,nb_handle);
 
1428
    }
 
1429
 
 
1430
    POSTPROCESS_STRIDED(tmp_count);
 
1431
 
 
1432
    ARMCI_PR_DBG("exit",proc);
 
1433
    if(rc) return FAIL6;
 
1434
    else return 0;
 
1435
}
 
1436
 
 
1437
 
 
1438
#if !defined(ACC_COPY)&&!defined(CRAY_YMP)&&!defined(CYGNUS)&&!defined(CYGWIN) &&!defined(BGML)
 
1439
#   define REMOTE_OP
 
1440
#endif
 
1441
 
 
1442
#define INIT_NB_HANDLE(nb,o,p) if(nb){\
 
1443
             (nb)->tag = 0;\
 
1444
             (nb)->op  = (o); (nb)->proc= (p);\
 
1445
             (nb)->bufid=NB_NONE;}\
 
1446
             else { (nb)=armci_set_implicit_handle(o, p); (nb)->tag=0; }
 
1447
 
 
1448
void set_nbhandle(armci_ihdl_t *nbh, armci_hdl_t *nb_handle, int op,
 
1449
                         int proc)
 
1450
{
 
1451
   if(nb_handle)
 
1452
   {
 
1453
      *nbh=(armci_ihdl_t)nb_handle;
 
1454
   }
 
1455
   else
 
1456
   {
 
1457
      *nbh=armci_set_implicit_handle(op, proc);
 
1458
   }
 
1459
}
 
1460
 
 
1461
 
 
1462
int PARMCI_NbPut(void *src, void* dst, int bytes, int proc,armci_hdl_t* uhandle)
 
1463
{
 
1464
 
 
1465
int rc=0, direct=0;
 
1466
armci_ihdl_t nb_handle = (armci_ihdl_t)uhandle;
 
1467
    ARMCI_PR_DBG("enter",proc);
 
1468
    
 
1469
    if(src == NULL || dst == NULL) return FAIL;
 
1470
 
 
1471
    direct =SAMECLUSNODE(proc);
 
1472
 
 
1473
    /* aggregate put */
 
1474
    if(nb_handle && nb_handle->agg_flag == SET) {
 
1475
      if(direct) { armci_copy(src,dst,bytes); rc=0; }
 
1476
      else
 
1477
        rc=armci_agg_save_descriptor(src,dst,bytes,proc,PUT,0,nb_handle); 
 
1478
      return rc;
 
1479
    }
 
1480
 
 
1481
    if(direct) {
 
1482
      /*armci_wait needs proc to compute direct*/
 
1483
      INIT_NB_HANDLE(nb_handle,PUT,proc);
 
1484
      armci_copy(src,dst,bytes);
 
1485
    }
 
1486
    else{
 
1487
    # ifdef PORTALS
 
1488
      rc=PARMCI_NbPutS(src, NULL,dst,NULL, &bytes,0,proc,uhandle);
 
1489
    # else
 
1490
#     ifdef ARMCI_NB_PUT
 
1491
      INIT_NB_HANDLE(nb_handle,PUT,proc);
 
1492
      UPDATE_FENCE_STATE(proc, PUT, 1);
 
1493
      ARMCI_NB_PUT(src, dst, bytes, proc, &nb_handle->cmpl_info);
 
1494
#     else
 
1495
      rc=PARMCI_NbPutS(src, NULL,dst,NULL, &bytes,0,proc,uhandle);
 
1496
#     endif
 
1497
    # endif
 
1498
    }
 
1499
 
 
1500
    ARMCI_PR_DBG("exit",proc);
 
1501
    return(rc);
 
1502
}
 
1503
 
 
1504
 
 
1505
int PARMCI_NbGet(void *src, void* dst, int bytes, int proc,armci_hdl_t* uhandle)
 
1506
{
 
1507
 
 
1508
int rc=0, direct=0;
 
1509
armci_ihdl_t nb_handle = (armci_ihdl_t)uhandle;
 
1510
    ARMCI_PR_DBG("enter",proc);
 
1511
    
 
1512
    if(src == NULL || dst == NULL) return FAIL;
 
1513
 
 
1514
    direct =SAMECLUSNODE(proc);
 
1515
 
 
1516
    if(nb_handle && nb_handle->agg_flag == SET) {
 
1517
      if(direct) { armci_copy(src,dst,bytes); rc=0; }
 
1518
      else
 
1519
        rc=armci_agg_save_descriptor(src,dst,bytes,proc,GET,0,nb_handle);
 
1520
      return rc;
 
1521
    }
 
1522
 
 
1523
    if(direct) {
 
1524
      /*armci_wait needs proc to compute direct*/
 
1525
      INIT_NB_HANDLE(nb_handle,PUT,proc);
 
1526
      armci_copy(src,dst,bytes);
 
1527
    }else{
 
1528
    
 
1529
    # ifdef PORTALS
 
1530
      rc=PARMCI_NbGetS(src, NULL,dst,NULL, &bytes,0,proc,uhandle);
 
1531
    # else
 
1532
#     ifdef ARMCI_NB_GET
 
1533
      /*set tag and op in the nb handle*/
 
1534
      INIT_NB_HANDLE(nb_handle,GET,proc);
 
1535
      
 
1536
      ARMCI_NB_GET(src, dst, bytes, proc, &nb_handle->cmpl_info);
 
1537
#     else
 
1538
      rc=PARMCI_NbGetS(src, NULL,dst,NULL, &bytes,0,proc,uhandle);
 
1539
#     endif
 
1540
    # endif
 
1541
    }
 
1542
    ARMCI_PR_DBG("exit",proc);
 
1543
    return(rc);
 
1544
}
 
1545
 
 
1546
 
 
1547
static void _armci_rem_value(int op, void *src, void *dst, int proc, 
 
1548
                             int bytes) {  
 
1549
    int rc=0;
 
1550
    int armci_th_idx = ARMCI_THREAD_IDX;
 
1551
 
 
1552
    ORDER(op,proc); /* ensure ordering */
 
1553
 
 
1554
#if defined(REMOTE_OP) && !defined(QUADRICS)
 
1555
    rc = armci_rem_strided(op, NULL, proc, src, NULL, dst, NULL,
 
1556
                           &bytes, 0, NULL, 0, NULL);
 
1557
    if(rc) armci_die("ARMCI_Value: armci_rem_strided incomplete", FAIL6);
 
1558
#else
 
1559
 
 
1560
    if(op==PUT) {
 
1561
      UPDATE_FENCE_STATE(proc, PUT, 1);
 
1562
#     ifdef LAPI
 
1563
      SET_COUNTER(ack_cntr[armci_th_idx], 1);
 
1564
#     endif
 
1565
#if defined(BGML)
 
1566
      /* fprintf(stderr,"bytes: %d\n",bytes); */
 
1567
      /* this call is blocking, so local count is fine */
 
1568
      BG1S_t req;
 
1569
      unsigned count=1;
 
1570
      BGML_Callback_t cb_wait={wait_callback, &count};
 
1571
      BG1S_Memput(&req, proc, src, 0, dst, bytes, &cb_wait, 1);
 
1572
      BGML_Wait(&count);
 
1573
#else
 
1574
 
 
1575
      armci_put(src, dst, bytes, proc);
 
1576
#endif
 
1577
    }
 
1578
    else {
 
1579
#     ifdef LAPI
 
1580
      SET_COUNTER(get_cntr[armci_th_idx], 1);
 
1581
#     endif
 
1582
#if defined(BGML)
 
1583
      /* fprintf(stderr,"before memget\n"); */
 
1584
   BG1S_t req;
 
1585
   unsigned count=1;
 
1586
   BGML_Callback_t cb_wait={wait_callback, &count};
 
1587
   BG1S_Memget(&req, proc, dst, 0, src, bytes, &cb_wait, 1);
 
1588
   BGML_Wait(&count);
 
1589
 
 
1590
#else
 
1591
      armci_get(src, dst, bytes, proc);
 
1592
#endif
 
1593
    }
 
1594
    
 
1595
    /* deal with non-blocking loads and stores */
 
1596
# if defined(LAPI) || defined(_ELAN_PUTGET_H)
 
1597
    if(proc != armci_me){
 
1598
      if(op == GET){
 
1599
        WAIT_FOR_GETS; /* wait for data arrival */
 
1600
      }else {
 
1601
        WAIT_FOR_PUTS; /* data must be copied out*/
 
1602
      }
 
1603
    }
 
1604
#endif
 
1605
#endif
 
1606
}
 
1607
 
 
1608
/* non-blocking remote value put/get operation */
 
1609
static void _armci_nb_rem_value(int op, void *src, void *dst, int proc, 
 
1610
                                int bytes, armci_ihdl_t nb_handle) {  
 
1611
    int rc=0, pv=0;
 
1612
    int armci_th_idx = ARMCI_THREAD_IDX;
 
1613
 
 
1614
    if(nb_handle && nb_handle->agg_flag == SET) {
 
1615
      if(op==PUT) pv = 1;
 
1616
      (void)armci_agg_save_descriptor(src,dst,bytes,proc,op,pv,nb_handle);
 
1617
      return;
 
1618
    }
 
1619
    else {
 
1620
      if(op==PUT) UPDATE_FENCE_INFO(proc); 
 
1621
      
 
1622
      /*set tag and op in the nb handle*/
 
1623
      if(nb_handle){
 
1624
        nb_handle->tag = GET_NEXT_NBTAG();
 
1625
        nb_handle->op  = op;
 
1626
        nb_handle->proc= proc;
 
1627
        nb_handle->bufid=NB_NONE;
 
1628
      }
 
1629
      else 
 
1630
        nb_handle = armci_set_implicit_handle(op, proc);
 
1631
    }
 
1632
 
 
1633
#if defined(REMOTE_OP) && !defined(QUADRICS)
 
1634
    rc = armci_rem_strided(op, NULL, proc, src, NULL, dst, NULL,
 
1635
                           &bytes, 0, NULL, 0, nb_handle);
 
1636
    if(rc) armci_die("ARMCI_Value: armci_rem_strided incomplete", FAIL6);
 
1637
#else
 
1638
    
 
1639
    if(op==PUT) {
 
1640
      UPDATE_FENCE_STATE(proc, PUT, 1);
 
1641
#     ifdef LAPI
 
1642
      SET_COUNTER(ack_cntr[armci_th_idx], 1);
 
1643
#     endif
 
1644
      armci_put(src, dst, bytes, proc);
 
1645
    }
 
1646
    else {
 
1647
#     ifdef LAPI
 
1648
      SET_COUNTER(get_cntr[armci_th_idx], 1);
 
1649
#     endif
 
1650
      armci_get(src, dst, bytes, proc);
 
1651
    }
 
1652
    
 
1653
    /* deal with non-blocking loads and stores */
 
1654
# if defined(LAPI) || defined(_ELAN_PUTGET_H)
 
1655
#   ifdef LAPI
 
1656
    if(!nb_handle)
 
1657
#   endif
 
1658
      {
 
1659
        if(proc != armci_me){
 
1660
          if(op == GET){
 
1661
            WAIT_FOR_GETS; /* wait for data arrival */
 
1662
          }else {
 
1663
            WAIT_FOR_PUTS; /* data must be copied out*/
 
1664
          }
 
1665
        }
 
1666
      }
 
1667
# endif
 
1668
#endif
 
1669
}
 
1670
 
 
1671
 
 
1672
#define CHK_ERR(dst, proc)       \
 
1673
    if(dst==NULL) armci_die("PARMCI_PutValue: NULL pointer passed",FAIL);  \
 
1674
    if(proc<0) armci_die("PARMCI_PutValue: Invalid process rank", proc);
 
1675
 
 
1676
#define CHK_ERR_GET(src, dst, proc, bytes)       \
 
1677
    if(src==NULL || dst==NULL) armci_die("PARMCI_GetValue: NULL pointer passed",FAIL);  \
 
1678
    if(proc<0) armci_die("PARMCI_GetValue: Invalid process rank", proc); \
 
1679
    if(bytes<0) armci_die("PARMCI_GetValue: Invalid size", bytes);
 
1680
 
 
1681
/** 
 
1682
 * Register-Originated Put.
 
1683
 */
 
1684
int PARMCI_PutValueInt(int src, void *dst, int proc) 
 
1685
{
 
1686
    CHK_ERR(dst, proc);
 
1687
    if( SAMECLUSNODE(proc) ) *(int *)dst = src;
 
1688
    else _armci_rem_value(PUT, &src, dst, proc, sizeof(int));
 
1689
    return 0;
 
1690
}
 
1691
 
 
1692
int PARMCI_PutValueLong(long src, void *dst, int proc) 
 
1693
{
 
1694
    CHK_ERR(dst, proc);
 
1695
    if( SAMECLUSNODE(proc) ) *(long *)dst = src;
 
1696
    else _armci_rem_value(PUT, &src, dst, proc, sizeof(long));
 
1697
    return 0;
 
1698
}
 
1699
 
 
1700
int PARMCI_PutValueFloat(float src, void *dst, int proc) 
 
1701
{
 
1702
    CHK_ERR(dst, proc);
 
1703
    if( SAMECLUSNODE(proc) ) *(float *)dst = src;
 
1704
    else _armci_rem_value(PUT, &src, dst, proc, sizeof(float));
 
1705
    return 0;
 
1706
}
 
1707
 
 
1708
int PARMCI_PutValueDouble(double src, void *dst, int proc) 
 
1709
{
 
1710
    CHK_ERR(dst, proc);
 
1711
    if( SAMECLUSNODE(proc) ) *(double *)dst = src;
 
1712
    else _armci_rem_value(PUT, &src, dst, proc, sizeof(double));
 
1713
    return 0;
 
1714
}
 
1715
 
 
1716
/**
 
1717
 * Non-Blocking register-originated put.
 
1718
 */
 
1719
int PARMCI_NbPutValueInt(int src, void *dst, int proc, armci_hdl_t* usr_hdl) 
 
1720
{
 
1721
    CHK_ERR(dst, proc);
 
1722
    if( SAMECLUSNODE(proc) ) *(int *)dst = src;
 
1723
    else _armci_nb_rem_value(PUT,&src,dst,proc,sizeof(int),(armci_ihdl_t)usr_hdl);
 
1724
    return 0;
 
1725
}
 
1726
 
 
1727
int PARMCI_NbPutValueLong(long src, void *dst, int proc, armci_hdl_t* usr_hdl) 
 
1728
{
 
1729
    CHK_ERR(dst, proc);
 
1730
    if( SAMECLUSNODE(proc) ) *(long *)dst = src;
 
1731
    else _armci_nb_rem_value(PUT,&src,dst,proc,sizeof(long),(armci_ihdl_t)usr_hdl);
 
1732
    return 0;
 
1733
}
 
1734
 
 
1735
int PARMCI_NbPutValueFloat(float src, void *dst, int proc, armci_hdl_t* usr_hdl)
 
1736
{
 
1737
    CHK_ERR(dst, proc);
 
1738
    if( SAMECLUSNODE(proc) ) *(float *)dst = src;
 
1739
    else  _armci_nb_rem_value(PUT,&src,dst,proc,sizeof(float),(armci_ihdl_t)usr_hdl);
 
1740
    return 0;
 
1741
}
 
1742
 
 
1743
int PARMCI_NbPutValueDouble(double src, void *dst, int proc, armci_hdl_t* usr_hdl)
 
1744
{
 
1745
    CHK_ERR(dst, proc);
 
1746
    if( SAMECLUSNODE(proc) ) *(double *)dst = src;
 
1747
    else  _armci_nb_rem_value(PUT,&src,dst,proc,sizeof(double),(armci_ihdl_t)usr_hdl);
 
1748
     return 0;
 
1749
 }
 
1750
 
 
1751
#if 1
 
1752
/** 
 
1753
 * Register-Originated Get.
 
1754
 */
 
1755
int PARMCI_GetValueInt(void *src, int proc) 
 
1756
{
 
1757
    int dst;
 
1758
    if( SAMECLUSNODE(proc) ) return *(int *)src;
 
1759
    else _armci_rem_value(GET, src, &dst, proc, sizeof(int));
 
1760
    return dst;
 
1761
}
 
1762
 
 
1763
long PARMCI_GetValueLong(void *src, int proc) 
 
1764
{
 
1765
    long dst;
 
1766
    if( SAMECLUSNODE(proc) ) return *(long *)src;
 
1767
    else _armci_rem_value(GET, src, &dst, proc, sizeof(long));
 
1768
    return dst;
 
1769
}
 
1770
 
 
1771
float PARMCI_GetValueFloat(void *src, int proc) 
 
1772
{
 
1773
    float dst;
 
1774
    if( SAMECLUSNODE(proc) ) return *(float *)src;
 
1775
    else _armci_rem_value(GET, src, &dst, proc, sizeof(float));
 
1776
    return dst;
 
1777
}
 
1778
 
 
1779
double PARMCI_GetValueDouble(void *src, int proc) 
 
1780
{
 
1781
    double dst;
 
1782
    if( SAMECLUSNODE(proc) ) return *(double *)src;
 
1783
    else _armci_rem_value(GET, src, &dst, proc, sizeof(double));
 
1784
    return dst;
 
1785
}
 
1786
 
 
1787
#endif
 
1788
 
 
1789
#if 0
 
1790
/**
 
1791
 * Register-Originated Get.
 
1792
 */
 
1793
int PARMCI_GetValue(void *src, void *dst, int proc, int bytes) 
 
1794
{
 
1795
    CHK_ERR_GET(src, dst, proc, bytes);
 
1796
    if( SAMECLUSNODE(proc) ) { armci_copy(src, dst, bytes); }
 
1797
    else _armci_rem_value(GET, src, dst, proc, bytes);
 
1798
    return 0;
 
1799
}
 
1800
 
 
1801
/**
 
1802
 * Non-Blocking register-originated get.
 
1803
 */
 
1804
int PARMCI_NbGetValue(void *src, void *dst, int proc, int bytes, armci_hdl_t* usr_hdl) 
 
1805
{
 
1806
    CHK_ERR_GET(src, dst, proc, bytes);
 
1807
    if( SAMECLUSNODE(proc) ) { armci_copy(src, dst, bytes); }
 
1808
    else _armci_nb_rem_value(GET, src, dst, proc, bytes, (armci_ihdl_t)usr_hdl);
 
1809
    return 0;
 
1810
}
 
1811
#endif
 
1812