DIY 3.0 data-parallel out-of-core C++ library

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Examples

- File List

All Classes Namespaces Functions Typedefs Groups Pages
link.hpp
1 #ifndef DIY_COVER_HPP
2 #define DIY_COVER_HPP
3
4 #include <vector>
5 #include <map>
6 #include <algorithm>
7
8 #include "types.hpp"
9 #include "serialization.hpp"
10 #include "assigner.hpp"
11
12 namespace diy
13 {
14 // Local view of a distributed representation of a cover, a completely unstructured link
15 class Link
16 {
17 public:
18 virtual ~Link() {} // need to be able to delete derived classes
19
20 int size() const { return static_cast<int>(neighbors_.size()); }
21 inline
22 int size_unique() const;
23 BlockID target(int i) const { return neighbors_[static_cast<size_t>(i)]; }
24 BlockID& target(int i) { return neighbors_[static_cast<size_t>(i)]; }
25 inline
26 int find(int gid) const;
27
28 void add_neighbor(const BlockID& block) { neighbors_.push_back(block); }
29
30 void fix(const Assigner& assigner) { for (unsigned i = 0; i < neighbors_.size(); ++i) { neighbors_[i].proc = assigner.rank(neighbors_[i].gid); } }
31
32 void swap(Link& other) { neighbors_.swap(other.neighbors_); }
33
34 virtual void save(BinaryBuffer& bb) const { diy::save(bb, neighbors_); }
35 virtual void load(BinaryBuffer& bb) { diy::load(bb, neighbors_); }
36
37 virtual size_t id() const { return 0; }
38
39 private:
40 std::vector<BlockID> neighbors_;
41 };
42
43 template<class Bounds_>
44 class RegularLink;
45
46 typedef RegularLink<DiscreteBounds> RegularGridLink;
47 typedef RegularLink<ContinuousBounds> RegularContinuousLink;
48
49 // Selector between regular discrete and contious links given bounds type
50 template<class Bounds_>
51 struct RegularLinkSelector;
52
53 template<>
54 struct RegularLinkSelector<DiscreteBounds>
55 {
56 typedef RegularGridLink type;
57 static const size_t id = 1;
58 };
59
60 template<>
61 struct RegularLinkSelector<ContinuousBounds>
62 {
63 typedef RegularContinuousLink type;
64 static const size_t id = 2;
65 };
66
67
68 // for a regular decomposition, it makes sense to address the neighbors by direction
69 // and store local and neighbor bounds
70 template<class Bounds_>
71 class RegularLink: public Link
72 {
73 public:
74 typedef Bounds_ Bounds;
75
76 typedef std::map<Direction, int> DirMap;
77 typedef std::vector<Direction> DirVec;
78
79 public:
80 RegularLink(int dim, const Bounds& core__, const Bounds& bounds__):
81 dim_(dim), core_(core__), bounds_(bounds__) {}
82
83 // dimension
84 int dimension() const { return dim_; }
85
86 // direction
87 int direction(Direction dir) const; // convert direction to a neighbor (-1 if no neighbor)
88 Direction direction(int i) const { return dir_vec_[i]; }
89 void add_direction(Direction dir) { int c = dir_map_.size(); dir_map_[dir] = c; dir_vec_.push_back(dir); }
90
91 // wrap
92 void add_wrap(Direction dir) { wrap_.push_back(dir); }
93 Direction wrap(int i) const { return wrap_[i]; }
94 Direction& wrap(int i) { return wrap_[i]; }
95
96 // bounds
97 const Bounds& core() const { return core_; }
98 Bounds& core() { return core_; }
99 const Bounds& bounds() const { return bounds_; }
100 Bounds& bounds() { return bounds_; }
101 const Bounds& bounds(int i) const { return nbr_bounds_[i]; }
102 void add_bounds(const Bounds& bounds__) { nbr_bounds_.push_back(bounds__); }
103
104 void swap(RegularLink& other) { Link::swap(other); dir_map_.swap(other.dir_map_); dir_vec_.swap(other.dir_vec_); nbr_bounds_.swap(other.nbr_bounds_); std::swap(dim_, other.dim_); wrap_.swap(other.wrap_); std::swap(core_, other.core_); std::swap(bounds_, other.bounds_); }
105
106 void save(BinaryBuffer& bb) const
107 {
108 Link::save(bb);
109 diy::save(bb, dim_);
110 diy::save(bb, dir_map_);
111 diy::save(bb, dir_vec_);
112 diy::save(bb, core_);
113 diy::save(bb, bounds_);
114 diy::save(bb, nbr_bounds_);
115 diy::save(bb, wrap_);
116 }
117
118 void load(BinaryBuffer& bb)
119 {
120 Link::load(bb);
121 diy::load(bb, dim_);
122 diy::load(bb, dir_map_);
123 diy::load(bb, dir_vec_);
124 diy::load(bb, core_);
125 diy::load(bb, bounds_);
126 diy::load(bb, nbr_bounds_);
127 diy::load(bb, wrap_);
128 }
129
130 virtual size_t id() const { return RegularLinkSelector<Bounds>::id; }
131
132 private:
133 int dim_;
134
135 DirMap dir_map_;
136 DirVec dir_vec_;
137
138 Bounds core_;
139 Bounds bounds_;
140 std::vector<Bounds> nbr_bounds_;
141 std::vector<Direction> wrap_;
142 };
143
144 // Other cover candidates: KDTreeLink, AMRGridLink
145
146 struct LinkFactory
147 {
148 public:
149 static Link* create(size_t id)
150 {
151 // not pretty, but will do for now
152 if (id == 0)
153 return new Link;
154 else if (id == 1)
155 return new RegularGridLink(0, DiscreteBounds(), DiscreteBounds());
156 else if (id == 2)
157 return new RegularContinuousLink(0, ContinuousBounds(), ContinuousBounds());
158 else
159 return 0;
160 }
161
162 inline static void save(BinaryBuffer& bb, const Link* l);
163 inline static Link* load(BinaryBuffer& bb);
164 };
165 }
166
167
168 void
169 diy::LinkFactory::
170 save(BinaryBuffer& bb, const Link* l)
171 {
172 diy::save(bb, l->id());
173 l->save(bb);
174 }
175
176 diy::Link*
177 diy::LinkFactory::
178 load(BinaryBuffer& bb)
179 {
180 size_t id;
181 diy::load(bb, id);
182 Link* l = create(id);
183 l->load(bb);
184 return l;
185 }
186
187 int
188 diy::Link::
189 find(int gid) const
190 {
191 for (int i = 0; i < size(); ++i)
192 {
193 if (target(i).gid == gid)
194 return i;
195 }
196 return -1;
197 }
198 int
199 diy::Link::
200 size_unique() const
201 {
202 std::vector<BlockID> tmp(neighbors_.begin(), neighbors_.end());
203 std::sort(tmp.begin(), tmp.end());
204 return static_cast<int>(std::unique(tmp.begin(), tmp.end()) - tmp.begin());
205 }
206
207 template<class Bounds>
208 int
209 diy::RegularLink<Bounds>::
210 direction(Direction dir) const
211 {
212 DirMap::const_iterator it = dir_map_.find(dir);
213 if (it == dir_map_.end())
214 return -1;
215 else
216 return it->second;
217 }
218
219 #endif
diy::load
void load(BinaryBuffer &bb, T &x)
Loads x from bb by calling diy::Serialization<T>::load(bb,x).
Definition: serialization.hpp:106
diy::BlockID
Definition: types.hpp:10
diy::save
void save(BinaryBuffer &bb, const T &x)
Saves x to bb by calling diy::Serialization<T>::save(bb,x).
Definition: serialization.hpp:102
diy::RegularLinkSelector
Definition: link.hpp:51
diy::Assigner::rank
virtual int rank(int gid) const =0
returns the process rank of the block with global id gid (need not be local)
diy::Assigner
Definition: assigner.hpp:11
diy::Link
Definition: link.hpp:15
diy::LinkFactory
Definition: link.hpp:146
diy::RegularLink
Definition: link.hpp:44
diy::Bounds
Definition: types.hpp:16
diy::BinaryBuffer
A serialization buffer.
Definition: serialization.hpp:19
diy::sort
void sort(Master &master, const Assigner &assigner, std::vector< T > Block::*values, std::vector< T > Block::*samples, size_t num_samples, const Cmp &cmp, int k=2, bool samples_only=false)
sample sort values of each block, store the boundaries between blocks in samples
Definition: algorithms.hpp:25