MPQC 3.0.0-alpha
Loading...
Searching...
No Matches
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
9namespace mpqc {
10namespace 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>
30 : ArrayBase, boost::noncopyable
31 {
32
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
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 */
std::string string_cast(const T &value)
cast type T to string
Definition string.hpp:14
Contains new MPQC code since version 3.
Definition integralenginepool.hpp:37
MPI_Comm object wrapper/stub.
Definition comm.hpp:14
Definition forward.hpp:23
Definition forward.hpp:18
Definition parallel.hpp:31
Definition thread.hpp:338
Definition parallel.hpp:13
Definition range.hpp:25

Generated at Wed Sep 25 2024 02:45:30 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.12.0.