~ubuntu-branches/ubuntu/utopic/nwchem/utopic

« back to all changes in this revision

Viewing changes to src/tools/ga-5-1/armci/src/devices/dcmf/dcmf-0.2.0/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/armcix/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
 
    DCMF_DefaultNetwork,
201
 
    ARMCIX_DCMF_RecvAcc1,
202
 
    connection_array,
203
 
    ARMCIX_DCMF_RecvAcc2,
204
 
    connection_array
205
 
  };
206
 
  DCMF_Send_register (&__acc_protocol, &configuration);
207
 
 
208
 
  DCMF_CriticalSection_exit (0);
209
 
}
210
 
 
211
 
/**
212
 
 * \brief ARMCI Extension blocking accumulate operation.
213
 
 *
214
 
 * \param[in] datatype  accumulate datatype (operation code)
215
 
 * \param[in] scale     opaque pointer to the scaling factor for accumulate
216
 
 * \param[in] src       Source buffer on the local node
217
 
 * \param[in] dst       Destination buffer on the remote node
218
 
 * \param[in] bytes     Number of bytes to transfer
219
 
 * \param[in] proc      Remote node rank
220
 
 *
221
 
 * \return ???
222
 
 */
223
 
int ARMCIX_Acc (int datatype, void * scale, void * src, void * dst, int bytes, int proc)
224
 
{
225
 
  DCMF_CriticalSection_enter (0);
226
 
 
227
 
  volatile unsigned active = 1;
228
 
  DCMF_Callback_t cb_wait = { ARMCIX_DCMF_cb_decrement, (void *)&active };
229
 
  DCMF_Request_t request;
230
 
 
231
 
  ARMCIX_DCMF_AccInfo_t info;
232
 
  info.dst = dst;
233
 
  info.bytes = bytes;
234
 
  info.datatype = datatype;
235
 
  switch (datatype)
236
 
  {
237
 
    case ARMCI_ACC_INT:
238
 
      info.ival = *((int *)scale);
239
 
      break;
240
 
    case ARMCI_ACC_DBL:
241
 
      info.dval = *((double *)scale);
242
 
      break;
243
 
    case ARMCI_ACC_FLT:
244
 
      info.fval = *((float *)scale);
245
 
      break;
246
 
    case ARMCI_ACC_CPL:
247
 
      info.cplxval.real = ((complex_t *)scale)->real;
248
 
      info.cplxval.imag = ((complex_t *)scale)->imag;
249
 
      break;
250
 
    case ARMCI_ACC_DCP:
251
 
      info.dcplxval.real = ((dcomplex_t *)scale)->real;
252
 
      info.dcplxval.imag = ((dcomplex_t *)scale)->imag;
253
 
      break;
254
 
    case ARMCI_ACC_LNG:
255
 
      info.lval = *((long *)scale);
256
 
      break;
257
 
    default:
258
 
      assert (0);
259
 
      break;
260
 
  }
261
 
 
262
 
  DCMF_Send ( &__acc_protocol,
263
 
              &request,
264
 
              cb_wait,
265
 
              DCMF_SEQUENTIAL_CONSISTENCY,
266
 
              proc,
267
 
              bytes,
268
 
              (char *) src,
269
 
              (DCQuad *) &info,
270
 
              2);
271
 
 
272
 
#ifdef BLOCKING_OPERATIONS_REQUIRE_FENCE
273
 
  ARMCIX_Fence (proc);
274
 
#else
275
 
  while (active) DCMF_Messager_advance ();
276
 
#endif
277
 
 
278
 
  DCMF_CriticalSection_exit  (0);
279
 
 
280
 
  return 0;
281
 
}
282
 
 
283
 
 
284
 
/**
285
 
 * \brief ARMCI Extension non-blocking accumulate operation.
286
 
 *
287
 
 * \param[in] datatype  accumulate datatype (operation code)
288
 
 * \param[in] scale     opaque pointer to the scaling factor for accumulate
289
 
 * \param[in] src       Source buffer on the local node
290
 
 * \param[in] dst       Destination buffer on the remote node
291
 
 * \param[in] bytes     Number of bytes to transfer
292
 
 * \param[in] proc      Remote node rank
293
 
 * \param[in] nb_handle ARMCI non-blocking handle
294
 
 *
295
 
 * \return ???
296
 
 */
297
 
int ARMCIX_NbAcc (int datatype, void * scale, void * src, void * dst, int bytes, int proc, armci_ihdl_t nb_handle)
298
 
{
299
 
  DCMF_CriticalSection_enter (0);
300
 
 
301
 
  armcix_dcmf_opaque_t * dcmf = (armcix_dcmf_opaque_t *) &nb_handle->cmpl_info;
302
 
  dcmf->active++;
303
 
  dcmf->connection = &__connection[proc];
304
 
 
305
 
  __connection[proc].active++;
306
 
  __global_connection.active++;
307
 
 
308
 
  DCMF_Callback_t cb_free = { ARMCIX_DCMF_NbOp_cb_done, nb_handle };
309
 
  ARMCIX_DCMF_Request_t * new_request = ARMCIX_DCMF_request_allocate (cb_free);
310
 
  DCMF_Callback_t cb_done = { (void (*)(void *, DCMF_Error_t *))ARMCIX_DCMF_request_free, new_request };
311
 
 
312
 
  ARMCIX_DCMF_AccInfo_t * info = (ARMCIX_DCMF_AccInfo_t *) &(new_request->quad[0]);
313
 
  info->dst = dst;
314
 
  info->bytes = bytes;
315
 
  info->datatype = datatype;
316
 
  switch (datatype)
317
 
  {
318
 
    case ARMCI_ACC_INT:
319
 
      info->ival = *((int *)scale);
320
 
      break;
321
 
    case ARMCI_ACC_DBL:
322
 
      info->dval = *((double *)scale);
323
 
      break;
324
 
    case ARMCI_ACC_FLT:
325
 
      info->fval = *((float *)scale);
326
 
      break;
327
 
    case ARMCI_ACC_CPL:
328
 
      info->cplxval.real = ((complex_t *)scale)->real;
329
 
      info->cplxval.imag = ((complex_t *)scale)->imag;
330
 
      break;
331
 
    case ARMCI_ACC_DCP:
332
 
      info->dcplxval.real = ((dcomplex_t *)scale)->real;
333
 
      info->dcplxval.imag = ((dcomplex_t *)scale)->imag;
334
 
      break;
335
 
    case ARMCI_ACC_LNG:
336
 
      info->lval = *((long *)scale);
337
 
      break;
338
 
    default:
339
 
      assert (0);
340
 
      break;
341
 
  }
342
 
 
343
 
  DCMF_Send ( &__acc_protocol,
344
 
              &(new_request->request),
345
 
              cb_done,
346
 
              DCMF_SEQUENTIAL_CONSISTENCY,
347
 
              proc,
348
 
              bytes,
349
 
              (char *) src,
350
 
              (DCQuad *) info,
351
 
              2);
352
 
 
353
 
  DCMF_CriticalSection_exit  (0);
354
 
 
355
 
  return 0;
356
 
}
357
 
 
358
 
 
359
 
/**
360
 
 * \brief ARMCI Extension blocking vector accumulate operation.
361
 
 *
362
 
 * \todo something goofy with AccV .. should be able to replace with combination of
363
 
 *       ARMCIX_AccV and ARMCIX_Wait, but that causes test-ibm.x to hang. Maybe
364
 
 *       related to interrupts?
365
 
 *
366
 
 * \param[in] datatype accumulate datatype (operation code)
367
 
 * \param[in] scale opaque pointer to the scaling factor for accumulate
368
 
 * \param[in] darr descriptor array
369
 
 * \param[in] len length of the descriptor array
370
 
 * \param[in] proc process(or) ID
371
 
 */
372
 
int ARMCIX_AccV (int datatype, void * scale, armci_giov_t * darr, int len, int proc)
373
 
{
374
 
#if 0
375
 
#error causes test-ibm.x to hang!
376
 
  armci_ireq_t nb_request;
377
 
  armci_ihdl_t nb_handle = (armci_ihdl_t) &nb_request;
378
 
  ARMCIX_NbAccV (datatype, scale, darr, len, proc, nb_handle);
379
 
#warning remove this ARMCIX_Fence() and implement some sort of ack scheme.
380
 
  ARMCIX_Fence (proc);
381
 
  ARMCIX_Wait (&nb_handle->cmpl_info);
382
 
#else
383
 
  DCMF_CriticalSection_enter (0);
384
 
 
385
 
  // Calculate the number of requests
386
 
  unsigned n = 0;
387
 
  unsigned i, j;
388
 
  for (i = 0; i < len; i++)
389
 
    for (j = 0; j < darr[i].ptr_array_len; j++)
390
 
      n++;
391
 
 
392
 
  volatile unsigned active = n;
393
 
  DCMF_Callback_t cb_wait = { ARMCIX_DCMF_cb_decrement, (void *)&active };
394
 
  DCMF_Request_t request[n];
395
 
 
396
 
  ARMCIX_DCMF_AccInfo_t info;
397
 
  info.datatype = datatype;
398
 
  switch (datatype)
399
 
  {
400
 
    case ARMCI_ACC_INT:
401
 
      info.ival = *((int *)scale);
402
 
      break;
403
 
    case ARMCI_ACC_DBL:
404
 
      info.dval = *((double *)scale);
405
 
      break;
406
 
    case ARMCI_ACC_FLT:
407
 
      info.fval = *((float *)scale);
408
 
      break;
409
 
    case ARMCI_ACC_CPL:
410
 
      info.cplxval.real = ((complex_t *)scale)->real;
411
 
      info.cplxval.imag = ((complex_t *)scale)->imag;
412
 
      break;
413
 
    case ARMCI_ACC_DCP:
414
 
      info.dcplxval.real = ((dcomplex_t *)scale)->real;
415
 
      info.dcplxval.imag = ((dcomplex_t *)scale)->imag;
416
 
      break;
417
 
    case ARMCI_ACC_LNG:
418
 
      info.lval = *((long *)scale);
419
 
      break;
420
 
    default:
421
 
      assert (0);
422
 
      break;
423
 
  }
424
 
 
425
 
  for (i = 0; i < len; i++)
426
 
  {
427
 
    info.bytes = darr[i].bytes;
428
 
    for (j = 0; j < darr[i].ptr_array_len; j++)
429
 
    {
430
 
      info.dst = darr[i].dst_ptr_array[j];
431
 
      DCMF_Send ( &__acc_protocol,
432
 
                  &request[--n],
433
 
                  cb_wait,
434
 
                  DCMF_SEQUENTIAL_CONSISTENCY,
435
 
                  proc,
436
 
                  info.bytes,
437
 
                  (char *) darr[i].src_ptr_array[j],
438
 
                  (DCQuad *) &info,
439
 
                  2);
440
 
    }
441
 
  }
442
 
 
443
 
#ifdef BLOCKING_OPERATIONS_REQUIRE_FENCE
444
 
  ARMCIX_Fence (proc);
445
 
#else
446
 
  // Poll until all accumulate messages have been sent.
447
 
  while (active) DCMF_Messager_advance ();
448
 
#endif
449
 
 
450
 
  DCMF_CriticalSection_exit  (0);
451
 
#endif
452
 
  return 0;
453
 
}
454
 
 
455
 
 
456
 
/**
457
 
 * \brief ARMCI Extension non-blocking vector accumulate operation.
458
 
 *
459
 
 * \param[in] datatype  accumulate datatype (operation code)
460
 
 * \param[in] scale     opaque pointer to the scaling factor for accumulate
461
 
 * \param[in] darr      Descriptor array
462
 
 * \param[in] len       Length of descriptor array
463
 
 * \param[in] proc      Remote process(or) ID
464
 
 * \param[in] nb_handle ARMCI non-blocking handle
465
 
 *
466
 
 * \return ???
467
 
 */
468
 
int ARMCIX_NbAccV (int datatype, void * scale, armci_giov_t * darr, int len, int proc, armci_ihdl_t nb_handle)
469
 
{
470
 
  DCMF_CriticalSection_enter (0);
471
 
 
472
 
  // Calculate the number of requests
473
 
  unsigned n = 0;
474
 
  unsigned i, j;
475
 
  for (i = 0; i < len; i++)
476
 
    for (j = 0; j < darr[i].ptr_array_len; j++)
477
 
      n++;
478
 
 
479
 
  armcix_dcmf_opaque_t * dcmf = (armcix_dcmf_opaque_t *) &nb_handle->cmpl_info;
480
 
  dcmf->connection = &__connection[proc];
481
 
  dcmf->active += n;
482
 
 
483
 
  __connection[proc].active += n;
484
 
  __global_connection.active += n;
485
 
#if 0
486
 
  ARMCIX_DCMF_AccInfo_t info;
487
 
  info.datatype = datatype;
488
 
  switch (datatype)
489
 
  {
490
 
    case ARMCI_ACC_INT:
491
 
      info.ival = *((int *)scale);
492
 
      break;
493
 
    case ARMCI_ACC_DBL:
494
 
      info.dval = *((double *)scale);
495
 
      break;
496
 
    case ARMCI_ACC_FLT:
497
 
      info.fval = *((float *)scale);
498
 
      break;
499
 
    case ARMCI_ACC_CPL:
500
 
      info.cplxval.real = ((complex_t *)scale)->real;
501
 
      info.cplxval.imag = ((complex_t *)scale)->imag;
502
 
      break;
503
 
    case ARMCI_ACC_DCP:
504
 
      info.dcplxval.real = ((dcomplex_t *)scale)->real;
505
 
      info.dcplxval.imag = ((dcomplex_t *)scale)->imag;
506
 
      break;
507
 
    case ARMCI_ACC_LNG:
508
 
      info.lval = *((long *)scale);
509
 
      break;
510
 
    default:
511
 
      assert (0);
512
 
      break;
513
 
  }
514
 
#endif
515
 
 
516
 
  for (i = 0; i < len; i++)
517
 
  {
518
 
    //info.bytes = darr[i].bytes;
519
 
    for (j = 0; j < darr[i].ptr_array_len; j++)
520
 
    {
521
 
      DCMF_Callback_t cb_free = { ARMCIX_DCMF_NbOp_cb_done, nb_handle };
522
 
      ARMCIX_DCMF_Request_t * new_request = ARMCIX_DCMF_request_allocate (cb_free);
523
 
      DCMF_Callback_t cb_done = { (void (*)(void *, DCMF_Error_t *))ARMCIX_DCMF_request_free, new_request };
524
 
 
525
 
      ARMCIX_DCMF_AccInfo_t * info = (ARMCIX_DCMF_AccInfo_t *) &(new_request->quad[0]);
526
 
      //info->dst = dst;
527
 
      //info->bytes = bytes;
528
 
      info->datatype = datatype;
529
 
      info->bytes = darr[i].bytes;
530
 
      switch (datatype)
531
 
      {
532
 
        case ARMCI_ACC_INT:
533
 
          info->ival = *((int *)scale);
534
 
          break;
535
 
        case ARMCI_ACC_DBL:
536
 
          info->dval = *((double *)scale);
537
 
          break;
538
 
        case ARMCI_ACC_FLT:
539
 
          info->fval = *((float *)scale);
540
 
          break;
541
 
        case ARMCI_ACC_CPL:
542
 
          info->cplxval.real = ((complex_t *)scale)->real;
543
 
          info->cplxval.imag = ((complex_t *)scale)->imag;
544
 
          break;
545
 
        case ARMCI_ACC_DCP:
546
 
          info->dcplxval.real = ((dcomplex_t *)scale)->real;
547
 
          info->dcplxval.imag = ((dcomplex_t *)scale)->imag;
548
 
          break;
549
 
        case ARMCI_ACC_LNG:
550
 
          info->lval = *((long *)scale);
551
 
          break;
552
 
        default:
553
 
          assert (0);
554
 
          break;
555
 
      }
556
 
 
557
 
      info->dst = darr[i].dst_ptr_array[j];
558
 
      DCMF_Send ( &__acc_protocol,
559
 
                  &(new_request->request),
560
 
                  cb_done,
561
 
                  DCMF_SEQUENTIAL_CONSISTENCY,
562
 
                  proc,
563
 
                  info->bytes,
564
 
                  (char *) darr[i].src_ptr_array[j],
565
 
                  (DCQuad *) info,
566
 
                  2);
567
 
    }
568
 
  }
569
 
 
570
 
  DCMF_CriticalSection_exit  (0);
571
 
 
572
 
  return 0;
573
 
}
574
 
 
575
 
 
576
 
 
577
 
 
578
 
unsigned ARMCIX_DCMF_AccS_recurse (int datatype, void * scale,
579
 
                                   void * src_ptr, int * src_stride_arr,
580
 
                                   void * dst_ptr, int * dst_stride_arr,
581
 
                                   int * seg_count, int stride_levels, int proc,
582
 
                                   armci_ihdl_t nb_handle)
583
 
{
584
 
  unsigned num_requests = 0;
585
 
 
586
 
  //fprintf (stderr, "ARMCIX_DCMF_AccS_recurse() >> \n");
587
 
 
588
 
  if (stride_levels == 0)
589
 
  {
590
 
    DCMF_Callback_t cb_free = { ARMCIX_DCMF_NbOp_cb_done, nb_handle };
591
 
    ARMCIX_DCMF_Request_t * new_request = ARMCIX_DCMF_request_allocate (cb_free);
592
 
    DCMF_Callback_t cb_done = { (void (*)(void *, DCMF_Error_t *))ARMCIX_DCMF_request_free, new_request };
593
 
 
594
 
    ARMCIX_DCMF_AccInfo_t * info = (ARMCIX_DCMF_AccInfo_t *) &(new_request->quad[0]);
595
 
    //info->dst = dst;
596
 
    //info->bytes = bytes;
597
 
    info->datatype = datatype;
598
 
    switch (datatype)
599
 
    {
600
 
      case ARMCI_ACC_INT:
601
 
        info->ival = *((int *)scale);
602
 
        break;
603
 
      case ARMCI_ACC_DBL:
604
 
        info->dval = *((double *)scale);
605
 
        break;
606
 
      case ARMCI_ACC_FLT:
607
 
        info->fval = *((float *)scale);
608
 
        break;
609
 
      case ARMCI_ACC_CPL:
610
 
        info->cplxval.real = ((complex_t *)scale)->real;
611
 
        info->cplxval.imag = ((complex_t *)scale)->imag;
612
 
        break;
613
 
      case ARMCI_ACC_DCP:
614
 
        info->dcplxval.real = ((dcomplex_t *)scale)->real;
615
 
        info->dcplxval.imag = ((dcomplex_t *)scale)->imag;
616
 
        break;
617
 
      case ARMCI_ACC_LNG:
618
 
        info->lval = *((long *)scale);
619
 
        break;
620
 
      default:
621
 
        assert (0);
622
 
        break;
623
 
      }
624
 
#if 0
625
 
    ARMCIX_DCMF_AccInfo_t info;
626
 
    info.datatype = datatype;
627
 
    switch (datatype)
628
 
    {
629
 
      case ARMCI_ACC_INT:
630
 
        info.ival = *((int *)scale);
631
 
        break;
632
 
      case ARMCI_ACC_DBL:
633
 
        info.dval = *((double *)scale);
634
 
        break;
635
 
      case ARMCI_ACC_FLT:
636
 
        info.fval = *((float *)scale);
637
 
        break;
638
 
      case ARMCI_ACC_CPL:
639
 
        info.cplxval.real = ((complex_t *)scale)->real;
640
 
        info.cplxval.imag = ((complex_t *)scale)->imag;
641
 
        break;
642
 
      case ARMCI_ACC_DCP:
643
 
        info.dcplxval.real = ((dcomplex_t *)scale)->real;
644
 
        info.dcplxval.imag = ((dcomplex_t *)scale)->imag;
645
 
        break;
646
 
      case ARMCI_ACC_LNG:
647
 
        info.lval = *((long *)scale);
648
 
        break;
649
 
      default:
650
 
        assert (0);
651
 
        break;
652
 
    }
653
 
 
654
 
    DCMF_Callback_t cb_free = { ARMCIX_DCMF_NbOp_cb_done, nb_handle };
655
 
    DCMF_Request_t * new_request = ARMCIX_DCMF_request_allocate (cb_free);
656
 
    DCMF_Callback_t cb_done = { (void(*)(void *)) ARMCIX_DCMF_request_free, new_request };
657
 
#endif
658
 
    info->bytes = seg_count[0];
659
 
    info->dst = dst_ptr;
660
 
 
661
 
    DCMF_Send ( &__acc_protocol,
662
 
                &(new_request->request),
663
 
                cb_done,
664
 
                DCMF_SEQUENTIAL_CONSISTENCY,
665
 
                proc,
666
 
                info->bytes,
667
 
                (char *) src_ptr,
668
 
                (DCQuad *) info,
669
 
                2);
670
 
 
671
 
    num_requests++;
672
 
  }
673
 
  else
674
 
  {
675
 
    char * src_tmp = (char *) src_ptr;
676
 
    char * dst_tmp = (char *) dst_ptr;
677
 
    unsigned i;
678
 
    for (i = 0; i < seg_count[stride_levels]; i++)
679
 
    {
680
 
      num_requests += ARMCIX_DCMF_AccS_recurse (datatype, scale,
681
 
                                                src_tmp, src_stride_arr,
682
 
                                                dst_tmp, dst_stride_arr,
683
 
                                                seg_count, (stride_levels-1), proc,
684
 
                                                nb_handle);
685
 
 
686
 
      src_tmp += src_stride_arr[(stride_levels-1)];
687
 
      dst_tmp += dst_stride_arr[(stride_levels-1)];
688
 
    }
689
 
  }
690
 
 
691
 
  //fprintf (stderr, "ARMCIX_DCMF_AccS_recurse() << num_requests = %d\n", num_requests);
692
 
 
693
 
  return num_requests;
694
 
}
695
 
 
696
 
 
697
 
/**
698
 
 * \brief ARMCI Extension blocking strided accumulate operation.
699
 
 *
700
 
 * \param[in] datatype       accumulate datatype (operation code)
701
 
 * \param[in] scale          opaque pointer to the scaling factor for accumulate
702
 
 * \param[in] src_ptr        pointer to 1st segment at source
703
 
 * \param[in] src_stride_arr array of strides at source
704
 
 * \param[in] dst_ptr        pointer to 1st segment at destination
705
 
 * \param[in] dst_stride_arr array of strides at destination
706
 
 * \param[in] seg_count      number of segments at each stride levels: count[0]=bytes
707
 
 * \param[in] stride_levels  number of stride levels
708
 
 * \param[in] proc           remote process(or) ID
709
 
 *
710
 
 * \return ???
711
 
 */
712
 
int ARMCIX_AccS (int datatype, void * scale,
713
 
                 void * src_ptr, int * src_stride_arr, 
714
 
                 void * dst_ptr, int * dst_stride_arr, 
715
 
                 int * seg_count, int stride_levels, int proc)
716
 
{
717
 
#if 0
718
 
#error causes test-ibm.x to hang!
719
 
  armci_ireq_t nb_request;
720
 
  armci_ihdl_t nb_handle = (armci_ihdl_t) &nb_request;
721
 
  ARMCIX_NbAccS (datatype, scale,
722
 
                 src_ptr, src_stride_arr,
723
 
                 dst_ptr, dst_stride_arr,
724
 
                 seg_count, stride_levels, proc,
725
 
                 nb_handle);
726
 
#warning remove this ARMCIX_Fence() and implement some sort of ack scheme.
727
 
  ARMCIX_Fence (proc);
728
 
  ARMCIX_Wait (&nb_handle->cmpl_info);
729
 
#else
730
 
  DCMF_CriticalSection_enter (0);
731
 
 
732
 
  //fprintf (stderr, "ARMCIX_AccS() >> \n");
733
 
  //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);
734
 
 
735
 
  // Calculate the number of requests
736
 
  unsigned i;
737
 
  unsigned n = 1;
738
 
  for (i = 0; i < stride_levels; i++) n = n * seg_count[i+1];
739
 
 
740
 
  armci_ireq_t nb_handle;
741
 
  armcix_dcmf_opaque_t * dcmf = (armcix_dcmf_opaque_t *) &nb_handle.cmpl_info;
742
 
  dcmf->connection = &__connection[proc];
743
 
  dcmf->active = n;
744
 
 
745
 
  __connection[proc].active += n;
746
 
  __global_connection.active += n;
747
 
 
748
 
  unsigned count;
749
 
  count = ARMCIX_DCMF_AccS_recurse (datatype, scale,
750
 
                                    src_ptr, src_stride_arr,
751
 
                                    dst_ptr, dst_stride_arr,
752
 
                                    seg_count, stride_levels, proc,
753
 
                                    (armci_ihdl_t) &nb_handle);
754
 
 
755
 
#ifdef BLOCKING_OPERATIONS_REQUIRE_FENCE
756
 
  ARMCIX_Fence (proc);
757
 
#else
758
 
  assert (n == count);
759
 
  while (dcmf->active) DCMF_Messager_advance ();
760
 
#endif
761
 
 
762
 
  //fprintf (stderr, "ARMCIX_AccS() << \n");
763
 
 
764
 
  DCMF_CriticalSection_exit  (0);
765
 
#endif
766
 
  return 0;
767
 
}
768
 
 
769
 
/**
770
 
 * \brief ARMCI Extension non-blocking strided accumulate operation.
771
 
 *
772
 
 * \param[in] datatype       accumulate datatype (operation code)
773
 
 * \param[in] scale          opaque pointer to the scaling factor for accumulate
774
 
 * \param[in] src_ptr        pointer to 1st segment at source
775
 
 * \param[in] src_stride_arr array of strides at source
776
 
 * \param[in] dst_ptr        pointer to 1st segment at destination
777
 
 * \param[in] dst_stride_arr array of strides at destination
778
 
 * \param[in] seg_count      number of segments at each stride levels: count[0]=bytes
779
 
 * \param[in] stride_levels  number of stride levels
780
 
 * \param[in] proc           remote process(or) ID
781
 
 * \param[in] nb_handle      ARMCI non-blocking handle
782
 
 *
783
 
 * \return ???
784
 
 */
785
 
int ARMCIX_NbAccS (int datatype, void * scale,
786
 
                   void * src_ptr, int * src_stride_arr, 
787
 
                   void * dst_ptr, int * dst_stride_arr, 
788
 
                   int * seg_count, int stride_levels, int proc,
789
 
                   armci_ihdl_t nb_handle)
790
 
{
791
 
  DCMF_CriticalSection_enter (0);
792
 
 
793
 
  // Calculate the number of requests
794
 
  unsigned i;
795
 
  unsigned n = 1;
796
 
  for (i = 0; i < stride_levels; i++) n = n * seg_count[i+1];
797
 
 
798
 
  armcix_dcmf_opaque_t * dcmf = (armcix_dcmf_opaque_t *) &nb_handle->cmpl_info;
799
 
  dcmf->connection = &__connection[proc];
800
 
  dcmf->active += n;
801
 
 
802
 
  __connection[proc].active += n;
803
 
  __global_connection.active += n;
804
 
 
805
 
  unsigned count;
806
 
  count = ARMCIX_DCMF_AccS_recurse (datatype, scale,
807
 
                                    src_ptr, src_stride_arr, 
808
 
                                    dst_ptr, dst_stride_arr, 
809
 
                                    seg_count, stride_levels, proc,
810
 
                                    nb_handle);
811
 
 
812
 
  assert (n == count);
813
 
 
814
 
  DCMF_CriticalSection_exit  (0);
815
 
 
816
 
  return 0;
817
 
}