SimiLie
Loading...
Searching...
No Matches
csr.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
13#include "csr_dynamic.hpp"
14
15namespace sil {
16
17namespace csr {
18
19namespace detail {
20
21template <class Ids>
22struct ArrayOfVectorsToArrayOfArrays;
23
24template <std::size_t... I>
25struct ArrayOfVectorsToArrayOfArrays<std::index_sequence<I...>>
26{
27 template <std::size_t N>
28 static void run(
29 std::array<std::array<std::size_t, N>, sizeof...(I)>& arr,
30 std::array<std::vector<std::size_t>, sizeof...(I)> const& vec)
31 {
32 (std::copy_n(vec[I].begin(), N, arr[I].begin()), ...);
33 }
34};
35
36} // namespace detail
37
38// Only natural indexing supported
39template <
40 std::size_t N,
41 tensor::TensorIndex HeadTensorIndex,
42 tensor::TensorNatIndex... TailTensorIndex>
43class Csr
44{
45private:
46 ddc::DiscreteDomain<HeadTensorIndex, TailTensorIndex...> m_domain;
47 std::array<std::size_t, HeadTensorIndex::mem_size() + 1> m_coalesc_idx;
48 std::array<std::array<std::size_t, N>, sizeof...(TailTensorIndex)> m_idx;
49 std::array<double, N> m_values;
50
51public:
52 constexpr Csr(
53 ddc::DiscreteDomain<HeadTensorIndex, TailTensorIndex...> domain,
54 std::array<std::size_t, HeadTensorIndex::mem_size() + 1> coalesc_idx,
55 std::array<std::array<std::size_t, N>, sizeof...(TailTensorIndex)> idx,
56 std::array<double, N> values)
57 : m_domain(domain)
58 , m_coalesc_idx(coalesc_idx)
59 , m_idx(idx)
60 , m_values(values)
61 {
62 }
63
65 {
66 std::
67 copy_n(csr_dyn.coalesc_idx().begin(),
68 HeadTensorIndex::mem_size() + 1,
69 m_coalesc_idx.begin());
70 detail::ArrayOfVectorsToArrayOfArrays<
71 std::make_index_sequence<sizeof...(TailTensorIndex)>>::run(m_idx, csr_dyn.idx());
72 std::copy_n(csr_dyn.values().begin(), N, m_values.begin());
73 }
74
75 ddc::DiscreteDomain<HeadTensorIndex, TailTensorIndex...> domain()
76 {
77 return m_domain;
78 }
79
80 constexpr std::array<std::size_t, HeadTensorIndex::mem_size() + 1> coalesc_idx() const
81 {
82 return m_coalesc_idx;
83 }
84
85 constexpr std::array<std::array<std::size_t, N>, sizeof...(TailTensorIndex)> idx() const
86 {
87 return m_idx;
88 }
89
90 constexpr std::array<double, N> values() const
91 {
92 return m_values;
93 }
94};
95
96/*
97 Vector-Csr multiplication
98 */
99template <
100 std::size_t N,
101 tensor::TensorIndex HeadTensorIndex,
102 tensor::TensorNatIndex... TailTensorIndex>
104 double,
105 ddc::DiscreteDomain<TailTensorIndex...>,
106 Kokkos::layout_right,
107 Kokkos::DefaultHostExecutionSpace::memory_space>
110 double,
111 ddc::DiscreteDomain<TailTensorIndex...>,
112 Kokkos::layout_right,
113 Kokkos::DefaultHostExecutionSpace::memory_space> prod,
115 double,
116 ddc::DiscreteDomain<HeadTensorIndex>,
117 Kokkos::layout_right,
118 Kokkos::DefaultHostExecutionSpace::memory_space> dense,
120{
121 SIMILIE_DEBUG_LOG("similie_compute_vector_dense_multiplication");
122 ddc::parallel_fill(prod, 0.);
123 for (std::size_t i = 0; i < csr.coalesc_idx().size() - 1;
124 ++i) { // TODO base on iterator ? Kokkosify ?
125 double const dense_value = dense.mem(ddc::DiscreteElement<HeadTensorIndex>(i));
126 std::size_t const j_begin = csr.coalesc_idx()[i];
127 std::size_t const j_end = csr.coalesc_idx()[i + 1];
128 Kokkos::parallel_for(
129 "similie_compute_vector_dense_multiplication",
130 Kokkos::RangePolicy<Kokkos::DefaultHostExecutionSpace>(j_begin, j_end),
131 [&](const int j) {
132 prod(ddc::DiscreteElement<TailTensorIndex...>(csr.idx()[ddc::type_seq_rank_v<
133 TailTensorIndex,
134 ddc::detail::TypeSeq<TailTensorIndex...>>][j]...))
135 += dense_value * csr.values()[j];
136 });
137 }
138 return prod;
139}
140
141/*
142 Csr-dense multiplication
143 */
144template <
145 std::size_t N,
146 tensor::TensorIndex HeadTensorIndex,
147 tensor::TensorNatIndex... TailTensorIndex>
149 double,
150 ddc::DiscreteDomain<HeadTensorIndex>,
151 Kokkos::layout_right,
152 Kokkos::DefaultHostExecutionSpace::memory_space>
155 double,
156 ddc::DiscreteDomain<HeadTensorIndex>,
157 Kokkos::layout_right,
158 Kokkos::DefaultHostExecutionSpace::memory_space> prod,
161 double,
162 ddc::DiscreteDomain<TailTensorIndex...>,
163 Kokkos::layout_right,
164 Kokkos::DefaultHostExecutionSpace::memory_space> dense)
165{
166 SIMILIE_DEBUG_LOG("similie_compute_csr_dense_multiplication");
167 ddc::parallel_fill(prod, 0.);
168 for (std::size_t i = 0; i < csr.coalesc_idx().size() - 1;
169 ++i) { // TODO base on iterator ? Kokkosify ?
170 std::size_t const j_begin = csr.coalesc_idx()[i];
171 std::size_t const j_end = csr.coalesc_idx()[i + 1];
172 Kokkos::parallel_reduce(
173 "similie_compute_csr_dense_multiplication",
174 Kokkos::RangePolicy<Kokkos::DefaultHostExecutionSpace>(j_begin, j_end),
175 [&](const int j, double& lsum) {
176 double const dense_value = dense(
177 ddc::DiscreteElement<TailTensorIndex...>(csr.idx()[ddc::type_seq_rank_v<
178 TailTensorIndex,
179 ddc::detail::TypeSeq<TailTensorIndex...>>][j]...));
180 lsum += dense_value * csr.values()[j];
181 },
182 prod.mem(ddc::DiscreteElement<HeadTensorIndex>(i)));
183 }
184 return prod;
185}
186
187template <std::size_t N, class... TensorIndex>
188std::ostream& operator<<(std::ostream& os, Csr<N, TensorIndex...> const& csr)
189{
190 os << "----------\n";
191 for (std::size_t i = 0; i < csr.coalesc_idx().size(); ++i) {
192 os << csr.coalesc_idx()[i] << " ";
193 }
194 os << "\n";
195 for (std::size_t i = 0; i < N; ++i) {
196 for (std::size_t j = 0; j < sizeof...(TensorIndex) - 1; ++j) {
197 os << csr.idx()[j][i] << " ";
198 }
199 os << csr.values()[i];
200 os << "\n";
201 }
202 return os;
203}
204
205} // namespace csr
206
207} // namespace sil
std::array< std::vector< std::size_t >, sizeof...(TailTensorIndex)> idx() const
std::vector< double > values() const
std::vector< std::size_t > coalesc_idx() const
constexpr std::array< std::array< std::size_t, N >, sizeof...(TailTensorIndex)> idx() const
Definition csr.hpp:85
constexpr std::array< double, N > values() const
Definition csr.hpp:90
constexpr std::array< std::size_t, HeadTensorIndex::mem_size()+1 > coalesc_idx() const
Definition csr.hpp:80
Csr(CsrDynamic< HeadTensorIndex, TailTensorIndex... > csr_dyn)
Definition csr.hpp:64
ddc::DiscreteDomain< HeadTensorIndex, TailTensorIndex... > domain()
Definition csr.hpp:75
constexpr Csr(ddc::DiscreteDomain< HeadTensorIndex, TailTensorIndex... > domain, std::array< std::size_t, HeadTensorIndex::mem_size()+1 > coalesc_idx, std::array< std::array< std::size_t, N >, sizeof...(TailTensorIndex)> idx, std::array< double, N > values)
Definition csr.hpp:52
sil::tensor::Tensor< double, ddc::DiscreteDomain< TailTensorIndex... >, Kokkos::layout_right, Kokkos::DefaultHostExecutionSpace::memory_space > tensor_prod(sil::tensor::Tensor< double, ddc::DiscreteDomain< TailTensorIndex... >, Kokkos::layout_right, Kokkos::DefaultHostExecutionSpace::memory_space > prod, sil::tensor::Tensor< double, ddc::DiscreteDomain< HeadTensorIndex >, Kokkos::layout_right, Kokkos::DefaultHostExecutionSpace::memory_space > dense, Csr< N, HeadTensorIndex, TailTensorIndex... > csr)
Definition csr.hpp:108
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