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 : };