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

« back to all changes in this revision

Viewing changes to src/tools/ga-5-2/tascel/src/SharedQueue.cc

  • 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 <cstdio>
 
6
#include <cstring>
 
7
 
 
8
#include <armci.h>
 
9
 
 
10
#include "Comm.h"
 
11
#include "massert.h"
 
12
#include "SharedQueue.h"
 
13
 
 
14
using namespace std;
 
15
using namespace tascel;
 
16
using namespace tascel::comm;
 
17
 
 
18
 
 
19
SharedQueue::SharedQueue(int _tsk_size, int _max_ntsks)
 
20
  : max_ntsks(_max_ntsks)
 
21
  , tsk_size(_tsk_size)
 
22
  , q(NULL)
 
23
  , sq_state(NULL)
 
24
  , head(NULL)
 
25
  , tail(NULL)
 
26
  , size(NULL)
 
27
  , dirty(NULL)
 
28
  , td() {
 
29
  q = new char *[nproc()];
 
30
  massert(q);
 
31
  ARMCI_Malloc((void **)q, max_ntsks * tsk_size);
 
32
  massertl(q[me()], error1);
 
33
  ARMCI_Create_mutexes(1);
 
34
  sq_state = new sq_state_t*[nproc()];
 
35
  massertl(sq_state, error1);
 
36
  ARMCI_Malloc((void **)sq_state, nproc()*sizeof(sq_state_t));
 
37
  massertl(sq_state[me()], error2);
 
38
  head = &sq_state[me()]->head;
 
39
  tail = &sq_state[me()]->tail;
 
40
  size = &sq_state[me()]->size;
 
41
  dirty = &sq_state[me()]->dirty;
 
42
  *head = *tail = *size = *dirty = 0;
 
43
  //printf("(cons) %d: *head=%p *tail=%p *size=%p\n", me(), head, tail, size);
 
44
  return;
 
45
 
 
46
error2:
 
47
  printf("Error2 in SharedQueue constructor\n");
 
48
  delete [] sq_state;
 
49
error1:
 
50
  printf("Error1 in SharedQueue constructor\n");
 
51
  delete [] q;
 
52
error:
 
53
  printf("Error in SharedQueue constructor\n");
 
54
  throw TSL_ERR;
 
55
}
 
56
 
 
57
SharedQueue::~SharedQueue() {
 
58
  barrier();
 
59
  ARMCI_Free(sq_state[me()]);
 
60
  ARMCI_Destroy_mutexes();
 
61
  ARMCI_Free(q[me()]);
 
62
  delete [] sq_state;
 
63
  delete [] q;
 
64
}
 
65
 
 
66
bool
 
67
SharedQueue::empty() const {
 
68
  /*SK: speculative implementation. It could become empty while this
 
69
    operation is ongoing. However, the converse is not true, since
 
70
    only the host process call empty() or can add tasks (thus
 
71
    incrementing size) */
 
72
  massert(*size >= 0);
 
73
  return (*size == 0);
 
74
 
 
75
error:
 
76
  throw TSL_ERR;
 
77
}
 
78
 
 
79
bool
 
80
SharedQueue::getTask(void *dscr, int dlen) {
 
81
  massert(dscr);
 
82
  massert(dlen == tsk_size);
 
83
  ARMCI_Lock(0, me());
 
84
  if (*size == 0) {
 
85
    ARMCI_Unlock(0, me());
 
86
    return false;
 
87
  }
 
88
  *head = (*head - 1 + max_ntsks) % max_ntsks;
 
89
  memcpy(dscr, &q[me()][*head*tsk_size], tsk_size);
 
90
  *size -= 1;
 
91
  ARMCI_Unlock(0, me());
 
92
  return true;
 
93
  //  return false;
 
94
 
 
95
error:
 
96
  throw TSL_ERR;
 
97
}
 
98
 
 
99
void
 
100
SharedQueue::addTask(void *dscr, int dlen) {
 
101
  massert(dscr);
 
102
  massert(dlen == tsk_size);
 
103
  ARMCI_Lock(0, me());
 
104
  //   printf("addTask. %d: *head=%p *tail=%p *size=%p\n", me(), head, tail, size);
 
105
  massertl(*size != max_ntsks, error2);
 
106
  memcpy(&q[me()][*head*tsk_size], dscr, tsk_size);
 
107
  *head  = (*head + 1) % max_ntsks;
 
108
  *size += 1;
 
109
  ARMCI_Unlock(0, me());
 
110
  return;
 
111
 
 
112
error2:
 
113
  ARMCI_Unlock(0, me());
 
114
error:
 
115
  throw TSL_ERR;
 
116
}
 
117
 
 
118
bool
 
119
SharedQueue::steal(int proc) {
 
120
  char *buf;
 
121
  massert(*size == 0);
 
122
  buf = new char[tsk_size];
 
123
  massert(buf);
 
124
 
 
125
  //FIXME: might need a lock+unlock to ensure both size and dirty are
 
126
  //updated atomically by any thief (say through RDMA)
 
127
  td.progress(*dirty == 0);
 
128
  *dirty = 0;
 
129
  if (td.hasTerminated()) {
 
130
    return false;
 
131
  }
 
132
 
 
133
  ARMCI_Lock(0, proc);
 
134
  sq_state_t sq;
 
135
  ARMCI_Get(sq_state[proc], &sq, sizeof(sq), proc);
 
136
  //   printf("%d: Locked %d for steal. size=%d\n", me(), proc, sq.size);
 
137
  if (sq.size == 0) {
 
138
    //nothing to steal
 
139
    ARMCI_Unlock(0, proc);
 
140
    return false;
 
141
  }
 
142
  sq.size = sq.size - 1;
 
143
  sq.dirty = 1; //mark dirty for termination detection
 
144
  sq.head = (sq.head - 1 + max_ntsks) % max_ntsks;
 
145
  ARMCI_Get(&q[proc][sq.head*tsk_size], buf, tsk_size, proc);
 
146
  ARMCI_Put(&sq, sq_state[proc], sizeof(sq), proc);
 
147
  //FIXME: does unlock imply an ARMCI_Fence. If not, add one
 
148
  ARMCI_Unlock(0, proc);
 
149
 
 
150
  addTask(buf, tsk_size);
 
151
  delete [] buf;
 
152
  return true;
 
153
 
 
154
error:
 
155
  throw TSL_ERR;
 
156
}
 
157
 
 
158
bool
 
159
SharedQueue::hasTerminated() {
 
160
  return td.hasTerminated();
 
161
}
 
162
 
 
163
void
 
164
SharedQueue::td_progress() {
 
165
  td.progress(*dirty == 0);
 
166
  *dirty = 0;
 
167
}
 
168