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

« back to all changes in this revision

Viewing changes to src/tools/ga-5-1/global/src/base.h

  • 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
 
/*$Id: base.h,v 1.40.2.4 2007/12/18 18:41:27 d3g293 Exp $ */
2
 
#include "armci.h"
3
 
#include "gaconfig.h"
4
 
#include "typesf2c.h"
5
 
 
6
 
extern int _max_global_array;
7
 
extern Integer *_ga_map;
8
 
extern Integer GAme, GAnproc;
9
 
extern Integer *GA_proclist;
10
 
extern int GA_Default_Proc_Group;
11
 
extern int* GA_Proc_list;
12
 
extern int* GA_inv_Proc_list;
13
 
extern int** GA_Update_Flags;
14
 
extern int* GA_Update_Signal;
15
 
extern short int _ga_irreg_flag; 
16
 
extern Integer GA_Debug_flag;
17
 
extern int *ProcListPerm;            /*permuted list of processes */
18
 
 
19
 
#define FNAM        31              /* length of array names   */
20
 
#define CACHE_SIZE  512             /* size of the cache inside GA DS*/
21
 
 
22
 
#ifdef __crayx1
23
 
#define __CRAYX1_PRAGMA _Pragma
24
 
#else
25
 
#define __CRAYX1_PRAGMA(_pragf)
26
 
#endif
27
 
 
28
 
 
29
 
typedef int ARMCI_Datatype;
30
 
typedef struct {
31
 
       int mirrored;
32
 
       int map_nproc;
33
 
       int actv;
34
 
       int parent;
35
 
       int *map_proc_list;
36
 
       int *inv_map_proc_list;
37
 
#ifdef MPI
38
 
       ARMCI_Group group;
39
 
#endif
40
 
} proc_list_t;
41
 
 
42
 
typedef Integer C_Integer;
43
 
typedef armci_size_t C_Long;
44
 
 
45
 
typedef struct {
46
 
       short int  ndim;             /* number of dimensions                 */
47
 
       short int  irreg;            /* 0-regular; 1-irregular distribution  */
48
 
       int  type;                   /* data type in array                   */
49
 
       int  actv;                   /* activity status, GA is allocated     */
50
 
       int  actv_handle;            /* handle is created                    */
51
 
       C_Long   size;               /* size of local data in bytes          */
52
 
       int  elemsize;               /* sizeof(datatype)                     */
53
 
       int  ghosts;                 /* flag indicating presence of ghosts   */
54
 
       long lock;                   /* lock                                 */
55
 
       long id;                     /* ID of shmem region / MA handle       */
56
 
       C_Integer  dims[MAXDIM];     /* global array dimensions              */
57
 
       C_Integer  chunk[MAXDIM];    /* chunking                             */
58
 
       int  nblock[MAXDIM];         /* number of blocks per dimension       */
59
 
       C_Integer  width[MAXDIM];    /* boundary cells per dimension         */
60
 
       C_Integer  first[MAXDIM];    /* (Mirrored only) first local element  */
61
 
       C_Integer  last[MAXDIM];     /* (Mirrored only) last local element   */
62
 
       C_Long  shm_length;          /* (Mirrored only) local shmem length   */
63
 
       C_Integer  lo[MAXDIM];       /* top/left corner in local patch       */
64
 
       double scale[MAXDIM];        /* nblock/dim (precomputed)             */
65
 
       char **ptr;                  /* arrays of pointers to remote data    */
66
 
       C_Integer  *mapc;            /* block distribution map               */
67
 
       char name[FNAM+1];           /* array name                           */
68
 
       int p_handle;                /* pointer to processor list for array  */
69
 
       double *cache;               /* store for frequently accessed ptrs   */
70
 
       int corner_flag;             /* flag for updating corner ghost cells */
71
 
       int block_flag;              /* flag to indicate block-cyclic data   */
72
 
       int block_sl_flag;           /* flag to indicate block-cyclic data   */
73
 
                                    /* using ScaLAPACK format               */
74
 
       C_Integer block_dims[MAXDIM];/* array of block dimensions            */
75
 
       C_Integer num_blocks[MAXDIM];/* number of blocks in each dimension   */
76
 
       C_Integer block_total;       /* total number of blocks in array      */
77
 
                                    /* using restricted arrays              */
78
 
       C_Integer *rstrctd_list;     /* list of processors with data         */
79
 
       C_Integer num_rstrctd;       /* number of processors with data       */
80
 
       C_Integer has_data;          /* flag that processor has data         */
81
 
       C_Integer rstrctd_id;        /* rank of processor in restricted list */
82
 
       C_Integer *rank_rstrctd;     /* ranks of processors with data        */
83
 
 
84
 
#ifdef ENABLE_CHECKPOINT
85
 
       int record_id;               /* record id for writing ga to disk     */
86
 
#endif
87
 
} global_array_t;
88
 
 
89
 
extern global_array_t *_ga_main_data_structure; 
90
 
extern proc_list_t *_proc_list_main_data_structure; 
91
 
/*\
92
 
 *The following statement had to be moved here because of a problem in the c
93
 
 *compiler on SV1. The problem is that when a c file is compiled with a 
94
 
 *-htaskprivate option on SV1, all global objects are given task-private status
95
 
 *even static variables are supposed to be initialized and given a task-private
96
 
 *memory/status. Somehow SV1 fails to do this for global variables that are 
97
 
 *initialized during declaration.
98
 
 *So to handle that,we cannot initialize global variables to be able to run 
99
 
 *on SV1.
100
 
\*/
101
 
extern global_array_t *GA;
102
 
extern proc_list_t *PGRP_LIST;
103
 
 
104
 
 
105
 
#define ERR_STR_LEN 256               /* length of string for error reporting */
106
 
 
107
 
/**************************** MACROS ************************************/
108
 
 
109
 
 
110
 
#define ga_check_handleM(g_a, string) \
111
 
{\
112
 
    if(GA_OFFSET+ (g_a) < 0 || GA_OFFSET+(g_a) >=_max_global_array){   \
113
 
      char err_string[ERR_STR_LEN];                                    \
114
 
      sprintf(err_string, "%s: INVALID ARRAY HANDLE", string);         \
115
 
      pnga_error(err_string, (g_a));                                   \
116
 
    }                                                                  \
117
 
    if( ! (GA[GA_OFFSET+(g_a)].actv) ){                                \
118
 
      char err_string[ERR_STR_LEN];                                    \
119
 
      sprintf(err_string, "%s: ARRAY NOT ACTIVE", string);             \
120
 
      pnga_error(err_string, (g_a));                                   \
121
 
    }                                                                  \
122
 
}
123
 
 
124
 
/* this macro finds cordinates of the chunk of array owned by processor proc */
125
 
#define ga_ownsM_no_handle(ndim, dims, nblock, mapc, proc, lo, hi)             \
126
 
{                                                                              \
127
 
   Integer _loc, _nb, _d, _index, _dim=ndim,_dimstart=0, _dimpos;              \
128
 
   for(_nb=1, _d=0; _d<_dim; _d++)_nb *= (Integer)nblock[_d];                  \
129
 
   if((Integer)proc > _nb - 1 || proc<0){                                      \
130
 
      __CRAYX1_PRAGMA("_CRI novector");                                        \
131
 
           for(_d=0; _d<_dim; _d++){                                           \
132
 
         lo[_d] = (Integer)0;                                                  \
133
 
         hi[_d] = (Integer)-1;}                                                \
134
 
   }                                                                           \
135
 
   else{                                                                       \
136
 
         _index = proc;                                                        \
137
 
         if(GA_inv_Proc_list) _index = GA_inv_Proc_list[proc];                 \
138
 
      __CRAYX1_PRAGMA("_CRI novector");                                        \
139
 
         for(_d=0; _d<_dim; _d++){                                             \
140
 
             _loc = _index% (Integer)nblock[_d];                               \
141
 
             _index  /= (Integer)nblock[_d];                                   \
142
 
             _dimpos = _loc + _dimstart; /* correction to find place in mapc */\
143
 
             _dimstart += (Integer)nblock[_d];                                 \
144
 
             lo[_d] = (Integer)mapc[_dimpos];                                  \
145
 
             if (_loc==nblock[_d]-1) hi[_d]=dims[_d];                          \
146
 
             else hi[_d] = mapc[_dimpos+1]-1;                                  \
147
 
         }                                                                     \
148
 
   }                                                                           \
149
 
}
150
 
 
151
 
/* this macro finds the block indices for a given block */
152
 
#define gam_find_block_indices(ga_handle,nblock,index) {                       \
153
 
  int _itmp, _i;                                                       \
154
 
  int _ndim = GA[ga_handle].ndim;                                              \
155
 
  _itmp = nblock;                                                              \
156
 
  index[0] = _itmp%GA[ga_handle].num_blocks[0];                                \
157
 
  for (_i=1; _i<_ndim; _i++) {                                                 \
158
 
    _itmp = (_itmp-index[_i-1])/GA[ga_handle].num_blocks[_i-1];                \
159
 
    index[_i] = _itmp%GA[ga_handle].num_blocks[_i];                            \
160
 
  }                                                                            \
161
 
}
162
 
 
163
 
/* this macro finds the ScaLAPACK indices for a given processor */
164
 
#ifdef COMPACT_SCALAPACK
165
 
#define gam_find_proc_indices(ga_handle,proc,index) {                          \
166
 
  Integer _itmp, _i;                                                           \
167
 
  Integer _ndim = GA[ga_handle].ndim;                                          \
168
 
  _itmp = proc;                                                                \
169
 
  index[0] = _itmp%GA[ga_handle].nblock[0];                                    \
170
 
  for (_i=1; _i<_ndim; _i++) {                                                 \
171
 
    _itmp = (_itmp-index[_i-1])/GA[ga_handle].nblock[_i-1];                    \
172
 
    index[_i] = _itmp%GA[ga_handle].nblock[_i];                                \
173
 
  }                                                                            \
174
 
}
175
 
#else
176
 
#define gam_find_proc_indices(ga_handle,proc,index) {                          \
177
 
  Integer _itmp, _i;                                                           \
178
 
  Integer _ndim = GA[ga_handle].ndim;                                          \
179
 
  _itmp = proc;                                                                \
180
 
  index[_ndim-1] = _itmp%GA[ga_handle].nblock[_ndim-1];                        \
181
 
  for (_i=_ndim-2; _i>=0; _i--) {                                              \
182
 
    _itmp = (_itmp-index[_i+1])/GA[ga_handle].nblock[_i+1];                    \
183
 
    index[_i] = _itmp%GA[ga_handle].nblock[_i];                                \
184
 
  }                                                                            \
185
 
}
186
 
#endif
187
 
 
188
 
/* this macro finds cordinates of the chunk of array owned by processor proc */
189
 
#define ga_ownsM(ga_handle, proc, lo, hi)                                      \
190
 
{                                                                              \
191
 
  if (GA[ga_handle].block_flag == 0) {                                         \
192
 
    if (GA[ga_handle].num_rstrctd == 0) {                                      \
193
 
      ga_ownsM_no_handle(GA[ga_handle].ndim, GA[ga_handle].dims,               \
194
 
                         GA[ga_handle].nblock, GA[ga_handle].mapc,             \
195
 
                         proc,lo, hi )                                         \
196
 
    } else {                                                                   \
197
 
      if (proc < GA[ga_handle].num_rstrctd) {                                  \
198
 
        ga_ownsM_no_handle(GA[ga_handle].ndim, GA[ga_handle].dims,             \
199
 
                           GA[ga_handle].nblock, GA[ga_handle].mapc,           \
200
 
                           proc,lo, hi )                                       \
201
 
      } else {                                                                 \
202
 
        int _i;                                                                \
203
 
        int _ndim = GA[ga_handle].ndim;                                        \
204
 
        for (_i=0; _i<_ndim; _i++) {                                           \
205
 
          lo[_i] = 0;                                                          \
206
 
          hi[_i] = -1;                                                         \
207
 
        }                                                                      \
208
 
      }                                                                        \
209
 
    }                                                                          \
210
 
  } else {                                                                     \
211
 
    int _index[MAXDIM];                                                        \
212
 
    int _i;                                                                    \
213
 
    int _ndim = GA[ga_handle].ndim;                                            \
214
 
    gam_find_block_indices(ga_handle,proc,_index);                             \
215
 
    for (_i=0; _i<_ndim; _i++) {                                               \
216
 
      lo[_i] = _index[_i]*GA[ga_handle].block_dims[_i]+1;    \
217
 
      hi[_i] = (_index[_i]+1)*GA[ga_handle].block_dims[_i];  \
218
 
      if (hi[_i] > GA[ga_handle].dims[_i]) hi[_i]=GA[ga_handle].dims[_i];      \
219
 
    }                                                                          \
220
 
  }                                                                            \
221
 
}
222
 
 
223
 
/* this macro finds the block index corresponding to a given set of indices */
224
 
#define gam_find_block_from_indices(ga_handle,nblock,index) {                  \
225
 
  int _ndim = GA[ga_handle].ndim;                                              \
226
 
  int _i;                                                                      \
227
 
  nblock = index[_ndim-1];                                                     \
228
 
  for (_i=_ndim-2; _i >= 0; _i--) {                                            \
229
 
    nblock  = nblock*GA[ga_handle].num_blocks[_i]+index[_i];                   \
230
 
  }                                                                            \
231
 
}
232
 
 
233
 
/* this macro finds the proc that owns a given set block indices
234
 
   using the ScaLAPACK data distribution */
235
 
#ifdef COMPACT_SCALAPACK
236
 
#define gam_find_proc_from_sl_indices(ga_handle,proc,index) {                  \
237
 
  int _ndim = GA[ga_handle].ndim;                                              \
238
 
  int _i;                                                                      \
239
 
  Integer _index2[MAXDIM];                                                     \
240
 
  for (_i=0; _i<_ndim; _i++) {                                                 \
241
 
    _index2[_i] = index[_i]%GA[ga_handle].nblock[_i];                          \
242
 
  }                                                                            \
243
 
  proc = _index2[_ndim-1];                                                     \
244
 
  for (_i=_ndim-2; _i >= 0; _i--) {                                            \
245
 
    proc = proc*GA[ga_handle].nblock[_i]+_index2[_i];                          \
246
 
  }                                                                            \
247
 
}
248
 
#else
249
 
#define gam_find_proc_from_sl_indices(ga_handle,proc,index) {                  \
250
 
  int _ndim = GA[ga_handle].ndim;                                              \
251
 
  int _i;                                                                      \
252
 
  Integer _index2[MAXDIM];                                                     \
253
 
  for (_i=0; _i<_ndim; _i++) {                                                 \
254
 
    _index2[_i] = index[_i]%GA[ga_handle].nblock[_i];                          \
255
 
  }                                                                            \
256
 
  proc = _index2[0];                                                           \
257
 
  for (_i=1; _i < _ndim; _i++) {                                               \
258
 
    proc = proc*GA[ga_handle].nblock[_i]+_index2[_i];                          \
259
 
  }                                                                            \
260
 
}
261
 
#endif
262
 
/* this macro computes the strides on both the remote and local
263
 
   processors that map out the data. ld and ldrem are the physical dimensions
264
 
   of the memory on both the local and remote processors. */
265
 
/* NEEDS C_INT64 CONVERSION */
266
 
#define gam_setstride(ndim, size, ld, ldrem, stride_rem, stride_loc){\
267
 
  int _i;                                                            \
268
 
  stride_rem[0]= stride_loc[0] = (int)size;                          \
269
 
  __CRAYX1_PRAGMA("_CRI novector");                                  \
270
 
  for(_i=0;_i<ndim-1;_i++){                                          \
271
 
    stride_rem[_i] *= (int)ldrem[_i];                                \
272
 
    stride_loc[_i] *= (int)ld[_i];                                   \
273
 
      stride_rem[_i+1] = stride_rem[_i];                             \
274
 
      stride_loc[_i+1] = stride_loc[_i];                             \
275
 
  }                                                                  \
276
 
}
277
 
 
278
 
/* Count total number of elmenents in array based on values of ndim,
279
 
      lo, and hi */
280
 
#define gam_CountElems(ndim, lo, hi, pelems){                        \
281
 
  int _d;                                                            \
282
 
  __CRAYX1_PRAGMA("_CRI novector");                                         \
283
 
  for(_d=0,*pelems=1; _d< ndim;_d++)  *pelems *= hi[_d]-lo[_d]+1;    \
284
 
}
285
 
 
286
 
/* NEEDS C_INT64 CONVERSION */
287
 
#define gam_ComputeCount(ndim, lo, hi, count){                       \
288
 
  int _d;                                                            \
289
 
  __CRAYX1_PRAGMA("_CRI novector");                                         \
290
 
  for(_d=0; _d< ndim;_d++) count[_d] = (int)(hi[_d]-lo[_d])+1;       \
291
 
}
292
 
 
293
 
#define ga_RegionError(ndim, lo, hi, val){                           \
294
 
  int _d, _l;                                                        \
295
 
  char *str= "cannot locate region: ";                               \
296
 
  char err_string[ERR_STR_LEN];                                      \
297
 
  sprintf(err_string, str);                                          \
298
 
  _d=0;                                                              \
299
 
  _l = strlen(str);                                                  \
300
 
  sprintf(err_string+_l, "[%ld:%ld ",(long)lo[_d],(long)hi[_d]);     \
301
 
  _l=strlen(err_string);                                             \
302
 
  __CRAYX1_PRAGMA("_CRI novector");                                  \
303
 
  for(_d=1; _d< ndim; _d++){                                         \
304
 
    sprintf(err_string+_l, ",%ld:%ld ",(long)lo[_d],(long)hi[_d]);   \
305
 
    _l=strlen(err_string);                                           \
306
 
  }                                                                  \
307
 
  sprintf(err_string+_l, "]");                                       \
308
 
  _l=strlen(err_string);                                             \
309
 
  pnga_error(err_string, val);                                       \
310
 
}
311
 
 
312
 
/*\ Just return pointer (ptr_loc) to location in memory of element with
313
 
 *  subscripts (subscript).
314
 
\*/
315
 
#define gam_Loc_ptr(proc, g_handle,  subscript, ptr_loc)                      \
316
 
{                                                                             \
317
 
Integer _offset=0, _d, _w, _factor=1, _last=GA[g_handle].ndim-1;              \
318
 
Integer _lo[MAXDIM], _hi[MAXDIM], _p_handle, _iproc;                          \
319
 
                                                                              \
320
 
      ga_ownsM(g_handle, proc, _lo, _hi);                                     \
321
 
      _p_handle = GA[g_handle].p_handle;                                      \
322
 
      _iproc = proc;                                                          \
323
 
      gaCheckSubscriptM(subscript, _lo, _hi, GA[g_handle].ndim);              \
324
 
  __CRAYX1_PRAGMA("_CRI novector");                                           \
325
 
      for(_d=0; _d < _last; _d++)            {                                \
326
 
          _w = (Integer)GA[g_handle].width[_d];                               \
327
 
          _offset += (subscript[_d]-_lo[_d]+_w) * _factor;                    \
328
 
          _factor *= _hi[_d] - _lo[_d]+1+2*_w;                                \
329
 
      }                                                                       \
330
 
      _offset += (subscript[_last]-_lo[_last]                                 \
331
 
               + (Integer)GA[g_handle].width[_last])                          \
332
 
               * _factor;                                                     \
333
 
      if (_p_handle == 0) {                                                   \
334
 
        _iproc = PGRP_LIST[_p_handle].inv_map_proc_list[_iproc];              \
335
 
      }                                                                       \
336
 
      if (GA[g_handle].num_rstrctd > 0)                                       \
337
 
        _iproc = GA[g_handle].rstrctd_list[_iproc];                           \
338
 
      *(ptr_loc) =  GA[g_handle].ptr[_iproc]+_offset*GA[g_handle].elemsize;   \
339
 
}
340
 
 
341
 
#define ga_check_regionM(g_a, ilo, ihi, jlo, jhi, string){                     \
342
 
   if (*(ilo) <= 0 || *(ihi) > GA[GA_OFFSET + *(g_a)].dims[0] ||               \
343
 
       *(jlo) <= 0 || *(jhi) > GA[GA_OFFSET + *(g_a)].dims[1] ||               \
344
 
       *(ihi) < *(ilo) ||  *(jhi) < *(jlo)){                                   \
345
 
       char err_string[ERR_STR_LEN];                                           \
346
 
       sprintf(err_string,"%s:req(%ld:%ld,%ld:%ld) out of range (1:%ld,1:%ld)",\
347
 
               string, (long)*(ilo), (long)*(ihi), (long)*(jlo), (long)*(jhi), \
348
 
               (long)GA[GA_OFFSET + *(g_a)].dims[0],                           \
349
 
               (long)GA[GA_OFFSET + *(g_a)].dims[1]);                          \
350
 
       pnga_error(err_string, *(g_a));                                         \
351
 
   }                                                                           \
352
 
}
353
 
 
354
 
#define gaCheckSubscriptM(subscr, lo, hi, ndim)                                \
355
 
{                                                                              \
356
 
Integer _d;                                                                    \
357
 
  __CRAYX1_PRAGMA("_CRI novector");                                            \
358
 
   for(_d=0; _d<  ndim; _d++)                                                  \
359
 
      if( subscr[_d]<  lo[_d] ||  subscr[_d]>  hi[_d]){                        \
360
 
        char err_string[ERR_STR_LEN];                                          \
361
 
        sprintf(err_string,"check subscript failed:%ld not in (%ld:%ld) dim=", \
362
 
                  (long)subscr[_d],  (long)lo[_d],  (long)hi[_d]);             \
363
 
          pnga_error(err_string, _d);                                          \
364
 
      }\
365
 
}