18#ifndef AMESOS2_UTIL_HPP
19#define AMESOS2_UTIL_HPP
25#include "Amesos2_config.h"
27#include "Teuchos_RCP.hpp"
28#include "Teuchos_BLAS_types.hpp"
29#include "Teuchos_Array.hpp"
30#include "Teuchos_ArrayView.hpp"
31#include "Teuchos_FancyOStream.hpp"
33#include <Tpetra_Map.hpp>
34#include <Tpetra_DistObject_decl.hpp>
35#include <Tpetra_ComputeGatherMap.hpp>
41#ifdef HAVE_AMESOS2_METIS
56 using Teuchos::ArrayView;
74 template <
typename LO,
typename GO,
typename GS,
typename Node>
75 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
76 getGatherMap(
const Teuchos::RCP<
const Tpetra::Map<LO,GO,Node> > &map );
79 template <
typename LO,
typename GO,
typename GS,
typename Node>
80 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
81 getDistributionMap(EDistribution distribution,
82 GS num_global_elements,
83 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
85 const Teuchos::RCP<
const Tpetra::Map<LO,GO,Node> >& map = Teuchos::null);
92 template <
typename Scalar,
93 typename GlobalOrdinal,
96 ArrayView<GlobalOrdinal> indices,
97 ArrayView<GlobalSizeT> ptr,
98 ArrayView<Scalar> trans_vals,
99 ArrayView<GlobalOrdinal> trans_indices,
100 ArrayView<GlobalSizeT> trans_ptr);
115 template <
typename Scalar1,
typename Scalar2>
116 void scale(ArrayView<Scalar1> vals,
size_t l,
117 size_t ld, ArrayView<Scalar2> s);
137 template <
typename Scalar1,
typename Scalar2,
class BinaryOp>
138 void scale(ArrayView<Scalar1> vals,
size_t l,
139 size_t ld, ArrayView<Scalar2> s, BinaryOp binary_op);
143 void printLine( Teuchos::FancyOStream &out );
148 template <
class T0,
class T1 >
149 struct getStdCplxType
151 using common_type =
typename std::common_type<T0,T1>::type;
152 using type = common_type;
155 template <
class T0,
class T1 >
156 struct getStdCplxType< T0, T1* >
158 using common_type =
typename std::common_type<T0,T1>::type;
159 using type = common_type;
162#if defined(HAVE_TEUCHOS_COMPLEX) && defined(HAVE_AMESOS2_KOKKOS)
163 template <
class T0 >
164 struct getStdCplxType< T0, Kokkos::complex<T0>* >
166 using type = std::complex<T0>;
169 template <
class T0 ,
class T1 >
170 struct getStdCplxType< T0, Kokkos::complex<T1>* >
172 using common_type =
typename std::common_type<T0,T1>::type;
173 using type = std::complex<common_type>;
196 template<
class M,
typename KV_S,
typename KV_GO,
typename KV_GS,
class Op>
199 static void do_get(
const Teuchos::Ptr<const M> mat,
203 typename KV_GS::value_type& nnz,
205 const Tpetra::Map<
typename M::local_ordinal_t,
206 typename M::global_ordinal_t,
207 typename M::node_t> > map,
211 Op::template apply_kokkos_view<KV_S, KV_GO, KV_GS>(mat, nzvals,
212 indices, pointers, nnz, map, distribution, ordering);
216 template<
class M,
typename KV_S,
typename KV_GO,
typename KV_GS,
class Op>
217 struct diff_gs_helper_kokkos_view
219 static void do_get(
const Teuchos::Ptr<const M> mat,
223 typename KV_GS::value_type& nnz,
225 const Tpetra::Map<
typename M::local_ordinal_t,
226 typename M::global_ordinal_t,
227 typename M::node_t> > map,
231 typedef typename M::global_size_t mat_gs_t;
232 typedef typename Kokkos::View<mat_gs_t*, Kokkos::HostSpace> KV_TMP;
233 size_t i,
size = (pointers.extent(0) > 0 ? pointers.extent(0) : 1);
234 KV_TMP pointers_tmp(Kokkos::ViewAllocateWithoutInitializing(
"pointers_tmp"),
size);
236 mat_gs_t nnz_tmp = 0;
237 Op::template apply_kokkos_view<KV_S, KV_GO, KV_TMP>(mat, nzvals,
238 indices, pointers_tmp, nnz_tmp, Teuchos::ptrInArg(*map), distribution, ordering);
239 nnz = Teuchos::as<typename KV_GS::value_type>(nnz_tmp);
241 typedef typename KV_GS::value_type view_gs_t;
242 if (pointers.extent(0) == 1) {
243 Kokkos::deep_copy(pointers, 0);
245 auto host_pointers = Kokkos::create_mirror_view(pointers);
246 for (i = 0; i < pointers.extent(0); ++i){
247 host_pointers(i) = Teuchos::as<view_gs_t>(pointers_tmp(i));
249 Kokkos::deep_copy(pointers, host_pointers);
251 nnz = Teuchos::as<view_gs_t>(nnz_tmp);
255 template<
class M,
typename KV_S,
typename KV_GO,
typename KV_GS,
class Op>
256 struct same_go_helper_kokkos_view
258 static void do_get(
const Teuchos::Ptr<const M> mat,
262 typename KV_GS::value_type& nnz,
264 const Tpetra::Map<
typename M::local_ordinal_t,
265 typename M::global_ordinal_t,
266 typename M::node_t> > map,
267 EDistribution distribution,
268 EStorage_Ordering ordering)
270 typedef typename M::global_size_t mat_gs_t;
271 typedef typename KV_GS::value_type view_gs_t;
272 std::conditional_t<std::is_same_v<view_gs_t,mat_gs_t>,
273 same_gs_helper_kokkos_view<M, KV_S, KV_GO, KV_GS, Op>,
274 diff_gs_helper_kokkos_view<M, KV_S, KV_GO, KV_GS, Op> >::do_get(mat, nzvals, indices,
276 distribution, ordering);
280 template<
class M,
typename KV_S,
typename KV_GO,
typename KV_GS,
class Op>
281 struct diff_go_helper_kokkos_view
283 static void do_get(
const Teuchos::Ptr<const M> mat,
287 typename KV_GS::value_type& nnz,
289 const Tpetra::Map<
typename M::local_ordinal_t,
290 typename M::global_ordinal_t,
291 typename M::node_t> > map,
292 EDistribution distribution,
293 EStorage_Ordering ordering)
295 typedef typename M::global_ordinal_t mat_go_t;
296 typedef typename M::global_size_t mat_gs_t;
297 typedef typename Kokkos::View<mat_go_t*, Kokkos::HostSpace> KV_TMP;
298 size_t i,
size = indices.extent(0);
299 KV_TMP indices_tmp(Kokkos::ViewAllocateWithoutInitializing(
"indices_tmp"),
size);
301 typedef typename KV_GO::value_type view_go_t;
302 typedef typename KV_GS::value_type view_gs_t;
303 std::conditional_t<std::is_same_v<view_gs_t,mat_gs_t>,
304 same_gs_helper_kokkos_view<M, KV_S, KV_TMP, KV_GS, Op>,
305 diff_gs_helper_kokkos_view<M, KV_S, KV_TMP, KV_GS, Op> >::do_get(mat, nzvals, indices_tmp,
307 distribution, ordering);
308 auto host_indices = Kokkos::create_mirror_view(indices);
309 for (i = 0; i <
size; ++i){
310 host_indices(i) = Teuchos::as<view_go_t>(indices_tmp(i));
312 Kokkos::deep_copy(indices, host_indices);
316 template<
class M,
typename KV_S,
typename KV_GO,
typename KV_GS,
class Op>
317 struct same_scalar_helper_kokkos_view
319 static void do_get(
const Teuchos::Ptr<const M> mat,
323 typename KV_GS::value_type& nnz,
325 const Tpetra::Map<
typename M::local_ordinal_t,
326 typename M::global_ordinal_t,
327 typename M::node_t> > map,
328 EDistribution distribution,
329 EStorage_Ordering ordering)
331 typedef typename M::global_ordinal_t mat_go_t;
332 typedef typename KV_GO::value_type view_go_t;
333 std::conditional_t<std::is_same_v<view_go_t, mat_go_t>,
334 same_go_helper_kokkos_view<M, KV_S, KV_GO, KV_GS, Op>,
335 diff_go_helper_kokkos_view<M, KV_S, KV_GO, KV_GS, Op> >::do_get(mat, nzvals, indices,
337 distribution, ordering);
341 template<
class M,
typename KV_S,
typename KV_GO,
typename KV_GS,
class Op>
342 struct diff_scalar_helper_kokkos_view
344 static void do_get(
const Teuchos::Ptr<const M> mat,
348 typename KV_GS::value_type& nnz,
350 const Tpetra::Map<
typename M::local_ordinal_t,
351 typename M::global_ordinal_t,
352 typename M::node_t> > map,
353 EDistribution distribution,
354 EStorage_Ordering ordering)
356 typedef typename M::global_ordinal_t mat_go_t;
357 typedef typename KokkosKernels::ArithTraits<typename M::scalar_t>::val_type mat_scalar_t;
358 typedef typename Kokkos::View<mat_scalar_t*, Kokkos::HostSpace> KV_TMP;
359 size_t i,
size = nzvals.extent(0);
360 KV_TMP nzvals_tmp(Kokkos::ViewAllocateWithoutInitializing(
"nzvals_tmp"),
size);
362 typedef typename KV_S::value_type view_scalar_t;
363 typedef typename KV_GO::value_type view_go_t;
364 std::conditional_t<std::is_same_v<view_go_t, mat_go_t>,
365 same_go_helper_kokkos_view<M, KV_TMP, KV_GO, KV_GS, Op>,
366 diff_go_helper_kokkos_view<M, KV_TMP, KV_GO, KV_GS, Op> >::do_get(mat, nzvals_tmp, indices,
368 distribution, ordering);
370 auto host_nzvals = Kokkos::create_mirror_view(nzvals);
371 for (i = 0; i <
size; ++i){
372 host_nzvals(i) = Teuchos::as<view_scalar_t>(nzvals_tmp(i));
374 Kokkos::deep_copy(nzvals, host_nzvals);
379 template<
class Matrix,
typename KV_S,
typename KV_GO,
typename KV_GS,
class Op>
380 struct get_cxs_helper_kokkos_view
382 static void do_get(
const Teuchos::Ptr<const Matrix> mat,
386 typename KV_GS::value_type& nnz,
387 EDistribution distribution,
388 EStorage_Ordering ordering=ARBITRARY,
389 typename KV_GO::value_type indexBase = 0)
391 typedef typename Matrix::local_ordinal_t lo_t;
392 typedef typename Matrix::global_ordinal_t go_t;
393 typedef typename Matrix::global_size_t gs_t;
394 typedef typename Matrix::node_t node_t;
396 const Teuchos::RCP<const Tpetra::Map<lo_t,go_t,node_t> > map
397 = getDistributionMap<lo_t,go_t,gs_t,node_t>(distribution,
398 Op::get_dimension(mat),
401 Op::getMapFromMatrix(mat)
403 do_get(mat, nzvals, indices, pointers, nnz, Teuchos::ptrInArg(*map), distribution, ordering);
410 static void do_get(
const Teuchos::Ptr<const Matrix> mat,
414 typename KV_GS::value_type& nnz,
415 EDistribution distribution,
416 EStorage_Ordering ordering=ARBITRARY)
418 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
419 typename Matrix::global_ordinal_t,
420 typename Matrix::node_t> > map
422 do_get(mat, nzvals, indices, pointers, nnz, Teuchos::ptrInArg(*map), distribution, ordering);
429 static void do_get(
const Teuchos::Ptr<const Matrix> mat,
433 typename KV_GS::value_type& nnz,
435 const Tpetra::Map<
typename Matrix::local_ordinal_t,
436 typename Matrix::global_ordinal_t,
437 typename Matrix::node_t> > map,
438 EDistribution distribution,
439 EStorage_Ordering ordering=ARBITRARY)
441 typedef typename Matrix::scalar_t mat_scalar;
442 typedef typename KV_S::value_type view_scalar_t;
444 std::conditional_t<std::is_same_v<mat_scalar,view_scalar_t>,
445 same_scalar_helper_kokkos_view<Matrix,KV_S,KV_GO,KV_GS,Op>,
446 diff_scalar_helper_kokkos_view<Matrix,KV_S,KV_GO,KV_GS,Op> >::do_get(mat,
450 distribution, ordering);
454#ifndef DOXYGEN_SHOULD_SKIP_THIS
459 template<
class Matrix>
462 template<
typename KV_S,
typename KV_GO,
typename KV_GS>
463 static void apply_kokkos_view(
const Teuchos::Ptr<const Matrix> mat,
467 typename Matrix::global_size_t& nnz,
469 const Tpetra::Map<
typename Matrix::local_ordinal_t,
470 typename Matrix::global_ordinal_t,
471 typename Matrix::node_t> > map,
472 EDistribution distribution,
473 EStorage_Ordering ordering)
475 mat->getCcs_kokkos_view(nzvals, rowind, colptr, nnz, map, ordering, distribution);
479 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
480 typename Matrix::global_ordinal_t,
481 typename Matrix::node_t> >
482 getMapFromMatrix(
const Teuchos::Ptr<const Matrix> mat)
484 return mat->getMap();
488 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
489 typename Matrix::global_ordinal_t,
490 typename Matrix::node_t> >
491 getMap(
const Teuchos::Ptr<const Matrix> mat)
493 return mat->getColMap();
497 typename Matrix::global_size_t
498 get_dimension(
const Teuchos::Ptr<const Matrix> mat)
500 return mat->getGlobalNumCols();
504 template<
class Matrix>
507 template<
typename KV_S,
typename KV_GO,
typename KV_GS>
508 static void apply_kokkos_view(
const Teuchos::Ptr<const Matrix> mat,
512 typename Matrix::global_size_t& nnz,
514 const Tpetra::Map<
typename Matrix::local_ordinal_t,
515 typename Matrix::global_ordinal_t,
516 typename Matrix::node_t> > map,
517 EDistribution distribution,
518 EStorage_Ordering ordering)
520 mat->getCrs_kokkos_view(nzvals, colind, rowptr, nnz, map, ordering, distribution);
524 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
525 typename Matrix::global_ordinal_t,
526 typename Matrix::node_t> >
527 getMapFromMatrix(
const Teuchos::Ptr<const Matrix> mat)
529 return mat->getMap();
533 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
534 typename Matrix::global_ordinal_t,
535 typename Matrix::node_t> >
536 getMap(
const Teuchos::Ptr<const Matrix> mat)
538 return mat->getRowMap();
542 typename Matrix::global_size_t
543 get_dimension(
const Teuchos::Ptr<const Matrix> mat)
545 return mat->getGlobalNumRows();
587 template<
class Matrix,
typename KV_S,
typename KV_GO,
typename KV_GS>
598 template<
class Matrix,
typename KV_S,
typename KV_GO,
typename KV_GS>
609 template <
typename LO,
typename GO,
typename GS,
typename Node>
610 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
611 getGatherMap(
const Teuchos::RCP<
const Tpetra::Map<LO,GO,Node> > &map )
614 Teuchos::RCP< const Tpetra::Map<LO,GO,Node> > gather_map = Tpetra::Details::computeGatherMap(map, Teuchos::null);
619 template <
typename LO,
typename GO,
typename GS,
typename Node>
620 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
622 GS num_global_elements,
623 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
625 const Teuchos::RCP<
const Tpetra::Map<LO,GO,Node> >& map)
629 switch( distribution ){
632 return Tpetra::createUniformContigMapWithNode<LO,GO, Node>(num_global_elements, comm);
634 return Tpetra::createLocalMapWithNode<LO,GO, Node>(num_global_elements, comm);
637 int rank = Teuchos::rank(*comm);
638 size_t my_num_elems = Teuchos::OrdinalTraits<size_t>::zero();
639 if( rank == 0 ) { my_num_elems = num_global_elements; }
641 return rcp(
new Tpetra::Map<LO,GO, Node>(num_global_elements,
642 my_num_elems, indexBase, comm));
646 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> > gathermap
647 = getGatherMap<LO,GO,GS,Node>( map );
651 TEUCHOS_TEST_FOR_EXCEPTION(
true,
653 "Control should never reach this point. "
654 "Please contact the Amesos2 developers." );
658 template <
typename Scalar,
659 typename GlobalOrdinal,
660 typename GlobalSizeT>
661 void transpose(Teuchos::ArrayView<Scalar> vals,
662 Teuchos::ArrayView<GlobalOrdinal> indices,
663 Teuchos::ArrayView<GlobalSizeT> ptr,
664 Teuchos::ArrayView<Scalar> trans_vals,
665 Teuchos::ArrayView<GlobalOrdinal> trans_indices,
666 Teuchos::ArrayView<GlobalSizeT> trans_ptr)
674#ifdef HAVE_AMESOS2_DEBUG
675 typename Teuchos::ArrayView<GlobalOrdinal>::iterator ind_it, ind_begin, ind_end;
676 ind_begin = indices.begin();
677 ind_end = indices.end();
678 size_t min_trans_ptr_size = *std::max_element(ind_begin, ind_end) + 1;
679 TEUCHOS_TEST_FOR_EXCEPTION( Teuchos::as<size_t>(trans_ptr.size()) < min_trans_ptr_size,
680 std::invalid_argument,
681 "Transpose pointer size not large enough." );
682 TEUCHOS_TEST_FOR_EXCEPTION( trans_vals.size() < vals.size(),
683 std::invalid_argument,
684 "Transpose values array not large enough." );
685 TEUCHOS_TEST_FOR_EXCEPTION( trans_indices.size() < indices.size(),
686 std::invalid_argument,
687 "Transpose indices array not large enough." );
689 typename Teuchos::ArrayView<GlobalOrdinal>::iterator ind_it, ind_end;
692 Teuchos::Array<GlobalSizeT> count(trans_ptr.size(), 0);
693 ind_end = indices.end();
694 for( ind_it = indices.begin(); ind_it != ind_end; ++ind_it ){
695 ++(count[(*ind_it) + 1]);
698 typename Teuchos::Array<GlobalSizeT>::iterator cnt_it, cnt_end;
699 cnt_end = count.end();
700 for( cnt_it = count.begin() + 1; cnt_it != cnt_end; ++cnt_it ){
701 *cnt_it = *cnt_it + *(cnt_it - 1);
704 trans_ptr.assign(count);
718 GlobalSizeT
size = ptr.size();
719 for( GlobalSizeT i = 0; i <
size - 1; ++i ){
720 GlobalOrdinal u = ptr[i];
721 GlobalOrdinal v = ptr[i + 1];
722 for( GlobalOrdinal j = u; j < v; ++j ){
723 GlobalOrdinal k = count[indices[j]];
724 trans_vals[k] = vals[j];
725 trans_indices[k] = i;
726 ++(count[indices[j]]);
732 template <
typename Scalar1,
typename Scalar2>
734 scale(Teuchos::ArrayView<Scalar1> vals,
size_t l,
735 size_t ld, Teuchos::ArrayView<Scalar2> s)
737 size_t vals_size = vals.size();
738#ifdef HAVE_AMESOS2_DEBUG
739 size_t s_size = s.size();
740 TEUCHOS_TEST_FOR_EXCEPTION( s_size < l,
741 std::invalid_argument,
742 "Scale vector must have length at least that of the vector" );
745 for( i = 0, s_i = 0; i < vals_size; ++i, ++s_i ){
755 template <
typename Scalar1,
typename Scalar2,
class BinaryOp>
757 scale(Teuchos::ArrayView<Scalar1> vals,
size_t l,
758 size_t ld, Teuchos::ArrayView<Scalar2> s,
761 size_t vals_size = vals.size();
762#ifdef HAVE_AMESOS2_DEBUG
763 size_t s_size = s.size();
764 TEUCHOS_TEST_FOR_EXCEPTION( s_size < l,
765 std::invalid_argument,
766 "Scale vector must have length at least that of the vector" );
769 for( i = 0, s_i = 0; i < vals_size; ++i, ++s_i ){
775 vals[i] = binary_op(vals[i], s[s_i]);
779 template<
class row_ptr_view_t,
class cols_view_t,
class per_view_t>
781 reorder(row_ptr_view_t & row_ptr, cols_view_t & cols,
782 per_view_t & perm, per_view_t & peri,
size_t & nnz,
785 #ifndef HAVE_AMESOS2_METIS
786 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
787 "Cannot reorder for cuSolver because no METIS is available.");
789 typedef typename cols_view_t::value_type ordinal_type;
790 typedef typename row_ptr_view_t::value_type size_type;
793 auto host_row_ptr = Kokkos::create_mirror_view(row_ptr);
794 auto host_cols = Kokkos::create_mirror_view(cols);
795 Kokkos::deep_copy(host_row_ptr, row_ptr);
796 Kokkos::deep_copy(host_cols, cols);
800 typedef Kokkos::View<idx_t*, Kokkos::HostSpace> host_metis_array;
801 const ordinal_type
size = row_ptr.size() - 1;
802 size_type max_nnz = host_row_ptr(
size);
803 host_metis_array host_strip_diag_row_ptr(
804 Kokkos::ViewAllocateWithoutInitializing(
"host_strip_diag_row_ptr"),
806 host_metis_array host_strip_diag_cols(
807 Kokkos::ViewAllocateWithoutInitializing(
"host_strip_diag_cols"),
810 size_type new_nnz = 0;
811 for(ordinal_type i = 0; i <
size; ++i) {
812 host_strip_diag_row_ptr(i) = new_nnz;
813 for(size_type j = host_row_ptr(i); j < host_row_ptr(i+1); ++j) {
814 if (i != host_cols(j)) {
815 host_strip_diag_cols(new_nnz++) = host_cols(j);
819 host_strip_diag_row_ptr(
size) = new_nnz;
822 host_metis_array host_perm(
823 Kokkos::ViewAllocateWithoutInitializing(
"host_perm"),
size);
824 host_metis_array host_peri(
825 Kokkos::ViewAllocateWithoutInitializing(
"host_peri"),
size);
829 idx_t metis_size =
size;
830 int err = METIS_NodeND(&metis_size, host_strip_diag_row_ptr.data(), host_strip_diag_cols.data(),
831 NULL, NULL, host_perm.data(), host_peri.data());
833 TEUCHOS_TEST_FOR_EXCEPTION(err != METIS_OK, std::runtime_error,
834 "METIS_NodeND failed to sort matrix.");
838 typedef typename cols_view_t::execution_space exec_space_t;
839 auto device_perm = Kokkos::create_mirror_view(exec_space_t(), host_perm);
840 auto device_peri = Kokkos::create_mirror_view(exec_space_t(), host_peri);
841 deep_copy(device_perm, host_perm);
842 deep_copy(device_peri, host_peri);
846 deep_copy_or_assign_view(perm, device_perm);
847 deep_copy_or_assign_view(peri, device_peri);
849 if (permute_matrix) {
851 row_ptr_view_t new_row_ptr(
852 Kokkos::ViewAllocateWithoutInitializing(
"new_row_ptr"), row_ptr.size());
853 cols_view_t new_cols(
854 Kokkos::ViewAllocateWithoutInitializing(
"new_cols"), cols.size() - new_nnz/2);
857 Kokkos::RangePolicy<exec_space_t> policy_row(0, row_ptr.size());
858 Kokkos::parallel_scan(policy_row, KOKKOS_LAMBDA(
859 ordinal_type i, size_type & update,
const bool &
final) {
861 new_row_ptr(i) = update;
864 ordinal_type count = 0;
865 const ordinal_type row = device_perm(i);
866 for(ordinal_type k = row_ptr(row); k < row_ptr(row + 1); ++k) {
867 const ordinal_type j = device_peri(cols(k));
875 Kokkos::RangePolicy<exec_space_t> policy_col(0,
size);
876 Kokkos::parallel_for(policy_col, KOKKOS_LAMBDA(ordinal_type i) {
877 const ordinal_type kbeg = new_row_ptr(i);
878 const ordinal_type row = device_perm(i);
879 const ordinal_type col_beg = row_ptr(row);
880 const ordinal_type col_end = row_ptr(row + 1);
881 const ordinal_type nk = col_end - col_beg;
882 for(ordinal_type k = 0, t = 0; k < nk; ++k) {
883 const ordinal_type tk = kbeg + t;
884 const ordinal_type sk = col_beg + k;
885 const ordinal_type j = device_peri(cols(sk));
894 row_ptr = new_row_ptr;
902 template<
class values_view_t,
class row_ptr_view_t,
903 class cols_view_t,
class per_view_t>
905 reorder_values(values_view_t & values,
const row_ptr_view_t & orig_row_ptr,
906 const row_ptr_view_t & new_row_ptr,
907 const cols_view_t & orig_cols,
const per_view_t & perm,
const per_view_t & peri,
910 typedef typename cols_view_t::value_type ordinal_type;
911 typedef typename cols_view_t::execution_space exec_space_t;
913 auto device_perm = Kokkos::create_mirror_view(exec_space_t(), perm);
914 auto device_peri = Kokkos::create_mirror_view(exec_space_t(), peri);
915 deep_copy(device_perm, perm);
916 deep_copy(device_peri, peri);
918 const ordinal_type
size = orig_row_ptr.size() - 1;
920 auto host_orig_row_ptr = Kokkos::create_mirror_view(orig_row_ptr);
921 auto new_nnz = host_orig_row_ptr(
size);
923 values_view_t new_values(
924 Kokkos::ViewAllocateWithoutInitializing(
"new_values"), values.size() - new_nnz/2);
927 Kokkos::RangePolicy<exec_space_t> policy_col(0,
size);
928 Kokkos::parallel_for(policy_col, KOKKOS_LAMBDA(ordinal_type i) {
929 const ordinal_type kbeg = new_row_ptr(i);
930 const ordinal_type row = device_perm(i);
931 const ordinal_type col_beg = orig_row_ptr(row);
932 const ordinal_type col_end = orig_row_ptr(row + 1);
933 const ordinal_type nk = col_end - col_beg;
934 for(ordinal_type k = 0, t = 0; k < nk; ++k) {
935 const ordinal_type tk = kbeg + t;
936 const ordinal_type sk = col_beg + k;
937 const ordinal_type j = device_peri(orig_cols(sk));
939 new_values(tk) = values(sk);
948 template<
class array_view_t,
class per_view_t>
950 apply_reorder_permutation(
const array_view_t & array,
951 array_view_t & permuted_array,
const per_view_t & permutation) {
952 if(permuted_array.extent(0) != array.extent(0) || permuted_array.extent(1) != array.extent(1)) {
953 permuted_array = array_view_t(
954 Kokkos::ViewAllocateWithoutInitializing(
"permuted_array"),
955 array.extent(0), array.extent(1));
957 typedef typename array_view_t::execution_space exec_space_t;
958 Kokkos::RangePolicy<exec_space_t> policy(0, array.extent(0));
959 Kokkos::parallel_for(policy, KOKKOS_LAMBDA(
size_t i) {
960 for(
size_t j = 0; j < array.extent(1); ++j) {
961 permuted_array(i, j) = array(permutation(i), j);
968 template <
typename GO,
typename Scalar>
970 readEntryFromFile (GO& gblRowInd, GO& gblColInd, Scalar& val,
const std::string& s)
972 if (s.size () == 0 || s.find (
"%") != std::string::npos) {
975 std::istringstream in (s);
992 template<
class map_type,
class MAT>
994 readCrsMatrixFromFile (
const std::string& matrixFilename,
995 Teuchos::RCP<Teuchos::FancyOStream> & fos,
996 const Teuchos::RCP<const map_type>& rowMap,
997 const Teuchos::RCP<const map_type>& domainMap,
998 const Teuchos::RCP<const map_type>& rangeMap,
999 const bool convert_to_zero_base,
1000 const int header_size)
1002 using Scalar =
typename MAT::scalar_type;
1003 using GO =
typename MAT::global_ordinal_type;
1005 using counter_type = std::map<GO, size_t>;
1006 using pair_type = std::pair<const GO, size_t>;
1009 auto comm = rowMap->getComm ();
1010 const int myRank = comm->getRank ();
1012 std::ifstream inFile;
1017 inFile.open (matrixFilename);
1026 Teuchos::broadcast<int, int> (*comm, 0, Teuchos::outArg (opened));
1027 TEUCHOS_TEST_FOR_EXCEPTION
1028 (opened == 0, std::runtime_error,
"readCrsMatrixFromFile: "
1029 "Failed to open file \"" << matrixFilename <<
"\" on Process 0.");
1038 for (
int i = 0; i < header_size; ++i ) {
1039 std::getline (inFile, line);
1042 counter_type counts;
1043 Teuchos::Array<Scalar> vals;
1044 Teuchos::Array<GO> gblRowInds;
1045 Teuchos::Array<GO> gblColInds;
1047 std::getline (inFile, line);
1051 const bool gotLine = readEntryFromFile (gblRowInd, gblColInd, val, line);
1054 if ( convert_to_zero_base ) {
1058 counts[gblRowInd]++;
1059 vals.push_back(val);
1060 gblRowInds.push_back(gblRowInd);
1061 gblColInds.push_back(gblColInd);
1066 auto pr = std::max_element(
1069 [] (pair_type
const& p1, pair_type
const& p2){
return p1.second < p2.second; }
1071 size_t maxCount = (counts.empty()) ?
size_t(0) : pr->second;
1072 A = Teuchos::rcp(
new MAT(rowMap, maxCount));
1073 for (
typename Teuchos::Array<GO>::size_type i=0; i<gblRowInds.size(); i++) {
1074 A->insertGlobalValues (gblRowInds[i], gblColInds(i,1), vals(i,1));
1077 A = Teuchos::rcp(
new MAT(rowMap, 0));
1080 A->fillComplete (domainMap, rangeMap);
Copy or assign views based on memory spaces.
Enum and other types declarations for Amesos2.
EDistribution
Definition Amesos2_TypeDecl.hpp:89
@ DISTRIBUTED
Definition Amesos2_TypeDecl.hpp:90
@ GLOBALLY_REPLICATED
Definition Amesos2_TypeDecl.hpp:92
@ DISTRIBUTED_NO_OVERLAP
Definition Amesos2_TypeDecl.hpp:91
@ ROOTED
Definition Amesos2_TypeDecl.hpp:93
@ CONTIGUOUS_AND_ROOTED
Definition Amesos2_TypeDecl.hpp:94
EStorage_Ordering
Definition Amesos2_TypeDecl.hpp:107
void printLine(Teuchos::FancyOStream &out)
Prints a line of 70 "-"s on std::cout.
Definition Amesos2_Util.cpp:20
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 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:611
const int size
Definition klu2_simple.cpp:50
A generic helper class for getting a CCS representation of a Matrix.
Definition Amesos2_Util.hpp:589
Similar to get_ccs_helper , but used to get a CRS representation of the given matrix.
Definition Amesos2_Util.hpp:600
A generic base class for the CRS and CCS helpers.
Definition Amesos2_Util.hpp:198