27 #include <flatbuffers/flatbuffers.h>
28 #include <fmt/format.h>
40 template <
typename UnsignedIntegralType,
41 typename = std::enable_if_t<std::is_unsigned_v<UnsignedIntegralType>>>
42 std::vector<UnsignedIntegralType>
RandomVector(std::size_t length) {
43 const auto byte_size =
sizeof(UnsignedIntegralType) * length;
44 std::vector<UnsignedIntegralType> vec(length);
47 rng.RandomBytes(
reinterpret_cast<std::byte*
>(vec.data()), byte_size);
55 template <
typename UnsignedIntegralType,
56 typename = std::enable_if_t<std::is_unsigned_v<UnsignedIntegralType>>>
57 inline std::vector<std::uint8_t>
ToByteVector(
const std::vector<UnsignedIntegralType>& values) {
58 std::vector<std::uint8_t> result(
reinterpret_cast<const std::uint8_t*
>(values.data()),
59 reinterpret_cast<const std::uint8_t*
>(values.data()) +
60 sizeof(UnsignedIntegralType) * values.size());
67 template <
typename UnsignedIntegralType,
68 typename = std::enable_if_t<std::is_unsigned_v<UnsignedIntegralType>>>
69 inline std::vector<UnsignedIntegralType>
FromByteVector(
const std::vector<std::uint8_t>& buffer) {
70 assert(buffer.size() %
sizeof(UnsignedIntegralType) ==
72 std::vector<UnsignedIntegralType> result(
sizeof(UnsignedIntegralType) * buffer.size());
73 std::copy(buffer.data(), buffer.data() + buffer.size(),
74 reinterpret_cast<std::uint8_t*
>(result.data()));
81 template <
typename UnsignedIntegralType,
82 typename = std::enable_if_t<std::is_unsigned_v<UnsignedIntegralType>>>
84 const flatbuffers::Vector<std::uint8_t>& buffer) {
85 assert(buffer.size() %
sizeof(UnsignedIntegralType) ==
87 std::vector<UnsignedIntegralType> result(buffer.size() /
sizeof(UnsignedIntegralType));
88 std::copy(buffer.data(), buffer.data() + buffer.size(),
89 reinterpret_cast<std::uint8_t*
>(result.data()));
100 inline std::vector<T>
AddVectors(
const std::vector<T>& a,
const std::vector<T>& b) {
101 assert(a.size() == b.size());
105 std::vector<T> result = a;
107 for (
auto j = 0ull; j < result.size(); ++j) {
108 result.at(j) += b.at(j);
119 template <
typename T>
120 inline std::vector<T>
SubVectors(
const std::vector<T>& a,
const std::vector<T>& b) {
121 assert(a.size() == b.size());
125 std::vector<T> result = a;
126 for (
auto j = 0ull; j < result.size(); ++j) {
127 result.at(j) -= b.at(j);
138 template <
typename T>
140 assert(a.size() == b.size());
144 std::vector<T> result = a;
146 for (
auto j = 0ull; j < result.size(); ++j) {
147 result.at(j) *= b.at(j);
158 template <
typename T>
159 inline std::vector<T>
AddVectors(std::vector<std::vector<T>>& vectors) {
160 if (vectors.size() == 0) {
164 std::vector<T> result = vectors.at(0);
166 for (
auto i = 1ull; i < vectors.size(); ++i) {
167 auto& inner_vector = vectors.at(i);
168 assert(inner_vector.size() == result.size());
169 for (
auto j = 0ull; j < result.size(); ++j) {
170 result.at(j) += inner_vector.at(j);
182 template <
typename T>
183 inline std::vector<T>
AddVectors(std::vector<std::vector<T>>&& vectors) {
196 template <
typename T>
198 assert(a.size() == b.size());
202 std::vector<T> result(a.size());
203 const T* __restrict__ a_pointer{a.data()};
204 const T* __restrict__ b_pointer{b.data()};
205 T* __restrict__ result_pointer{result.data()};
206 std::transform(a_pointer, a_pointer + a.size(), b_pointer, result_pointer,
207 [](
const T& a_value,
const T& b_value) { return a_value + b_value; });
218 template <
typename T>
220 assert(a.size() == b.size());
224 std::vector<T> result(a.size());
225 const T* __restrict__ a_pointer{a.data()};
226 const T* __restrict__ b_pointer{b.data()};
227 T* __restrict__ result_pointer{result.data()};
228 std::transform(a_pointer, a_pointer + a.size(), b_pointer, result_pointer,
229 [](
const T& a_value,
const T& b_value) { return a_value - b_value; });
240 template <
typename T>
242 assert(a.size() == b.size());
246 std::vector<T> result(a.size());
247 const T* __restrict__ a_pointer{a.data()};
248 const T* __restrict__ b_pointer{b.data()};
249 T* __restrict__ result_pointer{result.data()};
250 std::transform(a_pointer, a_pointer + a.size(), b_pointer, result_pointer,
251 [](
const T& a_value,
const T& b_value) { return a_value * b_value; });
258 template <
typename T>
260 if (values.size() == 0) {
262 }
else if (values.size() == 1) {
266 #pragma omp parallel for reduction(+ : sum) default(none) shared(values)
267 for (
auto i = 0ull; i < values.size(); ++i) {
277 template <
typename T>
279 if (values.size() == 0) {
282 T result = values.at(0);
283 for (
auto i = 1ull; i < values.size(); ++i) {
284 result -= values.at(i);
293 template <
typename T>
295 if (values.size() == 0) {
298 T product = values.at(0);
299 for (
auto i = 1ull; i < values.size(); ++i) {
300 product *= values.at(i);
316 template <
typename T>
318 if (values.size() == 0) {
321 std::vector<T> sum(values.at(0).size());
322 for (
auto i = 1ull; i < values.size(); ++i) {
323 assert(values.at(0).size() == values.at(i).size());
326 for (
auto i = 0ull; i < sum.size(); ++i) {
327 for (
auto j = 0ull; j < values.size(); ++j) {
328 sum.at(i) += values.at(j).at(i);
331 return std::move(sum);
345 template <
typename T>
347 if (values.size() == 0) {
350 std::vector<T> result = values.at(0);
351 for (
auto i = 1ull; i < values.size(); ++i) {
352 assert(values.at(0).size() == values.at(i).size());
355 for (
auto i = 0ull; i < result.size(); ++i) {
356 for (
auto j = 1ull; j < values.size(); ++j) {
357 result.at(i) -= values.at(j).at(i);
360 return std::move(result);
374 template <
typename T>
376 if (values.size() == 0) {
379 std::vector<T> product(values.at(0).size(), 1);
380 for (
auto i = 1ull; i < values.size(); ++i) {
381 assert(values.at(0).size() == values.at(i).size());
384 for (
auto i = 0ull; i < product.size(); ++i) {
385 for (
auto j = 0ull; j < values.size(); ++j) {
386 product.at(i) *= values.at(j).at(i);
389 return std::move(product);
396 template <
typename UnsignedIntegralType,
397 typename = std::enable_if_t<std::is_unsigned_v<UnsignedIntegralType>>>
399 return x > 0 && (!(x & (x - 1)));
405 inline std::string
Hex(
const std::uint8_t* values, std::size_t n) {
407 for (
auto i = 0ull; i < n; ++i) {
408 buffer.append(fmt::format(
"{0:#x} ", values[i]));
410 buffer.erase(buffer.end() - 1);
417 inline std::string
Hex(
const std::byte* values, std::size_t n) {
418 return Hex(
reinterpret_cast<const std::uint8_t*
>(values), n);
423 template <std::
size_t N>
424 inline std::string
Hex(
const std::array<std::byte, N>& values) {
425 return Hex(
reinterpret_cast<const std::uint8_t*
>(values.data()), values.size());
430 template <std::
size_t N>
431 inline std::string
Hex(
const std::array<std::uint8_t, N>& values) {
432 return Hex(values.data(), values.size());
437 inline std::string
Hex(
const std::vector<std::uint8_t>& values) {
438 return Hex(values.data(), values.size());
443 inline std::string
Hex(
const std::vector<std::byte>& values) {
444 return Hex(values.data(), values.size());
449 inline std::string
Hex(
const std::vector<std::uint8_t>&& values) {
return Hex(values); }
454 template <
typename T>
458 for (
auto& v : values) {
466 template <
typename T>
467 inline bool Vectors(
const std::vector<T>& a,
const std::vector<T>& b) {
468 if (a.size() != b.size()) {
471 for (
auto i = 0ull; i < a.size(); ++i) {
472 if (a.at(i) != b.at(i)) {
481 template <
typename T>
482 inline bool Dimensions(
const std::vector<std::vector<T>>& values) {
483 if (values.size() <= 1) {
486 auto first_size = values.at(0).size();
487 for (
auto i = 1ull; i < values.size(); ++i) {
488 if (first_size != values.at(i).size()) {
500 std::size_t
DivideAndCeil(std::size_t dividend, std::size_t divisor);
504 constexpr std::size_t
BitsToBytes(
const std::size_t bits) {
return (bits + 7) / 8; }