SimiLie
Loading...
Searching...
No Matches
csr_dynamic.hpp
1// SPDX-FileCopyrightText: 2024 Baptiste Legouix
2// SPDX-License-Identifier: MIT
3
4#pragma once
5
6#include <fstream>
7
8#include <ddc/ddc.hpp>
9
10#include <similie/tensor/tensor_impl.hpp>
11
12namespace sil {
13
14namespace csr {
15
16// Only natural indexing supported
17template <tensor::TensorIndex HeadTensorIndex, tensor::TensorNatIndex... TailTensorIndex>
19{
20private:
21 ddc::DiscreteDomain<HeadTensorIndex, TailTensorIndex...> m_domain;
22 std::vector<std::size_t> m_coalesc_idx;
23 std::array<std::vector<std::size_t>, sizeof...(TailTensorIndex)> m_idx;
24 std::vector<double> m_values;
25
26public:
27 CsrDynamic(ddc::DiscreteDomain<HeadTensorIndex, TailTensorIndex...> domain)
28 : m_domain(domain)
29 , m_coalesc_idx({0})
30 , m_idx()
31 , m_values()
32 {
33 }
34
36 ddc::DiscreteDomain<HeadTensorIndex, TailTensorIndex...> domain,
37 std::vector<std::size_t> coalesc_idx,
38 std::array<std::vector<std::size_t>, sizeof...(TailTensorIndex)> idx,
39 std::vector<double> values)
40 : m_domain(domain)
41 , m_coalesc_idx(coalesc_idx)
42 , m_idx(idx)
43 , m_values(values)
44 {
45 }
46
47 ddc::DiscreteDomain<HeadTensorIndex, TailTensorIndex...> domain()
48 {
49 return m_domain;
50 }
51
52 std::vector<std::size_t> coalesc_idx() const // Can be constexpr with C++23
53 {
54 return m_coalesc_idx;
55 }
56
57 std::array<std::vector<std::size_t>, sizeof...(TailTensorIndex)> idx()
58 const // Can be constexpr with C++23
59 {
60 return m_idx;
61 }
62
63 std::vector<double> values() const // Can be constexpr with C++23
64 {
65 return m_values;
66 }
67
70 double,
71 ddc::DiscreteDomain<TailTensorIndex...>,
72 Kokkos::layout_right,
73 Kokkos::DefaultHostExecutionSpace::memory_space> dense)
74 {
75 m_coalesc_idx.push_back(m_coalesc_idx.back());
76 ddc::for_each(dense.domain(), [&](ddc::DiscreteElement<TailTensorIndex...> elem) {
77 if (dense(elem) != 0) {
78 m_coalesc_idx.back() += 1;
79 (m_idx[ddc::type_seq_rank_v<
80 TailTensorIndex,
81 ddc::detail::TypeSeq<TailTensorIndex...>>]
82 .push_back(elem.template uid<TailTensorIndex>()),
83 ...);
84 m_values.push_back(dense(elem));
85 }
86 });
87 }
88
89 // Returns a slice orthogonal to first index
90 CsrDynamic<HeadTensorIndex, TailTensorIndex...> get(
91 ddc::DiscreteElement<HeadTensorIndex> id) const
92 {
93 const std::size_t id_begin = m_coalesc_idx[id.uid()];
94 const std::size_t id_end = m_coalesc_idx[id.uid() + 1];
95 std::vector<std::size_t> new_coalesc_idx {0, id_end - id_begin};
96 std::array<std::vector<std::size_t>, sizeof...(TailTensorIndex)> new_idx;
97 ((new_idx[ddc::type_seq_rank_v<TailTensorIndex, ddc::detail::TypeSeq<TailTensorIndex...>>]
98 = std::vector<std::size_t>(
99 m_idx[ddc::type_seq_rank_v<
100 TailTensorIndex,
101 ddc::detail::TypeSeq<TailTensorIndex...>>]
102 .begin()
103 + id_begin,
104 m_idx[ddc::type_seq_rank_v<
105 TailTensorIndex,
106 ddc::detail::TypeSeq<TailTensorIndex...>>]
107 .begin()
108 + id_begin + id_end)),
109 ...);
110 std::vector<double>
111 new_values(m_values.begin() + id_begin, m_values.begin() + id_begin + id_end);
112
113 return CsrDynamic<HeadTensorIndex, TailTensorIndex...>(
114 ddc::DiscreteDomain<HeadTensorIndex, TailTensorIndex...>(m_domain),
115 new_coalesc_idx,
116 new_idx,
117 new_values);
118 }
119
120 void write(std::ofstream& file)
121 {
122 file
123 .write(reinterpret_cast<const char*>(coalesc_idx().data()),
124 coalesc_idx().size() * sizeof(std::size_t));
125 file << "break\n";
126 for (std::size_t i = 0; i < sizeof...(TailTensorIndex); ++i) {
127 file
128 .write(reinterpret_cast<const char*>(idx()[i].data()),
129 idx()[i].size() * sizeof(std::size_t));
130 file << "break\n";
131 }
132 file
133 .write(reinterpret_cast<const char*>(values().data()),
134 m_values.size() * sizeof(double));
135 file << "break\n";
136 }
137};
138
139// Convert Csr to dense tensor
140template <tensor::TensorIndex HeadId, tensor::TensorNatIndex... TailId>
142 double,
143 ddc::DiscreteDomain<HeadId, TailId...>,
144 Kokkos::layout_right,
145 Kokkos::DefaultHostExecutionSpace::memory_space>
148 double,
149 ddc::DiscreteDomain<HeadId, TailId...>,
150 Kokkos::layout_right,
151 Kokkos::DefaultHostExecutionSpace::memory_space> dense,
153{
154 ddc::parallel_fill(dense, 0.);
155 for (std::size_t i = 0; i < csr.coalesc_idx().size() - 1; ++i) {
156 std::size_t const j_begin = csr.coalesc_idx()[i];
157 std::size_t const j_end = csr.coalesc_idx()[i + 1];
158 Kokkos::parallel_for(
159 "csr2dense",
160 Kokkos::RangePolicy<Kokkos::DefaultHostExecutionSpace>(j_begin, j_end),
161 [&](const int j) {
162 dense(ddc::DiscreteElement<HeadId>(i),
163 ddc::DiscreteElement<TailId...>(csr.idx()[ddc::type_seq_rank_v<
164 TailId,
165 ddc::detail::TypeSeq<TailId...>>][j]...))
166 = csr.values()[j];
167 });
168 }
169 return dense;
170}
171
172template <class... TensorIndex>
173std::ostream& operator<<(std::ostream& os, CsrDynamic<TensorIndex...> const& csr)
174{
175 os << "----------\n";
176 for (std::size_t i = 0; i < csr.coalesc_idx().size(); ++i) {
177 os << csr.coalesc_idx()[i] << " ";
178 }
179 os << "\n";
180 for (std::size_t i = 0; i < csr.idx()[0].size(); ++i) {
181 for (std::size_t j = 0; j < sizeof...(TensorIndex) - 1; ++j) {
182 os << csr.idx()[j][i] << " ";
183 }
184 os << csr.values()[i];
185 os << "\n";
186 }
187 return os;
188}
189
190} // namespace csr
191
192} // namespace sil
CsrDynamic(ddc::DiscreteDomain< HeadTensorIndex, TailTensorIndex... > domain)
CsrDynamic(ddc::DiscreteDomain< HeadTensorIndex, TailTensorIndex... > domain, std::vector< std::size_t > coalesc_idx, std::array< std::vector< std::size_t >, sizeof...(TailTensorIndex)> idx, std::vector< double > values)
std::array< std::vector< std::size_t >, sizeof...(TailTensorIndex)> idx() const
void write(std::ofstream &file)
std::vector< double > values() const
CsrDynamic< HeadTensorIndex, TailTensorIndex... > get(ddc::DiscreteElement< HeadTensorIndex > id) const
ddc::DiscreteDomain< HeadTensorIndex, TailTensorIndex... > domain()
void push_back(sil::tensor::Tensor< double, ddc::DiscreteDomain< TailTensorIndex... >, Kokkos::layout_right, Kokkos::DefaultHostExecutionSpace::memory_space > dense)
std::vector< std::size_t > coalesc_idx() const
sil::tensor::Tensor< double, ddc::DiscreteDomain< HeadId, TailId... >, Kokkos::layout_right, Kokkos::DefaultHostExecutionSpace::memory_space > csr2dense(sil::tensor::Tensor< double, ddc::DiscreteDomain< HeadId, TailId... >, Kokkos::layout_right, Kokkos::DefaultHostExecutionSpace::memory_space > dense, CsrDynamic< HeadId, TailId... > csr)
std::ostream & operator<<(std::ostream &os, Csr< N, TensorIndex... > const &csr)
Definition csr.hpp:185
Tensor(ddc::Chunk< ElementType, SupportType, Allocator >) -> Tensor< ElementType, SupportType, Kokkos::layout_right, typename Allocator::memory_space >
The top-level namespace of SimiLie.
Definition csr.hpp:14