SpinParser  1.0
ValueBundle.hpp
Go to the documentation of this file.
1 
9 #pragma once
10 #include <cstring>
11 
17 template <class T> struct ValueBundle
18 {
19 public:
23  ValueBundle() : _data(nullptr), _size(0) {}
24 
31  ValueBundle(T *data, const int size) : _data(data), _size(size) {}
32 
40  {
41  _size = rhs._size;
42  _data = rhs._data;
43  return *this;
44  }
45 
52  T &operator[](const int n)
53  {
54  return _data[n];
55  }
56 
62  int size() const
63  {
64  return _size;
65  }
66 
72  T *data() const
73  {
74  return _data;
75  }
76 
84  ValueBundle &multAdd(const T &rhs1, const ValueBundle<T> &rhs2)
85  {
86  for (int i = 0; i < _size; ++i) _data[i] += rhs1 * rhs2._data[i];
87  return *this;
88  }
89 
97  ValueBundle &multAdd(const ValueBundle<T> &rhs1, const T &rhs2)
98  {
99  return multAdd(rhs2, rhs1);
100  }
101 
110  {
111  for (int i = 0; i < _size; ++i) _data[i] += rhs1._data[i] * rhs2._data[i];
112  return *this;
113  }
114 
123  ValueBundle &multAdd(const T &rhs1, const ValueBundle<T> &rhs2, const ValueBundle<T> &rhs3)
124  {
125  for (int i = 0; i < _size; ++i) _data[i] += rhs1 * rhs2._data[i] * rhs3._data[i];
126  return *this;
127  }
128 
136  ValueBundle &multSub(const T &rhs1, const ValueBundle<T> &rhs2)
137  {
138  for (int i = 0; i < _size; ++i) _data[i] -= rhs1 * rhs2._data[i];
139  return *this;
140  }
141 
149  ValueBundle &multSub(const ValueBundle<T> &rhs1, const T &rhs2)
150  {
151  return multSub(rhs2, rhs1);
152  }
153 
162  {
163  for (int i = 0; i < _size; ++i) _data[i] -= rhs1._data[i] * rhs2._data[i];
164  return *this;
165  }
166 
175  ValueBundle &multSub(const T &rhs1, const ValueBundle<T> &rhs2, const ValueBundle<T> &rhs3)
176  {
177  for (int i = 0; i < _size; ++i) _data[i] -= rhs1 * rhs2._data[i] * rhs3._data[i];
178  return *this;
179  }
180 
188  {
189  for (int i = 0; i < _size; ++i) _data[i] += rhs._data[i];
190  return *this;
191  }
192 
200  {
201  for (int i = 0; i < _size; ++i) _data[i] -= rhs._data[i];
202  return *this;
203  }
204 
211  ValueBundle &operator*=(const T &rhs)
212  {
213  for (int i = 0; i < _size; ++i) _data[i] *= rhs;
214  return *this;
215  }
216 
223  ValueBundle &operator/=(const T &rhs)
224  {
225  for (int i = 0; i < _size; ++i) _data[i] /= rhs;
226  return *this;
227  }
228 
229 private:
230  T *_data;
231  int _size;
232 };
233 
240 template <class T, int n> struct ValueSuperbundle
241 {
242 public:
248  ValueSuperbundle(const int bundleSize) : hasOwnership(true)
249  {
250  for (int i = 0; i < n; ++i) bundles[i] = ValueBundle<T>(new T[bundleSize], bundleSize);
251  reset();
252  }
253 
259  ValueSuperbundle(const ValueSuperbundle &rhs) : hasOwnership(false)
260  {
261  for (int i = 0; i < n; ++i) bundles[i] = ValueBundle<T>(rhs.bundles[i].data(), rhs.bundles[i].size());
262  }
263 
268  {
269  if (hasOwnership)
270  {
271  for (int i = 0; i < n; ++i) delete[] bundles[i].data();
272  }
273  }
274 
281  ValueBundle<T> &bundle(const int m)
282  {
283  return bundles[m];
284  }
285 
292  {
293  for (int i = 0; i < n; ++i) memset(bundles[i].data(), 0, bundles[i].size() * sizeof(T));
294  return *this;
295  }
296 
304  ValueSuperbundle &multAdd(const T &rhs1, const ValueSuperbundle<T, n> &rhs2)
305  {
306  for (int i = 0; i < n; ++i) bundles[i].multAdd(rhs1, rhs2.bundles[i]);
307  return *this;
308  }
309 
317  {
318  for (int i = 0; i < n; ++i) bundles[i] *= rhs;
319  return *this;
320  }
321 
329  {
330  for (int i = 0; i < n; ++i) bundles[i] /= rhs;
331  return *this;
332  }
333 
341  {
342  for (int i = 0; i < n; ++i) bundles[i] += rhs.bundles[i];
343  return *this;
344  }
345 
346 private:
347  ValueBundle<T> bundles[n];
348  bool hasOwnership;
349 };
ValueBundle::multSub
ValueBundle & multSub(const T &rhs1, const ValueBundle< T > &rhs2)
Fused multiply-sub, equivalent to operator-=(rhs1 * rhs2).
Definition: ValueBundle.hpp:136
ValueSuperbundle::operator/=
ValueSuperbundle & operator/=(const T &rhs)
Division assignment.
Definition: ValueBundle.hpp:328
ValueBundle::operator-=
ValueBundle & operator-=(const ValueBundle &rhs)
Subtraction assignment.
Definition: ValueBundle.hpp:199
ValueSuperbundle::multAdd
ValueSuperbundle & multAdd(const T &rhs1, const ValueSuperbundle< T, n > &rhs2)
Fused multiply-add on all ValueBundles.
Definition: ValueBundle.hpp:304
ValueBundle::ValueBundle
ValueBundle()
Construct an empty ValueBundle object.
Definition: ValueBundle.hpp:23
ValueBundle::multAdd
ValueBundle & multAdd(const ValueBundle< T > &rhs1, const ValueBundle< T > &rhs2)
Elementwise fused multiply-add. Equivalent to elementwise operator+=(rhs1 * rhs2).
Definition: ValueBundle.hpp:109
ValueSuperbundle::operator*=
ValueSuperbundle & operator*=(const T &rhs)
Multiplication assignent.
Definition: ValueBundle.hpp:316
ValueBundle::operator[]
T & operator[](const int n)
Access the nth value stored in the value bundle.
Definition: ValueBundle.hpp:52
ValueBundle
Value array implementation. The object does not hold ownership of its memory.
Definition: ValueBundle.hpp:17
ValueBundle::ValueBundle
ValueBundle(T *data, const int size)
Construct a new ValueBundle object.
Definition: ValueBundle.hpp:31
ValueSuperbundle::~ValueSuperbundle
~ValueSuperbundle()
Destroy the ValueSuperbundle object.
Definition: ValueBundle.hpp:267
ValueBundle::data
T * data() const
Retrieve the pointer to the first value stored in the bundle.
Definition: ValueBundle.hpp:72
ValueBundle::multAdd
ValueBundle & multAdd(const ValueBundle< T > &rhs1, const T &rhs2)
Fused multiply-add for scalar right-multiplication, equivalent to operator+=(rhs1 * rhs2).
Definition: ValueBundle.hpp:97
ValueSuperbundle::operator+=
ValueSuperbundle & operator+=(const ValueSuperbundle< T, n > &rhs)
Addition assignment.
Definition: ValueBundle.hpp:340
ValueBundle::operator=
ValueBundle & operator=(const ValueBundle< T > &rhs)
Assignment operator.
Definition: ValueBundle.hpp:39
ValueBundle::multSub
ValueBundle & multSub(const ValueBundle< T > &rhs1, const ValueBundle< T > &rhs2)
Elementwise fused multiply-sub. Equivalent to elementwise operator-=(rhs1 * rhs2).
Definition: ValueBundle.hpp:161
ValueBundle::multAdd
ValueBundle & multAdd(const T &rhs1, const ValueBundle< T > &rhs2)
Fused multiply-add, equivalent to operator+=(rhs1 * rhs2).
Definition: ValueBundle.hpp:84
ValueSuperbundle::bundle
ValueBundle< T > & bundle(const int m)
Return reference to ValueBundle.
Definition: ValueBundle.hpp:281
ValueBundle::operator+=
ValueBundle & operator+=(const ValueBundle &rhs)
Addition assignment.
Definition: ValueBundle.hpp:187
ValueBundle::multSub
ValueBundle & multSub(const ValueBundle< T > &rhs1, const T &rhs2)
Fused multiply-sub for scalar right-multiplication, equivalent to operator-=(rhs1 * rhs2).
Definition: ValueBundle.hpp:149
ValueBundle::operator*=
ValueBundle & operator*=(const T &rhs)
Multiplication assignment.
Definition: ValueBundle.hpp:211
ValueSuperbundle::ValueSuperbundle
ValueSuperbundle(const int bundleSize)
Construct a new ValueSuperbundle object and allocate ValueBundles.
Definition: ValueBundle.hpp:248
ValueBundle::operator/=
ValueBundle & operator/=(const T &rhs)
Division assignment.
Definition: ValueBundle.hpp:223
ValueBundle::size
int size() const
Retrieve the number of elements in the value bundle.
Definition: ValueBundle.hpp:62
ValueSuperbundle::reset
ValueSuperbundle & reset()
Write zeros to all ValueBundles.
Definition: ValueBundle.hpp:291
ValueBundle::multSub
ValueBundle & multSub(const T &rhs1, const ValueBundle< T > &rhs2, const ValueBundle< T > &rhs3)
Elementwise double-multiply sub. Equivalent to elementwise operator-=(rhs1 * rhs2 * rhs3).
Definition: ValueBundle.hpp:175
ValueSuperbundle
Collection of ValueBundles.
Definition: ValueBundle.hpp:240
ValueSuperbundle::ValueSuperbundle
ValueSuperbundle(const ValueSuperbundle &rhs)
Copy constructor. The copy will not have ownership of the ValueBundle memory.
Definition: ValueBundle.hpp:259
ValueBundle::multAdd
ValueBundle & multAdd(const T &rhs1, const ValueBundle< T > &rhs2, const ValueBundle< T > &rhs3)
Elementwise double-multiply add. Equivalent to elementwise operator+=(rhs1 * rhs2 * rhs3).
Definition: ValueBundle.hpp:123