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;
 
   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. 
 
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...