MPQC  3.0.0-alpha
task.hpp
1 #ifndef MPQC_MPI_TASK_HPP
2 #define MPQC_MPI_TASK_HPP
3 
4 #include "mpqc/mpi.hpp"
5 #include "mpqc/utility/mutex.hpp"
6 
7 #ifdef HAVE_ARMCI
8 extern "C" {
9 #include <armci.h>
10 }
11 #endif
12 
13 #if (defined HAVE_MPI) && !(defined HAVE_ARMCI)
14 #error mpqc::MPI::Task requires ARMCI if using MPI
15 #endif
16 
17 namespace mpqc {
18 namespace MPI {
19 
22  struct Task : boost::noncopyable {
23 
24  typedef int T;
25 
28  explicit Task(const MPI::Comm &comm)
29  : comm_(comm), data_(0)
30  {
31 #ifdef HAVE_ARMCI
32  MPQC_ASSERT(comm == MPI_COMM_WORLD);
33  ARMCI_Init();
34  data_.resize(comm_.size());
35  ARMCI_Malloc(&data_[0], sizeof(T));
36 #endif
37  reset(0);
38  }
39 
42  ~Task() {
43 #ifdef HAVE_ARMCI
44  ARMCI_Free(data_[comm_.rank()]);
45 #endif
46  }
47 
49  void reset(const T &value = T(0)) {
50  mutex::global::lock();
51 #ifdef HAVE_ARMCI
52  comm_.barrier();
53  if (comm_.rank() == 0) {
54  ARMCI_PutValueInt(value, this->value(), 0);
55  ARMCI_Fence(0);
56  }
57  comm_.barrier();
58 #else
59  data_ = 0;
60 #endif
61  mutex::global::unlock();
62  }
63 
65  T operator++(int) {
66  int next;
67  mutex::global::lock();
68 #ifdef HAVE_ARMCI
69  ARMCI_Rmw(ARMCI_FETCH_AND_ADD, &next, this->value(), 1, 0);
70 #else
71  next = this->data_++;
72 #endif
73  mutex::global::unlock();
74  return next;
75  }
76 
78  mpqc::range next(range r, int block = 1) {
79  int i = block*((*this)++);
80  return (r & mpqc::range(i, i+block));
81  }
82 
83  template<typename Iterator>
84  Iterator next(Iterator begin, Iterator end) {
85  Iterator it = begin;
86  int n = (*this)++;
87  for (int i = 0; i < n; ++i) {
88  if (it == end) break;
89  ++it;
90  }
91  return it;
92  }
93 
94  private:
95 
96  MPI::Comm comm_;
97 #ifdef HAVE_ARMCI
98  std::vector< void* > data_;
99  T* value() {
100  return (T*)data_[0];
101  }
102 #else
103  T data_;
104 #endif
105 
106  };
107 
108 
109 } // namespace mpi
110 } // namespace mpqc
111 
112 #endif /* MPQC_MPI_TASK_HPP */
mpqc::MPI::Task::Task
Task(const MPI::Comm &comm)
Construct new task.
Definition: task.hpp:28
mpqc
Contains new MPQC code since version 3.
Definition: integralenginepool.hpp:37
mpqc::range
Definition: range.hpp:23
mpqc::MPI::Task::reset
void reset(const T &value=T(0))
Reset task.
Definition: task.hpp:49
mpqc::MPI::Task::next
mpqc::range next(range r, int block=1)
Get next task range.
Definition: task.hpp:78
mpqc::MPI::Task
Distributed task.
Definition: task.hpp:22
mpqc::MPI::Task::operator++
T operator++(int)
Get next task.
Definition: task.hpp:65
mpqc::MPI::Task::~Task
~Task()
Destructor.
Definition: task.hpp:42
mpqc::MPI::Comm
MPI_Comm object wrapper/stub.
Definition: comm.hpp:14

Generated at Sun Jan 26 2020 23:24:01 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.8.16.