Tenncor
shape.hpp
Go to the documentation of this file.
1 
9 #include <array>
10 #include <cmath>
11 #include <numeric>
12 #include <vector>
13 
14 #include "logs/logs.hpp"
15 
16 #ifndef TEQ_SHAPE_HPP
17 #define TEQ_SHAPE_HPP
18 
19 namespace teq
20 {
21 
23 using RankT = uint8_t;
24 
25 #define SDIM_BYTES 2
26 
28 #if !defined(SDIM_BYTES) || SDIM_BYTES <= 1
29 using DimT = uint8_t;
30 #elif SDIM_BYTES <= 2
31 using DimT = uint16_t;
32 #elif SDIM_BYTES <= 4
33 using DimT = uint32_t;
34 #else
35 using DimT = uint64_t;
36 #endif
37 
39 using CDimT = double;
40 
44 using NElemT = uint64_t;
45 
47 const RankT rank_cap = 8;
48 
50 using ShapeT = std::array<DimT,rank_cap>;
51 
56 using CoordT = std::array<CDimT,rank_cap>;
57 
62 struct Shape final
63 {
65  using iterator = ShapeT::iterator;
66 
68  using const_iterator = ShapeT::const_iterator;
69 
70  Shape (void)
71  {
72  std::fill(dims_.begin(), dims_.end(), 1);
73  }
74 
75  Shape (std::vector<DimT> dims)
76  {
77  vector_assign(dims);
78  }
79 
80  Shape (const Shape& other) = default;
81 
82  Shape& operator = (const Shape& other) = default;
83 
84  Shape& operator = (const std::vector<DimT>& dims)
85  {
86  vector_assign(dims);
87  return *this;
88  }
89 
90  Shape (Shape&& other)
91  {
92  move_helper(std::move(other));
93  }
94 
96  {
97  if (this != &other)
98  {
99  move_helper(std::move(other));
100  }
101  return *this;
102  }
103 
104 
105  // >>>> ACCESSORS <<<<
106 
108  DimT at (RankT idx) const
109  {
110  if (rank_cap <= idx)
111  {
112  logs::fatalf("cannot access out of bounds index %d", idx);
113  }
114  return dims_.at(idx);
115  }
116 
118  NElemT n_elems (void) const
119  {
120  auto it = dims_.begin();
121  return std::accumulate(it, it + rank_cap, (NElemT) 1,
122  std::multiplies<NElemT>());
123  }
124 
127  bool compatible_before (const Shape& other, RankT idx) const
128  {
129  auto it = dims_.begin();
130  return std::equal(it, it + std::min(idx, rank_cap), other.dims_.begin());
131  }
132 
136  bool compatible_after (const Shape& other, RankT idx) const
137  {
138  bool compatible = false;
139  if (idx < rank_cap)
140  {
141  compatible = std::equal(dims_.begin() + idx,
142  dims_.end(), other.dims_.begin() + idx);
143  }
144  return compatible;
145  }
146 
148  std::string to_string (void) const
149  {
150  return fmts::to_string(begin(), end());
151  }
152 
153  // >>>> INTERNAL CONTROL <<<<
154 
157  {
158  return dims_.begin();
159  }
160 
162  iterator end (void)
163  {
164  return dims_.end();
165  }
166 
168  const_iterator begin (void) const
169  {
170  return dims_.begin();
171  }
172 
174  const_iterator end (void) const
175  {
176  return dims_.end();
177  }
178 
179 private:
180  void vector_assign (const std::vector<DimT>& dims)
181  {
182  auto src = dims.begin();
183  if (std::any_of(src, dims.end(),
184  [](DimT d)
185  {
186  return d == 0;
187  }))
188  {
189  logs::fatalf("cannot create shape with vector containing zero: %s",
190  fmts::to_string(dims.begin(), dims.end()).c_str());
191  }
192  auto dest = dims_.begin();
193  RankT rank = std::min((size_t) rank_cap, dims.size());
194  std::copy(src, src + rank, dest);
195  std::fill(dest + rank, dest + rank_cap, 1);
196  }
197 
198  void move_helper (Shape&& other)
199  {
200  dims_ = std::move(other.dims_);
201  std::fill(other.dims_.begin(), other.dims_.end(), 1);
202  }
203 
206 };
207 
214 NElemT index (Shape shape, CoordT coord);
215 
219 CoordT coordinate (Shape shape, NElemT idx);
220 
221 }
222 
223 #endif // TEQ_SHAPE_HPP
std::array< CDimT, rank_cap > CoordT
Definition: shape.hpp:56
std::string to_string(void) const
Return string representation of shape.
Definition: shape.hpp:148
const RankT rank_cap
Number of dimsensions in a shape/coordinate.
Definition: shape.hpp:47
uint64_t NElemT
Definition: shape.hpp:44
ShapeT::const_iterator const_iterator
Type of constant iterator used to iterate through internal array.
Definition: shape.hpp:68
uint8_t RankT
Type used for shape rank.
Definition: shape.hpp:23
Definition: shape.hpp:62
bool compatible_after(const Shape &other, RankT idx) const
Definition: shape.hpp:136
void move_helper(Shape &&other)
Definition: shape.hpp:198
const_iterator begin(void) const
Return begin constant iterator of internal array.
Definition: shape.hpp:168
Shape(Shape &&other)
Definition: shape.hpp:90
double CDimT
Type used for coordinate dimensions.
Definition: shape.hpp:39
Shape(std::vector< DimT > dims)
Definition: shape.hpp:75
std::string to_string(teq::CoordptrT c)
Return brief hashable string representation of coordinate mapper.
Shape & operator=(const Shape &other)=default
uint16_t DimT
Type used for shape dimension.
Definition: shape.hpp:31
ShapeT dims_
Array of dimension values.
Definition: shape.hpp:205
void vector_assign(const std::vector< DimT > &dims)
Definition: shape.hpp:180
bool compatible_before(const Shape &other, RankT idx) const
Definition: shape.hpp:127
Shape(void)
Definition: shape.hpp:70
std::array< DimT, rank_cap > ShapeT
Array type used to hold dimension info in Shape.
Definition: shape.hpp:50
ShapeT::iterator iterator
Type of iterator used to iterate through internal array.
Definition: shape.hpp:65
EigenptrT< T > min(teq::Shape &outshape, const OpArg< T > &a, const OpArg< T > &b)
Definition: operator.hpp:939
Definition: coord.hpp:16
NElemT index(Shape shape, CoordT coord)
iterator end(void)
Return end iterator of internal array.
Definition: shape.hpp:162
iterator begin(void)
Return begin iterator of internal array.
Definition: shape.hpp:156
const_iterator end(void) const
Return end constant iterator of internal array.
Definition: shape.hpp:174
DimT at(RankT idx) const
Return DimT element at idx for any index in range [0:rank_cap)
Definition: shape.hpp:108
NElemT n_elems(void) const
Return the total number of elements represented by the shape.
Definition: shape.hpp:118
CoordT coordinate(Shape shape, NElemT idx)