8#include <ryujin/base/compile_time_options.h>
12#include <deal.II/base/aligned_vector.h>
13#include <deal.II/base/config.h>
14#include <deal.II/base/partitioner.h>
15#include <deal.II/lac/dynamic_sparsity_pattern.h>
19 template <
int warp_size,
typename MemorySpace = dealii::MemorySpace::Host>
20 class SparsityPatternView;
48 template <
int warp_size>
85 const unsigned int n_internal_dofs,
86 const dealii::DynamicSparsityPattern &sparsity,
87 const std::shared_ptr<const dealii::Utilities::MPI::Partitioner>
89 bool symmetrize_ghost_range =
true,
103 void reinit(
const unsigned int n_internal_dofs,
104 const dealii::DynamicSparsityPattern &sparsity,
105 const std::shared_ptr<const dealii::Utilities::MPI::Partitioner>
107 bool symmetrize_ghost_range =
true,
115 template <
typename MemorySpace = dealii::MemorySpace::Host>
156 std::shared_ptr<const dealii::Utilities::MPI::Partitioner> partitioner_;
158 unsigned int n_internal_dofs_;
159 unsigned int n_locally_owned_dofs_;
161 using KokkosHost = dealii::MemorySpace::Host::kokkos_space;
162 mutable Kokkos::View<unsigned int *, KokkosHost> row_starts_host_;
163 mutable Kokkos::View<unsigned int *, KokkosHost> column_indices_host_;
164 mutable Kokkos::View<unsigned int *, KokkosHost> indices_transposed_host_;
166 using KokkosDefault = dealii::MemorySpace::Default::kokkos_space;
167 mutable Kokkos::View<unsigned int *, KokkosDefault> row_starts_default_;
168 mutable Kokkos::View<unsigned int *, KokkosDefault> column_indices_default_;
169 mutable Kokkos::View<unsigned int *, KokkosDefault>
170 indices_transposed_default_;
173 "sparsity_pattern_entries_to_be_sent"};
175 std::vector<std::pair<unsigned int, unsigned int>> send_targets_;
176 std::vector<std::pair<unsigned int, unsigned int>> receive_targets_;
182 template <
typename MemorySpace>
183 void allocate_storage()
const;
185 template <
typename To,
typename From>
186 void deep_copy_storage()
const;
188 template <
typename MemorySpace>
189 void deallocate_storage();
194 template <
int,
typename>
214 template <
int warp_size,
typename MemorySpace>
287 const unsigned int *
columns(
const unsigned int row)
const;
302 const unsigned int column)
const;
315 template <
unsigned int n_components = 1>
316 DEAL_II_HOST_DEVICE
unsigned int
319 const unsigned int component = 0)
const;
333 template <
unsigned int n_components = 1>
334 DEAL_II_HOST_DEVICE
unsigned int
343 template <
unsigned int n_components = 1>
344 DEAL_II_HOST_DEVICE
unsigned int
347 const unsigned int component = 0)
const;
356 template <
unsigned int n_components = 1>
357 DEAL_II_HOST_DEVICE
const unsigned int *
370 template <
unsigned int n_components = 1>
380 unsigned int n_internal_dofs_;
381 unsigned int n_locally_owned_dofs_;
383 using KokkosSpace =
typename MemorySpace::kokkos_space;
384 Kokkos::View<const unsigned int *, KokkosSpace> row_starts_;
385 Kokkos::View<const unsigned int *, KokkosSpace> column_indices_;
386 Kokkos::View<const unsigned int *, KokkosSpace> indices_transposed_;
399 template <
int warp_size>
400 template <
typename MemorySpace>
404 this->
template prepare_read_access<MemorySpace>();
410 template <
int warp_size>
411 template <
typename MemorySpace>
412 void SparsityPattern<warp_size>::allocate_storage()
const
414 using HostSpace = dealii::MemorySpace::Host;
415 using Aligned = Kokkos::MemoryTraits<Kokkos::Aligned>;
419 if constexpr (std::is_same_v<MemorySpace, HostSpace>) {
420 row_starts_host_ = Kokkos::View<unsigned int *, KokkosHost, Aligned>(
421 Kokkos::view_alloc(Kokkos::WithoutInitializing,
422 "sparsity_pattern_row_starts"),
423 row_starts_default_.extent(0));
425 column_indices_host_ = Kokkos::View<unsigned int *, KokkosHost, Aligned>(
426 Kokkos::view_alloc(Kokkos::WithoutInitializing,
427 "sparsity_pattern_column_indices"),
428 column_indices_default_.extent(0));
430 indices_transposed_host_ =
431 Kokkos::View<unsigned int *, KokkosHost, Aligned>(
432 Kokkos::view_alloc(Kokkos::WithoutInitializing,
433 "sparsity_pattern_indices_transposed"),
434 indices_transposed_default_.extent(0));
437 row_starts_default_ = Kokkos::View<unsigned int *, KokkosDefault>(
438 Kokkos::view_alloc(Kokkos::WithoutInitializing,
439 "sparsity_pattern_row_starts"),
440 row_starts_host_.extent(0));
442 column_indices_default_ = Kokkos::View<unsigned int *, KokkosDefault>(
443 Kokkos::view_alloc(Kokkos::WithoutInitializing,
444 "sparsity_pattern_column_indices"),
445 column_indices_host_.extent(0));
447 indices_transposed_default_ = Kokkos::View<unsigned int *, KokkosDefault>(
448 Kokkos::view_alloc(Kokkos::WithoutInitializing,
449 "sparsity_pattern_indices_transposed"),
450 indices_transposed_host_.extent(0));
455 template <
int warp_size>
456 template <
typename To,
typename From>
457 void SparsityPattern<warp_size>::deep_copy_storage()
const
459 using HostSpace = dealii::MemorySpace::Host;
461 if constexpr (std::is_same_v<To, HostSpace>) {
462 Kokkos::deep_copy( row_starts_host_, row_starts_default_);
463 Kokkos::deep_copy( column_indices_host_,
464 column_indices_default_);
465 Kokkos::deep_copy( indices_transposed_host_,
466 indices_transposed_default_);
468 Kokkos::deep_copy( row_starts_default_, row_starts_host_);
469 Kokkos::deep_copy( column_indices_default_,
470 column_indices_host_);
471 Kokkos::deep_copy( indices_transposed_default_,
472 indices_transposed_host_);
477 template <
int warp_size>
478 template <
typename MemorySpace>
479 void SparsityPattern<warp_size>::deallocate_storage()
481 using HostSpace = dealii::MemorySpace::Host;
483 if constexpr (std::is_same_v<MemorySpace, HostSpace>) {
484 row_starts_host_ = {};
485 column_indices_host_ = {};
486 indices_transposed_host_ = {};
489 row_starts_default_ = {};
490 column_indices_default_ = {};
491 indices_transposed_default_ = {};
496 template <
int warp_size,
typename MemorySpace>
498 const SparsityPattern<warp_size> &sparsity_pattern)
500 reinit(sparsity_pattern);
504 template <
int warp_size,
typename MemorySpace>
506 const SparsityPattern<warp_size> &sparsity_pattern)
508 n_internal_dofs_ = sparsity_pattern.n_internal_dofs_;
509 n_locally_owned_dofs_ = sparsity_pattern.n_locally_owned_dofs_;
511 using HostSpace = dealii::MemorySpace::Host;
512 using DefaultSpace = dealii::MemorySpace::Default;
514 static_assert(std::is_same_v<MemorySpace, HostSpace> ||
515 std::is_same_v<MemorySpace, DefaultSpace>,
516 "Unexpected memory space");
523 !std::is_same_v<MemorySpace, HostSpace>) {
524 row_starts_ = sparsity_pattern.row_starts_default_;
525 column_indices_ = sparsity_pattern.column_indices_default_;
526 indices_transposed_ = sparsity_pattern.indices_transposed_default_;
528 row_starts_ = sparsity_pattern.row_starts_host_;
529 column_indices_ = sparsity_pattern.column_indices_host_;
530 indices_transposed_ = sparsity_pattern.indices_transposed_host_;
535 template <
int warp_size,
typename MemorySpace>
536 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
unsigned int
539 return n_internal_dofs_;
543 template <
int warp_size,
typename MemorySpace>
544 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
unsigned int
547 return n_locally_owned_dofs_;
551 template <
int warp_size,
typename MemorySpace>
552 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
unsigned int
555 Assert(row_starts_.size() > 0, dealii::ExcNotInitialized());
557 return row_starts_.size() - 1;
561 template <
int warp_size,
typename MemorySpace>
562 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
unsigned int
565 Assert(row_starts_.size() > 0, dealii::ExcNotInitialized());
567 return row_starts_(row_starts_.size() - 1);
571 template <
int warp_size,
typename MemorySpace>
572 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
unsigned int
574 const unsigned int row)
const
576 AssertIndexRange(row, n_rows());
578 if (row < n_internal_dofs_)
585 template <
int warp_size,
typename MemorySpace>
586 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
const unsigned int *
588 const unsigned int row)
const
590 AssertIndexRange(row, n_rows());
592 if (row < n_internal_dofs_)
593 return column_indices_.data() + row_starts_(row /
warp_size) +
596 return column_indices_.data() + row_starts_(row);
600 template <
int warp_size,
typename MemorySpace>
601 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
unsigned int
603 const unsigned int row)
const
605 AssertIndexRange(row, n_rows());
607 if (row < n_internal_dofs_) {
608 const unsigned int warp = row /
warp_size;
609 return (row_starts_(warp + 1) - row_starts_(warp)) /
warp_size;
611 return row_starts_(row + 1) - row_starts_(row);
616 template <
int warp_size,
typename MemorySpace>
617 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
unsigned int
619 const unsigned int row,
const unsigned int column)
const
621 const auto &row_length = this->row_length(row);
622 const auto &stride_size = this->stride_of_row(row);
626 const unsigned int *js = columns(row);
627 for (
unsigned int k = 0; k < row_length; ++k)
628 if (js[k * stride_size] == column)
631 Assert(
false, dealii::ExcMessage(
"Column index not found in given row"));
636 template <
int warp_size,
typename MemorySpace>
637 template <
unsigned int n_components>
638 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
unsigned int
640 const unsigned int row,
641 const unsigned int column_index,
642 const unsigned int comp)
const
644 AssertIndexRange(row, n_rows());
645 AssertIndexRange(column_index, row_length(row));
646 AssertIndexRange(comp, n_components);
648 const unsigned int warp = row /
warp_size;
649 const unsigned int lane = row %
warp_size;
651 if (row < n_internal_dofs_) {
652 const unsigned int scalar_offset =
653 row_starts_(warp) + column_index *
warp_size;
654 return scalar_offset * n_components + comp *
warp_size + lane;
657 const unsigned int scalar_offset = row_starts_(row) + column_index;
659 return scalar_offset * n_components + comp;
664 template <
int warp_size,
typename MemorySpace>
665 template <
unsigned int n_components>
666 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
unsigned int
668 const unsigned int row,
669 const unsigned int column_index,
670 const unsigned int component)
const
672 AssertIndexRange(row, n_rows());
673 AssertIndexRange(column_index, row_length(row));
674 AssertIndexRange(component, n_components);
678 const unsigned int scalar_offset = offset(row, column_index);
679 const unsigned int transposed_scalar_offset =
680 indices_transposed_(scalar_offset);
683 const unsigned int j = column_indices_(scalar_offset);
685 unsigned int transposed_offset = transposed_scalar_offset;
686 if constexpr (n_components > 1) {
687 if (j < n_internal_dofs_) {
691 return transposed_offset + component *
warp_size;
695 transposed_offset *= n_components;
696 return transposed_offset + component;
701 return transposed_offset;
706 template <
int warp_size,
typename MemorySpace>
707 template <
unsigned int n_components>
708 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
unsigned int
710 const unsigned int row,
const unsigned int column_index)
const
712 AssertIndexRange(row, n_rows());
713 AssertIndexRange(column_index, row_length(row));
714 AssertIndexRange(row, n_internal_dofs_);
716 const unsigned int warp = row /
warp_size;
717 const unsigned int lane = row %
warp_size;
719 const unsigned int scalar_offset =
720 row_starts_(warp) + column_index *
warp_size;
722 return scalar_offset * n_components + lane;
726 template <
int warp_size,
typename MemorySpace>
727 template <
unsigned int n_components>
728 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
const unsigned int *
730 const unsigned int row,
const unsigned int column_index)
const
732 static_assert(n_components == 1,
733 "Vectorized transposed access to multiple components is not "
735 AssertIndexRange(row, row_starts_.size() - 1);
736 AssertIndexRange(column_index, row_length(row));
737 AssertIndexRange(row, n_internal_dofs_);
739 const unsigned int warp = row /
warp_size;
740 const unsigned int lane = row %
warp_size;
742 const unsigned int scalar_offset =
743 row_starts_(warp) + column_index *
warp_size;
746 return indices_transposed_.data() + scalar_offset + lane;
750 template <
int warp_size,
typename MemorySpace>
751 template <
unsigned int n_components>
752 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
unsigned int
755 const auto scalar_offset = row_starts_(n_locally_owned_dofs_);
756 return scalar_offset * n_components;
TransferPolicy transfer_policy() const
DEAL_II_HOST_DEVICE unsigned int offset_internal(const unsigned int row, const unsigned int column_index) const
DEAL_II_HOST_DEVICE unsigned int n_nonzero_elements() const
DEAL_II_HOST_DEVICE const unsigned int * transposed_offset_internal(const unsigned int row, const unsigned int column_index) const
DEAL_II_HOST_DEVICE unsigned int n_internal_dofs() const
void reinit(const SparsityPattern< warp_size > &sparsity_pattern)
DEAL_II_HOST_DEVICE unsigned int stride_of_row(const unsigned int row) const
SparsityPatternView(const SparsityPattern< warp_size > &sparsity_pattern)
DEAL_II_HOST_DEVICE unsigned int row_length(const unsigned int row) const
DEAL_II_HOST_DEVICE const unsigned int * columns(const unsigned int row) const
SparsityPatternView()=default
DEAL_II_HOST_DEVICE unsigned int offset(const unsigned int row, const unsigned int column_index, const unsigned int component=0) const
DEAL_II_HOST_DEVICE unsigned int n_locally_owned_dofs() const
DEAL_II_HOST_DEVICE unsigned int ghost_offset() const
DEAL_II_HOST_DEVICE unsigned int n_rows() const
DEAL_II_HOST_DEVICE unsigned int transposed_offset(const unsigned int row, const unsigned int column_index, const unsigned int component=0) const
DEAL_II_HOST_DEVICE unsigned int column_index(const unsigned int row, const unsigned int column) const
ACCESSOR_READ_ONLY(entries_to_be_sent)
SparsityPatternView< warp_size, MemorySpace > view() const
void reinit(const unsigned int n_internal_dofs, const dealii::DynamicSparsityPattern &sparsity, const std::shared_ptr< const dealii::Utilities::MPI::Partitioner > &partitioner, bool symmetrize_ghost_range=true, const TransferPolicy transfer_policy=TransferPolicy::explicit_transfers)
SparsityPattern(const unsigned int n_internal_dofs, const dealii::DynamicSparsityPattern &sparsity, const std::shared_ptr< const dealii::Utilities::MPI::Partitioner > &partitioner, bool symmetrize_ghost_range=true, const TransferPolicy transfer_policy=TransferPolicy::explicit_transfers)
ACCESSOR_READ_ONLY(receive_targets)
ACCESSOR_READ_ONLY(send_targets)
ACCESSOR_READ_ONLY_NO_DEREFERENCE(partitioner)
constexpr unsigned int warp_size
constexpr bool have_separate_memory_spaces
unsigned int column_index