17 #ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
18 #include <Kokkos_Macros.hpp>
20 "Including non-public Kokkos header files is not allowed.");
22 #ifndef KOKKOS_CRS_HPP
23 #define KOKKOS_CRS_HPP
25 #include <Kokkos_View.hpp>
26 #include <Kokkos_CopyViews.hpp>
60 template <
class DataType,
class Arg1Type,
class Arg2Type = void,
61 typename SizeType =
typename ViewTraits<DataType*, Arg1Type, Arg2Type,
65 using traits = ViewTraits<DataType*, Arg1Type, Arg2Type, void>;
68 using data_type = DataType;
69 using array_layout =
typename traits::array_layout;
70 using execution_space =
typename traits::execution_space;
71 using memory_space =
typename traits::memory_space;
72 using device_type =
typename traits::device_type;
73 using size_type = SizeType;
75 using staticcrsgraph_type = Crs<DataType, Arg1Type, Arg2Type, SizeType>;
77 Crs<DataType, array_layout, typename traits::host_mirror_space, SizeType>;
78 using row_map_type = View<size_type*, array_layout, device_type>;
79 using entries_type = View<DataType*, array_layout, device_type>;
87 KOKKOS_DEFAULTED_FUNCTION
Crs() =
default;
88 KOKKOS_DEFAULTED_FUNCTION
Crs(Crs
const&) =
default;
89 KOKKOS_DEFAULTED_FUNCTION
Crs(Crs&&) =
default;
90 KOKKOS_DEFAULTED_FUNCTION
Crs& operator=(Crs
const&) =
default;
91 KOKKOS_DEFAULTED_FUNCTION
Crs& operator=(Crs&&) =
default;
92 KOKKOS_DEFAULTED_FUNCTION ~
Crs() =
default;
98 template <
class EntriesType,
class RowMapType>
99 KOKKOS_INLINE_FUNCTION
Crs(
const RowMapType& row_map_,
100 const EntriesType& entries_)
101 : row_map(row_map_), entries(entries_) {}
105 KOKKOS_INLINE_FUNCTION
107 return (row_map.extent(0) != 0)
108 ? row_map.extent(0) -
static_cast<size_type
>(1)
109 : static_cast<size_type>(0);
115 template <
class OutCounts,
class DataType,
class Arg1Type,
class Arg2Type,
117 void get_crs_transpose_counts(
118 OutCounts& out, Crs<DataType, Arg1Type, Arg2Type, SizeType>
const& in,
119 std::string
const& name =
"transpose_counts");
121 template <
class OutCounts,
class InCrs>
122 typename OutCounts::value_type get_crs_row_map_from_counts(
123 OutCounts& out, InCrs
const& in, std::string
const& name =
"row_map");
125 template <
class DataType,
class Arg1Type,
class Arg2Type,
class SizeType>
126 void transpose_crs(Crs<DataType, Arg1Type, Arg2Type, SizeType>& out,
127 Crs<DataType, Arg1Type, Arg2Type, SizeType>
const& in);
138 template <
class InCrs,
class OutCounts>
139 class GetCrsTransposeCounts {
141 using execution_space =
typename InCrs::execution_space;
142 using self_type = GetCrsTransposeCounts<InCrs, OutCounts>;
143 using index_type =
typename InCrs::size_type;
150 KOKKOS_INLINE_FUNCTION
151 void operator()(index_type i)
const { atomic_inc(&out[in.entries(i)]); }
152 GetCrsTransposeCounts(InCrs
const& arg_in, OutCounts
const& arg_out)
153 : in(arg_in), out(arg_out) {
154 using policy_type = RangePolicy<index_type, execution_space>;
156 const closure_type closure(*
this,
157 policy_type(0, index_type(in.entries.size())));
159 execution_space().fence(
160 "Kokkos::Impl::GetCrsTransposeCounts::GetCrsTransposeCounts: fence "
161 "after functor execution");
165 template <
class InCounts,
class OutRowMap>
166 class CrsRowMapFromCounts {
168 using execution_space =
typename InCounts::execution_space;
169 using value_type =
typename OutRowMap::value_type;
170 using index_type =
typename InCounts::size_type;
171 using last_value_type =
172 Kokkos::View<value_type, typename InCounts::device_type>;
177 last_value_type m_last_value;
180 KOKKOS_INLINE_FUNCTION
181 void operator()(index_type i, value_type& update,
bool final_pass)
const {
182 if (i < static_cast<index_type>(m_in.size())) {
184 if (final_pass) m_out(i + 1) = update;
185 }
else if (final_pass) {
187 m_last_value() = update;
190 KOKKOS_INLINE_FUNCTION
191 void init(value_type& update)
const { update = 0; }
192 KOKKOS_INLINE_FUNCTION
193 void join(value_type& update,
const value_type& input)
const {
196 using self_type = CrsRowMapFromCounts<InCounts, OutRowMap>;
197 CrsRowMapFromCounts(InCounts
const& arg_in, OutRowMap
const& arg_out)
198 : m_in(arg_in), m_out(arg_out), m_last_value(
"last_value") {}
199 value_type execute() {
200 using policy_type = RangePolicy<index_type, execution_space>;
202 closure_type closure(*
this, policy_type(0, m_in.size() + 1));
210 template <
class InCrs,
class OutCrs>
211 class FillCrsTransposeEntries {
213 using execution_space =
typename InCrs::execution_space;
214 using memory_space =
typename InCrs::memory_space;
215 using value_type =
typename OutCrs::entries_type::value_type;
216 using index_type =
typename InCrs::size_type;
219 using counters_type = View<index_type*, memory_space>;
222 counters_type counters;
225 KOKKOS_INLINE_FUNCTION
226 void operator()(index_type i)
const {
227 auto begin = in.row_map(i);
228 auto end = in.row_map(i + 1);
229 for (
auto j = begin; j < end; ++j) {
230 auto ti = in.entries(j);
231 auto tbegin = out.row_map(ti);
232 auto tj = atomic_fetch_add(&counters(ti), 1);
233 out.entries(tbegin + tj) = i;
236 using self_type = FillCrsTransposeEntries<InCrs, OutCrs>;
237 FillCrsTransposeEntries(InCrs
const& arg_in, OutCrs
const& arg_out)
238 : in(arg_in), out(arg_out), counters(
"counters", arg_out.numRows()) {
239 using policy_type = RangePolicy<index_type, execution_space>;
241 const closure_type closure(*
this, policy_type(0, index_type(in.numRows())));
243 execution_space().fence(
244 "Kokkos::Impl::FillCrsTransposeEntries::FillCrsTransposeEntries: fence "
245 "after functor execution");
258 template <
class OutCounts,
class DataType,
class Arg1Type,
class Arg2Type,
260 void get_crs_transpose_counts(
261 OutCounts& out, Crs<DataType, Arg1Type, Arg2Type, SizeType>
const& in,
262 std::string
const& name) {
263 using InCrs = Crs<DataType, Arg1Type, Arg2Type, SizeType>;
264 out = OutCounts(name, in.numRows());
265 Kokkos::Impl::GetCrsTransposeCounts<InCrs, OutCounts> functor(in, out);
268 template <
class OutRowMap,
class InCounts>
269 typename OutRowMap::value_type get_crs_row_map_from_counts(
270 OutRowMap& out, InCounts
const& in, std::string
const& name) {
271 out = OutRowMap(view_alloc(WithoutInitializing, name), in.size() + 1);
272 Kokkos::Impl::CrsRowMapFromCounts<InCounts, OutRowMap> functor(in, out);
273 return functor.execute();
276 template <
class DataType,
class Arg1Type,
class Arg2Type,
class SizeType>
277 void transpose_crs(Crs<DataType, Arg1Type, Arg2Type, SizeType>& out,
278 Crs<DataType, Arg1Type, Arg2Type, SizeType>
const& in) {
279 using crs_type = Crs<DataType, Arg1Type, Arg2Type, SizeType>;
280 using memory_space =
typename crs_type::memory_space;
281 using counts_type = View<SizeType*, memory_space>;
284 Kokkos::get_crs_transpose_counts(counts, in);
285 Kokkos::get_crs_row_map_from_counts(out.row_map, counts,
288 out.entries = decltype(out.entries)(
"transpose_entries", in.entries.size());
289 Kokkos::Impl::FillCrsTransposeEntries<crs_type, crs_type> entries_functor(
293 template <
class CrsType,
class Functor,
294 class ExecutionSpace =
typename CrsType::execution_space>
295 struct CountAndFillBase;
297 template <
class CrsType,
class Functor,
class ExecutionSpace>
298 struct CountAndFillBase {
299 using data_type =
typename CrsType::data_type;
300 using size_type =
typename CrsType::size_type;
301 using row_map_type =
typename CrsType::row_map_type;
302 using counts_type = row_map_type;
305 counts_type m_counts;
307 KOKKOS_FUNCTION
void operator()(Count, size_type i)
const {
308 m_counts(i) = m_functor(i,
nullptr);
311 KOKKOS_FUNCTION
void operator()(Fill, size_type i)
const {
312 auto j = m_crs.row_map(i);
318 data_type* fill = (j ==
static_cast<decltype(j)
>(m_crs.entries.extent(0)))
320 : (&(m_crs.entries(j)));
323 CountAndFillBase(CrsType& crs, Functor
const& f) : m_crs(crs), m_functor(f) {}
326 template <
class CrsType,
class Functor>
327 struct CountAndFill :
public CountAndFillBase<CrsType, Functor> {
328 using base_type = CountAndFillBase<CrsType, Functor>;
329 using typename base_type::Count;
330 using typename base_type::counts_type;
331 using typename base_type::data_type;
332 using typename base_type::Fill;
333 using typename base_type::size_type;
334 using entries_type =
typename CrsType::entries_type;
335 using self_type = CountAndFill<CrsType, Functor>;
336 CountAndFill(CrsType& crs, size_type nrows, Functor
const& f)
337 : base_type(crs, f) {
338 using execution_space =
typename CrsType::execution_space;
339 this->m_counts = counts_type(
"counts", nrows);
341 using count_policy_type = RangePolicy<size_type, execution_space, Count>;
342 using count_closure_type =
344 const count_closure_type closure(*
this, count_policy_type(0, nrows));
347 auto nentries = Kokkos::get_crs_row_map_from_counts(this->m_crs.row_map,
349 this->m_counts = counts_type();
350 this->m_crs.entries = entries_type(
"entries", nentries);
352 using fill_policy_type = RangePolicy<size_type, execution_space, Fill>;
353 using fill_closure_type =
355 const fill_closure_type closure(*
this, fill_policy_type(0, nrows));
362 template <
class CrsType,
class Functor>
363 void count_and_fill_crs(CrsType& crs,
typename CrsType::size_type nrows,
365 Kokkos::CountAndFill<CrsType, Functor>(crs, nrows, f);
Implementation detail of parallel_scan.
Memory management for host memory.
KOKKOS_INLINE_FUNCTION size_type numRows() const
KOKKOS_INLINE_FUNCTION Crs(const RowMapType &row_map_, const EntriesType &entries_)
Implementation of the ParallelFor operator that has a partial specialization for the device...