45 #ifndef KOKKOS_CRS_HPP
46 #define KOKKOS_CRS_HPP
80 template <
class DataType,
class Arg1Type,
class Arg2Type = void,
81 typename SizeType =
typename ViewTraits<DataType*, Arg1Type, Arg2Type,
88 typedef DataType data_type;
89 typedef typename traits::array_layout array_layout;
90 typedef typename traits::execution_space execution_space;
91 typedef typename traits::memory_space memory_space;
92 typedef typename traits::device_type device_type;
93 typedef SizeType size_type;
96 typedef Crs<DataType, array_layout,
typename traits::host_mirror_space,
108 KOKKOS_DEFAULTED_FUNCTION
Crs() =
default;
109 KOKKOS_DEFAULTED_FUNCTION
Crs(
Crs const&) =
default;
110 KOKKOS_DEFAULTED_FUNCTION
Crs(
Crs&&) =
default;
111 KOKKOS_DEFAULTED_FUNCTION
Crs& operator=(
Crs const&) =
default;
112 KOKKOS_DEFAULTED_FUNCTION
Crs& operator=(
Crs&&) =
default;
113 KOKKOS_DEFAULTED_FUNCTION ~
Crs() =
default;
119 template <
class EntriesType,
class RowMapType>
120 KOKKOS_INLINE_FUNCTION
Crs(
const RowMapType& row_map_,
121 const EntriesType& entries_)
122 : row_map(row_map_), entries(entries_) {}
126 KOKKOS_INLINE_FUNCTION
128 return (row_map.
extent(0) != 0)
129 ? row_map.
extent(0) -
static_cast<size_type
>(1)
130 : static_cast<size_type>(0);
136 template <
class OutCounts,
class DataType,
class Arg1Type,
class Arg2Type,
138 void get_crs_transpose_counts(
139 OutCounts& out, Crs<DataType, Arg1Type, Arg2Type, SizeType>
const& in,
140 std::string
const& name =
"transpose_counts");
142 template <
class OutCounts,
class InCrs>
143 typename OutCounts::value_type get_crs_row_map_from_counts(
144 OutCounts& out, InCrs
const& in, std::string
const& name =
"row_map");
146 template <
class DataType,
class Arg1Type,
class Arg2Type,
class SizeType>
147 void transpose_crs(Crs<DataType, Arg1Type, Arg2Type, SizeType>& out,
148 Crs<DataType, Arg1Type, Arg2Type, SizeType>
const& in);
159 template <
class InCrs,
class OutCounts>
160 class GetCrsTransposeCounts {
162 using execution_space =
typename InCrs::execution_space;
163 using self_type = GetCrsTransposeCounts<InCrs, OutCounts>;
164 using index_type =
typename InCrs::size_type;
171 KOKKOS_INLINE_FUNCTION
172 void operator()(index_type i)
const { atomic_increment(&out[in.entries(i)]); }
173 GetCrsTransposeCounts(InCrs
const& arg_in, OutCounts
const& arg_out)
174 : in(arg_in), out(arg_out) {
175 using policy_type = RangePolicy<index_type, execution_space>;
177 const closure_type closure(*
this,
178 policy_type(0, index_type(in.entries.size())));
180 execution_space().fence();
184 template <
class InCounts,
class OutRowMap>
185 class CrsRowMapFromCounts {
187 using execution_space =
typename InCounts::execution_space;
188 using value_type =
typename OutRowMap::value_type;
189 using index_type =
typename InCounts::size_type;
195 last_value_type m_last_value;
198 KOKKOS_INLINE_FUNCTION
199 void operator()(index_type i, value_type& update,
bool final_pass)
const {
200 if (i < m_in.size()) {
202 if (final_pass) m_out(i + 1) = update;
203 }
else if (final_pass) {
205 m_last_value() = update;
208 KOKKOS_INLINE_FUNCTION
209 void init(value_type& update)
const { update = 0; }
210 KOKKOS_INLINE_FUNCTION
211 void join(
volatile value_type& update,
212 const volatile value_type& input)
const {
215 using self_type = CrsRowMapFromCounts<InCounts, OutRowMap>;
216 CrsRowMapFromCounts(InCounts
const& arg_in, OutRowMap
const& arg_out)
217 : m_in(arg_in), m_out(arg_out), m_last_value(
"last_value") {}
218 value_type execute() {
219 using policy_type = RangePolicy<index_type, execution_space>;
221 closure_type closure(*
this, policy_type(0, m_in.size() + 1));
223 auto last_value = Kokkos::create_mirror_view(m_last_value);
229 template <
class InCrs,
class OutCrs>
230 class FillCrsTransposeEntries {
232 using execution_space =
typename InCrs::execution_space;
233 using memory_space =
typename InCrs::memory_space;
234 using value_type =
typename OutCrs::entries_type::value_type;
235 using index_type =
typename InCrs::size_type;
238 using counters_type = View<index_type*, memory_space>;
241 counters_type counters;
244 KOKKOS_INLINE_FUNCTION
245 void operator()(index_type i)
const {
246 auto begin = in.row_map(i);
247 auto end = in.row_map(i + 1);
248 for (
auto j = begin; j < end; ++j) {
249 auto ti = in.entries(j);
250 auto tbegin = out.row_map(ti);
251 auto tj = atomic_fetch_add(&counters(ti), 1);
252 out.entries(tbegin + tj) = i;
255 using self_type = FillCrsTransposeEntries<InCrs, OutCrs>;
256 FillCrsTransposeEntries(InCrs
const& arg_in, OutCrs
const& arg_out)
257 : in(arg_in), out(arg_out), counters(
"counters", arg_out.numRows()) {
258 using policy_type = RangePolicy<index_type, execution_space>;
260 const closure_type closure(*
this, policy_type(0, index_type(in.numRows())));
262 execution_space().fence();
275 template <
class OutCounts,
class DataType,
class Arg1Type,
class Arg2Type,
277 void get_crs_transpose_counts(
278 OutCounts& out, Crs<DataType, Arg1Type, Arg2Type, SizeType>
const& in,
279 std::string
const& name) {
280 using InCrs = Crs<DataType, Arg1Type, Arg2Type, SizeType>;
281 out = OutCounts(name, in.numRows());
282 Kokkos::Impl::GetCrsTransposeCounts<InCrs, OutCounts> functor(in, out);
285 template <
class OutRowMap,
class InCounts>
286 typename OutRowMap::value_type get_crs_row_map_from_counts(
287 OutRowMap& out, InCounts
const& in, std::string
const& name) {
288 out = OutRowMap(ViewAllocateWithoutInitializing(name), in.size() + 1);
289 Kokkos::Impl::CrsRowMapFromCounts<InCounts, OutRowMap> functor(in, out);
290 return functor.execute();
293 template <
class DataType,
class Arg1Type,
class Arg2Type,
class SizeType>
294 void transpose_crs(Crs<DataType, Arg1Type, Arg2Type, SizeType>& out,
295 Crs<DataType, Arg1Type, Arg2Type, SizeType>
const& in) {
296 typedef Crs<DataType, Arg1Type, Arg2Type, SizeType> crs_type;
297 typedef typename crs_type::memory_space memory_space;
298 typedef View<SizeType*, memory_space> counts_type;
301 Kokkos::get_crs_transpose_counts(counts, in);
302 Kokkos::get_crs_row_map_from_counts(out.row_map, counts,
305 out.entries = decltype(out.entries)(
"transpose_entries", in.entries.size());
306 Kokkos::Impl::FillCrsTransposeEntries<crs_type, crs_type> entries_functor(
310 template <
class CrsType,
class Functor,
311 class ExecutionSpace =
typename CrsType::execution_space>
312 struct CountAndFillBase;
314 template <
class CrsType,
class Functor,
class ExecutionSpace>
315 struct CountAndFillBase {
316 using data_type =
typename CrsType::data_type;
317 using size_type =
typename CrsType::size_type;
318 using row_map_type =
typename CrsType::row_map_type;
319 using counts_type = row_map_type;
322 counts_type m_counts;
324 inline void operator()(Count, size_type i)
const {
325 m_counts(i) = m_functor(i,
nullptr);
328 inline void operator()(Fill, size_type i)
const {
329 auto j = m_crs.row_map(i);
335 data_type* fill = (j ==
static_cast<decltype(j)
>(m_crs.entries.extent(0)))
337 : (&(m_crs.entries(j)));
340 CountAndFillBase(CrsType& crs, Functor
const& f) : m_crs(crs), m_functor(f) {}
343 #if defined(KOKKOS_ENABLE_CUDA)
344 template <
class CrsType,
class Functor>
345 struct CountAndFillBase<CrsType, Functor, Kokkos::Cuda> {
346 using data_type =
typename CrsType::data_type;
347 using size_type =
typename CrsType::size_type;
348 using row_map_type =
typename CrsType::row_map_type;
349 using counts_type = row_map_type;
352 counts_type m_counts;
354 __device__
inline void operator()(Count, size_type i)
const {
355 m_counts(i) = m_functor(i,
nullptr);
358 __device__
inline void operator()(Fill, size_type i)
const {
359 auto j = m_crs.row_map(i);
365 data_type* fill = (j ==
static_cast<decltype(j)
>(m_crs.entries.extent(0)))
367 : (&(m_crs.entries(j)));
370 CountAndFillBase(CrsType& crs, Functor
const& f) : m_crs(crs), m_functor(f) {}
374 template <
class CrsType,
class Functor>
375 struct CountAndFill :
public CountAndFillBase<CrsType, Functor> {
376 using base_type = CountAndFillBase<CrsType, Functor>;
377 using typename base_type::Count;
378 using typename base_type::counts_type;
379 using typename base_type::data_type;
380 using typename base_type::Fill;
381 using typename base_type::size_type;
382 using entries_type =
typename CrsType::entries_type;
383 using self_type = CountAndFill<CrsType, Functor>;
384 CountAndFill(CrsType& crs, size_type nrows, Functor
const& f)
385 : base_type(crs, f) {
386 using execution_space =
typename CrsType::execution_space;
387 this->m_counts = counts_type(
"counts", nrows);
389 using count_policy_type = RangePolicy<size_type, execution_space, Count>;
390 using count_closure_type =
392 const count_closure_type closure(*
this, count_policy_type(0, nrows));
395 auto nentries = Kokkos::get_crs_row_map_from_counts(this->m_crs.row_map,
397 this->m_counts = counts_type();
398 this->m_crs.entries = entries_type(
"entries", nentries);
400 using fill_policy_type = RangePolicy<size_type, execution_space, Fill>;
401 using fill_closure_type =
403 const fill_closure_type closure(*
this, fill_policy_type(0, nrows));
410 template <
class CrsType,
class Functor>
411 void count_and_fill_crs(CrsType& crs,
typename CrsType::size_type nrows,
413 Kokkos::CountAndFill<CrsType, Functor>(crs, nrows, f);
void deep_copy(const View< DT, DP...> &dst, typename ViewTraits< DT, DP...>::const_value_type &value, typename std::enable_if< std::is_same< typename ViewTraits< DT, DP...>::specialize, void >::value >::type *=nullptr)
Deep copy a value from Host memory into a view.
KOKKOS_INLINE_FUNCTION constexpr std::enable_if< std::is_integral< iType >::value, size_t >::type extent(const iType &r) const noexcept
rank() to be implemented
Implementation detail of parallel_scan.
Compressed row storage array.
KOKKOS_INLINE_FUNCTION size_type numRows() const
Return number of rows in the graph.
KOKKOS_INLINE_FUNCTION Crs(const RowMapType &row_map_, const EntriesType &entries_)
Assign to a view of the rhs array. If the old view is the last view then allocated memory is dealloca...
Implementation of the ParallelFor operator that has a partial specialization for the device...
Traits class for accessing attributes of a View.