Amesos2 - Direct Sparse Solver Interfaces Version of the Day
Amesos2_Kokkos_View_Copy_Assign.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Amesos2: Templated Direct Sparse Solver Package
4//
5// Copyright 2011 NTESS and the Amesos2 contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
18#ifndef AMESOS2_KOKKOS_VIEW_COPY_ASSIGN_HPP
19#define AMESOS2_KOKKOS_VIEW_COPY_ASSIGN_HPP
20
21namespace Amesos2 {
22
23// allocate dst size if necessary - 2 methods handle 1d and 2d
24template<class dst_t, class src_t> // version for 1d view
25typename std::enable_if<static_cast<int>(dst_t::rank) == 1>::type
26update_dst_size(dst_t & dst, const src_t & src) {
27 if(dst.extent(0) != src.extent(0)) { // templated just for 1D
28 dst = dst_t(Kokkos::ViewAllocateWithoutInitializing("dst"),
29 src.extent(0));
30 }
31}
32
33template<class dst_t, class src_t> // version for 2d view
34typename std::enable_if<static_cast<int>(dst_t::rank) == 2>::type
35update_dst_size(dst_t & dst, const src_t & src) { // templated just for 2d
36 if(dst.extent(0) != src.extent(0) || dst.extent(1) != src.extent(1)) {
37 dst = dst_t(Kokkos::ViewAllocateWithoutInitializing("dst"),
38 src.extent(0), src.extent(1));
39 }
40}
41
42// now handle type mismatch for same memory space - here types are same
43// bInitialize:
44// If bInitialize is false, then the data needs to be allocated but not initialized.
45// If we are about to solve into x we don't care about setting the original values.
46// In this case, we are assigning the view directly so bInitialize does not matter.
47// bAssigned:
48// bAssigned tells the caller if the data was simply assigned, so it is set true in this case.
49template<class dst_t, class src_t> // version for same memory spaces
50typename std::enable_if<std::is_same<typename dst_t::value_type,
51 typename src_t::value_type>::value>::type
52implement_copy_or_assign_same_mem_check_types(
53 [[maybe_unused]] bool bInitialize,
54 dst_t & dst,
55 const src_t & src,
56 bool & bAssigned
57) {
58 dst = src; // just assign the ptr - no need to copy
59 bAssigned = true;
60}
61
62
63// deep-copy version (no checking)
64// bInitialize:
65// If bInitialize is false, then the data needs to be allocated but not initialized.
66// If we are about to solve into x we don't care about setting the original values.
67// In this case, we are allocating so we first make the memory via update_dst_size.
68// Then we only copy from the source if bInitialize is true.
69// bAssigned:
70// bAssigned tells the caller if the data was simply assigned, so it is set false in this case.
71template<class dst_t, class src_t> // actual implementation
72void deep_copy_only(bool bInitialize, dst_t & dst, const src_t & src, bool & bAssigned) {
73 update_dst_size(dst, src); // allocates if necessary
74 if(bInitialize) { // bInitialize false would be for solver getting x, where the actual values are not needed
75 Kokkos::deep_copy(dst, src); // full copy
76 }
77 bAssigned = false;
78}
79
80template<class dst_t, class src_t> // actual implementation
81void deep_copy_only(dst_t & dst, const src_t & src) {
82 bool bAssigned;
83 deep_copy_only(true, dst, src, bAssigned);
84}
85
86// now handle type mismatch for same memory space - now types are different
87// bInitialize:
88// If bInitialize is false, then the data needs to be allocated but not initialized.
89// If we are about to solve into x we don't care about setting the original values.
90// In this case, we are allocating so we first make the memory via update_dst_size.
91// Then we only copy from the source if bInitialize is true.
92// bAssigned:
93// bAssigned tells the caller if the data was simply assigned, so it is set false in this case.
94template<class dst_t, class src_t> // version for same memory spaces
95typename std::enable_if<!std::is_same<typename dst_t::value_type,
96 typename src_t::value_type>::value>::type
97implement_copy_or_assign_same_mem_check_types(bool bInitialize, dst_t & dst, const src_t & src, bool & bAssigned) {
98 update_dst_size(dst, src); // allocates if necessary
99 if(bInitialize) { // bInitialize false would be for solver getting x, where the actual values are not needed
100 Kokkos::deep_copy(dst, src); // full copy
101 }
102 bAssigned = false;
103}
104
105// implement_copy_or_assign has 2 versions for matched memory and
106// mismatched memory. Right now we just check the memory space.
107// a layout mismatch is going to compile fail so probably reflects an error
108// in the initial setup.
109template<class dst_t, class src_t> // version for same memory spaces
110typename std::enable_if<std::is_same<typename dst_t::memory_space,
111 typename src_t::memory_space>::value>::type
112deep_copy_or_assign_view(bool bInitialize, dst_t & dst, const src_t & src, bool & bAssigned) {
113 implement_copy_or_assign_same_mem_check_types(bInitialize, dst, src, bAssigned);
114}
115
116// for convenience this version does not take bInitialize input and bAssigned ouput
117// then it's assumed you want bInitialize true and don't need to know bAssigned
118template<class dst_t, class src_t> // version for same memory spaces
119typename std::enable_if<std::is_same<typename dst_t::memory_space,
120 typename src_t::memory_space>::value>::type
121deep_copy_or_assign_view(dst_t & dst, const src_t & src) {
122 bool bAssigned; // output not needed
123 implement_copy_or_assign_same_mem_check_types(true, dst, src, bAssigned);
124}
125
126template<class dst_t, class src_t> // version for different memory spaces
127typename std::enable_if<std::is_same<typename dst_t::value_type,
128 typename src_t::value_type>::value>::type
129implement_copy_or_assign_diff_mem_check_types(bool bInitialize, dst_t & dst, const src_t & src, bool & bAssigned) {
130 update_dst_size(dst, src); // allocates if necessary
131 if(bInitialize) { // bInitialize false would be for solver getting x, where the actual values are not needed
132 Kokkos::deep_copy(dst, src); // full copy
133 }
134 bAssigned = false;
135}
136
137template<class dst_t, class src_t> // version for different memory spaces
138typename std::enable_if<static_cast<int>(dst_t::rank) == 1>::type
139implement_copy_or_assign_diff_mem_diff_types_check_dim(dst_t & dst, const src_t & src) {
140 Kokkos::View<typename dst_t::value_type*, typename src_t::execution_space>
141 intermediate(Kokkos::ViewAllocateWithoutInitializing("intermediate"), src.extent(0));
142 Kokkos::deep_copy(intermediate, src); // to dst type
143 Kokkos::deep_copy(dst, intermediate); // to dst mem
144}
145
146template<class dst_t, class src_t> // version for different memory spaces
147typename std::enable_if<static_cast<int>(dst_t::rank) == 2>::type
148implement_copy_or_assign_diff_mem_diff_types_check_dim(dst_t & dst, const src_t & src) {
149 Kokkos::View<typename dst_t::value_type**, Kokkos::LayoutLeft, typename src_t::execution_space>
150 intermediate(Kokkos::ViewAllocateWithoutInitializing("intermediate"), src.extent(0), src.extent(1));
151 Kokkos::deep_copy(intermediate, src); // to dst type
152 Kokkos::deep_copy(dst, intermediate); // to dst mem
153}
154
155template<class dst_t, class src_t> // version for different memory spaces
156typename std::enable_if<!std::is_same<typename dst_t::value_type,
157 typename src_t::value_type>::value>::type
158implement_copy_or_assign_diff_mem_check_types(bool bInitialize, dst_t & dst, const src_t & src, bool & bAssigned) {
159 update_dst_size(dst, src); // allocates if necessary
160 bAssigned = false;
161 if(bInitialize) { // bInitialize false would be for solver getting x, where the actual values are not needed
162 // since mem space and types are different, we specify the order of operations
163 // Kokkos::deep_copy won't do both since it would be a hidden deep_copy
164 implement_copy_or_assign_diff_mem_diff_types_check_dim(dst, src);
165 }
166}
167
168template<class dst_t, class src_t> // version for different memory spaces
169typename std::enable_if<!std::is_same<typename dst_t::memory_space,
170 typename src_t::memory_space>::value>::type
171deep_copy_or_assign_view(bool bInitialize, dst_t & dst, const src_t & src, bool & bAssigned) {
172 implement_copy_or_assign_diff_mem_check_types(bInitialize, dst, src, bAssigned); // full copy
173}
174
175// for convenience this version does not take bInitialize input and bAssigned ouput
176// then it's assumed you want bInitialize true and don't need to know bAssigned
177template<class dst_t, class src_t> // version for different memory spaces
178typename std::enable_if<!std::is_same<typename dst_t::memory_space,
179 typename src_t::memory_space>::value>::type
180deep_copy_or_assign_view(dst_t & dst, const src_t & src) {
181 bool bAssigned; // output not needed
182 implement_copy_or_assign_diff_mem_check_types(true, dst, src, bAssigned); // full copy
183}
184
185} // end namespace Amesos2
186
187#endif // AMESOS2_KOKKOS_VIEW_COPY_ASSIGN_HPP