https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
21template <class Cont, class InputIt>
22void unpackCopy(Cont & container, InputIt & input_iterator);
23
32template <typename BufferType, typename BufferIter, typename ValueType>
33void reinterpretPackCopy(const std::vector<ValueType> & values, BufferIter & out);
34
42template <typename BufferType, typename BufferIter, typename ValueType>
43void reinterpretUnpackCopy(std::vector<ValueType> & values, BufferIter & in);
44
51template <typename ValueType, typename BufferType>
52std::size_t reinterpretCopySize(const std::size_t input_size);
53
57template <typename BufferType, typename BufferIter, typename... ValueTypes>
58void mixedUnpack(BufferIter & in, ValueTypes &... values);
59
65template <typename BufferType, typename BufferIter, typename... ValueTypes>
66void mixedPack(BufferIter & out, ValueTypes const &... values);
67
74template <typename BufferType, typename... InputTypes>
75constexpr std::size_t mixedPackSize();
76
81template <typename BufferType, typename ValueType>
82BufferType pack(const ValueType value);
83
87template <typename BufferType, typename ValueType>
88void unpack(const BufferType value_as_buffer_type, ValueType & value);
89
94template <typename BufferType>
95BufferType pack(const Elem * elem, MeshBase * mesh_base = nullptr);
96
100template <typename BufferType>
101void unpack(const Elem *& elem, const BufferType id_as_buffer_type, MeshBase * mesh_base);
102
103namespace detail
104{
105
112template <typename BufferType>
113constexpr std::size_t
114mixedPackSizeHelper(const std::size_t offset, const std::size_t size)
115{
116 return offset ? size + 1 : size;
117}
118
125template <typename BufferType, typename InputType, typename... Rest>
126constexpr std::size_t
127mixedPackSizeHelper(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
137template <typename BufferType, typename BufferIter, typename ValueType>
138void
139mixedUnpackHelper(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
159template <typename BufferIter, typename BufferType, typename ValueType>
160void
161mixedPackHelper(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
179template <class Cont, class InputIt>
180void
181unpackCopy(Cont & container, InputIt & input_iterator)
182{
183 auto first = container.begin();
184 while (first != container.end())
185 *first++ = *input_iterator++;
186}
187
188template <typename BufferType, typename BufferIter, typename ValueType>
189void
190reinterpretPackCopy(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
214template <typename BufferType, typename BufferIter, typename ValueType>
215void
216reinterpretUnpackCopy(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
237template <typename ValueType, typename BufferType>
238std::size_t
239reinterpretCopySize(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
245template <typename BufferType, typename BufferIter, typename... ValueTypes>
246void
247mixedUnpack(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
259template <typename BufferType, typename BufferIter, typename... ValueTypes>
260void
261mixedPack(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
276template <typename BufferType, typename... InputTypes>
277constexpr 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
284template <typename BufferType, typename ValueType>
285BufferType
286pack(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
295template <typename BufferType, typename ValueType>
296void
297unpack(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
303template <typename BufferType>
304BufferType
305pack(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
314template <typename BufferType>
315void
316unpack(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}
std::array< Real, 2 > values
static constexpr dof_id_type invalid_id
constexpr std::size_t mixedPackSizeHelper(const std::size_t offset, const std::size_t size)
Helper for mixedPackSize().
void mixedUnpackHelper(BufferIter &in, const BufferType *&src, std::size_t &src_offset, ValueType &output)
Helper for mixedUnpack()
void mixedPackHelper(BufferIter &out, BufferType &dest, std::size_t &dest_offset, const ValueType &input)
Helper for mixedPack()
void mixedUnpack(BufferIter &in, ValueTypes &... values)
Unpacks the mixed-values from in into values that were packed with 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...
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.
void mixedPack(BufferIter &out, ValueTypes const &... values)
Packs the mixed-type values in values into out to be unpacked with mixedUnpack().
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 reinterpretPackCopy(const std::vector< ValueType > &values, BufferIter &out)
Packs the data in values into the iterator out and minimizes memory storage in said iterator.
void unpackCopy(Cont &container, InputIt &input_iterator)
Like std::copy, but passes the input iterator by reference.
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.