https://mooseframework.inl.gov
RayTracingPackingUtils.h
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #pragma once
11 
12 #include "libmesh/elem.h"
13 #include "libmesh/mesh_base.h"
14 
16 {
17 
21 template <class Cont, class InputIt>
22 void unpackCopy(Cont & container, InputIt & input_iterator);
23 
32 template <typename BufferType, typename BufferIter, typename ValueType>
33 void reinterpretPackCopy(const std::vector<ValueType> & values, BufferIter & out);
34 
42 template <typename BufferType, typename BufferIter, typename ValueType>
43 void reinterpretUnpackCopy(std::vector<ValueType> & values, BufferIter & in);
44 
51 template <typename ValueType, typename BufferType>
52 std::size_t reinterpretCopySize(const std::size_t input_size);
53 
57 template <typename BufferType, typename BufferIter, typename... ValueTypes>
58 void mixedUnpack(BufferIter & in, ValueTypes &... values);
59 
65 template <typename BufferType, typename BufferIter, typename... ValueTypes>
66 void mixedPack(BufferIter & out, ValueTypes const &... values);
67 
74 template <typename BufferType, typename... InputTypes>
75 constexpr std::size_t mixedPackSize();
76 
81 template <typename BufferType, typename ValueType>
82 BufferType pack(const ValueType value);
83 
87 template <typename BufferType, typename ValueType>
88 void unpack(const BufferType value_as_buffer_type, ValueType & value);
89 
94 template <typename BufferType>
95 BufferType pack(const Elem * elem, MeshBase * mesh_base = nullptr);
96 
100 template <typename BufferType>
101 void unpack(const Elem *& elem, const BufferType id_as_buffer_type, MeshBase * mesh_base);
102 
103 namespace detail
104 {
105 
112 template <typename BufferType>
113 constexpr std::size_t
114 mixedPackSizeHelper(const std::size_t offset, const std::size_t size)
115 {
116  return offset ? size + 1 : size;
117 }
118 
125 template <typename BufferType, typename InputType, typename... Rest>
126 constexpr std::size_t
127 mixedPackSizeHelper(std::size_t offset, std::size_t size)
128 {
129  return offset + sizeof(InputType) > sizeof(BufferType)
130  ? mixedPackSizeHelper<BufferType, Rest...>(sizeof(InputType), ++size)
131  : mixedPackSizeHelper<BufferType, Rest...>(offset + sizeof(InputType), size);
132 }
133 
137 template <typename BufferType, typename BufferIter, typename ValueType>
138 void
139 mixedUnpackHelper(BufferIter & in,
140  const BufferType *& src,
141  std::size_t & src_offset,
142  ValueType & output)
143 {
144  static_assert(sizeof(ValueType) <= sizeof(BufferType), "ValueType will not fit into BufferType");
145 
146  if (src_offset + sizeof(ValueType) > sizeof(BufferType))
147  {
148  src = &(*in++);
149  src_offset = 0;
150  }
151 
152  std::memcpy(&output, (char *)src + src_offset, sizeof(ValueType));
153  src_offset += sizeof(ValueType);
154 }
155 
159 template <typename BufferIter, typename BufferType, typename ValueType>
160 void
161 mixedPackHelper(BufferIter & out,
162  BufferType & dest,
163  std::size_t & dest_offset,
164  const ValueType & input)
165 {
166  static_assert(sizeof(ValueType) <= sizeof(BufferType), "ValueType will not fit into BufferType");
167 
168  if (dest_offset + sizeof(ValueType) > sizeof(BufferType))
169  {
170  out++ = dest;
171  dest_offset = 0;
172  }
173 
174  std::memcpy((char *)&dest + dest_offset, &input, sizeof(ValueType));
175  dest_offset += sizeof(ValueType);
176 }
177 }
178 
179 template <class Cont, class InputIt>
180 void
181 unpackCopy(Cont & container, InputIt & input_iterator)
182 {
183  auto first = container.begin();
184  while (first != container.end())
185  *first++ = *input_iterator++;
186 }
187 
188 template <typename BufferType, typename BufferIter, typename ValueType>
189 void
190 reinterpretPackCopy(const std::vector<ValueType> & values, BufferIter & out)
191 {
192  static_assert(sizeof(ValueType) <= sizeof(BufferType), "ValueType will not fit into BufferType");
193 
194  BufferType dest;
195  const ValueType * src = values.data();
196 
197  std::size_t dest_offset = 0;
198  for (std::size_t i = 0; i < values.size(); ++i)
199  {
200  if (dest_offset + sizeof(ValueType) > sizeof(BufferType))
201  {
202  out++ = dest;
203  dest_offset = 0;
204  }
205 
206  std::memcpy((char *)&dest + dest_offset, &src[i], sizeof(ValueType));
207  dest_offset += sizeof(ValueType);
208  }
209 
210  if (dest_offset)
211  out++ = dest;
212 }
213 
214 template <typename BufferType, typename BufferIter, typename ValueType>
215 void
216 reinterpretUnpackCopy(std::vector<ValueType> & values, BufferIter & in)
217 {
218  static_assert(sizeof(ValueType) <= sizeof(BufferType), "ValueType will not fit into BufferType");
219 
220  ValueType * dest = values.data();
221  const BufferType * src = nullptr;
222 
223  std::size_t src_offset = sizeof(BufferType);
224  for (std::size_t i = 0; i < values.size(); ++i)
225  {
226  if (src_offset + sizeof(ValueType) > sizeof(BufferType))
227  {
228  src = &(*in++);
229  src_offset = 0;
230  }
231 
232  std::memcpy(&dest[i], (char *)src + src_offset, sizeof(ValueType));
233  src_offset += sizeof(ValueType);
234  }
235 }
236 
237 template <typename ValueType, typename BufferType>
238 std::size_t
239 reinterpretCopySize(const std::size_t input_size)
240 {
241  const double input_per_output = std::floor(sizeof(BufferType) / sizeof(ValueType));
242  return (std::size_t)std::ceil((double)input_size / input_per_output);
243 }
244 
245 template <typename BufferType, typename BufferIter, typename... ValueTypes>
246 void
247 mixedUnpack(BufferIter & in, ValueTypes &... values)
248 {
249  std::size_t src_offset = sizeof(BufferType);
250  const BufferType * src = nullptr;
251 
252  int expander[] = {
253  0,
254  ((void)detail::mixedUnpackHelper(in, src, src_offset, std::forward<ValueTypes &>(values)),
255  0)...};
256  (void)expander;
257 }
258 
259 template <typename BufferType, typename BufferIter, typename... ValueTypes>
260 void
261 mixedPack(BufferIter & out, ValueTypes const &... values)
262 {
263  std::size_t dest_offset = 0;
264  BufferType dest;
265 
266  int expander[] = {0,
268  out, dest, dest_offset, std::forward<ValueTypes const &>(values)),
269  0)...};
270  (void)expander;
271 
272  if (dest_offset)
273  out++ = dest;
274 }
275 
276 template <typename BufferType, typename... InputTypes>
277 constexpr std::size_t
279 {
280  // Call the recursive helper with an initial offset and size of 0
281  return detail::mixedPackSizeHelper<BufferType, InputTypes...>(/* offset = */ 0, /* size = */ 0);
282 }
283 
284 template <typename BufferType, typename ValueType>
285 BufferType
286 pack(const ValueType value)
287 {
288  static_assert(sizeof(ValueType) <= sizeof(BufferType), "Value will won't fit into buffer type");
289 
290  BufferType value_as_buffer_type;
291  std::memcpy(&value_as_buffer_type, &value, sizeof(ValueType));
292  return value_as_buffer_type;
293 }
294 
295 template <typename BufferType, typename ValueType>
296 void
297 unpack(const BufferType value_as_buffer_type, ValueType & value)
298 {
299  static_assert(sizeof(ValueType) <= sizeof(BufferType), "Value will won't fit into buffer type");
300  std::memcpy(&value, &value_as_buffer_type, sizeof(ValueType));
301 }
302 
303 template <typename BufferType>
304 BufferType
305 pack(const Elem * elem, MeshBase * libmesh_dbg_var(mesh_base /* = nullptr */))
306 {
307  const dof_id_type id = elem ? elem->id() : libMesh::DofObject::invalid_id;
308  mooseAssert(mesh_base ? mesh_base->query_elem_ptr(id) == elem : true,
309  "Elem doesn't exist in mesh");
310 
311  return pack<BufferType>(id);
312 }
313 
314 template <typename BufferType>
315 void
316 unpack(const Elem *& elem, const BufferType id_as_buffer_type, MeshBase * mesh_base)
317 {
318  dof_id_type id;
319  unpack<BufferType>(id_as_buffer_type, id);
320 
321  elem = (id == libMesh::DofObject::invalid_id ? nullptr : mesh_base->query_elem_ptr(id));
322 }
323 }
void mixedPackHelper(BufferIter &out, BufferType &dest, std::size_t &dest_offset, const ValueType &input)
Helper for mixedPack()
BufferType pack(const ValueType value)
Packs value into a value of type BufferType at a byte level, to be unpacked with the unpack() routine...
void reinterpretUnpackCopy(std::vector< ValueType > &values, BufferIter &in)
Packs the data from in into the vector values.
constexpr std::size_t mixedPackSize()
Gets the number of BufferType required to store the expanded InputTypes for use with mixedPack() and ...
void unpack(const BufferType value_as_buffer_type, ValueType &value)
Unpacks value_as_buffer_type (which is packed with pack()) into value at a byte level.
constexpr std::size_t mixedPackSizeHelper(const std::size_t offset, const std::size_t size)
Helper for mixedPackSize().
void mixedUnpack(BufferIter &in, ValueTypes &... values)
Unpacks the mixed-values from in into values that were packed with mixedPack().
void mixedUnpackHelper(BufferIter &in, const BufferType *&src, std::size_t &src_offset, ValueType &output)
Helper for mixedUnpack()
std::size_t reinterpretCopySize(const std::size_t input_size)
Gets the minimum number of values of BufferType needed to represent input_size values of ValueType...
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
static const dof_id_type invalid_id
void mixedPack(BufferIter &out, ValueTypes const &... values)
Packs the mixed-type values in values into out to be unpacked with mixedUnpack(). ...
OStreamProxy out
class infix_ostream_iterator if void
void unpackCopy(Cont &container, InputIt &input_iterator)
Like std::copy, but passes the input iterator by reference.
void reinterpretPackCopy(const std::vector< ValueType > &values, BufferIter &out)
Packs the data in values into the iterator out and minimizes memory storage in said iterator...
uint8_t dof_id_type