DDC 0.10.0
Loading...
Searching...
No Matches
splines_linear_problem_3x3_blocks.cpp
1// Copyright (C) The DDC development team, see COPYRIGHT.md file
2//
3// SPDX-License-Identifier: MIT
4
5#include <cassert>
6#include <cstddef>
7#include <memory>
8#include <utility>
9
10#include <Kokkos_Core.hpp>
11
15
16namespace ddc::detail {
17
18template <class ExecSpace>
19SplinesLinearProblem3x3Blocks<ExecSpace>::SplinesLinearProblem3x3Blocks(
20 std::size_t const mat_size,
21 std::size_t const top_size,
22 std::unique_ptr<SplinesLinearProblem<ExecSpace>> center_block)
23 : SplinesLinearProblem2x2Blocks<ExecSpace>(mat_size, std::move(center_block))
24 , m_top_size(top_size)
25{
26}
27
28template <class ExecSpace>
29SplinesLinearProblem3x3Blocks<ExecSpace>::~SplinesLinearProblem3x3Blocks() = default;
30
31template <class ExecSpace>
32void SplinesLinearProblem3x3Blocks<ExecSpace>::adjust_indices(std::size_t& i, std::size_t& j) const
33{
34 std::size_t const nq = m_top_left_block->size(); // size of the center block
35
36 if (i < m_top_size) {
37 i += nq;
38 } else if (i < m_top_size + nq) {
39 i -= m_top_size;
40 }
41
42 if (j < m_top_size) {
43 j += nq;
44 } else if (j < m_top_size + nq) {
45 j -= m_top_size;
46 }
47}
48
49template <class ExecSpace>
50double SplinesLinearProblem3x3Blocks<ExecSpace>::get_element(std::size_t i, std::size_t j) const
51{
52 adjust_indices(i, j);
53 return SplinesLinearProblem2x2Blocks<ExecSpace>::get_element(i, j);
54}
55
56template <class ExecSpace>
57void SplinesLinearProblem3x3Blocks<ExecSpace>::set_element(
58 std::size_t i,
59 std::size_t j,
60 double const aij)
61{
62 adjust_indices(i, j);
63 SplinesLinearProblem2x2Blocks<ExecSpace>::set_element(i, j, aij);
64}
65
66template <class ExecSpace>
67void SplinesLinearProblem3x3Blocks<ExecSpace>::interchange_rows_from_3_to_2_blocks_rhs(
68 MultiRHS const b) const
69{
70 std::size_t const nq = m_top_left_block->size(); // size of the center block
71
72 MultiRHS const b_top
73 = Kokkos::subview(b, std::pair<std::size_t, std::size_t> {0, m_top_size}, Kokkos::ALL);
74 MultiRHS const b_bottom = Kokkos::
75 subview(b, std::pair<std::size_t, std::size_t> {m_top_size + nq, size()}, Kokkos::ALL);
76
77 MultiRHS const b_top_dst = Kokkos::
78 subview(b,
79 std::pair<std::size_t, std::size_t> {m_top_size + nq, 2 * m_top_size + nq},
80 Kokkos::ALL);
81 MultiRHS const b_bottom_dst = Kokkos::
82 subview(b,
83 std::pair<std::size_t, std::size_t> {2 * m_top_size + nq, m_top_size + size()},
84 Kokkos::ALL);
85
86 if (b_bottom.extent(0) > b_top.extent(0)) {
87 // Need a buffer to prevent overlapping
88 MultiRHS const buffer = Kokkos::create_mirror(ExecSpace(), b_bottom);
89
90 Kokkos::deep_copy(buffer, b_bottom);
91 Kokkos::deep_copy(b_bottom_dst, buffer);
92 } else {
93 Kokkos::deep_copy(b_bottom_dst, b_bottom);
94 }
95 Kokkos::deep_copy(b_top_dst, b_top);
96}
97
98template <class ExecSpace>
99void SplinesLinearProblem3x3Blocks<ExecSpace>::interchange_rows_from_2_to_3_blocks_rhs(
100 MultiRHS const b) const
101{
102 std::size_t const nq = m_top_left_block->size(); // size of the center block
103
104 MultiRHS const b_top
105 = Kokkos::subview(b, std::pair<std::size_t, std::size_t> {0, m_top_size}, Kokkos::ALL);
106 MultiRHS const b_bottom = Kokkos::
107 subview(b, std::pair<std::size_t, std::size_t> {m_top_size + nq, size()}, Kokkos::ALL);
108
109 MultiRHS const b_top_src = Kokkos::
110 subview(b,
111 std::pair<std::size_t, std::size_t> {m_top_size + nq, 2 * m_top_size + nq},
112 Kokkos::ALL);
113 MultiRHS const b_bottom_src = Kokkos::
114 subview(b,
115 std::pair<std::size_t, std::size_t> {2 * m_top_size + nq, m_top_size + size()},
116 Kokkos::ALL);
117
118 Kokkos::deep_copy(b_top, b_top_src);
119 if (b_bottom.extent(0) > b_top.extent(0)) {
120 // Need a buffer to prevent overlapping
121 MultiRHS const buffer = Kokkos::create_mirror(ExecSpace(), b_bottom);
122
123 Kokkos::deep_copy(buffer, b_bottom_src);
124 Kokkos::deep_copy(b_bottom, buffer);
125 } else {
126 Kokkos::deep_copy(b_bottom, b_bottom_src);
127 }
128}
129
130template <class ExecSpace>
131void SplinesLinearProblem3x3Blocks<ExecSpace>::solve(MultiRHS const b, bool const transpose) const
132{
133 assert(b.extent(0) == size() + m_top_size);
134
135 interchange_rows_from_3_to_2_blocks_rhs(b);
136 SplinesLinearProblem2x2Blocks<ExecSpace>::
137 solve(Kokkos::
138 subview(b,
139 std::pair<
140 std::size_t,
141 std::size_t> {m_top_size, m_top_size + size()},
142 Kokkos::ALL),
143 transpose);
144 interchange_rows_from_2_to_3_blocks_rhs(b);
145}
146
147template <class ExecSpace>
148std::size_t SplinesLinearProblem3x3Blocks<ExecSpace>::impl_required_number_of_rhs_rows() const
149{
150 return size() + m_top_size;
151}
152
153#if defined(KOKKOS_ENABLE_SERIAL)
154template class SplinesLinearProblem3x3Blocks<Kokkos::Serial>;
155#endif
156#if defined(KOKKOS_ENABLE_OPENMP)
157template class SplinesLinearProblem3x3Blocks<Kokkos::OpenMP>;
158#endif
159#if defined(KOKKOS_ENABLE_CUDA)
160template class SplinesLinearProblem3x3Blocks<Kokkos::Cuda>;
161#endif
162#if defined(KOKKOS_ENABLE_HIP)
163template class SplinesLinearProblem3x3Blocks<Kokkos::HIP>;
164#endif
165#if defined(KOKKOS_ENABLE_SYCL)
166template class SplinesLinearProblem3x3Blocks<Kokkos::SYCL>;
167#endif
168
169} // namespace ddc::detail
The top-level namespace of DDC.