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

« back to all changes in this revision

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