10#ifndef TPETRA_BLOCKVIEW_HPP
11#define TPETRA_BLOCKVIEW_HPP
21#include "TpetraCore_config.h"
22#if KOKKOS_VERSION >= 40799
23#include "KokkosKernels_ArithTraits.hpp"
25#include "Kokkos_ArithTraits.hpp"
27#include "Kokkos_Complex.hpp"
44template <
class ViewType1,
46 const int rank1 = ViewType1::rank>
63 static_assert(
static_cast<int>(ViewType1::rank) ==
static_cast<int>(ViewType2::rank),
64 "AbsMax: ViewType1 and ViewType2 must have the same rank.");
65 typedef typename std::remove_reference<
decltype(
Y(0, 0))>::type
STY;
66 static_assert(!std::is_const<STY>::value,
67 "AbsMax: The type of each entry of Y must be nonconst.");
68 typedef typename std::decay<
decltype(
X(0, 0))>::type
STX;
69 static_assert(std::is_same<STX, STY>::value,
70 "AbsMax: The type of each entry of X and Y must be the same.");
71#if KOKKOS_VERSION >= 40799
72 typedef KokkosKernels::ArithTraits<STY>
KAT;
74 typedef Kokkos::ArithTraits<STY>
KAT;
77 const int numCols =
Y.extent(1);
79 for (
int j = 0;
j < numCols; ++
j) {
104 static_assert(
static_cast<int>(ViewType1::rank) ==
static_cast<int>(ViewType2::rank),
105 "AbsMax: ViewType1 and ViewType2 must have the same rank.");
107 typedef typename std::remove_reference<
decltype(
Y(0))>::type
STY;
108 static_assert(!std::is_const<STY>::value,
109 "AbsMax: The type of each entry of Y must be nonconst.");
110 typedef typename std::remove_const<
typename std::remove_reference<
decltype(
X(0))>::type>::type
STX;
111 static_assert(std::is_same<STX, STY>::value,
112 "AbsMax: The type of each entry of X and Y must be the same.");
113#if KOKKOS_VERSION >= 40799
114 typedef KokkosKernels::ArithTraits<STY>
KAT;
116 typedef Kokkos::ArithTraits<STY>
KAT;
138template <
class ViewType1,
class ViewType2, const
int rank = ViewType1::rank>
141 static_assert(
static_cast<int>(ViewType1::rank) ==
static_cast<int>(ViewType2::rank),
142 "absMax: ViewType1 and ViewType2 must have the same rank.");
154 const int rank = ViewType::rank>
172#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
204 using x_value_type =
typename std::decay<
decltype(*
x.data())>::type;
207#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
219template <
class ViewType,
221 class IndexType = int,
222 const bool is_contiguous =
false,
223 const int rank = ViewType::rank>
266#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
278template <
class CoefficientType,
281 class IndexType = int,
282 const bool is_contiguous =
false,
283 const int rank = ViewType1::rank>
303#if KOKKOS_VERSION >= 40799
304 using KokkosKernels::ArithTraits;
306 using Kokkos::ArithTraits;
308 static_assert(
static_cast<int>(ViewType1::rank) ==
static_cast<int>(ViewType2::rank),
309 "AXPY: x and y must have the same rank.");
332#if KOKKOS_VERSION >= 40799
333 using KokkosKernels::ArithTraits;
335 using Kokkos::ArithTraits;
337 static_assert(
static_cast<int>(ViewType1::rank) ==
static_cast<int>(ViewType2::rank),
338 "AXPY: X and Y must have the same rank.");
361#if KOKKOS_VERSION >= 40799
362 using KokkosKernels::ArithTraits;
364 using Kokkos::ArithTraits;
366 static_assert(
static_cast<int>(ViewType1::rank) ==
static_cast<int>(ViewType2::rank),
367 "AXPY: x and y must have the same rank.");
370 using x_value_type =
typename std::decay<
decltype(*
x.data())>::type;
371 using y_value_type =
typename std::decay<
decltype(*
y.data())>::type;
375#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
388template <
class ViewType1,
390 class IndexType = int,
391 const bool is_contiguous =
false,
392 const int rank = ViewType1::rank>
441 using x_value_type =
typename std::decay<
decltype(*
x.data())>::type;
442 using y_value_type =
typename std::decay<
decltype(*
y.data())>::type;
446#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
454template <
class VecType1,
458 class IndexType = int,
459 bool is_contiguous =
false,
460 class BlkLayoutType =
typename BlkType::array_layout>
462 static KOKKOS_INLINE_FUNCTION
void
463 run(
const CoeffType& alpha,
467 static_assert(VecType1::rank == 1,
"GEMV: VecType1 must have rank 1.");
468 static_assert(BlkType::rank == 2,
"GEMV: BlkType must have rank 2.");
469 static_assert(VecType2::rank == 1,
"GEMV: VecType2 must have rank 1.");
471 const IndexType numRows =
static_cast<IndexType
>(A.extent(0));
472 const IndexType numCols =
static_cast<IndexType
>(A.extent(1));
475 for (IndexType i = 0; i < numRows; ++i)
476 for (IndexType j = 0; j < numCols; ++j)
477 y(i) += alpha * A(i, j) * x(j);
481template <
class VecType1,
486struct GEMV<VecType1, BlkType, VecType2, CoeffType, IndexType, true, Kokkos::LayoutLeft> {
487 static KOKKOS_INLINE_FUNCTION
void
488 run(
const CoeffType& alpha,
492 static_assert(VecType1::rank == 1,
"GEMV: VecType1 must have rank 1.");
493 static_assert(BlkType::rank == 2,
"GEMV: BlkType must have rank 2.");
494 static_assert(VecType2::rank == 1,
"GEMV: VecType2 must have rank 1.");
496 using A_value_type =
typename std::decay<
decltype(A(0, 0))>::type;
497 using x_value_type =
typename std::decay<
decltype(x(0))>::type;
498 using y_value_type =
typename std::decay<
decltype(y(0))>::type;
500 const IndexType numRows =
static_cast<IndexType
>(A.extent(0));
501 const IndexType numCols =
static_cast<IndexType
>(A.extent(1));
503 const A_value_type* __restrict A_ptr(A.data());
504 const IndexType as1(A.stride(1));
505 const x_value_type* __restrict x_ptr(x.data());
506 y_value_type* __restrict y_ptr(y.data());
508#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
511 for (IndexType j = 0; j < numCols; ++j) {
512 const x_value_type x_at_j = alpha * x_ptr[j];
513 const A_value_type* __restrict A_at_j = A_ptr + j * as1;
514#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
517 for (IndexType i = 0; i < numRows; ++i)
518 y_ptr[i] += A_at_j[i] * x_at_j;
523template <
class VecType1,
528struct GEMV<VecType1, BlkType, VecType2, CoeffType, IndexType, true, Kokkos::LayoutRight> {
529 static KOKKOS_INLINE_FUNCTION
void
530 run(
const CoeffType& alpha,
534 static_assert(VecType1::rank == 1,
"GEMV: VecType1 must have rank 1.");
535 static_assert(BlkType::rank == 2,
"GEMV: BlkType must have rank 2.");
536 static_assert(VecType2::rank == 1,
"GEMV: VecType2 must have rank 1.");
538 using A_value_type =
typename std::decay<
decltype(A(0, 0))>::type;
539 using x_value_type =
typename std::decay<
decltype(x(0))>::type;
540 using y_value_type =
typename std::decay<
decltype(y(0))>::type;
542 const IndexType numRows =
static_cast<IndexType
>(A.extent(0));
543 const IndexType numCols =
static_cast<IndexType
>(A.extent(1));
545 const A_value_type* __restrict A_ptr(A.data());
546 const IndexType as0(A.stride(0));
547 const x_value_type* __restrict x_ptr(x.data());
548 y_value_type* __restrict y_ptr(y.data());
550#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
553 for (IndexType i = 0; i < numRows; ++i) {
554 y_value_type y_at_i(0);
555 const auto A_at_i = A_ptr + i * as0;
556#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
559 for (IndexType j = 0; j < numCols; ++j)
560 y_at_i += A_at_i[j] * x_ptr[j];
561 y_ptr[i] += alpha * y_at_i;
570template <
class ViewType,
571 class CoefficientType,
572 class IndexType = int,
573 const int rank = ViewType::rank>
574KOKKOS_INLINE_FUNCTION
void
576 using LayoutType =
typename ViewType::array_layout;
577 constexpr bool is_contiguous = (std::is_same<LayoutType, Kokkos::LayoutLeft>::value ||
578 std::is_same<LayoutType, Kokkos::LayoutRight>::value);
583template <
class ViewType,
585 class IndexType = int,
586 const int rank = ViewType::rank>
587KOKKOS_INLINE_FUNCTION
void
589 using LayoutType =
typename ViewType::array_layout;
590 constexpr bool is_contiguous = (std::is_same<LayoutType, Kokkos::LayoutLeft>::value ||
591 std::is_same<LayoutType, Kokkos::LayoutRight>::value);
600template <
class CoefficientType,
603 class IndexType = int,
604 const int rank = ViewType1::rank>
605KOKKOS_INLINE_FUNCTION
void
609 static_assert(
static_cast<int>(ViewType1::rank) ==
610 static_cast<int>(ViewType2::rank),
611 "AXPY: x and y must have the same rank.");
612 using LayoutType1 =
typename ViewType1::array_layout;
613 using LayoutType2 =
typename ViewType2::array_layout;
614 constexpr bool is_layout_same = std::is_same<LayoutType1, LayoutType2>::value;
615 constexpr bool is_x_contiguous = (std::is_same<LayoutType1, Kokkos::LayoutLeft>::value ||
616 std::is_same<LayoutType1, Kokkos::LayoutRight>::value);
629template <
class ViewType1,
631 class IndexType = int,
632 const int rank = ViewType1::rank>
633KOKKOS_INLINE_FUNCTION
void
635 static_assert(
static_cast<int>(ViewType1::rank) ==
636 static_cast<int>(ViewType2::rank),
637 "COPY: x and y must have the same rank.");
638 using LayoutType1 =
typename ViewType1::array_layout;
639 using LayoutType2 =
typename ViewType2::array_layout;
640 constexpr bool is_layout_same = std::is_same<LayoutType1, LayoutType2>::value;
641 constexpr bool is_x_contiguous = (std::is_same<LayoutType1, Kokkos::LayoutLeft>::value ||
642 std::is_same<LayoutType1, Kokkos::LayoutRight>::value);
658template <
class VecType1,
662 class IndexType =
int>
663KOKKOS_INLINE_FUNCTION
void
668 constexpr bool is_A_contiguous = (std::is_same<typename BlkType::array_layout, Kokkos::LayoutLeft>::value ||
669 std::is_same<typename BlkType::array_layout, Kokkos::LayoutRight>::value);
670 constexpr bool is_x_contiguous = (std::is_same<typename VecType1::array_layout, Kokkos::LayoutLeft>::value ||
671 std::is_same<typename VecType1::array_layout, Kokkos::LayoutRight>::value);
672 constexpr bool is_y_contiguous = (std::is_same<typename VecType2::array_layout, Kokkos::LayoutLeft>::value ||
673 std::is_same<typename VecType2::array_layout, Kokkos::LayoutRight>::value);
675 Impl::GEMV<VecType1, BlkType, VecType2, CoeffType, IndexType, is_contiguous>::run(
alpha,
A,
x,
y);
685template <
class ViewType1,
688 class CoefficientType,
689 class IndexType =
int>
690KOKKOS_INLINE_FUNCTION
void
699 static_assert(ViewType1::rank == 2,
"GEMM: A must have rank 2 (be a matrix).");
700 static_assert(ViewType2::rank == 2,
"GEMM: B must have rank 2 (be a matrix).");
701 static_assert(ViewType3::rank == 2,
"GEMM: C must have rank 2 (be a matrix).");
703 typedef typename std::remove_reference<
decltype(
A(0, 0))>::type
Scalar;
704#if KOKKOS_VERSION >= 40799
705 typedef KokkosKernels::ArithTraits<Scalar> STS;
707 typedef Kokkos::ArithTraits<Scalar> STS;
821template <
class LittleBlockType,
822 class LittleVectorType>
823KOKKOS_INLINE_FUNCTION
void
826 typedef typename std::decay<
decltype(
ipiv(0))>::type
IndexType;
827 static_assert(std::is_integral<IndexType>::value,
828 "GETF2: The type of each entry of ipiv must be an integer type.");
829 typedef typename std::remove_reference<
decltype(
A(0, 0))>::type
Scalar;
830 static_assert(!std::is_const<Scalar>::value,
831 "GETF2: A must not be a const View (or LittleBlock).");
832 static_assert(!std::is_const<std::remove_reference<
decltype(
ipiv(0))>>::value,
833 "GETF2: ipiv must not be a const View (or LittleBlock).");
834 static_assert(LittleBlockType::rank == 2,
"GETF2: A must have rank 2 (be a matrix).");
835#if KOKKOS_VERSION >= 40799
836 typedef KokkosKernels::ArithTraits<Scalar> STS;
838 typedef Kokkos::ArithTraits<Scalar> STS;
860 if (STS::abs(
A(
i,
j)) > STS::abs(
A(
jp,
j))) {
880 }
else if (
info == 0) {
898template <
class LittleBlockType,
899 class LittleIntVectorType,
900 class LittleScalarVectorType,
901 const int rank = LittleScalarVectorType::rank>
904 run(
const char mode[],
917 run(
const char mode[],
923 typedef typename std::decay<
decltype(
ipiv(0))>::type
IndexType;
926 static_assert(std::is_integral<IndexType>::value &&
927 std::is_signed<IndexType>::value,
928 "GETRS: The type of each entry of ipiv must be a signed integer.");
929 typedef typename std::decay<
decltype(
A(0, 0))>::type
Scalar;
930 static_assert(!std::is_const<std::remove_reference<
decltype(
B(0))>>::value,
931 "GETRS: B must not be a const View (or LittleBlock).");
932 static_assert(LittleBlockType::rank == 2,
"GETRS: A must have rank 2 (be a matrix).");
933 static_assert(LittleIntVectorType::rank == 1,
"GETRS: ipiv must have rank 1.");
934 static_assert(LittleScalarVectorType::rank == 1,
"GETRS: For this specialization, B must have rank 1.");
936#if KOKKOS_VERSION >= 40799
937 typedef KokkosKernels::ArithTraits<Scalar> STS;
939 typedef Kokkos::ArithTraits<Scalar> STS;
961 if (
mode[0] ==
'n' ||
mode[0] ==
'N') {
993 else if (
mode[0] ==
't' ||
mode[0] ==
'T') {
998 else if (
mode[0] ==
'c' ||
mode[0] ==
'C') {
1014 run(
const char mode[],
1020 typedef typename std::decay<
decltype(
ipiv(0))>::type
IndexType;
1021 static_assert(std::is_integral<IndexType>::value,
1022 "GETRS: The type of each entry of ipiv must be an integer type.");
1023 static_assert(!std::is_const<std::remove_reference<
decltype(
B(0))>>::value,
1024 "GETRS: B must not be a const View (or LittleBlock).");
1025 static_assert(LittleBlockType::rank == 2,
"GETRS: A must have rank 2 (be a matrix).");
1026 static_assert(LittleIntVectorType::rank == 1,
"GETRS: ipiv must have rank 1.");
1027 static_assert(LittleScalarVectorType::rank == 2,
"GETRS: For this specialization, B must have rank 2.");
1036 auto B_cur = Kokkos::subview(
B, Kokkos::ALL(),
rhs);
1077template <
class LittleBlockType,
1078 class LittleIntVectorType,
1079 class LittleScalarVectorType>
1080KOKKOS_INLINE_FUNCTION
void
1086 typedef typename std::decay<
decltype(
ipiv(0))>::type
IndexType;
1089 static_assert(std::is_integral<IndexType>::value &&
1090 std::is_signed<IndexType>::value,
1091 "GETRI: The type of each entry of ipiv must be a signed integer.");
1092 typedef typename std::remove_reference<
decltype(
A(0, 0))>::type
Scalar;
1093 static_assert(!std::is_const<std::remove_reference<
decltype(
A(0, 0))>>::value,
1094 "GETRI: A must not be a const View (or LittleBlock).");
1095 static_assert(!std::is_const<std::remove_reference<
decltype(
work(0))>>::value,
1096 "GETRI: work must not be a const View (or LittleBlock).");
1097 static_assert(LittleBlockType::rank == 2,
"GETRI: A must have rank 2 (be a matrix).");
1098#if KOKKOS_VERSION >= 40799
1099 typedef KokkosKernels::ArithTraits<Scalar> STS;
1101 typedef Kokkos::ArithTraits<Scalar> STS;
1184template<
class LittleBlockType,
1185 class LittleVectorTypeX,
1186 class LittleVectorTypeY,
1187 class CoefficientType,
1188 class IndexType =
int>
1189KOKKOS_INLINE_FUNCTION
void
1190GEMV (
const char trans,
1191 const CoefficientType& alpha,
1192 const LittleBlockType& A,
1193 const LittleVectorTypeX& x,
1194 const CoefficientType& beta,
1195 const LittleVectorTypeY& y)
1201 typedef typename std::remove_reference<
decltype (y(0)) >::type y_value_type;
1202 const IndexType numRows =
static_cast<IndexType
> (A.extent (0));
1203 const IndexType numCols =
static_cast<IndexType
> (A.extent (1));
1207 for (IndexType i = 0; i < numRows; ++i) {
1212 for (IndexType i = 0; i < numRows; ++i) {
1213 y_value_type y_i = 0.0;
1214 for (IndexType j = 0; j < numCols; ++j) {
1215 y_i += A(i,j) * x(j);
1224 for (IndexType i = 0; i < numRows; ++i) {
1229 for (IndexType i = 0; i < numRows; ++i) {
1235 for (IndexType i = 0; i < numRows; ++i) {
1236 y_value_type y_i = beta * y(i);
1237 for (IndexType j = 0; j < numCols; ++j) {
1238 y_i += alpha * A(i,j) * x(j);
Struct that holds views of the contents of a CrsMatrix.
KOKKOS_INLINE_FUNCTION void absMax(const ViewType2 &Y, const ViewType1 &X)
Implementation of Tpetra's ABSMAX CombineMode for the small dense blocks in BlockCrsMatrix,...
Namespace Tpetra contains the class and methods constituting the Tpetra library.
KOKKOS_INLINE_FUNCTION void GEMV(const CoeffType &alpha, const BlkType &A, const VecType1 &x, const VecType2 &y)
y := y + alpha * A * x (dense matrix-vector multiply)
KOKKOS_INLINE_FUNCTION void GETF2(const LittleBlockType &A, const LittleVectorType &ipiv, int &info)
Computes A = P*L*U.
KOKKOS_INLINE_FUNCTION void GETRI(const LittleBlockType &A, const LittleIntVectorType &ipiv, const LittleScalarVectorType &work, int &info)
Compute inverse of A, using result of GETRF or GETF2.
KOKKOS_INLINE_FUNCTION void AXPY(const CoefficientType &alpha, const ViewType1 &x, const ViewType2 &y)
y := y + alpha * x (dense vector or matrix update)
KOKKOS_INLINE_FUNCTION void FILL(const ViewType &x, const InputType &val)
Set every entry of x to val.
KOKKOS_INLINE_FUNCTION void SCAL(const CoefficientType &alpha, const ViewType &x)
x := alpha*x, where x is either rank 1 (a vector) or rank 2 (a matrix).
KOKKOS_INLINE_FUNCTION void COPY(const ViewType1 &x, const ViewType2 &y)
Deep copy x into y, where x and y are either rank 1 (vectors) or rank 2 (matrices) with the same dime...
KOKKOS_INLINE_FUNCTION void GETRS(const char mode[], const LittleBlockType &A, const LittleIntVectorType &ipiv, const LittleScalarVectorType &B, int &info)
Solve the linear system(s) AX=B, using the result of GETRF or GETF2.
KOKKOS_INLINE_FUNCTION void GEMM(const char transA[], const char transB[], const CoefficientType &alpha, const ViewType1 &A, const ViewType2 &B, const CoefficientType &beta, const ViewType3 &C)
Small dense matrix-matrix multiply: C := alpha*A*B + beta*C
@ ZERO
Replace old values with zero.
static KOKKOS_INLINE_FUNCTION void run(const CoefficientType &alpha, const ViewType1 &x, const ViewType2 &y)
y := y + alpha*x (rank-1 x and y, i.e., vectors)
static KOKKOS_INLINE_FUNCTION void run(const CoefficientType &alpha, const ViewType1 &X, const ViewType2 &Y)
Y := Y + alpha*X (rank-2 X and Y, i.e., matrices)
Implementation of Tpetra::AXPY function.
static KOKKOS_INLINE_FUNCTION void run(const ViewType2 &Y, const ViewType1 &X)
(*this)(i) := max(abs((*this)(i)), abs(X(i))) for all i.
static KOKKOS_INLINE_FUNCTION void run(const ViewType2 &Y, const ViewType1 &X)
(*this)(i,j) := max(abs((*this)(i,j)), abs(X(i,j))) for all (i,j).
Implementation of Tpetra's ABSMAX CombineMode for the small dense blocks in BlockCrsMatrix,...
static KOKKOS_INLINE_FUNCTION void run(const ViewType1 &x, const ViewType2 &y)
y := x (rank-1 x and y, i.e., vectors)
static KOKKOS_INLINE_FUNCTION void run(const ViewType1 &X, const ViewType2 &Y)
Y := X (rank-2 X and Y, i.e., matrices)
Implementation of Tpetra::COPY function.
Implementation of Tpetra::FILL function.
Computes the solution to Ax=b.
static KOKKOS_INLINE_FUNCTION void run(const CoefficientType &alpha, const ViewType &x)
x := alpha*x (rank-1 x, i.e., a vector)
static KOKKOS_INLINE_FUNCTION void run(const CoefficientType &alpha, const ViewType &A)
A := alpha*A (rank-2 A, i.e., a matrix)
Implementation of Tpetra::SCAL function.