Interface Documentation
Version: invalid
crs.hh
Go to the documentation of this file.
1 /*
2  @@@@@@@@ @@ @@@@@@ @@@@@@@@ @@
3  /@@///// /@@ @@////@@ @@////// /@@
4  /@@ /@@ @@@@@ @@ // /@@ /@@
5  /@@@@@@@ /@@ @@///@@/@@ /@@@@@@@@@/@@
6  /@@//// /@@/@@@@@@@/@@ ////////@@/@@
7  /@@ /@@/@@//// //@@ @@ /@@/@@
8  /@@ @@@//@@@@@@ //@@@@@@ @@@@@@@@ /@@
9  // /// ////// ////// //////// //
10 
11  Copyright (c) 2016, Los Alamos National Security, LLC
12  All rights reserved.
13  */
14 #pragma once
15 
18 #include "flecsi/util/array_ref.hh"
19 
20 #include <algorithm>
21 #include <ostream>
22 
23 namespace flecsi {
24 namespace util {
25 
26 //----------------------------------------------------------------------------//
27 // Convenience macro to avoid having to reimplement this for each member.
28 //----------------------------------------------------------------------------//
29 
30 #define define_as(member) \
31  template<typename T> \
32  std::vector<T> member##_as() const { \
33  std::vector<T> asvec(member.begin(), member.end()); \
34  return asvec; \
35  }
36 
37 /*
38  This type is a container for compressed-storage of sparse data.
39 
40  @var offsets The offset at which each index begins and ends in the
41  list of indices.
42  @var indices The indices of the sparse structure of the data resolved
43  by this storage member.
44 
45  @ingroup coloring
46 */
47 
48 struct crs {
49 
50  using value_type = size_t;
51 
52  std::vector<size_t> offsets;
53  std::vector<size_t> indices;
54 
55  define_as(offsets) define_as(indices)
56 
57  size_t size() const {
58  if(offsets.empty())
59  return 0;
60  else
61  return offsets.size() - 1;
62  } // size
63 
65  void erase(const std::vector<size_t> & ids) {
66 
67  if(ids.empty())
68  return;
69 
70  // assume sorted
71  assert(std::is_sorted(ids.begin(), ids.end()) &&
72  "entries to delete are not sorted");
73 
74  auto num_remove = ids.size();
75  auto num_offsets = size();
76 
77  std::vector<size_t> new_offsets(offsets.size() - num_remove);
78  std::vector<size_t> new_indices;
79  new_indices.reserve(indices.size());
80 
81  new_offsets[0] = 0;
82  auto delete_it = ids.begin();
83 
84  for(size_t iold = 0, inew = 0; iold < num_offsets; ++iold) {
85 
86  // skip deleted items
87  if(delete_it != ids.end()) {
88  if(*delete_it == iold) {
89  delete_it++;
90  continue;
91  }
92  }
93 
94  // keep otherwise
95  auto start = offsets[iold];
96  auto end = offsets[iold + 1];
97  for(auto j = start; j < end; ++j) {
98  new_indices.push_back(indices[j]);
99  }
100  new_offsets[inew + 1] = new_indices.size();
101  inew++;
102  }
103 
104  assert(new_offsets.size() == offsets.size() - num_remove);
105 
106  // resize arrays
107  std::swap(offsets, new_offsets);
108  std::swap(indices, new_indices);
109  } // erase
110 
112  void clear() {
113  offsets.clear();
114  indices.clear();
115  }
116 
117  class iterator
118  {
119  crs & data_;
120  size_t pos_;
121 
122  public:
123  iterator(crs & data, size_t pos = 0) : data_(data), pos_(pos) {}
124  auto operator*() {
125  auto i = data_.offsets[pos_];
126  auto n = data_.offsets[pos_ + 1] - i;
127  return util::make_array_ref(&data_.indices[i], n);
128  }
129  auto & operator++() {
130  pos_++;
131  return *this;
132  } // prefix
133  auto operator++(int) {
134  auto i = *this;
135  pos_++;
136  return i;
137  } // postfix
138  bool operator!=(const iterator & it) const {
139  return (pos_ != it.pos_ || &data_ != &it.data_);
140  }
141  };
142 
144  {
145  const crs & data_;
146  size_t pos_;
147 
148  public:
149  const_iterator(const crs & data, size_t pos = 0) : data_(data), pos_(pos) {}
150  auto operator*() {
151  auto i = data_.offsets[pos_];
152  auto n = data_.offsets[pos_ + 1] - i;
153  return util::make_array_ref(&data_.indices[i], n);
154  }
155  auto & operator++() {
156  pos_++;
157  return *this;
158  } // prefix
159  auto operator++(int) {
160  auto i = *this;
161  pos_++;
162  return i;
163  } // postfix
164  bool operator!=(const const_iterator & it) const {
165  return (pos_ != it.pos_ || &data_ != &it.data_);
166  }
167  };
168 
169  auto begin() {
170  return iterator(*this);
171  }
172  auto end() {
173  return iterator(*this, size());
174  }
175 
176  auto begin() const {
177  return const_iterator(*this);
178  }
179  auto end() const {
180  return const_iterator(*this, size());
181  }
182 
183  auto at(size_t i) {
184  assert(i < size() && "index out of range");
185  return *iterator(*this, i);
186  }
187  auto at(size_t i) const {
188  assert(i < size() && "index out of range");
189  return *const_iterator(*this, i);
190  }
191  auto operator[](size_t i) {
192  return *iterator(*this, i);
193  }
194  auto operator[](size_t i) const {
195  return *const_iterator(*this, i);
196  }
197 
198  template<typename InputIt>
199  void append(InputIt first, InputIt last) {
200  if(first == last)
201  return;
202  if(offsets.empty())
203  offsets.emplace_back(0);
204  offsets.emplace_back(offsets.back() + std::distance(first, last));
205  indices.insert(indices.end(), first, last);
206  }
207 
208  template<typename U>
209  void append(const U & value) {
210  auto ptr = &value;
211  append(ptr, ptr + 1);
212  }
213 
214  template<typename U>
215  void push_back(std::initializer_list<U> init) {
216  append(init.begin(), init.end());
217  }
218 
219  template<typename U, template<typename> class Vector>
220  void push_back(const Vector<U> & init) {
221  append(init.begin(), init.end());
222  }
223 
224 }; // struct crs
225 
230 inline std::ostream &
231 operator<<(std::ostream & stream, const crs & crs) {
232  stream << "offsets: ";
233  for(auto i : crs.offsets) {
234  stream << i << " ";
235  } // for
236  stream << std::endl;
237 
238  stream << "indices: ";
239  for(auto i : crs.indices) {
240  stream << i << " ";
241  } // for
242 
243  return stream;
244 } // operator <<
245 
254 struct dcrs : public crs {
255  std::vector<size_t> distribution;
256 
257  define_as(distribution)
258 
259 
260  void clear() {
261  crs::clear();
262  distribution.clear();
263  }
264 
265 }; // struct dcrs
266 
271 inline std::ostream &
272 operator<<(std::ostream & stream, const dcrs & dcrs) {
273  stream << static_cast<const crs &>(dcrs) << std::endl;
274 
275  stream << "distribution: ";
276  for(auto i : dcrs.distribution) {
277  stream << i << " ";
278  } // for
279 
280  return stream;
281 } // operator <<
282 
283 #undef define_as
284 
285 } // namespace util
286 } // namespace flecsi
void clear()
clears the current storage
Definition: crs.hh:112
Definition: crs.hh:48
std::ostream & operator<<(std::ostream &ostr, const filling_curve< D, T, DER > &k)
output for filling_curve using output_ function defined in the class
Definition: filling_curve.hh:206
constexpr point< TYPE, DIMENSION > operator*(TYPE const val, point< TYPE, DIMENSION > const &p)
Definition: point.hh:52
int start(const std::function< int()> &action)
Definition: execution.hh:69
Definition: crs.hh:117
define_as(distribution) void clear()
clears the current storage
Definition: crs.hh:257
Definition: crs.hh:143
Definition: crs.hh:254
void erase(const std::vector< size_t > &ids)
erase a bunch of ids
Definition: crs.hh:65
Definition: control.hh:31