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

« back to all changes in this revision

Viewing changes to src/tools/ga-5-1/armci/src/xfer/rmw.c

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

[ Daniel Leidert ]
* debian/watch: Fixed.

[ Andreas Tille ]
* debian/upstream: References

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#if HAVE_CONFIG_H
2
 
#   include "config.h"
3
 
#endif
4
 
 
5
 
#include "armcip.h"
6
 
#include "locks.h"
7
 
#include "copy.h"
8
 
#if HAVE_STDIO_H
9
 
#   include <stdio.h>
10
 
#endif
11
 
#if (defined(__i386__) || defined(__x86_64__)) && !defined(NO_I386ASM)
12
 
#  include "atomics-i386.h"
13
 
#endif
14
 
 
15
 
 
16
 
/* enable use of newer interfaces in SHMEM */
17
 
#ifndef CRAY
18
 
#ifndef LIBELAN_ATOMICS
19
 
/* manpages for shmem_fadd exist on the T3E but library code does not */
20
 
#define SHMEM_FADD 
21
 
#endif
22
 
#endif
23
 
 
24
 
 
25
 
/* global scope to prevent compiler optimization of volatile code */
26
 
int  _a_temp;
27
 
long _a_ltemp;
28
 
 
29
 
/* JAD -- DCMF implements its own rmw
30
 
   there were linking errors with missing atomic_fetch_and_add for DCMF */
31
 
#if !ARMCIX
32
 
void armci_generic_rmw(int op, void *ploc, void *prem, int extra, int proc)
33
 
{
34
 
#if defined(CLUSTER) && !defined(SGIALTIX)
35
 
    int lock = (proc-armci_clus_info[armci_clus_id(proc)].master)%NUM_LOCKS;
36
 
#else
37
 
    int lock = 0;
38
 
#endif
39
 
 
40
 
    NATIVE_LOCK(lock,proc);
41
 
 
42
 
    switch (op) {
43
 
      case ARMCI_FETCH_AND_ADD:
44
 
#if (defined(__GNUC__) || defined(__INTEL_COMPILER__) ||defined(__PGIC__)) && (defined(__i386__) || defined(__x86_64__)) && !defined(PORTALS) && !defined(NO_I386ASM)
45
 
        if(SERVER_CONTEXT || armci_nclus == 1){
46
 
/*        *(int*)ploc = __sync_fetch_and_add((int*)prem, extra); */
47
 
          atomic_fetch_and_add(prem, ploc, extra, sizeof(int));
48
 
        }
49
 
        else 
50
 
#endif
51
 
          {
52
 
                armci_get(prem,ploc,sizeof(int),proc);
53
 
                _a_temp = *(int*)ploc + extra;
54
 
                armci_put(&_a_temp,prem,sizeof(int),proc);
55
 
          }
56
 
           break;
57
 
      case ARMCI_FETCH_AND_ADD_LONG:
58
 
                armci_get(prem,ploc,sizeof(long),proc);
59
 
                _a_ltemp = *(long*)ploc + extra;
60
 
                armci_put(&_a_ltemp,prem,sizeof(long),proc);
61
 
           break;
62
 
      case ARMCI_SWAP:
63
 
#if (defined(__i386__) || defined(__x86_64__)) && !defined(PORTALS) && !defined(NO_I386ASM)
64
 
        if(SERVER_CONTEXT || armci_nclus==1){
65
 
          atomic_exchange(ploc, prem, sizeof(int));
66
 
        }
67
 
        else 
68
 
#endif
69
 
        {
70
 
          armci_get(prem,&_a_temp,sizeof(int),proc);
71
 
          armci_put(ploc,prem,sizeof(int),proc);
72
 
          *(int*)ploc = _a_temp; 
73
 
        }
74
 
        break;
75
 
      case ARMCI_SWAP_LONG:
76
 
                armci_get(prem,&_a_ltemp,sizeof(long),proc);
77
 
                armci_put(ploc,prem,sizeof(long),proc);
78
 
                *(long*)ploc = _a_ltemp;
79
 
           break;
80
 
      default: armci_die("rmw: operation not supported",op);
81
 
    }
82
 
#ifdef VAPI
83
 
    if(!SERVER_CONTEXT)
84
 
#endif
85
 
      PARMCI_Fence(proc); 
86
 
    NATIVE_UNLOCK(lock,proc);
87
 
}
88
 
#endif /* ARMCIX */
89
 
 
90
 
 
91
 
int PARMCI_Rmw(int op, void *ploc, void *prem, int extra, int proc)
92
 
{
93
 
#ifdef LAPI64
94
 
    extern int LAPI_Rmw64(lapi_handle_t hndl, RMW_ops_t op, uint tgt, 
95
 
             long long *tgt_var,
96
 
             long long *in_val, long long *prev_tgt_val, lapi_cntr_t *org_cntr);
97
 
    long long llval, *pllarg = (long long*)ploc, lltmp;
98
 
/* enable RMWBROKEN if RMW fails for long datatype */
99
 
#define RMWBROKEN_ 
100
 
#endif
101
 
 
102
 
#ifdef LAPI
103
 
    int  ival, rc, opcode=SWAP, *parg=ploc;
104
 
    lapi_cntr_t req_id;
105
 
#elif defined(_CRAYMPP) || defined(QUADRICS) || defined(CRAY_SHMEM)
106
 
    int  ival;
107
 
    long lval;
108
 
#endif
109
 
 
110
 
#if defined(LAPI64) && defined(RMWBROKEN)
111
 
/* hack for rmw64 BROKEN: we operate on least significant part of long */
112
 
if(op==ARMCI_FETCH_AND_ADD_LONG || op==ARMCI_SWAP_LONG){
113
 
  ploc[0]=0;
114
 
  ploc[1]=0;
115
 
  ploc++;
116
 
  parg ++; prem++;
117
 
}
118
 
#endif
119
 
 
120
 
#if defined(CLUSTER) && !defined(LAPI) && !defined(QUADRICS) &&!defined(CYGWIN)\
121
 
    && !defined(HITACHI) && !defined(CRAY_SHMEM) && !defined(PORTALS)
122
 
     if(!SAMECLUSNODE(proc)){
123
 
       armci_rem_rmw(op, ploc, prem,  extra, proc);
124
 
       return 0;
125
 
     }
126
 
#endif
127
 
 
128
 
#ifdef REGION_ALLOC
129
 
     if(SAMECLUSNODE(proc)) (void)armci_region_fixup(proc,&prem);
130
 
#endif
131
 
#ifdef BGML     
132
 
   BGML_Op oper;
133
 
   BGML_Dt dt;  
134
 
   void *temp;
135
 
   long ltemp;
136
 
   switch(op)   
137
 
   {            
138
 
                
139
 
      case ARMCI_FETCH_AND_ADD:
140
 
      case ARMCI_FETCH_AND_ADD_LONG:
141
 
         dt=BGML_SIGNED_INT;
142
 
         temp=(int *)&extra;
143
 
         oper=BGML_SUM;
144
 
         break;
145
 
#if 0 
146
 
      case ARMCI_FETCH_AND_ADD_LONG:
147
 
         fprintf(stderr,"adding int to longs....\n");
148
 
         dt=BGML_SIGNED_LONG;
149
 
         ltemp=(long)extra;
150
 
         temp=&ltemp;
151
 
         oper=BGML_SUM;
152
 
         break;
153
 
#endif
154
 
      case ARMCI_SWAP:
155
 
      case ARMCI_SWAP_LONG:
156
 
         dt=BGML_SIGNED_INT;
157
 
         oper=BGML_NOOP;
158
 
         temp=(int *)ploc;
159
 
         break;
160
 
#if 0
161
 
      case ARMCI_SWAP_LONG:
162
 
         fprintf(stderr,"long armci_swap\n");
163
 
         dt=BGML_SIGNED_LONG;
164
 
         oper=BGML_NOOP;
165
 
         temp=(long *)ploc;
166
 
         break;
167
 
#endif
168
 
      default:
169
 
         ARMCI_Error("Invalid operation for RMW", op);
170
 
   }
171
 
    
172
 
   /* int PARMCI_Rmw(int op, int *ploc, int *prem, int extra, int proc) */
173
 
   /* assumes ploc will change
174
 
      dstbuf=prem, input=temp(extra), output=ploc
175
 
      val=ploc, arr[0]=prem, 1=extra */
176
 
 
177
 
    int me=armci_msg_me();
178
 
    BG1S_t request; 
179
 
    unsigned done=1;
180
 
    BGML_Callback_t cb_wait={wait_callback, &done};
181
 
    BG1S_rmw(&request, proc, 0, prem, temp, ploc, oper, dt, &cb_wait, 1);
182
 
    BGML_Wait(&done);
183
 
#elif ARMCIX
184
 
    ARMCIX_Rmw(op, ploc, prem, extra, proc);
185
 
#else
186
 
    switch (op) {
187
 
#   if defined(QUADRICS) || defined(_CRAYMPP) || defined(CRAY_SHMEM)
188
 
      case ARMCI_FETCH_AND_ADD:
189
 
#ifdef SHMEM_FADD
190
 
         /* printf(" calling intfdd arg %x %ld \n", prem, *prem); */
191
 
          *(int*) ploc = shmem_int_fadd(prem, extra, proc);
192
 
#elif defined(LIBELAN_ATOMICS)
193
 
          *(int*) ploc = elan_int_fadd(prem, extra, proc);
194
 
#else
195
 
          while ( (ival = shmem_int_swap(prem, INT_MAX, proc) ) == INT_MAX);
196
 
          (void) shmem_int_swap(prem, ival +extra, proc);
197
 
          *(int*) ploc = ival;
198
 
#endif
199
 
        break;
200
 
      case ARMCI_FETCH_AND_ADD_LONG:
201
 
#ifdef SHMEM_FADD
202
 
          *(long*) ploc = shmem_long_fadd( (long*)prem, (long) extra, proc);
203
 
#elif defined(LIBELAN_ATOMICS)
204
 
          *(long*) ploc = elan_long_fadd( (long*)prem, (long) extra, proc);
205
 
#else
206
 
          while ((lval=shmem_long_swap((long*)prem,LONG_MAX,proc)) == LONG_MAX);
207
 
          (void) shmem_long_swap((long*)prem, (lval + extra), proc);
208
 
          *(long*)ploc   = lval;
209
 
#endif
210
 
        break;
211
 
      case ARMCI_SWAP:
212
 
#ifdef LIBELAN_ATOMICS
213
 
          *(int*)ploc = elan_int_swap((int*)prem, *(int*)ploc,  proc); 
214
 
#else
215
 
          *(int*)ploc = shmem_int_swap((int*)prem, *(int*)ploc,  proc); 
216
 
#endif
217
 
        break;
218
 
      case ARMCI_SWAP_LONG:
219
 
#ifdef LIBELAN_ATOMICS
220
 
          *(long*)ploc = elan_long_swap((long*)prem, *(long*)ploc,  proc); 
221
 
#else
222
 
          *(long*)ploc = shmem_long_swap((long*)prem, *(long*)ploc,  proc); 
223
 
#endif
224
 
        break;
225
 
#   elif defined(LAPI)
226
 
#     if defined(LAPI64) && !defined(RMWBROKEN)
227
 
        case ARMCI_FETCH_AND_ADD_LONG:
228
 
           opcode = FETCH_AND_ADD;
229
 
           lltmp  = (long long)extra;
230
 
           pllarg = &lltmp;
231
 
        case ARMCI_SWAP_LONG:
232
 
#if 0
233
 
          printf("before opcode=%d rem=%ld, loc=(%ld,%ld) extra=%ld\n",
234
 
                  opcode,*prem,*(long*)ploc,llval, lltmp);  
235
 
          rc= sizeof(long);
236
 
          PARMCI_Get(prem, &llval, rc, proc);
237
 
          printf("%d:rem val before %ld\n",armci_me, llval); fflush(stdout);
238
 
#endif
239
 
          if( rc = LAPI_Setcntr(lapi_handle,&req_id,0))
240
 
                        armci_die("rmw setcntr failed",rc);
241
 
          if( rc = LAPI_Rmw64(lapi_handle, opcode, proc, (long long*)prem,
242
 
                        pllarg, &llval, &req_id)) armci_die("rmw failed",rc);
243
 
          if( rc = LAPI_Waitcntr(lapi_handle, &req_id, 1, NULL))
244
 
                        armci_die("rmw wait failed",rc);
245
 
 
246
 
          *(long*)ploc  = (long)llval;
247
 
#if 0
248
 
          rc= sizeof(long);
249
 
          PARMCI_Get(prem, &lltmp, rc, proc);
250
 
          printf("%d:after rmw remote val from rmw=%ld and get=%ld extra=%d\n",
251
 
                  armci_me,llval, lltmp,extra);  
252
 
#endif
253
 
        break;
254
 
#     endif
255
 
      /************** here sizeof(long)= sizeof(int) **************/
256
 
      case ARMCI_FETCH_AND_ADD:
257
 
#     if !defined(LAPI64) || defined(RMWBROKEN)
258
 
        case ARMCI_FETCH_AND_ADD_LONG:
259
 
#     endif
260
 
           opcode = FETCH_AND_ADD;
261
 
           parg = &extra;
262
 
      case ARMCI_SWAP:
263
 
#     if !defined(LAPI64) || defined(RMWBROKEN)
264
 
        case ARMCI_SWAP_LONG:
265
 
#     endif
266
 
          /* Within SMPs LAPI_Rmw needs target's address. */
267
 
          if(SAMECLUSNODE(proc)) proc=armci_me;
268
 
           
269
 
          if( rc = LAPI_Setcntr(lapi_handle,&req_id,0))
270
 
                        armci_die("rmw setcntr failed",rc);
271
 
          if( rc = LAPI_Rmw(lapi_handle, opcode, proc, prem,
272
 
                        parg, &ival, &req_id)) armci_die("rmw failed",rc);
273
 
          if( rc = LAPI_Waitcntr(lapi_handle, &req_id, 1, NULL))
274
 
                        armci_die("rmw wait failed",rc);
275
 
          * (int *)ploc  = ival;
276
 
        break;
277
 
#   else
278
 
      case ARMCI_FETCH_AND_ADD:
279
 
      case ARMCI_FETCH_AND_ADD_LONG:
280
 
      case ARMCI_SWAP:
281
 
      case ARMCI_SWAP_LONG:
282
 
           armci_generic_rmw(op, ploc, prem,  extra, proc);
283
 
        break;
284
 
#   endif
285
 
      default: armci_die("rmw: operation not supported",op);
286
 
    }
287
 
#endif /*bgml*/
288
 
 
289
 
    return 0;
290
 
}
291