Kokkos Core Kernels Package Version of the Day
Loading...
Searching...
No Matches
Kokkos_StaticCrsGraph.hpp
1//@HEADER
2// ************************************************************************
3//
4// Kokkos v. 4.0
5// Copyright (2022) National Technology & Engineering
6// Solutions of Sandia, LLC (NTESS).
7//
8// Under the terms of Contract DE-NA0003525 with NTESS,
9// the U.S. Government retains certain rights in this software.
10//
11// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
12// See https://kokkos.org/LICENSE for license information.
13// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14//
15//@HEADER
16
17#ifndef KOKKOS_STATICCRSGRAPH_HPP
18#define KOKKOS_STATICCRSGRAPH_HPP
19#ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
20#define KOKKOS_IMPL_PUBLIC_INCLUDE
21#define KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_STATICCRSGRAPH
22#endif
23
24#include <Kokkos_Macros.hpp>
25
26#if defined(KOKKOS_ENABLE_DEPRECATED_CODE_4)
27#if defined(KOKKOS_ENABLE_DEPRECATION_WARNINGS) && \
28 !defined(KOKKOS_IMPL_DO_NOT_WARN_INCLUDE_STATIC_CRS_GRAPH)
29namespace {
30[[deprecated("Deprecated <Kokkos_StaticCrsGraph.hpp> header is included")]] int
31emit_warning_kokkos_static_crs_graph_deprecated() {
32 return 0;
33}
34static auto do_not_include = emit_warning_kokkos_static_crs_graph_deprecated();
35} // namespace
36#endif
37#else
38#error "Deprecated <Kokkos_StaticCrsGraph.hpp> header is included"
39#endif
40
41#include <string>
42#include <vector>
43
44#include <Kokkos_View.hpp>
45#include <Kokkos_Parallel.hpp>
46#include <Kokkos_Parallel_Reduce.hpp>
47
48namespace Kokkos {
49
50namespace Impl {
51template <class RowOffsetsType, class RowBlockOffsetsType>
52struct StaticCrsGraphBalancerFunctor {
53 using int_type = typename RowOffsetsType::non_const_value_type;
54 RowOffsetsType row_offsets;
55 RowBlockOffsetsType row_block_offsets;
56
57 int_type cost_per_row, num_blocks;
58
59 StaticCrsGraphBalancerFunctor(RowOffsetsType row_offsets_,
60 RowBlockOffsetsType row_block_offsets_,
61 int_type cost_per_row_, int_type num_blocks_)
62 : row_offsets(row_offsets_),
63 row_block_offsets(row_block_offsets_),
64 cost_per_row(cost_per_row_),
65 num_blocks(num_blocks_) {}
66
67 KOKKOS_INLINE_FUNCTION
68 void operator()(const int_type& iRow) const {
69 const int_type num_rows = row_offsets.extent(0) - 1;
70 const int_type num_entries = row_offsets(num_rows);
71 const int_type total_cost = num_entries + num_rows * cost_per_row;
72
73 const double cost_per_workset = 1.0 * total_cost / num_blocks;
74
75 const int_type row_cost =
76 row_offsets(iRow + 1) - row_offsets(iRow) + cost_per_row;
77
78 int_type count = row_offsets(iRow + 1) + cost_per_row * iRow;
79
80 if (iRow == num_rows - 1) row_block_offsets(num_blocks) = num_rows;
81
82 if (true) {
83 int_type current_block =
84 (count - row_cost - cost_per_row) / cost_per_workset;
85 int_type end_block = count / cost_per_workset;
86
87 // Handle some corner cases for the last two blocks.
88 if (current_block >= num_blocks - 2) {
89 if ((current_block == num_blocks - 2) &&
90 (count >= (current_block + 1) * cost_per_workset)) {
91 int_type row = iRow;
92 int_type cc = count - row_cost - cost_per_row;
93 int_type block = cc / cost_per_workset;
94 while ((block > 0) && (block == current_block)) {
95 cc = row_offsets(row) + row * cost_per_row;
96 block = cc / cost_per_workset;
97 row--;
98 }
99 if ((count - cc - row_cost - cost_per_row) <
100 num_entries - row_offsets(iRow + 1)) {
101 row_block_offsets(current_block + 1) = iRow + 1;
102 } else {
103 row_block_offsets(current_block + 1) = iRow;
104 }
105 }
106 } else {
107 if ((count >= (current_block + 1) * cost_per_workset) ||
108 (iRow + 2 == int_type(row_offsets.extent(0)))) {
109 if (end_block > current_block + 1) {
110 int_type num_block = end_block - current_block;
111 row_block_offsets(current_block + 1) = iRow;
112 for (int_type block = current_block + 2; block <= end_block;
113 block++)
114 if ((block < current_block + 2 + (num_block - 1) / 2))
115 row_block_offsets(block) = iRow;
116 else
117 row_block_offsets(block) = iRow + 1;
118 } else {
119 row_block_offsets(current_block + 1) = iRow + 1;
120 }
121 }
122 }
123 }
124 }
125};
126} // namespace Impl
127
163template <class GraphType>
166 using ordinal_type = const typename GraphType::data_type;
167
168 private:
170 ordinal_type* colidx_;
178 const ordinal_type stride_;
179
180 public:
188 KOKKOS_INLINE_FUNCTION
190 const ordinal_type& count)
191 : colidx_(colidx_in), stride_(stride), length(count) {}
192
205 template <class OffsetType>
206 KOKKOS_INLINE_FUNCTION GraphRowViewConst(
207 const typename GraphType::entries_type& colidx_in,
208 const ordinal_type& stride, const ordinal_type& count,
209 const OffsetType& idx,
210 const std::enable_if_t<std::is_integral_v<OffsetType>, int>& = 0)
211 : colidx_(&colidx_in(idx)), stride_(stride), length(count) {}
212
224
230 KOKKOS_INLINE_FUNCTION
232 return colidx_[i * stride_];
233 }
234
236 KOKKOS_INLINE_FUNCTION
237 ordinal_type& operator()(const ordinal_type& i) const { return colidx(i); }
238};
239
273template <class DataType, class Arg1Type, class Arg2Type = void,
274 class Arg3Type = void,
275 typename SizeType = typename ViewTraits<DataType*, Arg1Type, Arg2Type,
276 Arg3Type>::size_type>
278 private:
280
281 public:
282 using data_type = DataType;
283 using array_layout = typename traits::array_layout;
284 using execution_space = typename traits::execution_space;
285 using device_type = typename traits::device_type;
286 using memory_traits = typename traits::memory_traits;
287 using size_type = SizeType;
288
289 using staticcrsgraph_type =
291 using HostMirror = StaticCrsGraph<data_type, array_layout,
292 typename traits::host_mirror_space,
293 memory_traits, size_type>;
294
295 using row_map_type =
297 using entries_type =
299 using row_block_type =
301
302 entries_type entries;
303 row_map_type row_map;
304 row_block_type row_block_offsets;
305
306 KOKKOS_DEFAULTED_FUNCTION
307 StaticCrsGraph() = default;
308
309 template <class EntriesType, class RowMapType>
310 KOKKOS_INLINE_FUNCTION StaticCrsGraph(const EntriesType& entries_,
311 const RowMapType& row_map_)
312 : entries(entries_), row_map(row_map_) {}
313
314 template <typename... Args>
315 KOKKOS_INLINE_FUNCTION StaticCrsGraph(const StaticCrsGraph<Args...>& other)
316 : entries(other.entries),
317 row_map(other.row_map),
318 row_block_offsets(other.row_block_offsets) {}
319
322 KOKKOS_INLINE_FUNCTION
324 return (row_map.extent(0) != 0)
325 ? row_map.extent(0) - static_cast<size_type>(1)
326 : static_cast<size_type>(0);
327 }
328
329 KOKKOS_INLINE_FUNCTION constexpr bool is_allocated() const {
330 return (row_map.is_allocated() && entries.is_allocated());
331 }
332
351 KOKKOS_INLINE_FUNCTION
353 const size_type start = row_map(i);
354 // count is guaranteed to fit in ordinal_type, as long as no row
355 // has duplicate entries.
356 const data_type count = static_cast<data_type>(row_map(i + 1) - start);
357
358 if (count == 0) {
359 return GraphRowViewConst<StaticCrsGraph>(nullptr, 1, 0);
360 } else {
361 return GraphRowViewConst<StaticCrsGraph>(entries, 1, count, start);
362 }
363 }
364
371 "StatisCrsGraph::load_balance_offsets", num_blocks + 1);
372
373 Impl::StaticCrsGraphBalancerFunctor<
375 partitioner(row_map, block_offsets, fix_cost_per_row, num_blocks);
376
377 Kokkos::parallel_for("Kokkos::StaticCrsGraph::create_block_partitioning",
380 typename device_type::execution_space().fence(
381 "Kokkos::StaticCrsGraph::create_block_partitioning:: fence after "
382 "partition");
383
384 row_block_offsets = block_offsets;
385 }
386};
387
388//----------------------------------------------------------------------------
389
390template <class StaticCrsGraphType, class InputSizeType>
391typename StaticCrsGraphType::staticcrsgraph_type create_staticcrsgraph(
392 const std::string& label, const std::vector<InputSizeType>& input);
393
394template <class StaticCrsGraphType, class InputSizeType>
395typename StaticCrsGraphType::staticcrsgraph_type create_staticcrsgraph(
396 const std::string& label,
397 const std::vector<std::vector<InputSizeType> >& input);
398
399//----------------------------------------------------------------------------
400
401template <class DataType, class Arg1Type, class Arg2Type, class Arg3Type,
402 typename SizeType>
403typename StaticCrsGraph<DataType, Arg1Type, Arg2Type, Arg3Type,
404 SizeType>::HostMirror
405create_mirror_view(const StaticCrsGraph<DataType, Arg1Type, Arg2Type, Arg3Type,
406 SizeType>& input);
407
408template <class DataType, class Arg1Type, class Arg2Type, class Arg3Type,
409 typename SizeType>
410typename StaticCrsGraph<DataType, Arg1Type, Arg2Type, Arg3Type,
411 SizeType>::HostMirror
412create_mirror(const StaticCrsGraph<DataType, Arg1Type, Arg2Type, Arg3Type,
413 SizeType>& input);
414
415} // namespace Kokkos
416
417//----------------------------------------------------------------------------
418//----------------------------------------------------------------------------
419
420#include <impl/Kokkos_StaticCrsGraph_factory.hpp>
421
422//----------------------------------------------------------------------------
423//----------------------------------------------------------------------------
424
425namespace Kokkos {
426namespace Impl {
427
428template <class GraphType>
429struct StaticCrsGraphMaximumEntry {
430 using execution_space = typename GraphType::execution_space;
431 using value_type = typename GraphType::data_type;
432
433 const typename GraphType::entries_type entries;
434
435 StaticCrsGraphMaximumEntry(const GraphType& graph) : entries(graph.entries) {}
436
437 KOKKOS_INLINE_FUNCTION
438 void operator()(const unsigned i, value_type& update) const {
439 if (update < entries(i)) update = entries(i);
440 }
441
442 KOKKOS_INLINE_FUNCTION
443 void init(value_type& update) const { update = 0; }
444
445 KOKKOS_INLINE_FUNCTION
446 void join(value_type& update, const value_type& input) const {
447 if (update < input) update = input;
448 }
449};
450
451} // namespace Impl
452
453template <class DataType, class Arg1Type, class Arg2Type, class Arg3Type,
454 typename SizeType>
455DataType maximum_entry(const StaticCrsGraph<DataType, Arg1Type, Arg2Type,
456 Arg3Type, SizeType>& graph) {
457 using GraphType =
458 StaticCrsGraph<DataType, Arg1Type, Arg2Type, Arg3Type, SizeType>;
459 using FunctorType = Impl::StaticCrsGraphMaximumEntry<GraphType>;
460
461 DataType result = 0;
462 Kokkos::parallel_reduce("Kokkos::maximum_entry", graph.entries.extent(0),
463 FunctorType(graph), result);
464 return result;
465}
466
467} // namespace Kokkos
468
469//----------------------------------------------------------------------------
470//----------------------------------------------------------------------------
471
472#ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_STATICCRSGRAPH
473#undef KOKKOS_IMPL_PUBLIC_INCLUDE
474#undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_STATICCRSGRAPH
475#endif
476#endif /* #ifndef KOKKOS_CRSARRAY_HPP */
Declaration of parallel operators.
A thread safe view to a bitset.
Compressed row storage array.
KOKKOS_INLINE_FUNCTION GraphRowViewConst< StaticCrsGraph > rowConst(const data_type i) const
Return a const view of row i of the graph.
void create_block_partitioning(size_type num_blocks, size_type fix_cost_per_row=4)
Create a row partitioning into a given number of blocks balancing non-zeros + a fixed cost per row.
KOKKOS_INLINE_FUNCTION size_type numRows() const
Return number of rows in the graph.
View of a row of a sparse graph.
KOKKOS_INLINE_FUNCTION GraphRowViewConst(ordinal_type *const colidx_in, const ordinal_type &stride, const ordinal_type &count)
Constructor.
KOKKOS_INLINE_FUNCTION GraphRowViewConst(const typename GraphType::entries_type &colidx_in, const ordinal_type &stride, const ordinal_type &count, const OffsetType &idx, const std::enable_if_t< std::is_integral_v< OffsetType >, int > &=0)
Constructor with offset into colidx array.
KOKKOS_INLINE_FUNCTION ordinal_type & colidx(const ordinal_type &i) const
(Const) reference to the column index of entry i in this row of the sparse matrix.
const ordinal_type length
Number of entries in the row.
const typename GraphType::data_type ordinal_type
The type of the column indices in the row.
KOKKOS_INLINE_FUNCTION ordinal_type & operator()(const ordinal_type &i) const
An alias for colidx.