Tpetra parallel linear algebra Version of the Day
Tpetra_Details_fill.hpp
Go to the documentation of this file.
1// @HEADER
2// ***********************************************************************
3//
4// Tpetra: Templated Linear Algebra Services Package
5// Copyright (2008) Sandia Corporation
6//
7// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8// the U.S. Government retains certain rights in this software.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// 3. Neither the name of the Corporation nor the names of the
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36//
37// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38//
39// ************************************************************************
40// @HEADER
41
42#ifndef TPETRA_DETAILS_FILL_HPP
43#define TPETRA_DETAILS_FILL_HPP
44
56
58#include <type_traits>
59
60namespace Tpetra {
61namespace Details {
62namespace Blas {
63namespace Impl {
64
66void*
67memsetWrapper (void* dest, int ch, std::size_t count);
68
70template<class ViewType,
71 class ValueType,
72 class ExecutionSpace,
73 class IndexType,
74 const int rank = ViewType::Rank>
75class Fill {
76public:
77 static void
78 fill (const ExecutionSpace& execSpace,
79 const ViewType& X,
80 const ValueType& alpha,
81 const IndexType /* numRows */,
82 const IndexType /* numCols */ )
83 {
84 static_assert (std::is_integral<IndexType>::value,
85 "IndexType must be a built-in integer type.");
86 Kokkos::deep_copy (execSpace, X, alpha);
87 }
88};
89
91template<class ViewType,
92 class ValueType,
93 class ExecutionSpace,
94 class IndexType>
95class Fill<ViewType, ValueType, ExecutionSpace, IndexType, 1> {
96public:
97 Fill (const ViewType& X, const ValueType& alpha) :
98 X_ (X), alpha_ (alpha)
99 {
100 static_assert (ViewType::Rank == 1,
101 "ViewType must be a rank-1 Kokkos::View.");
102 static_assert (std::is_integral<IndexType>::value,
103 "IndexType must be a built-in integer type.");
104 }
105
106 KOKKOS_INLINE_FUNCTION void
107 operator () (const IndexType& i) const
108 {
109 X_[i] = alpha_;
110 }
111
112 static void
113 fill (const ExecutionSpace& execSpace,
114 const ViewType& X,
115 const ValueType& alpha,
116 const IndexType numRows,
117 const IndexType /* numCols */)
118 {
119 typedef Kokkos::RangePolicy<ExecutionSpace, IndexType> range_type;
120 Kokkos::parallel_for ("fill", range_type (0, numRows),
121 Fill (X, alpha));
122 }
123
124private:
125 ViewType X_;
126 ValueType alpha_;
127};
128
130template<class ViewType,
131 class ValueType,
132 class ExecutionSpace,
133 class IndexType>
134class Fill<ViewType, ValueType, ExecutionSpace, IndexType, 2> {
135public:
136 Fill (const ViewType& X,
137 const ValueType& alpha,
138 const IndexType numCols) :
139 X_ (X), alpha_ (alpha), numCols_ (numCols)
140 {
141 static_assert (ViewType::Rank == 2,
142 "ViewType must be a rank-2 Kokkos::View.");
143 static_assert (std::is_integral<IndexType>::value,
144 "IndexType must be a built-in integer type.");
145 }
146
147 KOKKOS_INLINE_FUNCTION void
148 operator () (const IndexType& i) const
149 {
150 for (IndexType j = 0; j < numCols_; ++j) {
151 X_(i,j) = alpha_;
152 }
153 }
154
155 static void
156 fill (const ExecutionSpace& execSpace,
157 const ViewType& X,
158 const ValueType& alpha,
159 const IndexType numRows,
160 const IndexType numCols)
161 {
162 typedef Kokkos::RangePolicy<ExecutionSpace, IndexType> range_type;
163 Kokkos::parallel_for ("fill", range_type (0, numRows),
164 Fill (X, alpha, numCols));
165 }
166
167private:
168 ViewType X_;
169 ValueType alpha_;
170 IndexType numCols_;
171};
172
173#if defined(KOKKOS_ENABLE_SERIAL)
176template<class ViewType,
177 class ValueType,
178 class IndexType>
179struct Fill<ViewType,
180 ValueType,
181 Kokkos::Serial,
182 IndexType,
183 1>
184{
185 static void
186 fill (const Kokkos::Serial& /* execSpace */,
187 const ViewType& X,
188 const ValueType& alpha,
189 const IndexType numRows,
190 const IndexType /* numCols */ )
191 {
192 static_assert (ViewType::Rank == 1,
193 "ViewType must be a rank-1 Kokkos::View.");
194 static_assert (std::is_integral<IndexType>::value,
195 "IndexType must be a built-in integer type.");
196 using ::Tpetra::Details::Blas::BlasSupportsScalar;
197 typedef typename ViewType::non_const_value_type view_value_type;
198
199 // Do sizeof(view_value_type) and taking the address of a
200 // value_type instance work correctly with memset?
201 constexpr bool podType = BlasSupportsScalar<view_value_type>::value;
202
203 if (podType && X.span_is_contiguous () && alpha == ValueType (0.0)) {
204 memsetWrapper (X.data (), 0, X.span () * sizeof (view_value_type));
205 }
206 else {
207 for (IndexType k = 0; k < numRows; ++k) {
208 X[k] = alpha;
209 }
210 }
211 }
212};
213#endif // defined(KOKKOS_ENABLE_SERIAL)
214
215#if defined(KOKKOS_ENABLE_SERIAL)
218template<class ViewType,
219 class ValueType,
220 class IndexType>
221struct Fill<ViewType,
222 ValueType,
223 Kokkos::Serial,
224 IndexType,
225 2>
226{
227 static void
228 fill (const Kokkos::Serial& /* execSpace */,
229 const ViewType& X,
230 const ValueType& alpha,
231 const IndexType /* numRows */,
232 const IndexType numCols)
233 {
234 static_assert (ViewType::Rank == 2,
235 "ViewType must be a rank-2 Kokkos::View.");
236 static_assert (std::is_integral<IndexType>::value,
237 "IndexType must be a built-in integer type.");
238 using ::Tpetra::Details::Blas::BlasSupportsScalar;
239 typedef typename ViewType::non_const_value_type view_value_type;
240 typedef typename ViewType::array_layout array_layout;
241
242 // Do sizeof(view_value_type) and taking the address of a
243 // value_type instance work correctly with memset?
244 constexpr bool podType = BlasSupportsScalar<view_value_type>::value;
245
246 if (podType && alpha == ValueType (0.0)) {
247 if (X.span_is_contiguous ()) {
248 memsetWrapper (X.data (), 0, X.span () * sizeof (view_value_type));
249 }
250 else if (std::is_same<array_layout, Kokkos::LayoutLeft>::value) {
251 // Tpetra::MultiVector needs to optimize for LayoutLeft.
252 for (IndexType j = 0; j < numCols; ++j) {
253 auto X_j = Kokkos::subview (X, Kokkos::ALL (), j);
254 memsetWrapper (X_j.data (), 0,
255 X_j.extent (0) * sizeof (view_value_type));
256 }
257 }
258 else {
259 Kokkos::deep_copy (X, view_value_type (0.0));
260 }
261 }
262 else {
263 Kokkos::deep_copy (X, alpha);
264 }
265 }
266};
267#endif // defined(KOKKOS_ENABLE_SERIAL)
268
269} // namespace Impl
270
271//
272// SKIP TO HERE FOR THE ACTUAL INTERFACE
273//
274
282template<class ViewType,
283 class ValueType,
284 class IndexType,
285 class ExecutionSpace>
286void
287fill (const ExecutionSpace& execSpace,
288 const ViewType& X,
289 const ValueType& alpha,
290 const IndexType numRows,
291 const IndexType numCols)
292{
293 static_assert (std::is_integral<IndexType>::value,
294 "IndexType must be a built-in integer type.");
295 typedef Impl::Fill<ViewType, ValueType, ExecutionSpace,
296 IndexType, ViewType::Rank> impl_type;
297 impl_type::fill (execSpace, X, alpha, numRows, numCols);
298}
299
300template<class ViewType,
301 class ValueType,
302 class IndexType,
303 class ExecutionSpace>
304void
305fill (const ExecutionSpace& execSpace,
306 const ViewType& X,
307 const ValueType& alpha,
308 const IndexType numRows,
309 const IndexType numCols,
310 const size_t whichVectors[])
311{
312 static_assert (ViewType::Rank == 2, "ViewType must be a rank-2 "
313 "Kokkos::View in order to call the \"whichVectors\" "
314 "specialization of fill.");
315 static_assert (std::is_integral<IndexType>::value,
316 "IndexType must be a built-in integer type.");
317 for (IndexType k = 0; k < numCols; ++k) {
318 const IndexType j = whichVectors[k];
319 auto X_j = Kokkos::subview (X, Kokkos::ALL (), j);
320 typedef decltype (X_j) one_d_view_type;
321 typedef Impl::Fill<one_d_view_type, ValueType, ExecutionSpace,
322 IndexType, 1> impl_type;
323 impl_type::fill (execSpace, X_j, alpha, numRows, IndexType (1));
324 }
325}
326
327} // namespace Blas
328} // namespace Details
329} // namespace Tpetra
330
331#endif // TPETRA_DETAILS_FILL_HPP
Type traits for Tpetra's BLAS wrappers; an implementation detail of Tpetra::MultiVector.
void fill(const ExecutionSpace &execSpace, const ViewType &X, const ValueType &alpha, const IndexType numRows, const IndexType numCols)
Fill the entries of the given 1-D or 2-D Kokkos::View with the given scalar value alpha.
Implementation of ::Tpetra::Details::Blas::fill.
Implementation details of Tpetra.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
void deep_copy(MultiVector< DS, DL, DG, DN > &dst, const MultiVector< SS, SL, SG, SN > &src)
Copy the contents of the MultiVector src into dst.
Do BLAS libraries (all that are compliant with the BLAS Standard) support the given "scalar" (matrix ...