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