MPQC  3.0.0-alpha
parallel.hpp
1 #ifndef MPQC_ARRAY_PARALLEL_HPP
2 #define MPQC_ARRAY_PARALLEL_HPP
3 
4 #include "mpqc/range.hpp"
5 #include "mpqc/array/forward.hpp"
6 #include "mpqc/array/thread.hpp"
7 #include "mpqc/utility/string.hpp"
8 
9 namespace mpqc {
10 namespace detail {
11 
12  template<class Data>
13  struct array_tile {
14  std::vector<range> extents;
15  int proc, local;
16  Data data;
17  std::vector<range> subset(const std::vector<range> &ranges) const {
18  std::vector<range> s;
19  for (int i = 0; i < ranges.size(); ++i) {
20  range r = (ranges[i] & this->extents[i]);
21  if (!r.size()) return std::vector<range>();
22  s.push_back(r);
23  }
24  return s;
25  }
26  };
27 
28  template<typename T, typename Driver>
29  struct array_parallel_impl
30  : ArrayBase, boost::noncopyable
31  {
32 
33  typedef array_impl<T,Driver> Impl;
34  typedef array_tile<Impl*> Tile;
35 
36  array_parallel_impl(const std::string &name,
37  const std::vector<size_t> &dims,
38  MPI::Comm comm)
39  : ArrayBase(name, dims), thread_comm_(comm)
40  {
41  initialize(ArrayBase::dims_, comm);
42  }
43 
44  void initialize(const std::vector<size_t> &dims, const MPI::Comm &comm) {
45 
46  int np = comm.size();
47  size_t block = (dims.back() + np - 1)/np;
48 
49  for (int i = 0; i < dims.back(); i += block) {
50  Tile tile;
51 
52  int n = std::min(dims.back()-i, block);
53 
54  BOOST_FOREACH (size_t dim, dims) {
55  tile.extents.push_back(range(0, dim));
56  }
57  tile.extents.back() = range(i, i+n);
58 
59  tile.proc = (i/block)%np;
60  tile.local = (tile.proc == comm.rank());
61 
62  tile.data = NULL;
63  if (tile.local) {
64  std::string suffix = ".part" + string_cast(comm.rank());
65  try {
66  tile.data = new Impl(this->name() + suffix, tile.extents);
67  }
68  catch (std::exception e) {
69  comm.cout << e.what() << std::endl;
70  }
71  }
72 
73  comm.broadcast(tile.data, tile.proc);
74  if (!tile.data) {
75  throw std::runtime_error("failed to create parallel array segment");
76  }
77  tiles_.push_back(tile);
78  }
79  }
80 
81  ~array_parallel_impl() {
82  BOOST_FOREACH (Tile t, tiles_) {
83  if (t.local) delete t.data;
84  }
85  thread_comm_.comm().free();
86  }
87 
88  void sync() {
89  thread_comm_.sync();
90  }
91 
92  protected:
93 
94  void _put(const std::vector<range> &r, const void *buffer) {
95  _put(r, (const T*)buffer);
96  }
97 
98  void _get(const std::vector<range> &r, void *buffer) const {
99  _get(r, (T*)buffer);
100  }
101 
102  private:
103 
104  void _put(const std::vector<range> &r, const T *buffer) {
105  size_t total = size(r);
106  size_t count = 0;
107  BOOST_FOREACH (const auto &tile, tiles_) {
108  auto x = tile.subset(r);
109  if (!x.empty()) {
110  // if (tile.local) {
111  // tile.object->put(x, buffer);
112  // }
113  // // else {
114  // MPQC_PROFILE_LINE;
115  // printf("comm::write\n");
116  //if (tile.proc == 0)
117  thread_comm_.write(buffer + count, tile.data, x, tile.proc);
118  // //}
119  count += size(x);
120  }
121  }
122  MPQC_ASSERT(total == count);
123  }
124 
125  void _get(const std::vector<range> &r, T *buffer) const {
126  size_t total = size(r);
127  size_t count = 0;
128  BOOST_FOREACH (const auto &tile, tiles_) {
129  auto x = tile.subset(r);
130  if (!x.empty()) {
131  // if (tile.local) {
132  // tile.object->get(x, buffer);
133  // }
134  // // else {
135  // MPQC_PROFILE_LINE;
136  // printf("comm::read\n");
137  //if (tile.proc == 0)
138  // std::cout << "read " << x << " from " << tile.proc << std::endl;
139  thread_comm_.read(buffer + count, tile.data, x, tile.proc);
140  count += size(x);
141  // //}
142  }
143  }
144  MPQC_ASSERT(total == count);
145  }
146 
147  private:
148 
149  static size_t size(const std::vector<range> &R) {
150  size_t size = R.empty() ? 0 : 1;
151  BOOST_FOREACH (range r, R) {
152  size *= r.size();
153  }
154  //printf("size = %lu\n", size);
155  return size;
156  }
157 
158  std::vector<Tile> tiles_;
159  array_thread_comm thread_comm_;
160 
161  };
162 
163 
164 } // namespace detail
165 } // namespace mpqc
166 
167 #endif /* MPQC_ARRAY_PARALLEL_HPP */
mpqc::detail::array_impl
Definition: forward.hpp:18
mpqc
Contains new MPQC code since version 3.
Definition: integralenginepool.hpp:37
mpqc::range
Definition: range.hpp:23
mpqc::detail::array_tile
Definition: parallel.hpp:13
mpqc::string_cast
std::string string_cast(const T &value)
cast type T to string
Definition: string.hpp:14
mpqc::detail::array_parallel_impl
Definition: forward.hpp:21
mpqc::MPI::Comm
MPI_Comm object wrapper/stub.
Definition: comm.hpp:14
mpqc::detail::ArrayBase
Definition: forward.hpp:23

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