10#ifndef BELOS_KOKKOS_DENSE_MAT_TRAITS_HPP
11#define BELOS_KOKKOS_DENSE_MAT_TRAITS_HPP
19#include "Teuchos_Assert.hpp"
20#include "Teuchos_RCP.hpp"
21#include "Teuchos_ScalarTraits.hpp"
22#include "Teuchos_BLAS.hpp"
23#include "Teuchos_LAPACK.hpp"
26#include "Kokkos_DualView.hpp"
27#include "Kokkos_Random.hpp"
28#include "KokkosKernels_ArithTraits.hpp"
29#include "KokkosBlas1_scal.hpp"
30#include "KokkosBlas1_axpby.hpp"
40 Kokkos::parallel_for(Kokkos::MDRangePolicy<
typename V::execution_space, Kokkos::Rank<2>>({0, 0}, {dst.extent(0), dst.extent(1)}),
41 KOKKOS_LAMBDA(
int i,
int j)
43 dst(i, j) = KokkosKernels::ArithTraits<typename V::non_const_value_type>::conj( src(j, i) );
48 template<
class Scalar,
class DM>
52 typedef typename KokkosKernels::ArithTraits<Scalar>::val_type
IST;
105 Teuchos::LAPACK<int,Scalar> lapack;
109 int Min_MN = TEUCHOS_MIN(M,N);
112 IPIV_.resize( Min_MN );
124 MagnitudeType ROWCND, COLCND, AMAX;
126 lapack.POEQU (M, Aptr, LDA, &R_[0], &ROWCND, &AMAX, &INFO);
128 lapack.GEEQU (M, N, Aptr, LDA, &R_[0], &C_[0], &ROWCND, &COLCND, &AMAX, &INFO);
136 for (
int j=0; j<N; j++) {
139 for (
int i=0; i<=j; i++) {
140 *ptr = *ptr*s1*R_[i];
147 for (
int j=0; j<N; j++) {
150 for (
int i=0; i<M; i++) {
151 *ptr = *ptr*s1*R_[i];
160 lapack.POTRF(
'U', M, Aptr, LDA, &INFO);
163 lapack.GETRF(M, N, Aptr, LDA, &IPIV_[0], &INFO);
178 bool transpose = (
TRANS_ != Teuchos::NO_TRANS) ?
true :
false;
196 MagnitudeType * R_tmp = (transpose && !
spd_) ? &C_[0] : &R_[0];
199 for (
int j=0; j<NRHS; j++) {
201 for (
int i=0; i<M; i++) {
202 *ptr = *ptr*R_tmp[i];
212 Teuchos::LAPACK<int,Scalar> lapack;
215 lapack.POTRS(
'U', M, NRHS, Aptr, LDA, X, LDX, &INFO);
218 lapack.GETRS(Teuchos::ETranspChar[
TRANS_], M, NRHS,
219 Aptr, LDA, &IPIV_[0], X, LDX, &INFO);
225 MagnitudeType * C_tmp = (
spd_ || transpose) ? &R_[0] : &C_[0];
228 for (
int j=0; j<NRHS; j++) {
230 for (
int i=0; i<M; i++) {
231 *ptr = *ptr*C_tmp[i];
246 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType MagnitudeType;
248 std::vector<int> IPIV_;
249 std::vector<MagnitudeType> R_, C_;
264 template<
class Scalar,
class... Properties>
265 class DenseMatTraits<Scalar, Kokkos::DualView<typename KokkosKernels::ArithTraits<Scalar>::val_type **,Properties...>>{
268 typedef typename KokkosKernels::ArithTraits<Scalar>::val_type
IST;
269 using DM = Kokkos::DualView<
IST**,Properties...>;
278 return Teuchos::rcp(
new DM(
"BelosDenseCreate",0,0));
287 static Teuchos::RCP<DM>
288 Create(
const int numRows,
const int numCols,
bool initZero =
true) {
290 return Teuchos::rcp(
new DM(
"BelosDenseCreate2",numRows,numCols));
293 return Teuchos::rcp(
new DM(Kokkos::view_alloc(Kokkos::WithoutInitializing,
"BelosDenseCreate2"),numRows,numCols));
301 static Teuchos::RCP<DM>
304 Teuchos::RCP<DM> tmpCopyRCP = Teuchos::null;
308 tmpCopyRCP = Teuchos::rcp(
new DM
309 (Kokkos::view_alloc(Kokkos::WithoutInitializing,
"BelosDenseCreateCopy"),dm.extent_int(1),dm.extent_int(0)));
310 if(tmpCopyRCP->need_sync_device()) {
313 tmpCopyRCP->clear_sync_state();
314 tmpCopyRCP->modify_host();
318 tmpCopyRCP->clear_sync_state();
319 tmpCopyRCP->modify_device();
323 tmpCopyRCP = Teuchos::rcp(
new DM
324 (Kokkos::view_alloc(Kokkos::WithoutInitializing,
"BelosDenseCreateCopy"),dm.extent_int(0),dm.extent_int(1)));
325 Kokkos::deep_copy(*tmpCopyRCP, dm);
343 return reinterpret_cast<Scalar*
>(dm.view_host().data());
355 const_cast<DM*
>(&dm)->sync_host();
356 return reinterpret_cast<Scalar
const *
>(dm.view_host().data());
361 static Teuchos::RCP<DM>
362 Subview(
DM & source,
int numRows,
int numCols,
int startRow=0,
int startCol=0){
363 return Teuchos::rcp(
new DM(source,
364 Kokkos::pair<int,int>(startRow,startRow+numRows), Kokkos::pair<int,int>(startCol,startCol+numCols)));
367 static Teuchos::RCP<const DM>
368 SubviewConst(
const DM& source,
int numRows,
int numCols,
int startRow=0,
int startCol=0){
369 return Teuchos::rcp(
new DM(source,
370 Kokkos::pair<int,int>(startRow,startRow+numRows), Kokkos::pair<int,int>(startCol,startCol+numCols)));
374 static Teuchos::RCP<DM>
375 SubviewCopy(
const DM& source,
int numRows,
int numCols,
int startRow=0,
int startCol=0){
380 auto tmpViewRCP = Teuchos::rcp(
new DM
381 (Kokkos::view_alloc(Kokkos::WithoutInitializing,
"BelosDenseSubViewCopy"),numRows,numCols));
387 Kokkos::deep_copy(*tmpViewRCP, Kokkos::subview(source,
388 Kokkos::pair<int,int>(startRow,startRow+numRows), Kokkos::pair<int,int>(startCol,startCol+numCols)));
397 return dm.extent_int(0);
402 return dm.extent_int(1);
427 static void Reshape(
DM& dm,
const int numRows,
const int numCols,
bool initZero =
false) {
429 dm.realloc(numRows,numCols);
430 Kokkos::deep_copy(dm.view_device(), 0.0);
433 dm.resize(numRows,numCols);
442 static Scalar &
Value(
DM& dm,
const int i,
const int j )
447 return reinterpret_cast<Scalar&
>((dm.view_host())(i,j));
451 static const Scalar &
ValueConst(
const DM& dm,
const int i,
const int j ) {
453 const_cast<DM*
>(&dm)->sync_host();
454 return reinterpret_cast<Scalar
const &
>((dm.view_host())(i,j));
466 if(dm.need_sync_host()){
467 if(dm.view_host().span_is_contiguous() && dm.view_device().span_is_contiguous()){
470 DM compat_view(
"compat view",dm.extent_int(0),dm.extent_int(1));
471 Kokkos::deep_copy(compat_view,dm);
472 compat_view.sync_host();
473 Kokkos::deep_copy(dm,compat_view);
474 dm.clear_sync_state();
480 if(dm.need_sync_device()){
481 if(dm.view_host().span_is_contiguous() && dm.view_device().span_is_contiguous()){
485 DM compat_view(
"compat view",dm.extent_int(0),dm.extent_int(1));
486 Kokkos::deep_copy(compat_view,dm);
487 compat_view.sync_device();
488 Kokkos::deep_copy(dm,compat_view);
489 dm.clear_sync_state();
497 static void Add(
DM& thisDM,
const DM& sourceDM) {
498 thisDM.sync_device();
500 const_cast<DM*
>(&sourceDM)->sync_device();
501 KokkosBlas::axpy(1.0,sourceDM.view_device(), thisDM.view_device());
502 thisDM.modify_device();
506 static void PutScalar(
DM& dm, Scalar value = Teuchos::ScalarTraits<Scalar>::zero()){
507 dm.clear_sync_state();
508 Kokkos::deep_copy( dm.view_device(), value);
515 KokkosBlas::scal( dm.view_device(), value, dm.view_device());
522 int rand_seed = std::rand();
523 Kokkos::Random_XorShift64_Pool<> pool(rand_seed);
524 dm.clear_sync_state();
525 Kokkos::fill_random(dm.view_device(), pool, -1,1);
531 Kokkos::deep_copy(dest,source);
535 static typename Teuchos::ScalarTraits<Scalar>::magnitudeType
NormFrobenius(
const DM& dm) {
536 using KAT = KokkosKernels::ArithTraits<IST>;
537 using mag_t =
typename KAT::mag_type;
539 const_cast<DM*
>(&dm)->sync_device();
541 Kokkos::parallel_reduce(Kokkos::MDRangePolicy<Kokkos::Rank<2>>({0, 0}, {dm.extent(0), dm.extent(1)}),
542 KOKKOS_LAMBDA(
size_t i,
size_t j, mag_t& lfrobNorm)
544 mag_t absVal = KAT::abs((dm.view_device())(i, j));
545 lfrobNorm += absVal * absVal;
547 return Kokkos::sqrt(frobNorm);
551 static typename Teuchos::ScalarTraits<Scalar>::magnitudeType
NormOne(
const DM& dm) {
552 using KAT = KokkosKernels::ArithTraits<IST>;
553 using mag_t =
typename KAT::mag_type;
555 const_cast<DM*
>(&dm)->sync_device();
558 Kokkos::parallel_reduce(dm.extent(1), KOKKOS_LAMBDA(
const int j, mag_t& norm) {
560 for(
int i = 0; i < dm.extent_int(0); i++){
561 sum += KAT::abs((dm.view_device())(i,j));
563 norm = Kokkos::max(norm, sum);
564 }, Kokkos::Max<mag_t>(max_sum));
565 return KAT::abs(max_sum);
572 static Teuchos::RCP<DenseSolver<Scalar, DM>>
575 Teuchos::RCP<DenseSolver<Scalar, DM>> newSolver
static void Randomize(DM &dm)
Fill the Kokkos::DualView with random entries. Entries are assumed to be the same on each MPI rank (e...
static int GetNumRows(const DM &dm)
Obtain the number of rows of dm.
static void SyncHostToDevice(DM &dm)
static Teuchos::RCP< DM > Subview(DM &source, int numRows, int numCols, int startRow=0, int startCol=0)
Returns an RCP to a Kokkos::DualView which has a subview of the given Kokkos::DualView.
static Teuchos::RCP< DM > SubviewCopy(const DM &source, int numRows, int numCols, int startRow=0, int startCol=0)
Returns a deep copy of the requested subview.
static Teuchos::RCP< DM > Create()
Creates a new empty Kokkos::DualView with no dimension.
static Teuchos::RCP< DenseSolver< Scalar, DM > > createDenseSolver()
Returns a dense solver object for the dense matrix.
static Teuchos::RCP< DM > Create(const int numRows, const int numCols, bool initZero=true)
Creates a new empty Kokkos::DualView containing and numRows rows and numCols columns....
static Scalar * GetRawHostPtr(DM &dm)
Returns a raw pointer to the (non-const) data on the host.
static Teuchos::RCP< DM > CreateCopy(const DM &dm, bool transpose=false)
Create a new copy DM, possibly transposed.
static int GetNumCols(const DM &dm)
Obtain the number of columns of dm.
static const Scalar & ValueConst(const DM &dm, const int i, const int j)
Access a const reference to the (i,j) entry of dm, e_i^T dm e_j.
static void Reshape(DM &dm, const int numRows, const int numCols, bool initZero=false)
KokkosKernels::ArithTraits< Scalar >::val_type IST
static Scalar & Value(DM &dm, const int i, const int j)
Access a reference to the (i,j) entry of dm, e_i^T dm e_j.
static void SyncDeviceToHost(DM &dm)
If an accelorator is in use, sync it to device on this call.
static Scalar const * GetConstRawHostPtr(const DM &dm)
Returns a raw pointer to const data on the host.
static int GetStride(const DM &dm)
Obtain the stride between the columns of dm.
static Teuchos::RCP< const DM > SubviewConst(const DM &source, int numRows, int numCols, int startRow=0, int startCol=0)
static void Assign(DM &dest, const DM &source)
Copies entries of source to dest (deep copy).
static Teuchos::ScalarTraits< Scalar >::magnitudeType NormOne(const DM &dm)
Returns the one-norm of the dense matrix.
static void PutScalar(DM &dm, Scalar value=Teuchos::ScalarTraits< Scalar >::zero())
Fill all entries with value. Value is zero if not specified.
static void Add(DM &thisDM, const DM &sourceDM)
Adds sourceDM to thisDM and returns answer in thisDM.
static void Scale(DM &dm, Scalar value)
Multiply all entries by a scalar. DM = value.*DM.
static Teuchos::ScalarTraits< Scalar >::magnitudeType NormFrobenius(const DM &dm)
Returns the Frobenius norm of the dense matrix.
Kokkos::DualView< IST **, Properties... > DM
Virtual base class which defines basic traits for the multi-vector type.
static void SyncHostToDevice(DM &dm)
static int GetNumRows(const DM &dm)
static Scalar * GetRawHostPtr(DM &dm)
static void SyncDeviceToHost(DM &dm)
static void Assign(DM &thisDM, const DM &sourceDM)
static int GetStride(const DM &dm)
static int GetNumCols(const DM &dm)
void solveWithTransposeFlag(Teuchos::ETransp trans)
virtual int setMatrix(const Teuchos::RCP< DM > &A)
virtual int setVectors(const Teuchos::RCP< DM > &X, const Teuchos::RCP< DM > &B)
void factorWithEquilibration(bool flag)
Full specialization of Belos::DenseMatSolver for Kokkos::DualView.
virtual ~KokkosDenseSolver()
KokkosDenseSolver destructor.
int solve()
Computes the solution X to AX = B for the this matrix and the B provided.
int factor()
Computes the in-place LU factorization of the matrix.
KokkosDenseSolver()
Default constructor; matrix should be set using setMatrix(), LHS and RHS set with setVectors().
KokkosKernels::ArithTraits< Scalar >::val_type IST
DenseMatTraits< Scalar, DM > DMT
void kokkos_transpose(const V &dst, const V &src)
Helper function for copying Kokkos::DualView into conjugate Kokkos::DualView.