10#ifndef TPETRA_BLOCKVIEW_HPP
11#define TPETRA_BLOCKVIEW_HPP
21#include "TpetraCore_config.h"
22#include "KokkosKernels_ArithTraits.hpp"
23#include "Kokkos_Complex.hpp"
40template <
class ViewType1,
42 const int rank1 = ViewType1::rank>
44 static KOKKOS_INLINE_FUNCTION
void
45 run(
const ViewType2& Y,
const ViewType1& X);
52template <
class ViewType1,
54struct AbsMax<ViewType1, ViewType2, 2> {
57 static KOKKOS_INLINE_FUNCTION
void
58 run(
const ViewType2& Y,
const ViewType1& X) {
59 static_assert(
static_cast<int>(ViewType1::rank) ==
static_cast<int>(ViewType2::rank),
60 "AbsMax: ViewType1 and ViewType2 must have the same rank.");
61 typedef typename std::remove_reference<
decltype(Y(0, 0))>::type STY;
62 static_assert(!std::is_const<STY>::value,
63 "AbsMax: The type of each entry of Y must be nonconst.");
64 typedef typename std::decay<
decltype(X(0, 0))>::type STX;
65 static_assert(std::is_same<STX, STY>::value,
66 "AbsMax: The type of each entry of X and Y must be the same.");
67 typedef KokkosKernels::ArithTraits<STY> KAT;
69 const int numCols = Y.extent(1);
70 const int numRows = Y.extent(0);
71 for (
int j = 0; j < numCols; ++j) {
72 for (
int i = 0; i < numRows; ++i) {
74 const STX X_ij = X(i, j);
77 const auto Y_ij_abs = KAT::abs(Y_ij);
78 const auto X_ij_abs = KAT::abs(X_ij);
79 Y_ij = (Y_ij_abs >= X_ij_abs) ?
static_cast<STY
>(Y_ij_abs) :
static_cast<STY
>(X_ij_abs);
89template <
class ViewType1,
91struct AbsMax<ViewType1, ViewType2, 1> {
94 static KOKKOS_INLINE_FUNCTION
void
95 run(
const ViewType2& Y,
const ViewType1& X) {
96 static_assert(
static_cast<int>(ViewType1::rank) ==
static_cast<int>(ViewType2::rank),
97 "AbsMax: ViewType1 and ViewType2 must have the same rank.");
99 typedef typename std::remove_reference<
decltype(Y(0))>::type STY;
100 static_assert(!std::is_const<STY>::value,
101 "AbsMax: The type of each entry of Y must be nonconst.");
102 typedef typename std::remove_const<
typename std::remove_reference<
decltype(X(0))>::type>::type STX;
103 static_assert(std::is_same<STX, STY>::value,
104 "AbsMax: The type of each entry of X and Y must be the same.");
105 typedef KokkosKernels::ArithTraits<STY> KAT;
107 const int numRows = Y.extent(0);
108 for (
int i = 0; i < numRows; ++i) {
110 const STX X_i = X(i);
113 const auto Y_i_abs = KAT::abs(Y_i);
114 const auto X_i_abs = KAT::abs(X_i);
115 Y_i = (Y_i_abs >= X_i_abs) ?
static_cast<STY
>(Y_i_abs) :
static_cast<STY
>(X_i_abs);
126template <
class ViewType1,
class ViewType2, const
int rank = ViewType1::rank>
127KOKKOS_INLINE_FUNCTION
void
128absMax(
const ViewType2& Y,
const ViewType1& X) {
129 static_assert(
static_cast<int>(ViewType1::rank) ==
static_cast<int>(ViewType2::rank),
130 "absMax: ViewType1 and ViewType2 must have the same rank.");
131 AbsMax<ViewType1, ViewType2, rank>::run(Y, X);
138template <
class ViewType,
139 class CoefficientType,
140 class IndexType = int,
141 const bool is_contiguous =
false,
142 const int rank = ViewType::rank>
144 static KOKKOS_INLINE_FUNCTION
void
145 run(
const CoefficientType& alpha,
const ViewType& x);
150template <
class ViewType,
151 class CoefficientType,
153struct SCAL<ViewType, CoefficientType, IndexType, false, 1> {
155 static KOKKOS_INLINE_FUNCTION
void
156 run(
const CoefficientType& alpha,
const ViewType& x) {
157 const IndexType numRows =
static_cast<IndexType
>(x.extent(0));
160#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
163 for (IndexType i = 0; i < numRows; ++i)
169template <
class ViewType,
170 class CoefficientType,
172struct SCAL<ViewType, CoefficientType, IndexType, false, 2> {
174 static KOKKOS_INLINE_FUNCTION
void
175 run(
const CoefficientType& alpha,
const ViewType& A) {
176 const IndexType numRows =
static_cast<IndexType
>(A.extent(0));
177 const IndexType numCols =
static_cast<IndexType
>(A.extent(1));
179 for (IndexType j = 0; j < numCols; ++j)
180 for (IndexType i = 0; i < numRows; ++i)
181 A(i, j) = alpha * A(i, j);
184template <
class ViewType,
185 class CoefficientType,
188struct SCAL<ViewType, CoefficientType, IndexType, true, rank> {
190 static KOKKOS_INLINE_FUNCTION
void
191 run(
const CoefficientType& alpha,
const ViewType& x) {
192 using x_value_type =
typename std::decay<
decltype(*x.data())>::type;
193 const IndexType span =
static_cast<IndexType
>(x.span());
194 x_value_type* __restrict x_ptr(x.data());
195#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
198 for (IndexType i = 0; i < span; ++i)
199 x_ptr[i] = alpha * x_ptr[i];
207template <
class ViewType,
209 class IndexType = int,
210 const bool is_contiguous =
false,
211 const int rank = ViewType::rank>
213 static KOKKOS_INLINE_FUNCTION
void
214 run(
const ViewType& x,
const InputType& val);
219template <
class ViewType,
222struct FILL<ViewType, InputType, IndexType, false, 1> {
223 static KOKKOS_INLINE_FUNCTION
void
224 run(
const ViewType& x,
const InputType& val) {
225 const IndexType numRows =
static_cast<IndexType
>(x.extent(0));
226 for (IndexType i = 0; i < numRows; ++i)
232template <
class ViewType,
235struct FILL<ViewType, InputType, IndexType, false, 2> {
236 static KOKKOS_INLINE_FUNCTION
void
237 run(
const ViewType& X,
const InputType& val) {
238 const IndexType numRows =
static_cast<IndexType
>(X.extent(0));
239 const IndexType numCols =
static_cast<IndexType
>(X.extent(1));
240 for (IndexType j = 0; j < numCols; ++j)
241 for (IndexType i = 0; i < numRows; ++i)
245template <
class ViewType,
249struct FILL<ViewType, InputType, IndexType, true, rank> {
250 static KOKKOS_INLINE_FUNCTION
void
251 run(
const ViewType& x,
const InputType& val) {
252 const IndexType span =
static_cast<IndexType
>(x.span());
253 auto x_ptr = x.data();
254#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
257 for (IndexType i = 0; i < span; ++i)
266template <
class CoefficientType,
269 class IndexType = int,
270 const bool is_contiguous =
false,
271 const int rank = ViewType1::rank>
273 static KOKKOS_INLINE_FUNCTION
void
274 run(
const CoefficientType& alpha,
281template <
class CoefficientType,
285struct AXPY<CoefficientType, ViewType1, ViewType2, IndexType, false, 1> {
287 static KOKKOS_INLINE_FUNCTION
void
288 run(
const CoefficientType& alpha,
290 const ViewType2& y) {
291 using KokkosKernels::ArithTraits;
292 static_assert(
static_cast<int>(ViewType1::rank) ==
static_cast<int>(ViewType2::rank),
293 "AXPY: x and y must have the same rank.");
295 const IndexType numRows =
static_cast<IndexType
>(y.extent(0));
296 if (alpha != ArithTraits<CoefficientType>::zero()) {
298 for (IndexType i = 0; i < numRows; ++i)
299 y(i) += alpha * x(i);
306template <
class CoefficientType,
310struct AXPY<CoefficientType, ViewType1, ViewType2, IndexType, false, 2> {
312 static KOKKOS_INLINE_FUNCTION
void
313 run(
const CoefficientType& alpha,
315 const ViewType2& Y) {
316 using KokkosKernels::ArithTraits;
317 static_assert(
static_cast<int>(ViewType1::rank) ==
static_cast<int>(ViewType2::rank),
318 "AXPY: X and Y must have the same rank.");
319 const IndexType numRows =
static_cast<IndexType
>(Y.extent(0));
320 const IndexType numCols =
static_cast<IndexType
>(Y.extent(1));
322 if (alpha != ArithTraits<CoefficientType>::zero()) {
323 for (IndexType j = 0; j < numCols; ++j)
324 for (IndexType i = 0; i < numRows; ++i)
325 Y(i, j) += alpha * X(i, j);
330template <
class CoefficientType,
335struct AXPY<CoefficientType, ViewType1, ViewType2, IndexType, true, rank> {
337 static KOKKOS_INLINE_FUNCTION
void
338 run(
const CoefficientType& alpha,
340 const ViewType2& y) {
341 using KokkosKernels::ArithTraits;
342 static_assert(
static_cast<int>(ViewType1::rank) ==
static_cast<int>(ViewType2::rank),
343 "AXPY: x and y must have the same rank.");
345 if (alpha != ArithTraits<CoefficientType>::zero()) {
346 using x_value_type =
typename std::decay<
decltype(*x.data())>::type;
347 using y_value_type =
typename std::decay<
decltype(*y.data())>::type;
348 const IndexType span =
static_cast<IndexType
>(y.span());
349 const x_value_type* __restrict x_ptr(x.data());
350 y_value_type* __restrict y_ptr(y.data());
351#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
354 for (IndexType i = 0; i < span; ++i)
355 y_ptr[i] += alpha * x_ptr[i];
364template <
class ViewType1,
366 class IndexType = int,
367 const bool is_contiguous =
false,
368 const int rank = ViewType1::rank>
370 static KOKKOS_INLINE_FUNCTION
void
371 run(
const ViewType1& x,
const ViewType2& y);
376template <
class ViewType1,
379struct COPY<ViewType1, ViewType2, IndexType, false, 1> {
381 static KOKKOS_INLINE_FUNCTION
void
382 run(
const ViewType1& x,
const ViewType2& y) {
383 const IndexType numRows =
static_cast<IndexType
>(x.extent(0));
385 for (IndexType i = 0; i < numRows; ++i)
392template <
class ViewType1,
395struct COPY<ViewType1, ViewType2, IndexType, false, 2> {
397 static KOKKOS_INLINE_FUNCTION
void
398 run(
const ViewType1& X,
const ViewType2& Y) {
399 const IndexType numRows =
static_cast<IndexType
>(Y.extent(0));
400 const IndexType numCols =
static_cast<IndexType
>(Y.extent(1));
402 for (IndexType j = 0; j < numCols; ++j)
403 for (IndexType i = 0; i < numRows; ++i)
408template <
class ViewType1,
412struct COPY<ViewType1, ViewType2, IndexType, true, rank> {
414 static KOKKOS_INLINE_FUNCTION
void
415 run(
const ViewType1& x,
const ViewType2& y) {
416 const IndexType span =
static_cast<IndexType
>(x.span());
417 using x_value_type =
typename std::decay<
decltype(*x.data())>::type;
418 using y_value_type =
typename std::decay<
decltype(*y.data())>::type;
419 const x_value_type* __restrict x_ptr(x.data());
420 y_value_type* __restrict y_ptr(y.data());
422#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
425 for (IndexType i = 0; i < span; ++i)
430template <
class VecType1,
434 class IndexType = int,
435 bool is_contiguous =
false,
436 class BlkLayoutType =
typename BlkType::array_layout>
438 static KOKKOS_INLINE_FUNCTION
void
439 run(
const CoeffType& alpha,
443 static_assert(VecType1::rank == 1,
"GEMV: VecType1 must have rank 1.");
444 static_assert(BlkType::rank == 2,
"GEMV: BlkType must have rank 2.");
445 static_assert(VecType2::rank == 1,
"GEMV: VecType2 must have rank 1.");
447 const IndexType numRows =
static_cast<IndexType
>(A.extent(0));
448 const IndexType numCols =
static_cast<IndexType
>(A.extent(1));
451 for (IndexType i = 0; i < numRows; ++i)
452 for (IndexType j = 0; j < numCols; ++j)
453 y(i) += alpha * A(i, j) * x(j);
457template <
class VecType1,
462struct GEMV<VecType1, BlkType, VecType2, CoeffType, IndexType, true, Kokkos::LayoutLeft> {
463 static KOKKOS_INLINE_FUNCTION
void
464 run(
const CoeffType& alpha,
468 static_assert(VecType1::rank == 1,
"GEMV: VecType1 must have rank 1.");
469 static_assert(BlkType::rank == 2,
"GEMV: BlkType must have rank 2.");
470 static_assert(VecType2::rank == 1,
"GEMV: VecType2 must have rank 1.");
472 using A_value_type =
typename std::decay<
decltype(A(0, 0))>::type;
473 using x_value_type =
typename std::decay<
decltype(x(0))>::type;
474 using y_value_type =
typename std::decay<
decltype(y(0))>::type;
476 const IndexType numRows =
static_cast<IndexType
>(A.extent(0));
477 const IndexType numCols =
static_cast<IndexType
>(A.extent(1));
479 const A_value_type* __restrict A_ptr(A.data());
480 const IndexType as1(A.stride(1));
481 const x_value_type* __restrict x_ptr(x.data());
482 y_value_type* __restrict y_ptr(y.data());
484#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
487 for (IndexType j = 0; j < numCols; ++j) {
488 const x_value_type x_at_j = alpha * x_ptr[j];
489 const A_value_type* __restrict A_at_j = A_ptr + j * as1;
490#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
493 for (IndexType i = 0; i < numRows; ++i)
494 y_ptr[i] += A_at_j[i] * x_at_j;
499template <
class VecType1,
504struct GEMV<VecType1, BlkType, VecType2, CoeffType, IndexType, true, Kokkos::LayoutRight> {
505 static KOKKOS_INLINE_FUNCTION
void
506 run(
const CoeffType& alpha,
510 static_assert(VecType1::rank == 1,
"GEMV: VecType1 must have rank 1.");
511 static_assert(BlkType::rank == 2,
"GEMV: BlkType must have rank 2.");
512 static_assert(VecType2::rank == 1,
"GEMV: VecType2 must have rank 1.");
514 using A_value_type =
typename std::decay<
decltype(A(0, 0))>::type;
515 using x_value_type =
typename std::decay<
decltype(x(0))>::type;
516 using y_value_type =
typename std::decay<
decltype(y(0))>::type;
518 const IndexType numRows =
static_cast<IndexType
>(A.extent(0));
519 const IndexType numCols =
static_cast<IndexType
>(A.extent(1));
521 const A_value_type* __restrict A_ptr(A.data());
522 const IndexType as0(A.stride(0));
523 const x_value_type* __restrict x_ptr(x.data());
524 y_value_type* __restrict y_ptr(y.data());
526#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
529 for (IndexType i = 0; i < numRows; ++i) {
530 y_value_type y_at_i(0);
531 const auto A_at_i = A_ptr + i * as0;
532#if defined(KOKKOS_ENABLE_PRAGMA_UNROLL)
535 for (IndexType j = 0; j < numCols; ++j)
536 y_at_i += A_at_i[j] * x_ptr[j];
537 y_ptr[i] += alpha * y_at_i;
546template <
class ViewType,
547 class CoefficientType,
548 class IndexType = int,
549 const int rank = ViewType::rank>
550KOKKOS_INLINE_FUNCTION
void
551SCAL(
const CoefficientType& alpha,
const ViewType& x) {
552 using LayoutType =
typename ViewType::array_layout;
553 constexpr bool is_contiguous = (std::is_same<LayoutType, Kokkos::LayoutLeft>::value ||
554 std::is_same<LayoutType, Kokkos::LayoutRight>::value);
555 Impl::SCAL<ViewType, CoefficientType, IndexType, is_contiguous, rank>::run(alpha, x);
559template <
class ViewType,
561 class IndexType = int,
562 const int rank = ViewType::rank>
563KOKKOS_INLINE_FUNCTION
void
564FILL(
const ViewType& x,
const InputType& val) {
565 using LayoutType =
typename ViewType::array_layout;
566 constexpr bool is_contiguous = (std::is_same<LayoutType, Kokkos::LayoutLeft>::value ||
567 std::is_same<LayoutType, Kokkos::LayoutRight>::value);
568 Impl::FILL<ViewType, InputType, IndexType, is_contiguous, rank>::run(x, val);
576template <
class CoefficientType,
579 class IndexType = int,
580 const int rank = ViewType1::rank>
581KOKKOS_INLINE_FUNCTION
void
582AXPY(
const CoefficientType& alpha,
584 const ViewType2& y) {
585 static_assert(
static_cast<int>(ViewType1::rank) ==
586 static_cast<int>(ViewType2::rank),
587 "AXPY: x and y must have the same rank.");
588 using LayoutType1 =
typename ViewType1::array_layout;
589 using LayoutType2 =
typename ViewType2::array_layout;
590 constexpr bool is_layout_same = std::is_same<LayoutType1, LayoutType2>::value;
591 constexpr bool is_x_contiguous = (std::is_same<LayoutType1, Kokkos::LayoutLeft>::value ||
592 std::is_same<LayoutType1, Kokkos::LayoutRight>::value);
593 constexpr bool is_contiguous = is_layout_same && is_x_contiguous;
594 Impl::AXPY<CoefficientType, ViewType1, ViewType2, IndexType, is_contiguous, rank>::run(alpha, x, y);
605template <
class ViewType1,
607 class IndexType = int,
608 const int rank = ViewType1::rank>
609KOKKOS_INLINE_FUNCTION
void
610COPY(
const ViewType1& x,
const ViewType2& y) {
611 static_assert(
static_cast<int>(ViewType1::rank) ==
612 static_cast<int>(ViewType2::rank),
613 "COPY: x and y must have the same rank.");
614 using LayoutType1 =
typename ViewType1::array_layout;
615 using LayoutType2 =
typename ViewType2::array_layout;
616 constexpr bool is_layout_same = std::is_same<LayoutType1, LayoutType2>::value;
617 constexpr bool is_x_contiguous = (std::is_same<LayoutType1, Kokkos::LayoutLeft>::value ||
618 std::is_same<LayoutType1, Kokkos::LayoutRight>::value);
619 constexpr bool is_contiguous = is_layout_same && is_x_contiguous;
620 Impl::COPY<ViewType1, ViewType2, IndexType, is_contiguous, rank>::run(x, y);
634template <
class VecType1,
638 class IndexType =
int>
639KOKKOS_INLINE_FUNCTION
void
644 constexpr bool is_A_contiguous = (std::is_same<typename BlkType::array_layout, Kokkos::LayoutLeft>::value ||
645 std::is_same<typename BlkType::array_layout, Kokkos::LayoutRight>::value);
646 constexpr bool is_x_contiguous = (std::is_same<typename VecType1::array_layout, Kokkos::LayoutLeft>::value ||
647 std::is_same<typename VecType1::array_layout, Kokkos::LayoutRight>::value);
648 constexpr bool is_y_contiguous = (std::is_same<typename VecType2::array_layout, Kokkos::LayoutLeft>::value ||
649 std::is_same<typename VecType2::array_layout, Kokkos::LayoutRight>::value);
650 constexpr bool is_contiguous = is_A_contiguous && is_x_contiguous && is_y_contiguous;
651 Impl::GEMV<VecType1, BlkType, VecType2, CoeffType, IndexType, is_contiguous>::run(alpha, A, x, y);
661template <
class ViewType1,
664 class CoefficientType,
665 class IndexType =
int>
666KOKKOS_INLINE_FUNCTION
void
669 const CoefficientType& alpha,
672 const CoefficientType& beta,
673 const ViewType3& C) {
675 static_assert(ViewType1::rank == 2,
"GEMM: A must have rank 2 (be a matrix).");
676 static_assert(ViewType2::rank == 2,
"GEMM: B must have rank 2 (be a matrix).");
677 static_assert(ViewType3::rank == 2,
"GEMM: C must have rank 2 (be a matrix).");
679 typedef typename std::remove_reference<
decltype(A(0, 0))>::type Scalar;
680 typedef KokkosKernels::ArithTraits<Scalar> STS;
681 const Scalar
ZERO = STS::zero();
682 const Scalar ONE = STS::one();
686 if (transA[0] ==
'N' || transA[0] ==
'n') {
687 m =
static_cast<IndexType
>(A.extent(0));
688 n =
static_cast<IndexType
>(A.extent(1));
690 m =
static_cast<IndexType
>(A.extent(1));
691 n =
static_cast<IndexType
>(A.extent(0));
693 k =
static_cast<IndexType
>(C.extent(1));
696 if (alpha ==
ZERO && beta == ONE)
702 for (IndexType i = 0; i < m; i++) {
703 for (IndexType j = 0; j < k; j++) {
708 for (IndexType i = 0; i < m; i++) {
709 for (IndexType j = 0; j < k; j++) {
710 C(i, j) = beta * C(i, j);
717 if (transB[0] ==
'n' || transB[0] ==
'N') {
718 if (transA[0] ==
'n' || transA[0] ==
'N') {
720 for (IndexType j = 0; j < n; j++) {
722 for (IndexType i = 0; i < m; i++) {
725 }
else if (beta != ONE) {
726 for (IndexType i = 0; i < m; i++) {
727 C(i, j) = beta * C(i, j);
730 for (IndexType l = 0; l < k; l++) {
731 Scalar temp = alpha * B(l, j);
732 for (IndexType i = 0; i < m; i++) {
733 C(i, j) = C(i, j) + temp * A(i, l);
739 for (IndexType j = 0; j < n; j++) {
740 for (IndexType i = 0; i < m; i++) {
742 for (IndexType l = 0; l < k; l++) {
743 temp = temp + A(l, i) * B(l, j);
746 C(i, j) = alpha * temp;
748 C(i, j) = alpha * temp + beta * C(i, j);
754 if (transA[0] ==
'n' || transA[0] ==
'N') {
756 for (IndexType j = 0; j < n; j++) {
758 for (IndexType i = 0; i < m; i++) {
761 }
else if (beta != ONE) {
762 for (IndexType i = 0; i < m; i++) {
763 C(i, j) = beta * C(i, j);
766 for (IndexType l = 0; l < k; l++) {
767 Scalar temp = alpha * B(j, l);
768 for (IndexType i = 0; i < m; i++) {
769 C(i, j) = C(i, j) + temp * A(i, l);
775 for (IndexType j = 0; j < n; j++) {
776 for (IndexType i = 0; i < m; i++) {
778 for (IndexType l = 0; l < k; l++) {
779 temp = temp + A(l, i) * B(j, l);
782 C(i, j) = alpha * temp;
784 C(i, j) = alpha * temp + beta * C(i, j);
793template <
class LittleBlockType,
794 class LittleVectorType>
795KOKKOS_INLINE_FUNCTION
void
796GETF2(
const LittleBlockType& A,
const LittleVectorType& ipiv,
int& info) {
798 typedef typename std::decay<
decltype(ipiv(0))>::type IndexType;
799 static_assert(std::is_integral<IndexType>::value,
800 "GETF2: The type of each entry of ipiv must be an integer type.");
801 typedef typename std::remove_reference<
decltype(A(0, 0))>::type Scalar;
802 static_assert(!std::is_const<Scalar>::value,
803 "GETF2: A must not be a const View (or LittleBlock).");
804 static_assert(!std::is_const<std::remove_reference<
decltype(ipiv(0))>>::value,
805 "GETF2: ipiv must not be a const View (or LittleBlock).");
806 static_assert(LittleBlockType::rank == 2,
"GETF2: A must have rank 2 (be a matrix).");
807 typedef KokkosKernels::ArithTraits<Scalar> STS;
808 const Scalar
ZERO = STS::zero();
810 const IndexType numRows =
static_cast<IndexType
>(A.extent(0));
811 const IndexType numCols =
static_cast<IndexType
>(A.extent(1));
812 const IndexType pivDim =
static_cast<IndexType
>(ipiv.extent(0));
815 const IndexType minPivDim = (numRows < numCols) ? numRows : numCols;
816 if (pivDim < minPivDim) {
824 for (IndexType j = 0; j < pivDim; j++) {
827 for (IndexType i = j + 1; i < numRows; i++) {
828 if (STS::abs(A(i, j)) > STS::abs(A(jp, j))) {
834 if (A(jp, j) !=
ZERO) {
837 for (IndexType i = 0; i < numCols; i++) {
838 Scalar temp = A(jp, i);
845 for (IndexType i = j + 1; i < numRows; i++) {
846 A(i, j) = A(i, j) / A(j, j);
848 }
else if (info == 0) {
853 for (IndexType r = j + 1; r < numRows; r++) {
854 for (IndexType c = j + 1; c < numCols; c++) {
855 A(r, c) = A(r, c) - A(r, j) * A(j, c);
866template <
class LittleBlockType,
867 class LittleIntVectorType,
868 class LittleScalarVectorType,
869 const int rank = LittleScalarVectorType::rank>
871 static KOKKOS_INLINE_FUNCTION
void
872 run(
const char mode[],
873 const LittleBlockType& A,
874 const LittleIntVectorType& ipiv,
875 const LittleScalarVectorType& B,
880template <
class LittleBlockType,
881 class LittleIntVectorType,
882 class LittleScalarVectorType>
883struct GETRS<LittleBlockType, LittleIntVectorType, LittleScalarVectorType, 1> {
884 static KOKKOS_INLINE_FUNCTION
void
885 run(
const char mode[],
886 const LittleBlockType& A,
887 const LittleIntVectorType& ipiv,
888 const LittleScalarVectorType& B,
891 typedef typename std::decay<
decltype(ipiv(0))>::type IndexType;
894 static_assert(std::is_integral<IndexType>::value &&
895 std::is_signed<IndexType>::value,
896 "GETRS: The type of each entry of ipiv must be a signed integer.");
897 typedef typename std::decay<
decltype(A(0, 0))>::type Scalar;
898 static_assert(!std::is_const<std::remove_reference<
decltype(B(0))>>::value,
899 "GETRS: B must not be a const View (or LittleBlock).");
900 static_assert(LittleBlockType::rank == 2,
"GETRS: A must have rank 2 (be a matrix).");
901 static_assert(LittleIntVectorType::rank == 1,
"GETRS: ipiv must have rank 1.");
902 static_assert(LittleScalarVectorType::rank == 1,
"GETRS: For this specialization, B must have rank 1.");
904 typedef KokkosKernels::ArithTraits<Scalar> STS;
905 const Scalar
ZERO = STS::zero();
906 const IndexType numRows =
static_cast<IndexType
>(A.extent(0));
907 const IndexType numCols =
static_cast<IndexType
>(A.extent(1));
908 const IndexType pivDim =
static_cast<IndexType
>(ipiv.extent(0));
913 if (numRows != numCols) {
919 if (pivDim < numRows) {
925 if (mode[0] ==
'n' || mode[0] ==
'N') {
927 for (IndexType i = 0; i < numRows; i++) {
928 if (ipiv(i) != i + 1) {
930 B(i) = B(ipiv(i) - 1);
931 B(ipiv(i) - 1) = temp;
936 for (IndexType r = 1; r < numRows; r++) {
937 for (IndexType c = 0; c < r; c++) {
938 B(r) = B(r) - A(r, c) * B(c);
943 for (IndexType r = numRows - 1; r >= 0; r--) {
945 if (A(r, r) ==
ZERO) {
950 for (IndexType c = r + 1; c < numCols; c++) {
951 B(r) = B(r) - A(r, c) * B(c);
953 B(r) = B(r) / A(r, r);
957 else if (mode[0] ==
't' || mode[0] ==
'T') {
962 else if (mode[0] ==
'c' || mode[0] ==
'C') {
973template <
class LittleBlockType,
974 class LittleIntVectorType,
975 class LittleScalarVectorType>
976struct GETRS<LittleBlockType, LittleIntVectorType, LittleScalarVectorType, 2> {
977 static KOKKOS_INLINE_FUNCTION
void
978 run(
const char mode[],
979 const LittleBlockType& A,
980 const LittleIntVectorType& ipiv,
981 const LittleScalarVectorType& B,
984 typedef typename std::decay<
decltype(ipiv(0))>::type IndexType;
985 static_assert(std::is_integral<IndexType>::value,
986 "GETRS: The type of each entry of ipiv must be an integer type.");
987 static_assert(!std::is_const<std::remove_reference<
decltype(B(0))>>::value,
988 "GETRS: B must not be a const View (or LittleBlock).");
989 static_assert(LittleBlockType::rank == 2,
"GETRS: A must have rank 2 (be a matrix).");
990 static_assert(LittleIntVectorType::rank == 1,
"GETRS: ipiv must have rank 1.");
991 static_assert(LittleScalarVectorType::rank == 2,
"GETRS: For this specialization, B must have rank 2.");
996 const IndexType numRhs = B.extent(1);
999 for (IndexType rhs = 0; rhs < numRhs; ++rhs) {
1000 auto B_cur = Kokkos::subview(B, Kokkos::ALL(), rhs);
1001 GETRS<LittleBlockType, LittleIntVectorType,
decltype(B_cur), 1>::run(mode, A, ipiv, B_cur, info);
1014template <
class LittleBlockType,
1015 class LittleIntVectorType,
1016 class LittleScalarVectorType>
1017KOKKOS_INLINE_FUNCTION
void
1019 const LittleBlockType& A,
1020 const LittleIntVectorType& ipiv,
1021 const LittleScalarVectorType& B,
1023 Impl::GETRS<LittleBlockType, LittleIntVectorType, LittleScalarVectorType,
1024 LittleScalarVectorType::rank>::run(mode, A, ipiv, B, info);
1041template <
class LittleBlockType,
1042 class LittleIntVectorType,
1043 class LittleScalarVectorType>
1044KOKKOS_INLINE_FUNCTION
void
1046 const LittleIntVectorType& ipiv,
1047 const LittleScalarVectorType& work,
1050 typedef typename std::decay<
decltype(ipiv(0))>::type IndexType;
1053 static_assert(std::is_integral<IndexType>::value &&
1054 std::is_signed<IndexType>::value,
1055 "GETRI: The type of each entry of ipiv must be a signed integer.");
1056 typedef typename std::remove_reference<
decltype(A(0, 0))>::type Scalar;
1057 static_assert(!std::is_const<std::remove_reference<
decltype(A(0, 0))>>::value,
1058 "GETRI: A must not be a const View (or LittleBlock).");
1059 static_assert(!std::is_const<std::remove_reference<
decltype(work(0))>>::value,
1060 "GETRI: work must not be a const View (or LittleBlock).");
1061 static_assert(LittleBlockType::rank == 2,
"GETRI: A must have rank 2 (be a matrix).");
1062 typedef KokkosKernels::ArithTraits<Scalar> STS;
1063 const Scalar
ZERO = STS::zero();
1064 const Scalar ONE = STS::one();
1066 const IndexType numRows =
static_cast<IndexType
>(A.extent(0));
1067 const IndexType numCols =
static_cast<IndexType
>(A.extent(1));
1068 const IndexType pivDim =
static_cast<IndexType
>(ipiv.extent(0));
1069 const IndexType workDim =
static_cast<IndexType
>(work.extent(0));
1074 if (numRows != numCols) {
1080 if (pivDim < numRows) {
1086 if (workDim < numRows) {
1092 for (IndexType j = 0; j < numRows; j++) {
1093 if (A(j, j) ==
ZERO) {
1098 A(j, j) = ONE / A(j, j);
1101 for (IndexType r = 0; r < j; r++) {
1102 A(r, j) = A(r, r) * A(r, j);
1103 for (IndexType c = r + 1; c < j; c++) {
1104 A(r, j) = A(r, j) + A(r, c) * A(c, j);
1107 for (IndexType r = 0; r < j; r++) {
1108 A(r, j) = -A(j, j) * A(r, j);
1113 for (IndexType j = numCols - 2; j >= 0; j--) {
1115 for (IndexType r = j + 1; r < numRows; r++) {
1120 for (IndexType r = 0; r < numRows; r++) {
1121 for (IndexType i = j + 1; i < numRows; i++) {
1122 A(r, j) = A(r, j) - work(i) * A(r, i);
1128 for (IndexType j = numRows - 1; j >= 0; j--) {
1129 IndexType jp = ipiv(j) - 1;
1131 for (IndexType r = 0; r < numRows; r++) {
1132 Scalar temp = A(r, j);
1144template<
class LittleBlockType,
1145 class LittleVectorTypeX,
1146 class LittleVectorTypeY,
1147 class CoefficientType,
1148 class IndexType =
int>
1149KOKKOS_INLINE_FUNCTION
void
1150GEMV (
const char trans,
1151 const CoefficientType& alpha,
1152 const LittleBlockType& A,
1153 const LittleVectorTypeX& x,
1154 const CoefficientType& beta,
1155 const LittleVectorTypeY& y)
1161 typedef typename std::remove_reference<
decltype (y(0)) >::type y_value_type;
1162 const IndexType numRows =
static_cast<IndexType
> (A.extent (0));
1163 const IndexType numCols =
static_cast<IndexType
> (A.extent (1));
1167 for (IndexType i = 0; i < numRows; ++i) {
1172 for (IndexType i = 0; i < numRows; ++i) {
1173 y_value_type y_i = 0.0;
1174 for (IndexType j = 0; j < numCols; ++j) {
1175 y_i += A(i,j) * x(j);
1184 for (IndexType i = 0; i < numRows; ++i) {
1189 for (IndexType i = 0; i < numRows; ++i) {
1195 for (IndexType i = 0; i < numRows; ++i) {
1196 y_value_type y_i = beta * y(i);
1197 for (IndexType j = 0; j < numCols; ++j) {
1198 y_i += alpha * A(i,j) * x(j);
Namespace for new Tpetra features that are not ready for public release, but are ready for evaluation...
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.