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