Tpetra parallel linear algebra Version of the Day
Loading...
Searching...
No Matches
Tpetra_Details_computeOffsets.hpp
Go to the documentation of this file.
1/*
2// @HEADER
3// ***********************************************************************
4//
5// Tpetra: Templated Linear Algebra Services Package
6// Copyright (2008) Sandia Corporation
7//
8// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9// the U.S. Government retains certain rights in this software.
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//
18// 2. Redistributions in binary form must reproduce the above copyright
19// notice, this list of conditions and the following disclaimer in the
20// documentation and/or other materials provided with the distribution.
21//
22// 3. Neither the name of the Corporation nor the names of the
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// ************************************************************************
39// @HEADER
40*/
41
42#ifndef TPETRA_DETAILS_COMPUTEOFFSETS_HPP
43#define TPETRA_DETAILS_COMPUTEOFFSETS_HPP
44
51
52#include "TpetraCore_config.h"
54#include <limits>
55#include <type_traits>
56
57namespace Tpetra {
58namespace Details {
59
60//
61// Implementation details for computeOffsetsFromCounts (see below).
62// Users should skip over this anonymous namespace.
63//
64namespace { // (anonymous)
65
75template<class OffsetType,
76 class CountType,
77 class SizeType>
78class ComputeOffsetsFromCounts {
79public:
80 static_assert (std::is_integral<OffsetType>::value,
81 "OffsetType must be a built-in integer.");
82 static_assert (std::is_integral<CountType>::value,
83 "CountType must be a built-in integer.");
84 static_assert (std::is_integral<SizeType>::value,
85 "SizeType must be a built-in integer.");
86
87 using offsets_view_type =
88 Kokkos::View<OffsetType*, Kokkos::AnonymousSpace>;
89 using counts_view_type =
90 Kokkos::View<const CountType*, Kokkos::AnonymousSpace>;
91
97 ComputeOffsetsFromCounts (const offsets_view_type& offsets,
98 const counts_view_type& counts) :
99 offsets_ (offsets),
100 counts_ (counts),
101 size_ (counts.extent (0))
102 {}
103
105 KOKKOS_INLINE_FUNCTION void
106 operator () (const SizeType i, OffsetType& update,
107 const bool finalPass) const
108 {
109 const auto curVal = (i < size_) ? counts_[i] : OffsetType ();
110 if (finalPass) {
111 offsets_[i] = update;
112 }
113 update += (i < size_) ? curVal : OffsetType ();
114 }
115
116 template<class ExecutionSpace>
117 static OffsetType
118 run (const ExecutionSpace& execSpace,
119 const offsets_view_type& offsets,
120 const counts_view_type& counts)
121 {
122 const SizeType numCounts (counts.extent (0));
123 using range_type = Kokkos::RangePolicy<ExecutionSpace, SizeType>;
124 range_type range (execSpace, 0, numCounts + SizeType (1));
125 using functor_type =
126 ComputeOffsetsFromCounts<OffsetType, CountType, SizeType>;
127 functor_type functor (offsets, counts);
128 OffsetType total (0);
129 const char funcName[] = "Tpetra::Details::computeOffsetsFromCounts";
130 Kokkos::parallel_scan (funcName, range, functor, total);
131 return total;
132 }
133
134private:
136 offsets_view_type offsets_;
138 counts_view_type counts_;
140 SizeType size_;
141};
142
152template<class OffsetType,
153 class CountType,
154 class SizeType>
155class ComputeOffsetsFromConstantCount {
156public:
157 static_assert (std::is_integral<OffsetType>::value,
158 "OffsetType must be a built-in integer.");
159 static_assert (std::is_integral<CountType>::value,
160 "CountType must be a built-in integer.");
161 static_assert (std::is_integral<SizeType>::value,
162 "SizeType must be a built-in integer.");
163
164 using offsets_view_type =
165 Kokkos::View<OffsetType*, Kokkos::AnonymousSpace>;
166
172 ComputeOffsetsFromConstantCount (const offsets_view_type& offsets,
173 const CountType count) :
174 offsets_ (offsets),
175 count_ (count)
176 {}
177
179 KOKKOS_INLINE_FUNCTION void
180 operator () (const SizeType i) const
181 {
182 offsets_[i] = count_*i;
183 }
184
185 template<class ExecutionSpace>
186 static OffsetType
187 run (const ExecutionSpace& execSpace,
188 const offsets_view_type& offsets,
189 const CountType count)
190 {
191 const SizeType numOffsets (offsets.extent (0));
192 using range_type = Kokkos::RangePolicy<ExecutionSpace, SizeType>;
193 range_type range (execSpace, 0, numOffsets);
194 using functor_type =
195 ComputeOffsetsFromConstantCount<OffsetType, CountType, SizeType>;
196 functor_type functor (offsets, count);
197 const OffsetType total = numOffsets*count;
198 const char funcName[] =
199 "Tpetra::Details::computeOffsetsFromConstantCount";
200 Kokkos::parallel_for (funcName, range, functor);
201 return total;
202 }
203
204private:
206 offsets_view_type offsets_;
208 CountType count_;
209};
210
211} // namespace (anonymous)
212
238template<class ExecutionSpace,
239 class OffsetsViewType,
240 class CountsViewType,
241 class SizeType = typename OffsetsViewType::size_type>
242typename OffsetsViewType::non_const_value_type
244 const OffsetsViewType& ptr,
245 const CountsViewType& counts)
246{
247 static_assert (Kokkos::is_execution_space<ExecutionSpace>::value,
248 "ExecutionSpace must be a Kokkos execution space.");
249 static_assert (Kokkos::is_view<OffsetsViewType>::value,
250 "OffsetsViewType (the type of ptr) must be a Kokkos::View.");
251 static_assert (Kokkos::is_view<CountsViewType>::value,
252 "CountsViewType (the type of counts) must be a Kokkos::View.");
253 static_assert (std::is_same<typename OffsetsViewType::value_type,
254 typename OffsetsViewType::non_const_value_type>::value,
255 "OffsetsViewType (the type of ptr) must be a nonconst Kokkos::View.");
256 static_assert (static_cast<int> (OffsetsViewType::rank) == 1,
257 "OffsetsViewType (the type of ptr) must be a rank-1 Kokkos::View.");
258 static_assert (static_cast<int> (CountsViewType::rank) == 1,
259 "CountsViewType (the type of counts) must be a rank-1 Kokkos::View.");
260
261 using offset_type = typename OffsetsViewType::non_const_value_type;
262 static_assert (std::is_integral<offset_type>::value,
263 "The entries of ptr must be built-in integers.");
264 using count_type = typename CountsViewType::non_const_value_type;
265 static_assert (std::is_integral<count_type>::value,
266 "The entries of counts must be built-in integers.");
267 static_assert (std::is_integral<SizeType>::value,
268 "SizeType must be a built-in integer type.");
269
270 const char funcName[] = "Tpetra::Details::computeOffsetsFromCounts";
271
272 const auto numOffsets = ptr.size ();
273 const auto numCounts = counts.size ();
274 offset_type total (0);
275
276 if (numOffsets != 0) {
278 (numCounts >= numOffsets, std::invalid_argument, funcName <<
279 ": counts.size() = " << numCounts << " >= ptr.size() = " <<
280 numOffsets << ".");
281
282 using Kokkos::AnonymousSpace;
283 using Kokkos::View;
286
287 using offsets_device_type = typename OffsetsViewType::device_type;
290
292 typename offsets_device_type::memory_space;
293 using counts_memory_space = typename CountsViewType::memory_space;
295 Kokkos::SpaceAccessibility<
298 // NOTE (mfh 21 Aug 2019) Some compilers have trouble deducing
299 // that operator= works if more than one template argument
300 // differ. If that should happen, introduce an intermediate
301 // type here.
303 }
304 else {
305 using Kokkos::view_alloc;
306 using Kokkos::WithoutInitializing;
308 (view_alloc ("counts_copy", WithoutInitializing), numCounts);
309 Kokkos::deep_copy (execSpace, counts_copy, counts);
311 }
312
313 using functor_type =
315 total = functor_type::run (execSpace, ptr_a, counts_a);
316 }
317
318 return total;
319}
320
322template<class OffsetsViewType,
323 class CountsViewType,
324 class SizeType = typename OffsetsViewType::size_type>
325typename OffsetsViewType::non_const_value_type
327 const CountsViewType& counts)
328{
329 using execution_space = typename OffsetsViewType::execution_space;
330 return computeOffsetsFromCounts (execution_space (), ptr, counts);
331}
332
355template<class OffsetsViewType,
356 class CountType,
357 class SizeType = typename OffsetsViewType::size_type>
358typename OffsetsViewType::non_const_value_type
360 const CountType count)
361{
362 static_assert (Kokkos::is_view<OffsetsViewType>::value,
363 "ptr must be a Kokkos::View.");
364 static_assert (std::is_same<typename OffsetsViewType::value_type,
365 typename OffsetsViewType::non_const_value_type>::value,
366 "ptr must be a nonconst Kokkos::View.");
367 static_assert (static_cast<int> (OffsetsViewType::rank) == 1,
368 "ptr must be a rank-1 Kokkos::View.");
369
370 using offset_type = typename OffsetsViewType::non_const_value_type;
371 static_assert (std::is_integral<offset_type>::value,
372 "The type of each entry of ptr must be a "
373 "built-in integer.");
374 static_assert (std::is_integral<CountType>::value,
375 "CountType must be a built-in integer.");
376 static_assert (std::is_integral<SizeType>::value,
377 "SizeType must be a built-in integer.");
378
379 using device_type = typename OffsetsViewType::device_type;
380 using execution_space = typename device_type::execution_space;
381
382 offset_type total (0);
383 if (ptr.extent (0) != 0) {
384 using CT = CountType;
385 using functor_type =
387 execution_space execSpace;
388 functor_type::run (execSpace, ptr, count);
389 }
390 return total;
391}
392
393} // namespace Details
394} // namespace Tpetra
395
396#endif // TPETRA_DETAILS_COMPUTEOFFSETS_HPP
Declaration and definition of Tpetra::Details::getEntryOnHost.
Struct that holds views of the contents of a CrsMatrix.
Implementation details of Tpetra.
OffsetsViewType::non_const_value_type computeOffsetsFromCounts(const ExecutionSpace &execSpace, const OffsetsViewType &ptr, const CountsViewType &counts)
Compute offsets from counts.
OffsetsViewType::non_const_value_type computeOffsetsFromConstantCount(const OffsetsViewType &ptr, const CountType count)
Compute offsets from a constant count.
Namespace Tpetra contains the class and methods constituting the Tpetra library.