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

« back to all changes in this revision

Viewing changes to src/tools/ga-5-1/armci/src/devices/dcmf/dcmf2/armcix_acc.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
 
/* begin_generated_IBM_copyright_prolog                             */
6
 
/*                                                                  */
7
 
/* ---------------------------------------------------------------- */
8
 
/* (C)Copyright IBM Corp.  2007, 2008                               */
9
 
/* IBM BSD License                                                  */
10
 
/* ---------------------------------------------------------------- */
11
 
/*                                                                  */
12
 
/* end_generated_IBM_copyright_prolog                               */
13
 
/**
14
 
 * \file armci/src/x/dcmf/armcix_acc.c
15
 
 * \brief DCMF ARMCI Extension for accumulate operations.
16
 
 */
17
 
 
18
 
#include "armcix_impl.h"
19
 
 
20
 
typedef struct {
21
 
    float real;
22
 
    float imag;
23
 
} complex_t;
24
 
 
25
 
typedef struct {
26
 
    double real;
27
 
    double imag;
28
 
} dcomplex_t;
29
 
 
30
 
typedef union ARMCIX_DCMF_AccInfo_t
31
 
{
32
 
  DCQuad         raw[2];
33
 
  struct
34
 
  {
35
 
    void       * dst;
36
 
    int          datatype;
37
 
    unsigned     bytes;
38
 
    union
39
 
    {
40
 
      int        ival;
41
 
      long       lval;
42
 
      float      fval;
43
 
      double     dval;
44
 
      complex_t  cplxval;
45
 
      dcomplex_t dcplxval;
46
 
    };
47
 
  };
48
 
}
49
 
ARMCIX_DCMF_AccInfo_t __attribute__ ((__aligned__ (16)));
50
 
 
51
 
typedef struct ARMCIX_DCMF_AccNbInfo_t
52
 
{
53
 
  ARMCIX_DCMF_AccInfo_t      info;
54
 
  ARMCIX_DCMF_Connection_t * connection;
55
 
  void                     * buffer;
56
 
}
57
 
ARMCIX_DCMF_AccNbInfo_t;
58
 
 
59
 
#define ACCUMULATE( DTYPE, scale, elems, src, dst) {\
60
 
    int j;\
61
 
    DTYPE *a =(DTYPE *)(dst);\
62
 
    DTYPE *b =(DTYPE *)(src);\
63
 
    DTYPE alpha = *(DTYPE *)(scale);\
64
 
    for(j=0;j<(elems);j++)a[j] += alpha*b[j];\
65
 
}
66
 
        
67
 
#define CPL_ACCUMULATE( DTYPE, scale, elems, src, dst) {\
68
 
    int j;\
69
 
    DTYPE *a =(DTYPE *)(dst);\
70
 
    DTYPE *b =(DTYPE *)(src);\
71
 
    DTYPE alpha = *(DTYPE *)(scale);\
72
 
    for(j=0;j<(elems);j++){\
73
 
        a[j].real += alpha.real*b[j].real - alpha.imag*b[j].imag;\
74
 
        a[j].imag += alpha.imag*b[j].real + alpha.real*b[j].imag;\
75
 
    }\
76
 
}
77
 
 
78
 
DCMF_Protocol_t __acc_protocol;
79
 
 
80
 
/**
81
 
 * \brief DCMF ARMCI Extention receive short accumulate operation callback
82
 
 *
83
 
 * \see DCMF_RecvSendShort
84
 
 */
85
 
void ARMCIX_DCMF_RecvAcc1 (void           * clientdata,
86
 
                           const DCQuad   * msginfo,
87
 
                           unsigned         count,
88
 
                           unsigned         peer,
89
 
                           const char     * src,
90
 
                           unsigned         bytes)
91
 
{
92
 
  //ARMCIX_DCMF_Connection_t * connection = (ARMCIX_DCMF_Connection_t *) clientdata;
93
 
  ARMCIX_DCMF_AccInfo_t * info = (ARMCIX_DCMF_AccInfo_t *) msginfo;
94
 
 
95
 
  switch (info->datatype)
96
 
  {
97
 
    case ARMCI_ACC_INT:
98
 
      ACCUMULATE( int, &info->ival, bytes/sizeof(int), src, info->dst);
99
 
      break;
100
 
    case ARMCI_ACC_DBL:
101
 
      ACCUMULATE( double, &info->dval, bytes/sizeof(double), src, info->dst);
102
 
      break;
103
 
    case ARMCI_ACC_FLT:
104
 
      ACCUMULATE( float, &info->fval, bytes/sizeof(float), src, info->dst);
105
 
      break;
106
 
    case ARMCI_ACC_CPL:
107
 
      CPL_ACCUMULATE( complex_t, &info->cplxval, bytes/sizeof(complex_t), src, info->dst);
108
 
      break;
109
 
    case ARMCI_ACC_DCP:
110
 
      CPL_ACCUMULATE( dcomplex_t, &info->dcplxval, bytes/sizeof(dcomplex_t), src, info->dst);
111
 
      break;
112
 
    case ARMCI_ACC_LNG:
113
 
      ACCUMULATE( long, &info->lval, bytes/sizeof(long), src, info->dst);
114
 
      break;
115
 
    default:
116
 
      assert (0);
117
 
      break;
118
 
  }
119
 
}
120
 
 
121
 
 
122
 
void ARMCIX_DCMF_AccReceiveComplete (ARMCIX_DCMF_AccNbInfo_t * nbinfo)
123
 
{
124
 
  ARMCIX_DCMF_AccInfo_t * info = (ARMCIX_DCMF_AccInfo_t *) &nbinfo->info;
125
 
 
126
 
  switch (info->datatype)
127
 
  {
128
 
    case ARMCI_ACC_INT:
129
 
      ACCUMULATE( int, &info->ival, info->bytes/sizeof(int), nbinfo->buffer, info->dst);
130
 
      break;
131
 
    case ARMCI_ACC_DBL:
132
 
      ACCUMULATE( double, &info->dval, info->bytes/sizeof(double), nbinfo->buffer, info->dst);
133
 
      break;
134
 
    case ARMCI_ACC_FLT:
135
 
      ACCUMULATE( float, &info->fval, info->bytes/sizeof(float), nbinfo->buffer, info->dst);
136
 
      break;
137
 
    case ARMCI_ACC_CPL:
138
 
      CPL_ACCUMULATE( complex_t, &info->cplxval, info->bytes/sizeof(complex_t), nbinfo->buffer, info->dst);
139
 
      break;
140
 
    case ARMCI_ACC_DCP:
141
 
      CPL_ACCUMULATE( dcomplex_t, &info->dcplxval, info->bytes/sizeof(dcomplex_t), nbinfo->buffer, info->dst);
142
 
      break;
143
 
    case ARMCI_ACC_LNG:
144
 
      ACCUMULATE( long, &info->lval, info->bytes/sizeof(long), nbinfo->buffer, info->dst);
145
 
      break;
146
 
    default:
147
 
      assert (0);
148
 
      break;
149
 
  }
150
 
 
151
 
  free (nbinfo);
152
 
}
153
 
 
154
 
 
155
 
/**
156
 
 * \brief DCMF ARMCI Extention receive accumulate operation callback
157
 
 *
158
 
 * \see DCMF_RecvSend
159
 
 */
160
 
DCMF_Request_t * ARMCIX_DCMF_RecvAcc2 (void             * clientdata,
161
 
                                       const DCQuad     * msginfo,
162
 
                                       unsigned           count,
163
 
                                       unsigned           peer,
164
 
                                       unsigned           sndlen,
165
 
                                       unsigned         * rcvlen,
166
 
                                       char            ** rcvbuf,
167
 
                                       DCMF_Callback_t  * cb_done)
168
 
{
169
 
  ARMCIX_DCMF_Connection_t * connection = (ARMCIX_DCMF_Connection_t *) clientdata;
170
 
 
171
 
  ARMCIX_DCMF_AccNbInfo_t * nbinfo = (ARMCIX_DCMF_AccNbInfo_t *) malloc (sizeof(ARMCIX_DCMF_AccNbInfo_t) + sndlen);
172
 
 
173
 
  memcpy (&nbinfo->info, msginfo, sizeof(ARMCIX_DCMF_AccInfo_t));
174
 
  nbinfo->connection = &connection[peer];
175
 
  nbinfo->buffer = (void *)(((char *) nbinfo) + sizeof(ARMCIX_DCMF_AccNbInfo_t));
176
 
 
177
 
  *rcvlen = sndlen;
178
 
  *rcvbuf = nbinfo->buffer;
179
 
 
180
 
  cb_done->function   = (void *) ARMCIX_DCMF_AccReceiveComplete;
181
 
  cb_done->clientdata = (void *) nbinfo;
182
 
 
183
 
  return &connection[peer].request;
184
 
}
185
 
 
186
 
 
187
 
/**
188
 
 * \brief Register the DCMF ARMCI Extention accumulate operation.
189
 
 *
190
 
 * \param[in]  connection_array Connection array
191
 
 *
192
 
 * \see DCMF_Send_register
193
 
 */
194
 
void ARMCIX_DCMF_Acc_register (ARMCIX_DCMF_Connection_t * connection_array)
195
 
{
196
 
  DCMF_CriticalSection_enter (0);
197
 
 
198
 
  DCMF_Send_Configuration_t configuration = {
199
 
    DCMF_DEFAULT_SEND_PROTOCOL,
200
 
    ARMCIX_DCMF_RecvAcc1,
201
 
    connection_array,
202
 
    ARMCIX_DCMF_RecvAcc2,
203
 
    connection_array
204
 
  };
205
 
  DCMF_Send_register (&__acc_protocol, &configuration);
206
 
 
207
 
  DCMF_CriticalSection_exit (0);
208
 
}
209
 
 
210
 
/**
211
 
 * \brief ARMCI Extension blocking accumulate operation.
212
 
 *
213
 
 * \param[in] datatype  accumulate datatype (operation code)
214
 
 * \param[in] scale     opaque pointer to the scaling factor for accumulate
215
 
 * \param[in] src       Source buffer on the local node
216
 
 * \param[in] dst       Destination buffer on the remote node
217
 
 * \param[in] bytes     Number of bytes to transfer
218
 
 * \param[in] proc      Remote node rank
219
 
 *
220
 
 * \return ???
221
 
 */
222
 
int ARMCIX_Acc (int datatype, void * scale, void * src, void * dst, int bytes, int proc)
223
 
{
224
 
  DCMF_CriticalSection_enter (0);
225
 
 
226
 
  volatile unsigned active = 1;
227
 
  DCMF_Callback_t cb_wait = { ARMCIX_DCMF_cb_decrement, (void *)&active };
228
 
  DCMF_Request_t request;
229
 
 
230
 
  ARMCIX_DCMF_AccInfo_t info;
231
 
  info.dst = dst;
232
 
  info.bytes = bytes;
233
 
  info.datatype = datatype;
234
 
  switch (datatype)
235
 
  {
236
 
    case ARMCI_ACC_INT:
237
 
      info.ival = *((int *)scale);
238
 
      break;
239
 
    case ARMCI_ACC_DBL:
240
 
      info.dval = *((double *)scale);
241
 
      break;
242
 
    case ARMCI_ACC_FLT:
243
 
      info.fval = *((float *)scale);
244
 
      break;
245
 
    case ARMCI_ACC_CPL:
246
 
      info.cplxval.real = ((complex_t *)scale)->real;
247
 
      info.cplxval.imag = ((complex_t *)scale)->imag;
248
 
      break;
249
 
    case ARMCI_ACC_DCP:
250
 
      info.dcplxval.real = ((dcomplex_t *)scale)->real;
251
 
      info.dcplxval.imag = ((dcomplex_t *)scale)->imag;
252
 
      break;
253
 
    case ARMCI_ACC_LNG:
254
 
      info.lval = *((long *)scale);
255
 
      break;
256
 
    default:
257
 
      assert (0);
258
 
      break;
259
 
  }
260
 
 
261
 
  DCMF_Send ( &__acc_protocol,
262
 
              &request,
263
 
              cb_wait,
264
 
              DCMF_SEQUENTIAL_CONSISTENCY,
265
 
              proc,
266
 
              bytes,
267
 
              (char *) src,
268
 
              (DCQuad *) &info,
269
 
              2);
270
 
 
271
 
#ifdef BLOCKING_OPERATIONS_REQUIRE_FENCE
272
 
  ARMCIX_Fence (proc);
273
 
#else
274
 
  while (active) DCMF_Messager_advance ();
275
 
#endif
276
 
 
277
 
  DCMF_CriticalSection_exit  (0);
278
 
 
279
 
  return 0;
280
 
}
281
 
 
282
 
 
283
 
/**
284
 
 * \brief ARMCI Extension non-blocking accumulate operation.
285
 
 *
286
 
 * \param[in] datatype  accumulate datatype (operation code)
287
 
 * \param[in] scale     opaque pointer to the scaling factor for accumulate
288
 
 * \param[in] src       Source buffer on the local node
289
 
 * \param[in] dst       Destination buffer on the remote node
290
 
 * \param[in] bytes     Number of bytes to transfer
291
 
 * \param[in] proc      Remote node rank
292
 
 * \param[in] nb_handle ARMCI non-blocking handle
293
 
 *
294
 
 * \return ???
295
 
 */
296
 
int ARMCIX_NbAcc (int datatype, void * scale, void * src, void * dst, int bytes, int proc, armci_ihdl_t nb_handle)
297
 
{
298
 
  DCMF_CriticalSection_enter (0);
299
 
 
300
 
  armcix_dcmf_opaque_t * dcmf = (armcix_dcmf_opaque_t *) &nb_handle->cmpl_info;
301
 
  dcmf->active++;
302
 
  dcmf->connection = &__connection[proc];
303
 
 
304
 
  __connection[proc].active++;
305
 
  __global_connection.active++;
306
 
 
307
 
  DCMF_Callback_t cb_free = { ARMCIX_DCMF_NbOp_cb_done, nb_handle };
308
 
  ARMCIX_DCMF_Request_t * new_request = ARMCIX_DCMF_request_allocate (cb_free);
309
 
  DCMF_Callback_t cb_done = { (void(*)(void *)) ARMCIX_DCMF_request_free, new_request };
310
 
 
311
 
  ARMCIX_DCMF_AccInfo_t * info = (ARMCIX_DCMF_AccInfo_t *) &(new_request->quad[0]);
312
 
  info->dst = dst;
313
 
  info->bytes = bytes;
314
 
  info->datatype = datatype;
315
 
  switch (datatype)
316
 
  {
317
 
    case ARMCI_ACC_INT:
318
 
      info->ival = *((int *)scale);
319
 
      break;
320
 
    case ARMCI_ACC_DBL:
321
 
      info->dval = *((double *)scale);
322
 
      break;
323
 
    case ARMCI_ACC_FLT:
324
 
      info->fval = *((float *)scale);
325
 
      break;
326
 
    case ARMCI_ACC_CPL:
327
 
      info->cplxval.real = ((complex_t *)scale)->real;
328
 
      info->cplxval.imag = ((complex_t *)scale)->imag;
329
 
      break;
330
 
    case ARMCI_ACC_DCP:
331
 
      info->dcplxval.real = ((dcomplex_t *)scale)->real;
332
 
      info->dcplxval.imag = ((dcomplex_t *)scale)->imag;
333
 
      break;
334
 
    case ARMCI_ACC_LNG:
335
 
      info->lval = *((long *)scale);
336
 
      break;
337
 
    default:
338
 
      assert (0);
339
 
      break;
340
 
  }
341
 
 
342
 
  DCMF_Send ( &__acc_protocol,
343
 
              &(new_request->request),
344
 
              cb_done,
345
 
              DCMF_SEQUENTIAL_CONSISTENCY,
346
 
              proc,
347
 
              bytes,
348
 
              (char *) src,
349
 
              (DCQuad *) info,
350
 
              2);
351
 
 
352
 
  DCMF_CriticalSection_exit  (0);
353
 
 
354
 
  return 0;
355
 
}
356
 
 
357
 
 
358
 
/**
359
 
 * \brief ARMCI Extension blocking vector accumulate operation.
360
 
 *
361
 
 * \todo something goofy with AccV .. should be able to replace with combination of
362
 
 *       ARMCIX_AccV and ARMCIX_Wait, but that causes test-ibm.x to hang. Maybe
363
 
 *       related to interrupts?
364
 
 *
365
 
 * \param[in] datatype accumulate datatype (operation code)
366
 
 * \param[in] scale opaque pointer to the scaling factor for accumulate
367
 
 * \param[in] darr descriptor array
368
 
 * \param[in] len length of the descriptor array
369
 
 * \param[in] proc process(or) ID
370
 
 */
371
 
int ARMCIX_AccV (int datatype, void * scale, armci_giov_t * darr, int len, int proc)
372
 
{
373
 
#if 0
374
 
#error causes test-ibm.x to hang!
375
 
  armci_ireq_t nb_request;
376
 
  armci_ihdl_t nb_handle = (armci_ihdl_t) &nb_request;
377
 
  ARMCIX_NbAccV (datatype, scale, darr, len, proc, nb_handle);
378
 
#warning remove this ARMCIX_Fence() and implement some sort of ack scheme.
379
 
  ARMCIX_Fence (proc);
380
 
  ARMCIX_Wait (&nb_handle->cmpl_info);
381
 
#else
382
 
  DCMF_CriticalSection_enter (0);
383
 
 
384
 
  // Calculate the number of requests
385
 
  unsigned n = 0;
386
 
  unsigned i, j;
387
 
  for (i = 0; i < len; i++)
388
 
    for (j = 0; j < darr[i].ptr_array_len; j++)
389
 
      n++;
390
 
 
391
 
  volatile unsigned active = n;
392
 
  DCMF_Callback_t cb_wait = { ARMCIX_DCMF_cb_decrement, (void *)&active };
393
 
  DCMF_Request_t request[n];
394
 
 
395
 
  ARMCIX_DCMF_AccInfo_t info;
396
 
  info.datatype = datatype;
397
 
  switch (datatype)
398
 
  {
399
 
    case ARMCI_ACC_INT:
400
 
      info.ival = *((int *)scale);
401
 
      break;
402
 
    case ARMCI_ACC_DBL:
403
 
      info.dval = *((double *)scale);
404
 
      break;
405
 
    case ARMCI_ACC_FLT:
406
 
      info.fval = *((float *)scale);
407
 
      break;
408
 
    case ARMCI_ACC_CPL:
409
 
      info.cplxval.real = ((complex_t *)scale)->real;
410
 
      info.cplxval.imag = ((complex_t *)scale)->imag;
411
 
      break;
412
 
    case ARMCI_ACC_DCP:
413
 
      info.dcplxval.real = ((dcomplex_t *)scale)->real;
414
 
      info.dcplxval.imag = ((dcomplex_t *)scale)->imag;
415
 
      break;
416
 
    case ARMCI_ACC_LNG:
417
 
      info.lval = *((long *)scale);
418
 
      break;
419
 
    default:
420
 
      assert (0);
421
 
      break;
422
 
  }
423
 
 
424
 
  for (i = 0; i < len; i++)
425
 
  {
426
 
    info.bytes = darr[i].bytes;
427
 
    for (j = 0; j < darr[i].ptr_array_len; j++)
428
 
    {
429
 
      info.dst = darr[i].dst_ptr_array[j];
430
 
      DCMF_Send ( &__acc_protocol,
431
 
                  &request[--n],
432
 
                  cb_wait,
433
 
                  DCMF_SEQUENTIAL_CONSISTENCY,
434
 
                  proc,
435
 
                  info.bytes,
436
 
                  (char *) darr[i].src_ptr_array[j],
437
 
                  (DCQuad *) &info,
438
 
                  2);
439
 
    }
440
 
  }
441
 
 
442
 
#ifdef BLOCKING_OPERATIONS_REQUIRE_FENCE
443
 
  ARMCIX_Fence (proc);
444
 
#else
445
 
  // Poll until all accumulate messages have been sent.
446
 
  while (active) DCMF_Messager_advance ();
447
 
#endif
448
 
 
449
 
  DCMF_CriticalSection_exit  (0);
450
 
#endif
451
 
  return 0;
452
 
}
453
 
 
454
 
 
455
 
/**
456
 
 * \brief ARMCI Extension non-blocking vector accumulate operation.
457
 
 *
458
 
 * \param[in] datatype  accumulate datatype (operation code)
459
 
 * \param[in] scale     opaque pointer to the scaling factor for accumulate
460
 
 * \param[in] darr      Descriptor array
461
 
 * \param[in] len       Length of descriptor array
462
 
 * \param[in] proc      Remote process(or) ID
463
 
 * \param[in] nb_handle ARMCI non-blocking handle
464
 
 *
465
 
 * \return ???
466
 
 */
467
 
int ARMCIX_NbAccV (int datatype, void * scale, armci_giov_t * darr, int len, int proc, armci_ihdl_t nb_handle)
468
 
{
469
 
  DCMF_CriticalSection_enter (0);
470
 
 
471
 
  // Calculate the number of requests
472
 
  unsigned n = 0;
473
 
  unsigned i, j;
474
 
  for (i = 0; i < len; i++)
475
 
    for (j = 0; j < darr[i].ptr_array_len; j++)
476
 
      n++;
477
 
 
478
 
  armcix_dcmf_opaque_t * dcmf = (armcix_dcmf_opaque_t *) &nb_handle->cmpl_info;
479
 
  dcmf->connection = &__connection[proc];
480
 
  dcmf->active += n;
481
 
 
482
 
  __connection[proc].active += n;
483
 
  __global_connection.active += n;
484
 
#if 0
485
 
  ARMCIX_DCMF_AccInfo_t info;
486
 
  info.datatype = datatype;
487
 
  switch (datatype)
488
 
  {
489
 
    case ARMCI_ACC_INT:
490
 
      info.ival = *((int *)scale);
491
 
      break;
492
 
    case ARMCI_ACC_DBL:
493
 
      info.dval = *((double *)scale);
494
 
      break;
495
 
    case ARMCI_ACC_FLT:
496
 
      info.fval = *((float *)scale);
497
 
      break;
498
 
    case ARMCI_ACC_CPL:
499
 
      info.cplxval.real = ((complex_t *)scale)->real;
500
 
      info.cplxval.imag = ((complex_t *)scale)->imag;
501
 
      break;
502
 
    case ARMCI_ACC_DCP:
503
 
      info.dcplxval.real = ((dcomplex_t *)scale)->real;
504
 
      info.dcplxval.imag = ((dcomplex_t *)scale)->imag;
505
 
      break;
506
 
    case ARMCI_ACC_LNG:
507
 
      info.lval = *((long *)scale);
508
 
      break;
509
 
    default:
510
 
      assert (0);
511
 
      break;
512
 
  }
513
 
#endif
514
 
 
515
 
  for (i = 0; i < len; i++)
516
 
  {
517
 
    //info.bytes = darr[i].bytes;
518
 
    for (j = 0; j < darr[i].ptr_array_len; j++)
519
 
    {
520
 
      DCMF_Callback_t cb_free = { ARMCIX_DCMF_NbOp_cb_done, nb_handle };
521
 
      ARMCIX_DCMF_Request_t * new_request = ARMCIX_DCMF_request_allocate (cb_free);
522
 
      DCMF_Callback_t cb_done = { (void(*)(void *)) ARMCIX_DCMF_request_free, new_request };
523
 
 
524
 
      ARMCIX_DCMF_AccInfo_t * info = (ARMCIX_DCMF_AccInfo_t *) &(new_request->quad[0]);
525
 
      //info->dst = dst;
526
 
      //info->bytes = bytes;
527
 
      info->datatype = datatype;
528
 
      info->bytes = darr[i].bytes;
529
 
      switch (datatype)
530
 
      {
531
 
        case ARMCI_ACC_INT:
532
 
          info->ival = *((int *)scale);
533
 
          break;
534
 
        case ARMCI_ACC_DBL:
535
 
          info->dval = *((double *)scale);
536
 
          break;
537
 
        case ARMCI_ACC_FLT:
538
 
          info->fval = *((float *)scale);
539
 
          break;
540
 
        case ARMCI_ACC_CPL:
541
 
          info->cplxval.real = ((complex_t *)scale)->real;
542
 
          info->cplxval.imag = ((complex_t *)scale)->imag;
543
 
          break;
544
 
        case ARMCI_ACC_DCP:
545
 
          info->dcplxval.real = ((dcomplex_t *)scale)->real;
546
 
          info->dcplxval.imag = ((dcomplex_t *)scale)->imag;
547
 
          break;
548
 
        case ARMCI_ACC_LNG:
549
 
          info->lval = *((long *)scale);
550
 
          break;
551
 
        default:
552
 
          assert (0);
553
 
          break;
554
 
      }
555
 
 
556
 
      info->dst = darr[i].dst_ptr_array[j];
557
 
      DCMF_Send ( &__acc_protocol,
558
 
                  &(new_request->request),
559
 
                  cb_done,
560
 
                  DCMF_SEQUENTIAL_CONSISTENCY,
561
 
                  proc,
562
 
                  info->bytes,
563
 
                  (char *) darr[i].src_ptr_array[j],
564
 
                  (DCQuad *) info,
565
 
                  2);
566
 
    }
567
 
  }
568
 
 
569
 
  DCMF_CriticalSection_exit  (0);
570
 
 
571
 
  return 0;
572
 
}
573
 
 
574
 
 
575
 
 
576
 
 
577
 
unsigned ARMCIX_DCMF_AccS_recurse (int datatype, void * scale,
578
 
                                   void * src_ptr, int * src_stride_arr,
579
 
                                   void * dst_ptr, int * dst_stride_arr,
580
 
                                   int * seg_count, int stride_levels, int proc,
581
 
                                   armci_ihdl_t nb_handle)
582
 
{
583
 
  unsigned num_requests = 0;
584
 
 
585
 
  //fprintf (stderr, "ARMCIX_DCMF_AccS_recurse() >> \n");
586
 
 
587
 
  if (stride_levels == 0)
588
 
  {
589
 
    DCMF_Callback_t cb_free = { ARMCIX_DCMF_NbOp_cb_done, nb_handle };
590
 
    ARMCIX_DCMF_Request_t * new_request = ARMCIX_DCMF_request_allocate (cb_free);
591
 
    DCMF_Callback_t cb_done = { (void(*)(void *)) ARMCIX_DCMF_request_free, new_request };
592
 
 
593
 
    ARMCIX_DCMF_AccInfo_t * info = (ARMCIX_DCMF_AccInfo_t *) &(new_request->quad[0]);
594
 
    //info->dst = dst;
595
 
    //info->bytes = bytes;
596
 
    info->datatype = datatype;
597
 
    switch (datatype)
598
 
    {
599
 
      case ARMCI_ACC_INT:
600
 
        info->ival = *((int *)scale);
601
 
        break;
602
 
      case ARMCI_ACC_DBL:
603
 
        info->dval = *((double *)scale);
604
 
        break;
605
 
      case ARMCI_ACC_FLT:
606
 
        info->fval = *((float *)scale);
607
 
        break;
608
 
      case ARMCI_ACC_CPL:
609
 
        info->cplxval.real = ((complex_t *)scale)->real;
610
 
        info->cplxval.imag = ((complex_t *)scale)->imag;
611
 
        break;
612
 
      case ARMCI_ACC_DCP:
613
 
        info->dcplxval.real = ((dcomplex_t *)scale)->real;
614
 
        info->dcplxval.imag = ((dcomplex_t *)scale)->imag;
615
 
        break;
616
 
      case ARMCI_ACC_LNG:
617
 
        info->lval = *((long *)scale);
618
 
        break;
619
 
      default:
620
 
        assert (0);
621
 
        break;
622
 
      }
623
 
#if 0
624
 
    ARMCIX_DCMF_AccInfo_t info;
625
 
    info.datatype = datatype;
626
 
    switch (datatype)
627
 
    {
628
 
      case ARMCI_ACC_INT:
629
 
        info.ival = *((int *)scale);
630
 
        break;
631
 
      case ARMCI_ACC_DBL:
632
 
        info.dval = *((double *)scale);
633
 
        break;
634
 
      case ARMCI_ACC_FLT:
635
 
        info.fval = *((float *)scale);
636
 
        break;
637
 
      case ARMCI_ACC_CPL:
638
 
        info.cplxval.real = ((complex_t *)scale)->real;
639
 
        info.cplxval.imag = ((complex_t *)scale)->imag;
640
 
        break;
641
 
      case ARMCI_ACC_DCP:
642
 
        info.dcplxval.real = ((dcomplex_t *)scale)->real;
643
 
        info.dcplxval.imag = ((dcomplex_t *)scale)->imag;
644
 
        break;
645
 
      case ARMCI_ACC_LNG:
646
 
        info.lval = *((long *)scale);
647
 
        break;
648
 
      default:
649
 
        assert (0);
650
 
        break;
651
 
    }
652
 
 
653
 
    DCMF_Callback_t cb_free = { ARMCIX_DCMF_NbOp_cb_done, nb_handle };
654
 
    DCMF_Request_t * new_request = ARMCIX_DCMF_request_allocate (cb_free);
655
 
    DCMF_Callback_t cb_done = { (void(*)(void *)) ARMCIX_DCMF_request_free, new_request };
656
 
#endif
657
 
    info->bytes = seg_count[0];
658
 
    info->dst = dst_ptr;
659
 
 
660
 
    DCMF_Send ( &__acc_protocol,
661
 
                &(new_request->request),
662
 
                cb_done,
663
 
                DCMF_SEQUENTIAL_CONSISTENCY,
664
 
                proc,
665
 
                info->bytes,
666
 
                (char *) src_ptr,
667
 
                (DCQuad *) info,
668
 
                2);
669
 
 
670
 
    num_requests++;
671
 
  }
672
 
  else
673
 
  {
674
 
    char * src_tmp = (char *) src_ptr;
675
 
    char * dst_tmp = (char *) dst_ptr;
676
 
    unsigned i;
677
 
    for (i = 0; i < seg_count[stride_levels]; i++)
678
 
    {
679
 
      num_requests += ARMCIX_DCMF_AccS_recurse (datatype, scale,
680
 
                                                src_tmp, src_stride_arr,
681
 
                                                dst_tmp, dst_stride_arr,
682
 
                                                seg_count, (stride_levels-1), proc,
683
 
                                                nb_handle);
684
 
 
685
 
      src_tmp += src_stride_arr[(stride_levels-1)];
686
 
      dst_tmp += dst_stride_arr[(stride_levels-1)];
687
 
    }
688
 
  }
689
 
 
690
 
  //fprintf (stderr, "ARMCIX_DCMF_AccS_recurse() << num_requests = %d\n", num_requests);
691
 
 
692
 
  return num_requests;
693
 
}
694
 
 
695
 
 
696
 
/**
697
 
 * \brief ARMCI Extension blocking strided accumulate operation.
698
 
 *
699
 
 * \param[in] datatype       accumulate datatype (operation code)
700
 
 * \param[in] scale          opaque pointer to the scaling factor for accumulate
701
 
 * \param[in] src_ptr        pointer to 1st segment at source
702
 
 * \param[in] src_stride_arr array of strides at source
703
 
 * \param[in] dst_ptr        pointer to 1st segment at destination
704
 
 * \param[in] dst_stride_arr array of strides at destination
705
 
 * \param[in] seg_count      number of segments at each stride levels: count[0]=bytes
706
 
 * \param[in] stride_levels  number of stride levels
707
 
 * \param[in] proc           remote process(or) ID
708
 
 *
709
 
 * \return ???
710
 
 */
711
 
int ARMCIX_AccS (int datatype, void * scale,
712
 
                 void * src_ptr, int * src_stride_arr, 
713
 
                 void * dst_ptr, int * dst_stride_arr, 
714
 
                 int * seg_count, int stride_levels, int proc)
715
 
{
716
 
#if 0
717
 
#error causes test-ibm.x to hang!
718
 
  armci_ireq_t nb_request;
719
 
  armci_ihdl_t nb_handle = (armci_ihdl_t) &nb_request;
720
 
  ARMCIX_NbAccS (datatype, scale,
721
 
                 src_ptr, src_stride_arr,
722
 
                 dst_ptr, dst_stride_arr,
723
 
                 seg_count, stride_levels, proc,
724
 
                 nb_handle);
725
 
#warning remove this ARMCIX_Fence() and implement some sort of ack scheme.
726
 
  ARMCIX_Fence (proc);
727
 
  ARMCIX_Wait (&nb_handle->cmpl_info);
728
 
#else
729
 
  DCMF_CriticalSection_enter (0);
730
 
 
731
 
  //fprintf (stderr, "ARMCIX_AccS() >> \n");
732
 
  //fprintf (stderr, "ARMCIX_AccS() -- __connection[%d].sequence.origin=%d, __connection[%d].active=%d, __global_connection.active=%d\n", proc, __connection[proc].sequence.origin, proc, __connection[proc].active, __global_connection.active);
733
 
 
734
 
  // Calculate the number of requests
735
 
  unsigned i;
736
 
  unsigned n = 1;
737
 
  for (i = 0; i < stride_levels; i++) n = n * seg_count[i+1];
738
 
 
739
 
  armci_ireq_t nb_handle;
740
 
  armcix_dcmf_opaque_t * dcmf = (armcix_dcmf_opaque_t *) &nb_handle.cmpl_info;
741
 
  dcmf->connection = &__connection[proc];
742
 
  dcmf->active = n;
743
 
 
744
 
  __connection[proc].active += n;
745
 
  __global_connection.active += n;
746
 
 
747
 
  unsigned count;
748
 
  count = ARMCIX_DCMF_AccS_recurse (datatype, scale,
749
 
                                    src_ptr, src_stride_arr,
750
 
                                    dst_ptr, dst_stride_arr,
751
 
                                    seg_count, stride_levels, proc,
752
 
                                    (armci_ihdl_t) &nb_handle);
753
 
 
754
 
#ifdef BLOCKING_OPERATIONS_REQUIRE_FENCE
755
 
  ARMCIX_Fence (proc);
756
 
#else
757
 
  assert (n == count);
758
 
  while (dcmf->active) DCMF_Messager_advance ();
759
 
#endif
760
 
 
761
 
  //fprintf (stderr, "ARMCIX_AccS() << \n");
762
 
 
763
 
  DCMF_CriticalSection_exit  (0);
764
 
#endif
765
 
  return 0;
766
 
}
767
 
 
768
 
/**
769
 
 * \brief ARMCI Extension non-blocking strided accumulate operation.
770
 
 *
771
 
 * \param[in] datatype       accumulate datatype (operation code)
772
 
 * \param[in] scale          opaque pointer to the scaling factor for accumulate
773
 
 * \param[in] src_ptr        pointer to 1st segment at source
774
 
 * \param[in] src_stride_arr array of strides at source
775
 
 * \param[in] dst_ptr        pointer to 1st segment at destination
776
 
 * \param[in] dst_stride_arr array of strides at destination
777
 
 * \param[in] seg_count      number of segments at each stride levels: count[0]=bytes
778
 
 * \param[in] stride_levels  number of stride levels
779
 
 * \param[in] proc           remote process(or) ID
780
 
 * \param[in] nb_handle      ARMCI non-blocking handle
781
 
 *
782
 
 * \return ???
783
 
 */
784
 
int ARMCIX_NbAccS (int datatype, void * scale,
785
 
                   void * src_ptr, int * src_stride_arr, 
786
 
                   void * dst_ptr, int * dst_stride_arr, 
787
 
                   int * seg_count, int stride_levels, int proc,
788
 
                   armci_ihdl_t nb_handle)
789
 
{
790
 
  DCMF_CriticalSection_enter (0);
791
 
 
792
 
  // Calculate the number of requests
793
 
  unsigned i;
794
 
  unsigned n = 1;
795
 
  for (i = 0; i < stride_levels; i++) n = n * seg_count[i+1];
796
 
 
797
 
  armcix_dcmf_opaque_t * dcmf = (armcix_dcmf_opaque_t *) &nb_handle->cmpl_info;
798
 
  dcmf->connection = &__connection[proc];
799
 
  dcmf->active += n;
800
 
 
801
 
  __connection[proc].active += n;
802
 
  __global_connection.active += n;
803
 
 
804
 
  unsigned count;
805
 
  count = ARMCIX_DCMF_AccS_recurse (datatype, scale,
806
 
                                    src_ptr, src_stride_arr, 
807
 
                                    dst_ptr, dst_stride_arr, 
808
 
                                    seg_count, stride_levels, proc,
809
 
                                    nb_handle);
810
 
 
811
 
  assert (n == count);
812
 
 
813
 
  DCMF_CriticalSection_exit  (0);
814
 
 
815
 
  return 0;
816
 
}