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

« back to all changes in this revision

Viewing changes to src/tools/ga-5-2/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
}