Line data Source code
1 1 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : /// \file
5 : /// `blaze::CompressedVector` is a general-purpose sparse vector type. This file
6 : /// implements interoperability of `blaze::CompressedVector` with our data
7 : /// structures.
8 :
9 : #pragma once
10 :
11 : #include <blaze/math/CompressedVector.h>
12 : #include <cstddef>
13 : #include <pup.h>
14 : #include <vector>
15 :
16 : #include "Utilities/Gsl.hpp"
17 :
18 : /// \cond
19 : namespace Options {
20 : struct Option;
21 : template <typename T>
22 : struct create_from_yaml;
23 : } // namespace Options
24 : /// \endcond
25 :
26 : namespace PUP {
27 : /// @{
28 : /// Serialization of blaze::CompressedVector
29 : template <typename T, bool TF, typename Tag>
30 : void pup(er& p, blaze::CompressedVector<T, TF, Tag>& t) {
31 : size_t size = t.size();
32 : p | size;
33 : size_t num_non_zeros = t.nonZeros();
34 : p | num_non_zeros;
35 : // blaze::CompressedVector has no `.data()` access, so we use the low-level
36 : // `append` mechanism for serialization instead of `PUParray`. Maybe there's
37 : // an even faster way using PUPbytes.
38 : size_t index;
39 : if (p.isUnpacking()) {
40 : t.resize(size);
41 : t.reserve(num_non_zeros);
42 : T value;
43 : for (size_t i = 0; i < num_non_zeros; ++i) {
44 : p | index;
45 : p | value;
46 : t.append(index, value);
47 : }
48 : } else {
49 : for (auto it = t.begin(); it != t.end(); ++it) {
50 : index = it->index();
51 : p | index;
52 : p | it->value();
53 : }
54 : }
55 : }
56 : template <typename T, bool TF, typename Tag>
57 : void operator|(er& p, blaze::CompressedVector<T, TF, Tag>& t) {
58 : pup(p, t);
59 : }
60 : /// @}
61 : } // namespace PUP
62 :
63 : namespace CompressedVector_detail {
64 : template <typename T>
65 : std::vector<T> parse_to_vector(const Options::Option& options);
66 : } // namespace CompressedVector_detail
67 :
68 : template <typename T, bool TF, typename Tag>
69 0 : struct Options::create_from_yaml<blaze::CompressedVector<T, TF, Tag>> {
70 : template <typename Metavariables>
71 0 : static blaze::CompressedVector<T, TF, Tag> create(
72 : const Options::Option& options) {
73 : const auto data = CompressedVector_detail::parse_to_vector<T>(options);
74 : blaze::CompressedVector<T, TF, Tag> result(data.size());
75 : // Insert only non-zero elements. Can't use iterators and `std::copy`
76 : // because for sparse types the iterators only run over non-zero elements.
77 : // There's probably a faster way to do this construction using the low-level
78 : // `append` function, but it's probably not worth the effort for small
79 : // matrices created in input files.
80 : for (size_t i = 0; i < data.size(); ++i) {
81 : if (gsl::at(data, i) != 0.) {
82 : result[i] = gsl::at(data, i);
83 : }
84 : }
85 : return result;
86 : }
87 : };
|