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 KOKKOS_FUNCTION constexpr ddc::DiscreteDomain<HeadTensorIndex, TailTensorIndex...> domain()
76 const
77 {
78 return m_domain;
79 }
80
81 KOKKOS_FUNCTION constexpr std::array<std::size_t, HeadTensorIndex::mem_size() + 1> const&
83 {
84 return m_coalesc_idx;
85 }
86
87 KOKKOS_FUNCTION constexpr std::
88 array<std::array<std::size_t, N>, sizeof...(TailTensorIndex)> const&
89 idx() const
90 {
91 return m_idx;
92 }
93
94 KOKKOS_FUNCTION constexpr std::array<double, N> const& values() const
95 {
96 return m_values;
97 }
98};
99
100/*
101 Vector-Csr multiplication
102 */
103template <
104 std::size_t N,
105 tensor::TensorIndex HeadTensorIndex,
106 tensor::TensorNatIndex... TailTensorIndex>
108 double,
109 ddc::DiscreteDomain<TailTensorIndex...>,
110 Kokkos::layout_right,
111 Kokkos::DefaultHostExecutionSpace::memory_space>
114 double,
115 ddc::DiscreteDomain<TailTensorIndex...>,
116 Kokkos::layout_right,
117 Kokkos::DefaultHostExecutionSpace::memory_space> prod,
119 double,
120 ddc::DiscreteDomain<HeadTensorIndex>,
121 Kokkos::layout_right,
122 Kokkos::DefaultHostExecutionSpace::memory_space> dense,
124{
125 SIMILIE_DEBUG_LOG("similie_compute_vector_dense_multiplication");
126 ddc::host_for_each(prod.domain(), [&](const ddc::DiscreteElement<TailTensorIndex...> elem) {
127 prod.mem(elem) = 0.;
128 });
129 for (std::size_t i = 0; i < csr.coalesc_idx().size() - 1;
130 ++i) { // TODO base on iterator ? Kokkosify ?
131 double const dense_value = dense.mem(ddc::DiscreteElement<HeadTensorIndex>(i));
132 std::size_t const j_begin = csr.coalesc_idx()[i];
133 std::size_t const j_end = csr.coalesc_idx()[i + 1];
134 for (int j = j_begin; j < j_end; j++) {
135 prod(ddc::DiscreteElement<TailTensorIndex...>(csr.idx()[ddc::type_seq_rank_v<
136 TailTensorIndex,
137 ddc::detail::TypeSeq<TailTensorIndex...>>][j]...))
138 += dense_value * csr.values()[j];
139 };
140 }
141 return prod;
142}
143
144/*
145 Csr-dense multiplication
146 */
147template <
148 std::size_t N,
149 tensor::TensorIndex HeadTensorIndex,
150 tensor::TensorNatIndex... TailTensorIndex>
152 double,
153 ddc::DiscreteDomain<HeadTensorIndex>,
154 Kokkos::layout_right,
155 Kokkos::DefaultHostExecutionSpace::memory_space>
158 double,
159 ddc::DiscreteDomain<HeadTensorIndex>,
160 Kokkos::layout_right,
161 Kokkos::DefaultHostExecutionSpace::memory_space> prod,
164 double,
165 ddc::DiscreteDomain<TailTensorIndex...>,
166 Kokkos::layout_right,
167 Kokkos::DefaultHostExecutionSpace::memory_space> dense)
168{
169 SIMILIE_DEBUG_LOG("similie_compute_csr_dense_multiplication");
170 ddc::host_for_each(prod.domain(), [&](const ddc::DiscreteElement<HeadTensorIndex> elem) {
171 prod.mem(elem) = 0.;
172 });
173 for (std::size_t i = 0; i < csr.coalesc_idx().size() - 1;
174 ++i) { // TODO base on iterator ? Kokkosify ?
175 std::size_t const j_begin = csr.coalesc_idx()[i];
176 std::size_t const j_end = csr.coalesc_idx()[i + 1];
177 float lsum = 0;
178 for (int j = j_begin; j < j_end; j++) {
179 double const dense_value
180 = dense(ddc::DiscreteElement<TailTensorIndex...>(csr.idx()[ddc::type_seq_rank_v<
181 TailTensorIndex,
182 ddc::detail::TypeSeq<TailTensorIndex...>>][j]...));
183 lsum += dense_value * csr.values()[j];
184 }
185 prod.mem(ddc::DiscreteElement<HeadTensorIndex>(i)) = lsum;
186 }
187 return prod;
188}
189
190template <std::size_t N, class... TensorIndex>
191std::ostream& operator<<(std::ostream& os, Csr<N, TensorIndex...> const& csr)
192{
193 os << "----------\n";
194 for (std::size_t i = 0; i < csr.coalesc_idx().size(); ++i) {
195 os << csr.coalesc_idx()[i] << " ";
196 }
197 os << "\n";
198 for (std::size_t i = 0; i < N; ++i) {
199 for (std::size_t j = 0; j < sizeof...(TensorIndex) - 1; ++j) {
200 os << csr.idx()[j][i] << " ";
201 }
202 os << csr.values()[i];
203 os << "\n";
204 }
205 return os;
206}
207
208} // namespace csr
209
210} // 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
KOKKOS_FUNCTION constexpr std::array< std::size_t, HeadTensorIndex::mem_size()+1 > const & coalesc_idx() const
Definition csr.hpp:82
KOKKOS_FUNCTION constexpr std::array< std::array< std::size_t, N >, sizeof...(TailTensorIndex)> const & idx() const
Definition csr.hpp:89
KOKKOS_FUNCTION constexpr std::array< double, N > const & values() const
Definition csr.hpp:94
Csr(CsrDynamic< HeadTensorIndex, TailTensorIndex... > csr_dyn)
Definition csr.hpp:64
KOKKOS_FUNCTION constexpr ddc::DiscreteDomain< HeadTensorIndex, TailTensorIndex... > domain() const
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:112
std::ostream & operator<<(std::ostream &os, Csr< N, TensorIndex... > const &csr)
Definition csr.hpp:191
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