52#ifndef AMESOS2_UTIL_HPP
53#define AMESOS2_UTIL_HPP
55#include "Amesos2_config.h"
57#include "Teuchos_RCP.hpp"
58#include "Teuchos_BLAS_types.hpp"
59#include "Teuchos_Array.hpp"
60#include "Teuchos_ArrayView.hpp"
61#include "Teuchos_FancyOStream.hpp"
63#include <Tpetra_Map.hpp>
64#include <Tpetra_DistObject_decl.hpp>
65#include <Tpetra_ComputeGatherMap.hpp>
71#ifdef HAVE_AMESOS2_EPETRA
72#include <Epetra_Map.h>
75#ifdef HAVE_AMESOS2_METIS
90 using Teuchos::ArrayView;
93 using Meta::if_then_else;
111 template <
typename LO,
typename GO,
typename GS,
typename Node>
112 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
113 getGatherMap(
const Teuchos::RCP<
const Tpetra::Map<LO,GO,Node> > &map );
116 template <
typename LO,
typename GO,
typename GS,
typename Node>
117 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
119 GS num_global_elements,
120 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
122 const Teuchos::RCP<
const Tpetra::Map<LO,GO,Node> >& map = Teuchos::null);
125#ifdef HAVE_AMESOS2_EPETRA
132 template <
typename LO,
typename GO,
typename GS,
typename Node>
133 RCP<Tpetra::Map<LO,GO,Node> >
141 template <
typename LO,
typename GO,
typename GS,
typename Node>
165 template <
typename Scalar,
166 typename GlobalOrdinal,
167 typename GlobalSizeT>
169 ArrayView<GlobalOrdinal> indices,
170 ArrayView<GlobalSizeT> ptr,
171 ArrayView<Scalar> trans_vals,
172 ArrayView<GlobalOrdinal> trans_indices,
173 ArrayView<GlobalSizeT> trans_ptr);
188 template <
typename Scalar1,
typename Scalar2>
189 void scale(ArrayView<Scalar1> vals,
size_t l,
190 size_t ld, ArrayView<Scalar2> s);
210 template <
typename Scalar1,
typename Scalar2,
class BinaryOp>
211 void scale(ArrayView<Scalar1> vals,
size_t l,
212 size_t ld, ArrayView<Scalar2> s, BinaryOp binary_op);
216 void printLine( Teuchos::FancyOStream &out );
221 template <
class T0,
class T1 >
222 struct getStdCplxType
224 using common_type =
typename std::common_type<T0,T1>::type;
225 using type = common_type;
228 template <
class T0,
class T1 >
229 struct getStdCplxType< T0, T1* >
231 using common_type =
typename std::common_type<T0,T1>::type;
232 using type = common_type;
235#if defined(HAVE_TEUCHOS_COMPLEX) && defined(HAVE_AMESOS2_KOKKOS)
236 template <
class T0 >
237 struct getStdCplxType< T0, Kokkos::complex<T0>* >
239 using type = std::complex<T0>;
242 template <
class T0 ,
class T1 >
243 struct getStdCplxType< T0, Kokkos::complex<T1>* >
245 using common_type =
typename std::common_type<T0,T1>::type;
246 using type = std::complex<common_type>;
269 template<
class M,
typename KV_S,
typename KV_GO,
typename KV_GS,
class Op>
272 static void do_get(
const Teuchos::Ptr<const M> mat,
276 typename KV_GS::value_type& nnz,
278 const Tpetra::Map<
typename M::local_ordinal_t,
279 typename M::global_ordinal_t,
280 typename M::node_t> > map,
284 Op::template apply_kokkos_view<KV_S, KV_GO, KV_GS>(mat, nzvals,
285 indices, pointers, nnz, map, distribution, ordering);
289 template<
class M,
typename KV_S,
typename KV_GO,
typename KV_GS,
class Op>
290 struct diff_gs_helper_kokkos_view
292 static void do_get(
const Teuchos::Ptr<const M> mat,
296 typename KV_GS::value_type& nnz,
298 const Tpetra::Map<
typename M::local_ordinal_t,
299 typename M::global_ordinal_t,
300 typename M::node_t> > map,
304 typedef typename M::global_size_t mat_gs_t;
305 typedef typename Kokkos::View<mat_gs_t*, Kokkos::HostSpace> KV_TMP;
306 size_t i, size = pointers.extent(0);
307 KV_TMP pointers_tmp(Kokkos::ViewAllocateWithoutInitializing(
"pointers_tmp"), size);
309 mat_gs_t nnz_tmp = 0;
310 Op::template apply_kokkos_view<KV_S, KV_GO, KV_TMP>(mat, nzvals,
311 indices, pointers_tmp, nnz_tmp, Teuchos::ptrInArg(*map), distribution, ordering);
312 nnz = Teuchos::as<typename KV_GS::value_type>(nnz_tmp);
314 typedef typename KV_GS::value_type view_gs_t;
315 for (i = 0; i < size; ++i){
316 pointers(i) = Teuchos::as<view_gs_t>(pointers_tmp(i));
318 nnz = Teuchos::as<view_gs_t>(nnz_tmp);
322 template<
class M,
typename KV_S,
typename KV_GO,
typename KV_GS,
class Op>
323 struct same_go_helper_kokkos_view
325 static void do_get(
const Teuchos::Ptr<const M> mat,
329 typename KV_GS::value_type& nnz,
331 const Tpetra::Map<
typename M::local_ordinal_t,
332 typename M::global_ordinal_t,
333 typename M::node_t> > map,
337 typedef typename M::global_size_t mat_gs_t;
338 typedef typename KV_GS::value_type view_gs_t;
339 if_then_else<is_same<view_gs_t,mat_gs_t>::value,
340 same_gs_helper_kokkos_view<M, KV_S, KV_GO, KV_GS, Op>,
341 diff_gs_helper_kokkos_view<M, KV_S, KV_GO, KV_GS, Op> >::type::do_get(mat, nzvals, indices,
343 distribution, ordering);
347 template<
class M,
typename KV_S,
typename KV_GO,
typename KV_GS,
class Op>
348 struct diff_go_helper_kokkos_view
350 static void do_get(
const Teuchos::Ptr<const M> mat,
354 typename KV_GS::value_type& nnz,
356 const Tpetra::Map<
typename M::local_ordinal_t,
357 typename M::global_ordinal_t,
358 typename M::node_t> > map,
362 typedef typename M::global_ordinal_t mat_go_t;
363 typedef typename M::global_size_t mat_gs_t;
364 typedef typename Kokkos::View<mat_go_t*, Kokkos::HostSpace> KV_TMP;
365 size_t i, size = indices.extent(0);
366 KV_TMP indices_tmp(Kokkos::ViewAllocateWithoutInitializing(
"indices_tmp"), size);
368 typedef typename KV_GO::value_type view_go_t;
369 typedef typename KV_GS::value_type view_gs_t;
370 if_then_else<is_same<view_gs_t,mat_gs_t>::value,
371 same_gs_helper_kokkos_view<M, KV_S, KV_TMP, KV_GS, Op>,
372 diff_gs_helper_kokkos_view<M, KV_S, KV_TMP, KV_GS, Op> >::type::do_get(mat, nzvals, indices_tmp,
374 distribution, ordering);
375 for (i = 0; i < size; ++i){
376 indices(i) = Teuchos::as<view_go_t>(indices_tmp(i));
381 template<
class M,
typename KV_S,
typename KV_GO,
typename KV_GS,
class Op>
382 struct same_scalar_helper_kokkos_view
384 static void do_get(
const Teuchos::Ptr<const M> mat,
388 typename KV_GS::value_type& nnz,
390 const Tpetra::Map<
typename M::local_ordinal_t,
391 typename M::global_ordinal_t,
392 typename M::node_t> > map,
396 typedef typename M::global_ordinal_t mat_go_t;
397 typedef typename KV_GO::value_type view_go_t;
398 if_then_else<is_same<view_go_t,mat_go_t>::value,
399 same_go_helper_kokkos_view<M, KV_S, KV_GO, KV_GS, Op>,
400 diff_go_helper_kokkos_view<M, KV_S, KV_GO, KV_GS, Op> >::type::do_get(mat, nzvals, indices,
402 distribution, ordering);
406 template<
class M,
typename KV_S,
typename KV_GO,
typename KV_GS,
class Op>
407 struct diff_scalar_helper_kokkos_view
409 static void do_get(
const Teuchos::Ptr<const M> mat,
413 typename KV_GS::value_type& nnz,
415 const Tpetra::Map<
typename M::local_ordinal_t,
416 typename M::global_ordinal_t,
417 typename M::node_t> > map,
421 typedef typename M::global_ordinal_t mat_go_t;
422 typedef typename Kokkos::ArithTraits<typename M::scalar_t>::val_type mat_scalar_t;
423 typedef typename Kokkos::View<mat_scalar_t*, Kokkos::HostSpace> KV_TMP;
424 size_t i, size = nzvals.extent(0);
425 KV_TMP nzvals_tmp(Kokkos::ViewAllocateWithoutInitializing(
"nzvals_tmp"), size);
427 typedef typename KV_S::value_type view_scalar_t;
428 typedef typename KV_GO::value_type view_go_t;
429 if_then_else<is_same<view_go_t,mat_go_t>::value,
430 same_go_helper_kokkos_view<M, KV_TMP, KV_GO, KV_GS, Op>,
431 diff_go_helper_kokkos_view<M, KV_TMP, KV_GO, KV_GS, Op> >::type::do_get(mat, nzvals_tmp, indices,
433 distribution, ordering);
435 for (i = 0; i < size; ++i){
436 nzvals(i) = Teuchos::as<view_scalar_t>(nzvals_tmp(i));
442 template<
class Matrix,
typename KV_S,
typename KV_GO,
typename KV_GS,
class Op>
443 struct get_cxs_helper_kokkos_view
445 static void do_get(
const Teuchos::Ptr<const Matrix> mat,
449 typename KV_GS::value_type& nnz,
452 typename KV_GO::value_type indexBase = 0)
454 typedef typename Matrix::local_ordinal_t lo_t;
455 typedef typename Matrix::global_ordinal_t go_t;
456 typedef typename Matrix::global_size_t gs_t;
457 typedef typename Matrix::node_t node_t;
459 const Teuchos::RCP<const Tpetra::Map<lo_t,go_t,node_t> > map
460 = getDistributionMap<lo_t,go_t,gs_t,node_t>(distribution,
461 Op::get_dimension(mat),
464 Op::getMapFromMatrix(mat)
466 do_get(mat, nzvals, indices, pointers, nnz, Teuchos::ptrInArg(*map), distribution, ordering);
473 static void do_get(
const Teuchos::Ptr<const Matrix> mat,
477 typename KV_GS::value_type& nnz,
481 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
482 typename Matrix::global_ordinal_t,
483 typename Matrix::node_t> > map
485 do_get(mat, nzvals, indices, pointers, nnz, Teuchos::ptrInArg(*map), distribution, ordering);
492 static void do_get(
const Teuchos::Ptr<const Matrix> mat,
496 typename KV_GS::value_type& nnz,
498 const Tpetra::Map<
typename Matrix::local_ordinal_t,
499 typename Matrix::global_ordinal_t,
500 typename Matrix::node_t> > map,
504 typedef typename Matrix::scalar_t mat_scalar;
505 typedef typename KV_S::value_type view_scalar_t;
507 if_then_else<is_same<mat_scalar,view_scalar_t>::value,
508 same_scalar_helper_kokkos_view<Matrix,KV_S,KV_GO,KV_GS,Op>,
509 diff_scalar_helper_kokkos_view<Matrix,KV_S,KV_GO,KV_GS,Op> >::type::do_get(mat,
513 distribution, ordering);
517#ifndef DOXYGEN_SHOULD_SKIP_THIS
522 template<
class Matrix>
525 template<
typename KV_S,
typename KV_GO,
typename KV_GS>
526 static void apply_kokkos_view(
const Teuchos::Ptr<const Matrix> mat,
530 typename Matrix::global_size_t& nnz,
532 const Tpetra::Map<
typename Matrix::local_ordinal_t,
533 typename Matrix::global_ordinal_t,
534 typename Matrix::node_t> > map,
535 EDistribution distribution,
536 EStorage_Ordering ordering)
538 mat->getCcs_kokkos_view(nzvals, rowind, colptr, nnz, map, ordering, distribution);
542 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
543 typename Matrix::global_ordinal_t,
544 typename Matrix::node_t> >
545 getMapFromMatrix(
const Teuchos::Ptr<const Matrix> mat)
547 return mat->getMap();
551 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
552 typename Matrix::global_ordinal_t,
553 typename Matrix::node_t> >
554 getMap(
const Teuchos::Ptr<const Matrix> mat)
556 return mat->getColMap();
560 typename Matrix::global_size_t
561 get_dimension(
const Teuchos::Ptr<const Matrix> mat)
563 return mat->getGlobalNumCols();
567 template<
class Matrix>
570 template<
typename KV_S,
typename KV_GO,
typename KV_GS>
571 static void apply_kokkos_view(
const Teuchos::Ptr<const Matrix> mat,
575 typename Matrix::global_size_t& nnz,
577 const Tpetra::Map<
typename Matrix::local_ordinal_t,
578 typename Matrix::global_ordinal_t,
579 typename Matrix::node_t> > map,
580 EDistribution distribution,
581 EStorage_Ordering ordering)
583 mat->getCrs_kokkos_view(nzvals, colind, rowptr, nnz, map, ordering, distribution);
587 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
588 typename Matrix::global_ordinal_t,
589 typename Matrix::node_t> >
590 getMapFromMatrix(
const Teuchos::Ptr<const Matrix> mat)
592 return mat->getMap();
596 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
597 typename Matrix::global_ordinal_t,
598 typename Matrix::node_t> >
599 getMap(
const Teuchos::Ptr<const Matrix> mat)
601 return mat->getRowMap();
605 typename Matrix::global_size_t
606 get_dimension(
const Teuchos::Ptr<const Matrix> mat)
608 return mat->getGlobalNumRows();
650 template<
class Matrix,
typename KV_S,
typename KV_GO,
typename KV_GS>
661 template<
class Matrix,
typename KV_S,
typename KV_GO,
typename KV_GS>
672 template <
typename LO,
typename GO,
typename GS,
typename Node>
673 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
674 getGatherMap(
const Teuchos::RCP<
const Tpetra::Map<LO,GO,Node> > &map )
677 Teuchos::RCP< const Tpetra::Map<LO,GO,Node> > gather_map = Tpetra::Details::computeGatherMap(map, Teuchos::null);
682 template <
typename LO,
typename GO,
typename GS,
typename Node>
683 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
685 GS num_global_elements,
686 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
688 const Teuchos::RCP<
const Tpetra::Map<LO,GO,Node> >& map)
692 switch( distribution ){
695 return Tpetra::createUniformContigMapWithNode<LO,GO, Node>(num_global_elements, comm);
697 return Tpetra::createLocalMapWithNode<LO,GO, Node>(num_global_elements, comm);
700 int rank = Teuchos::rank(*comm);
701 size_t my_num_elems = Teuchos::OrdinalTraits<size_t>::zero();
702 if( rank == 0 ) { my_num_elems = num_global_elements; }
704 return rcp(
new Tpetra::Map<LO,GO, Node>(num_global_elements,
705 my_num_elems, indexBase, comm));
709 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> > gathermap
710 = getGatherMap<LO,GO,GS,Node>( map );
714 TEUCHOS_TEST_FOR_EXCEPTION(
true,
716 "Control should never reach this point. "
717 "Please contact the Amesos2 developers." );
722#ifdef HAVE_AMESOS2_EPETRA
727 template <
typename LO,
typename GO,
typename GS,
typename Node>
728 Teuchos::RCP<Tpetra::Map<LO,GO,Node> >
734 int num_my_elements = map.NumMyElements();
735 Teuchos::Array<int> my_global_elements(num_my_elements);
736 map.MyGlobalElements(my_global_elements.getRawPtr());
738 Teuchos::Array<GO> my_gbl_inds_buf;
739 Teuchos::ArrayView<GO> my_gbl_inds;
740 if (! std::is_same<int, GO>::value) {
741 my_gbl_inds_buf.resize (num_my_elements);
742 my_gbl_inds = my_gbl_inds_buf ();
743 for (
int k = 0; k < num_my_elements; ++k) {
744 my_gbl_inds[k] =
static_cast<GO
> (my_global_elements[k]);
748 using Teuchos::av_reinterpret_cast;
749 my_gbl_inds = av_reinterpret_cast<GO> (my_global_elements ());
752 typedef Tpetra::Map<LO,GO,Node> map_t;
753 RCP<map_t> tmap = rcp(
new map_t(Teuchos::OrdinalTraits<GS>::invalid(),
755 as<GO>(map.IndexBase()),
760 template <
typename LO,
typename GO,
typename GS,
typename Node>
761 Teuchos::RCP<Epetra_Map>
766 Teuchos::Array<GO> elements_tmp;
767 elements_tmp = map.getLocalElementList();
768 int num_my_elements = elements_tmp.size();
769 Teuchos::Array<int> my_global_elements(num_my_elements);
770 for (
int i = 0; i < num_my_elements; ++i){
771 my_global_elements[i] = as<int>(elements_tmp[i]);
775 RCP<Epetra_Map> emap = rcp(
new Epetra_Map(-1,
777 my_global_elements.getRawPtr(),
778 as<GO>(map.getIndexBase()),
784 template <
typename Scalar,
785 typename GlobalOrdinal,
786 typename GlobalSizeT>
787 void transpose(Teuchos::ArrayView<Scalar> vals,
788 Teuchos::ArrayView<GlobalOrdinal> indices,
789 Teuchos::ArrayView<GlobalSizeT> ptr,
790 Teuchos::ArrayView<Scalar> trans_vals,
791 Teuchos::ArrayView<GlobalOrdinal> trans_indices,
792 Teuchos::ArrayView<GlobalSizeT> trans_ptr)
800#ifdef HAVE_AMESOS2_DEBUG
801 typename Teuchos::ArrayView<GlobalOrdinal>::iterator ind_it, ind_begin, ind_end;
802 ind_begin = indices.begin();
803 ind_end = indices.end();
804 size_t min_trans_ptr_size = *std::max_element(ind_begin, ind_end) + 1;
805 TEUCHOS_TEST_FOR_EXCEPTION( Teuchos::as<size_t>(trans_ptr.size()) < min_trans_ptr_size,
806 std::invalid_argument,
807 "Transpose pointer size not large enough." );
808 TEUCHOS_TEST_FOR_EXCEPTION( trans_vals.size() < vals.size(),
809 std::invalid_argument,
810 "Transpose values array not large enough." );
811 TEUCHOS_TEST_FOR_EXCEPTION( trans_indices.size() < indices.size(),
812 std::invalid_argument,
813 "Transpose indices array not large enough." );
815 typename Teuchos::ArrayView<GlobalOrdinal>::iterator ind_it, ind_end;
818 Teuchos::Array<GlobalSizeT> count(trans_ptr.size(), 0);
819 ind_end = indices.end();
820 for( ind_it = indices.begin(); ind_it != ind_end; ++ind_it ){
821 ++(count[(*ind_it) + 1]);
824 typename Teuchos::Array<GlobalSizeT>::iterator cnt_it, cnt_end;
825 cnt_end = count.end();
826 for( cnt_it = count.begin() + 1; cnt_it != cnt_end; ++cnt_it ){
827 *cnt_it = *cnt_it + *(cnt_it - 1);
830 trans_ptr.assign(count);
844 GlobalSizeT size = ptr.size();
845 for( GlobalSizeT i = 0; i < size - 1; ++i ){
846 GlobalOrdinal u = ptr[i];
847 GlobalOrdinal v = ptr[i + 1];
848 for( GlobalOrdinal j = u; j < v; ++j ){
849 GlobalOrdinal k = count[indices[j]];
850 trans_vals[k] = vals[j];
851 trans_indices[k] = i;
852 ++(count[indices[j]]);
858 template <
typename Scalar1,
typename Scalar2>
860 scale(Teuchos::ArrayView<Scalar1> vals,
size_t l,
861 size_t ld, Teuchos::ArrayView<Scalar2> s)
863 size_t vals_size = vals.size();
864#ifdef HAVE_AMESOS2_DEBUG
865 size_t s_size = s.size();
866 TEUCHOS_TEST_FOR_EXCEPTION( s_size < l,
867 std::invalid_argument,
868 "Scale vector must have length at least that of the vector" );
871 for( i = 0, s_i = 0; i < vals_size; ++i, ++s_i ){
881 template <
typename Scalar1,
typename Scalar2,
class BinaryOp>
883 scale(Teuchos::ArrayView<Scalar1> vals,
size_t l,
884 size_t ld, Teuchos::ArrayView<Scalar2> s,
887 size_t vals_size = vals.size();
888#ifdef HAVE_AMESOS2_DEBUG
889 size_t s_size = s.size();
890 TEUCHOS_TEST_FOR_EXCEPTION( s_size < l,
891 std::invalid_argument,
892 "Scale vector must have length at least that of the vector" );
895 for( i = 0, s_i = 0; i < vals_size; ++i, ++s_i ){
901 vals[i] = binary_op(vals[i], s[s_i]);
905 template<
class row_ptr_view_t,
class cols_view_t,
class per_view_t>
907 reorder(row_ptr_view_t & row_ptr, cols_view_t & cols,
908 per_view_t & perm, per_view_t & peri,
size_t & nnz,
911 #ifndef HAVE_AMESOS2_METIS
912 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
913 "Cannot reorder for cuSolver because no METIS is available.");
915 typedef typename cols_view_t::value_type ordinal_type;
916 typedef typename row_ptr_view_t::value_type size_type;
919 auto host_row_ptr = Kokkos::create_mirror_view(row_ptr);
920 auto host_cols = Kokkos::create_mirror_view(cols);
921 Kokkos::deep_copy(host_row_ptr, row_ptr);
922 Kokkos::deep_copy(host_cols, cols);
926 typedef Kokkos::View<idx_t*, Kokkos::HostSpace> host_metis_array;
927 const ordinal_type size = row_ptr.size() - 1;
928 size_type max_nnz = host_row_ptr(size);
929 host_metis_array host_strip_diag_row_ptr(
930 Kokkos::ViewAllocateWithoutInitializing(
"host_strip_diag_row_ptr"),
932 host_metis_array host_strip_diag_cols(
933 Kokkos::ViewAllocateWithoutInitializing(
"host_strip_diag_cols"),
936 size_type new_nnz = 0;
937 for(ordinal_type i = 0; i < size; ++i) {
938 host_strip_diag_row_ptr(i) = new_nnz;
939 for(size_type j = host_row_ptr(i); j < host_row_ptr(i+1); ++j) {
940 if (i != host_cols(j)) {
941 host_strip_diag_cols(new_nnz++) = host_cols(j);
945 host_strip_diag_row_ptr(size) = new_nnz;
948 host_metis_array host_perm(
949 Kokkos::ViewAllocateWithoutInitializing(
"host_perm"), size);
950 host_metis_array host_peri(
951 Kokkos::ViewAllocateWithoutInitializing(
"host_peri"), size);
955 idx_t metis_size = size;
956 int err = METIS_NodeND(&metis_size, host_strip_diag_row_ptr.data(), host_strip_diag_cols.data(),
957 NULL, NULL, host_perm.data(), host_peri.data());
959 TEUCHOS_TEST_FOR_EXCEPTION(err != METIS_OK, std::runtime_error,
960 "METIS_NodeND failed to sort matrix.");
964 typedef typename cols_view_t::execution_space exec_space_t;
965 auto device_perm = Kokkos::create_mirror_view(exec_space_t(), host_perm);
966 auto device_peri = Kokkos::create_mirror_view(exec_space_t(), host_peri);
967 deep_copy(device_perm, host_perm);
968 deep_copy(device_peri, host_peri);
972 deep_copy_or_assign_view(perm, device_perm);
973 deep_copy_or_assign_view(peri, device_peri);
975 if (permute_matrix) {
977 row_ptr_view_t new_row_ptr(
978 Kokkos::ViewAllocateWithoutInitializing(
"new_row_ptr"), row_ptr.size());
979 cols_view_t new_cols(
980 Kokkos::ViewAllocateWithoutInitializing(
"new_cols"), cols.size() - new_nnz/2);
983 Kokkos::RangePolicy<exec_space_t> policy_row(0, row_ptr.size());
984 Kokkos::parallel_scan(policy_row, KOKKOS_LAMBDA(
985 ordinal_type i, size_type & update,
const bool &
final) {
987 new_row_ptr(i) = update;
990 ordinal_type count = 0;
991 const ordinal_type row = device_perm(i);
992 for(ordinal_type k = row_ptr(row); k < row_ptr(row + 1); ++k) {
993 const ordinal_type j = device_peri(cols(k));
1001 Kokkos::RangePolicy<exec_space_t> policy_col(0, size);
1002 Kokkos::parallel_for(policy_col, KOKKOS_LAMBDA(ordinal_type i) {
1003 const ordinal_type kbeg = new_row_ptr(i);
1004 const ordinal_type row = device_perm(i);
1005 const ordinal_type col_beg = row_ptr(row);
1006 const ordinal_type col_end = row_ptr(row + 1);
1007 const ordinal_type nk = col_end - col_beg;
1008 for(ordinal_type k = 0, t = 0; k < nk; ++k) {
1009 const ordinal_type tk = kbeg + t;
1010 const ordinal_type sk = col_beg + k;
1011 const ordinal_type j = device_peri(cols(sk));
1020 row_ptr = new_row_ptr;
1028 template<
class values_view_t,
class row_ptr_view_t,
1029 class cols_view_t,
class per_view_t>
1031 reorder_values(values_view_t & values,
const row_ptr_view_t & orig_row_ptr,
1032 const row_ptr_view_t & new_row_ptr,
1033 const cols_view_t & orig_cols,
const per_view_t & perm,
const per_view_t & peri,
1036 typedef typename cols_view_t::value_type ordinal_type;
1037 typedef typename cols_view_t::execution_space exec_space_t;
1039 auto device_perm = Kokkos::create_mirror_view(exec_space_t(), perm);
1040 auto device_peri = Kokkos::create_mirror_view(exec_space_t(), peri);
1041 deep_copy(device_perm, perm);
1042 deep_copy(device_peri, peri);
1044 const ordinal_type size = orig_row_ptr.size() - 1;
1046 auto host_orig_row_ptr = Kokkos::create_mirror_view(orig_row_ptr);
1047 auto new_nnz = host_orig_row_ptr(size);
1049 values_view_t new_values(
1050 Kokkos::ViewAllocateWithoutInitializing(
"new_values"), values.size() - new_nnz/2);
1053 Kokkos::RangePolicy<exec_space_t> policy_col(0, size);
1054 Kokkos::parallel_for(policy_col, KOKKOS_LAMBDA(ordinal_type i) {
1055 const ordinal_type kbeg = new_row_ptr(i);
1056 const ordinal_type row = device_perm(i);
1057 const ordinal_type col_beg = orig_row_ptr(row);
1058 const ordinal_type col_end = orig_row_ptr(row + 1);
1059 const ordinal_type nk = col_end - col_beg;
1060 for(ordinal_type k = 0, t = 0; k < nk; ++k) {
1061 const ordinal_type tk = kbeg + t;
1062 const ordinal_type sk = col_beg + k;
1063 const ordinal_type j = device_peri(orig_cols(sk));
1065 new_values(tk) = values(sk);
1071 values = new_values;
1074 template<
class array_view_t,
class per_view_t>
1076 apply_reorder_permutation(
const array_view_t & array,
1077 array_view_t & permuted_array,
const per_view_t & permutation) {
1078 if(permuted_array.extent(0) != array.extent(0) || permuted_array.extent(1) != array.extent(1)) {
1079 permuted_array = array_view_t(
1080 Kokkos::ViewAllocateWithoutInitializing(
"permuted_array"),
1081 array.extent(0), array.extent(1));
1083 typedef typename array_view_t::execution_space exec_space_t;
1084 Kokkos::RangePolicy<exec_space_t> policy(0, array.extent(0));
1085 Kokkos::parallel_for(policy, KOKKOS_LAMBDA(
size_t i) {
1086 for(
size_t j = 0; j < array.extent(1); ++j) {
1087 permuted_array(i, j) = array(permutation(i), j);
Copy or assign views based on memory spaces.
Enum and other types declarations for Amesos2.
@ DISTRIBUTED
Definition: Amesos2_TypeDecl.hpp:124
@ GLOBALLY_REPLICATED
Definition: Amesos2_TypeDecl.hpp:126
@ DISTRIBUTED_NO_OVERLAP
Definition: Amesos2_TypeDecl.hpp:125
@ ROOTED
Definition: Amesos2_TypeDecl.hpp:127
@ CONTIGUOUS_AND_ROOTED
Definition: Amesos2_TypeDecl.hpp:128
EDistribution
Definition: Amesos2_TypeDecl.hpp:123
EStorage_Ordering
Definition: Amesos2_TypeDecl.hpp:141
void printLine(Teuchos::FancyOStream &out)
Prints a line of 70 "-"s on std::cout.
Definition: Amesos2_Util.cpp:119
RCP< Epetra_Map > tpetra_map_to_epetra_map(const Tpetra::Map< LO, GO, Node > &map)
Transform a Tpetra::Map object into an Epetra_Map.
Definition: Amesos2_Util.hpp:762
void scale(ArrayView< Scalar1 > vals, size_t l, size_t ld, ArrayView< Scalar2 > s)
Scales a 1-D representation of a multivector.
void transpose(ArrayView< Scalar > vals, ArrayView< GlobalOrdinal > indices, ArrayView< GlobalSizeT > ptr, ArrayView< Scalar > trans_vals, ArrayView< GlobalOrdinal > trans_indices, ArrayView< GlobalSizeT > trans_ptr)
const RCP< const Epetra_Comm > to_epetra_comm(RCP< const Teuchos::Comm< int > > c)
Transfrom a Teuchos::Comm object into an Epetra_Comm object.
const RCP< const Teuchos::Comm< int > > to_teuchos_comm(RCP< const Epetra_Comm > c)
Transform an Epetra_Comm object into a Teuchos::Comm object.
const Teuchos::RCP< const Tpetra::Map< LO, GO, Node > > getGatherMap(const Teuchos::RCP< const Tpetra::Map< LO, GO, Node > > &map)
Gets a Tpetra::Map described by the EDistribution.
Definition: Amesos2_Util.hpp:674
RCP< Tpetra::Map< LO, GO, Node > > epetra_map_to_tpetra_map(const Epetra_BlockMap &map)
Transform an Epetra_Map object into a Tpetra::Map.
Definition: Amesos2_Util.hpp:729
A generic helper class for getting a CCS representation of a Matrix.
Definition: Amesos2_Util.hpp:652
Similar to get_ccs_helper , but used to get a CRS representation of the given matrix.
Definition: Amesos2_Util.hpp:663
A generic base class for the CRS and CCS helpers.
Definition: Amesos2_Util.hpp:271