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>
70 #ifdef HAVE_AMESOS2_EPETRA
71 #include <Epetra_Map.h>
86 using Teuchos::ArrayView;
89 using Meta::if_then_else;
107 template <
typename LO,
typename GO,
typename GS,
typename Node>
108 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
109 getGatherMap(
const Teuchos::RCP<
const Tpetra::Map<LO,GO,Node> > &map );
112 template <
typename LO,
typename GO,
typename GS,
typename Node>
113 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
115 GS num_global_elements,
116 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
118 const Teuchos::RCP<
const Tpetra::Map<LO,GO,Node> >& map = Teuchos::null);
121 #ifdef HAVE_AMESOS2_EPETRA
128 template <
typename LO,
typename GO,
typename GS,
typename Node>
129 RCP<Tpetra::Map<LO,GO,Node> >
137 template <
typename LO,
typename GO,
typename GS,
typename Node>
146 const RCP<const Teuchos::Comm<int> >
to_teuchos_comm(RCP<const Epetra_Comm> c);
153 const RCP<const Epetra_Comm>
to_epetra_comm(RCP<
const Teuchos::Comm<int> > c);
154 #endif // HAVE_AMESOS2_EPETRA
161 template <
typename Scalar,
162 typename GlobalOrdinal,
163 typename GlobalSizeT>
165 ArrayView<GlobalOrdinal> indices,
166 ArrayView<GlobalSizeT> ptr,
167 ArrayView<Scalar> trans_vals,
168 ArrayView<GlobalOrdinal> trans_indices,
169 ArrayView<GlobalSizeT> trans_ptr);
184 template <
typename Scalar1,
typename Scalar2>
185 void scale(ArrayView<Scalar1> vals,
size_t l,
186 size_t ld, ArrayView<Scalar2> s);
206 template <
typename Scalar1,
typename Scalar2,
class BinaryOp>
207 void scale(ArrayView<Scalar1> vals,
size_t l,
208 size_t ld, ArrayView<Scalar2> s, BinaryOp binary_op);
212 void printLine( Teuchos::FancyOStream &out );
217 template <
class T0,
class T1 >
218 struct getStdCplxType
220 using common_type =
typename std::common_type<T0,T1>::type;
221 using type = common_type;
224 template <
class T0,
class T1 >
225 struct getStdCplxType< T0, T1* >
227 using common_type =
typename std::common_type<T0,T1>::type;
228 using type = common_type;
231 #if defined(HAVE_TEUCHOS_COMPLEX) && defined(HAVE_AMESOS2_KOKKOS)
232 template <
class T0 >
233 struct getStdCplxType< T0, Kokkos::complex<T0>* >
235 using type = std::complex<T0>;
238 template <
class T0 ,
class T1 >
239 struct getStdCplxType< T0, Kokkos::complex<T1>* >
241 using common_type =
typename std::common_type<T0,T1>::type;
242 using type = std::complex<common_type>;
250 #ifndef DOXYGEN_SHOULD_SKIP_THIS
273 template <
class M,
typename S,
typename GO,
typename GS,
class Op>
274 struct same_gs_helper
276 static void do_get(
const Teuchos::Ptr<const M> mat,
277 const ArrayView<typename M::scalar_t> nzvals,
278 const ArrayView<typename M::global_ordinal_t> indices,
279 const ArrayView<GS> pointers,
282 const Tpetra::Map<
typename M::local_ordinal_t,
283 typename M::global_ordinal_t,
284 typename M::node_t> > map,
288 Op::apply(mat, nzvals, indices, pointers, nnz, map, distribution, ordering);
292 template <
class M,
typename S,
typename GO,
typename GS,
class Op>
293 struct diff_gs_helper
295 static void do_get(
const Teuchos::Ptr<const M> mat,
296 const ArrayView<typename M::scalar_t> nzvals,
297 const ArrayView<typename M::global_ordinal_t> indices,
298 const ArrayView<GS> pointers,
301 const Tpetra::Map<
typename M::local_ordinal_t,
302 typename M::global_ordinal_t,
303 typename M::node_t> > map,
307 typedef typename M::global_size_t mat_gs_t;
308 typename ArrayView<GS>::size_type i, size = pointers.size();
309 Teuchos::Array<mat_gs_t> pointers_tmp(size);
310 mat_gs_t nnz_tmp = 0;
312 Op::apply(mat, nzvals, indices, pointers_tmp, nnz_tmp, map, distribution, ordering);
314 for (i = 0; i < size; ++i){
315 pointers[i] = Teuchos::as<GS>(pointers_tmp[i]);
317 nnz = Teuchos::as<GS>(nnz_tmp);
321 template <
class M,
typename S,
typename GO,
typename GS,
class Op>
322 struct same_go_helper
324 static void do_get(
const Teuchos::Ptr<const M> mat,
325 const ArrayView<typename M::scalar_t> nzvals,
326 const ArrayView<GO> indices,
327 const ArrayView<GS> pointers,
330 const Tpetra::Map<
typename M::local_ordinal_t,
331 typename M::global_ordinal_t,
332 typename M::node_t> > map,
336 typedef typename M::global_size_t mat_gs_t;
337 if_then_else<is_same<GS,mat_gs_t>::value,
338 same_gs_helper<M,S,GO,GS,Op>,
339 diff_gs_helper<M,S,GO,GS,Op> >::type::do_get(mat, nzvals, indices,
341 distribution, ordering);
345 template <
class M,
typename S,
typename GO,
typename GS,
class Op>
346 struct diff_go_helper
348 static void do_get(
const Teuchos::Ptr<const M> mat,
349 const ArrayView<typename M::scalar_t> nzvals,
350 const ArrayView<GO> indices,
351 const ArrayView<GS> pointers,
354 const Tpetra::Map<
typename M::local_ordinal_t,
355 typename M::global_ordinal_t,
356 typename M::node_t> > map,
360 typedef typename M::global_ordinal_t mat_go_t;
361 typedef typename M::global_size_t mat_gs_t;
362 typename ArrayView<GO>::size_type i, size = indices.size();
363 Teuchos::Array<mat_go_t> indices_tmp(size);
365 if_then_else<is_same<GS,mat_gs_t>::value,
366 same_gs_helper<M,S,GO,GS,Op>,
367 diff_gs_helper<M,S,GO,GS,Op> >::type::do_get(mat, nzvals, indices_tmp,
369 distribution, ordering);
371 for (i = 0; i < size; ++i){
372 indices[i] = Teuchos::as<GO>(indices_tmp[i]);
377 template <
class M,
typename S,
typename GO,
typename GS,
class Op>
378 struct same_scalar_helper
380 static void do_get(
const Teuchos::Ptr<const M> mat,
381 const ArrayView<S> nzvals,
382 const ArrayView<GO> indices,
383 const ArrayView<GS> pointers,
386 const Tpetra::Map<
typename M::local_ordinal_t,
387 typename M::global_ordinal_t,
388 typename M::node_t> > map,
392 typedef typename M::global_ordinal_t mat_go_t;
393 if_then_else<is_same<GO,mat_go_t>::value,
394 same_go_helper<M,S,GO,GS,Op>,
395 diff_go_helper<M,S,GO,GS,Op> >::type::do_get(mat, nzvals, indices,
397 distribution, ordering);
401 template <
class M,
typename S,
typename GO,
typename GS,
class Op>
402 struct diff_scalar_helper
404 static void do_get(
const Teuchos::Ptr<const M> mat,
405 const ArrayView<S> nzvals,
406 const ArrayView<GO> indices,
407 const ArrayView<GS> pointers,
410 const Tpetra::Map<
typename M::local_ordinal_t,
411 typename M::global_ordinal_t,
412 typename M::node_t> > map,
416 typedef typename M::scalar_t mat_scalar_t;
417 typedef typename M::global_ordinal_t mat_go_t;
418 typename ArrayView<S>::size_type i, size = nzvals.size();
419 Teuchos::Array<mat_scalar_t> nzvals_tmp(size);
421 if_then_else<is_same<GO,mat_go_t>::value,
422 same_go_helper<M,S,GO,GS,Op>,
423 diff_go_helper<M,S,GO,GS,Op> >::type::do_get(mat, nzvals_tmp, indices,
425 distribution, ordering);
427 for (i = 0; i < size; ++i){
428 nzvals[i] = Teuchos::as<S>(nzvals_tmp[i]);
432 #endif // DOXYGEN_SHOULD_SKIP_THIS
446 template<
class Matrix,
typename S,
typename GO,
typename GS,
class Op>
449 static void do_get(
const Teuchos::Ptr<const Matrix> mat,
450 const ArrayView<S> nzvals,
451 const ArrayView<GO> indices,
452 const ArrayView<GS> pointers,
458 typedef typename Matrix::local_ordinal_t lo_t;
459 typedef typename Matrix::global_ordinal_t go_t;
460 typedef typename Matrix::global_size_t gs_t;
461 typedef typename Matrix::node_t node_t;
463 const Teuchos::RCP<const Tpetra::Map<lo_t,go_t,node_t> > map
464 = getDistributionMap<lo_t,go_t,gs_t,node_t>(distribution,
465 Op::get_dimension(mat),
468 Op::getMapFromMatrix(mat)
471 do_get(mat, nzvals, indices, pointers, nnz, Teuchos::ptrInArg(*map), distribution, ordering);
478 static void do_get(
const Teuchos::Ptr<const Matrix> mat,
479 const ArrayView<S> nzvals,
480 const ArrayView<GO> indices,
481 const ArrayView<GS> pointers,
486 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
487 typename Matrix::global_ordinal_t,
488 typename Matrix::node_t> > map
490 do_get(mat, nzvals, indices, pointers, nnz, Teuchos::ptrInArg(*map), distribution, ordering);
497 static void do_get(
const Teuchos::Ptr<const Matrix> mat,
498 const ArrayView<S> nzvals,
499 const ArrayView<GO> indices,
500 const ArrayView<GS> pointers,
503 const Tpetra::Map<
typename Matrix::local_ordinal_t,
504 typename Matrix::global_ordinal_t,
505 typename Matrix::node_t> > map,
509 typedef typename Matrix::scalar_t mat_scalar;
510 if_then_else<is_same<mat_scalar,S>::value,
511 same_scalar_helper<Matrix,S,GO,GS,Op>,
512 diff_scalar_helper<Matrix,S,GO,GS,Op> >::type::do_get(mat,
516 distribution, ordering);
520 #ifndef DOXYGEN_SHOULD_SKIP_THIS
525 template<
class Matrix>
528 static void apply(
const Teuchos::Ptr<const Matrix> mat,
529 const ArrayView<typename Matrix::scalar_t> nzvals,
530 const ArrayView<typename Matrix::global_ordinal_t> rowind,
531 const ArrayView<typename Matrix::global_size_t> colptr,
532 typename Matrix::global_size_t& nnz,
534 const Tpetra::Map<
typename Matrix::local_ordinal_t,
535 typename Matrix::global_ordinal_t,
536 typename Matrix::node_t> > map,
540 mat->getCcs(nzvals, rowind, colptr, nnz, map, ordering, distribution);
545 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
546 typename Matrix::global_ordinal_t,
547 typename Matrix::node_t> >
548 getMapFromMatrix(
const Teuchos::Ptr<const Matrix> mat)
550 return mat->getMap();
554 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
555 typename Matrix::global_ordinal_t,
556 typename Matrix::node_t> >
557 getMap(
const Teuchos::Ptr<const Matrix> mat)
559 return mat->getColMap();
563 typename Matrix::global_size_t
564 get_dimension(
const Teuchos::Ptr<const Matrix> mat)
566 return mat->getGlobalNumCols();
570 template<
class Matrix>
573 static void apply(
const Teuchos::Ptr<const Matrix> mat,
574 const ArrayView<typename Matrix::scalar_t> nzvals,
575 const ArrayView<typename Matrix::global_ordinal_t> colind,
576 const ArrayView<typename Matrix::global_size_t> rowptr,
577 typename Matrix::global_size_t& nnz,
579 const Tpetra::Map<
typename Matrix::local_ordinal_t,
580 typename Matrix::global_ordinal_t,
581 typename Matrix::node_t> > map,
585 mat->getCrs(nzvals, colind, rowptr, nnz, map, ordering, distribution);
590 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
591 typename Matrix::global_ordinal_t,
592 typename Matrix::node_t> >
593 getMapFromMatrix(
const Teuchos::Ptr<const Matrix> mat)
595 return mat->getMap();
599 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
600 typename Matrix::global_ordinal_t,
601 typename Matrix::node_t> >
602 getMap(
const Teuchos::Ptr<const Matrix> mat)
604 return mat->getRowMap();
608 typename Matrix::global_size_t
609 get_dimension(
const Teuchos::Ptr<const Matrix> mat)
611 return mat->getGlobalNumRows();
614 #endif // DOXYGEN_SHOULD_SKIP_THIS
653 template<
class Matrix,
typename S,
typename GO,
typename GS>
664 template<
class Matrix,
typename S,
typename GO,
typename GS>
676 template <
typename LO,
typename GO,
typename GS,
typename Node>
677 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
678 getGatherMap(
const Teuchos::RCP<
const Tpetra::Map<LO,GO,Node> > &map )
681 Teuchos::RCP< const Tpetra::Map<LO,GO,Node> > gather_map = Tpetra::Details::computeGatherMap(map, Teuchos::null);
686 template <
typename LO,
typename GO,
typename GS,
typename Node>
687 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
689 GS num_global_elements,
690 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
692 const Teuchos::RCP<
const Tpetra::Map<LO,GO,Node> >& map)
696 switch( distribution ){
698 case DISTRIBUTED_NO_OVERLAP:
699 return Tpetra::createUniformContigMapWithNode<LO,GO, Node>(num_global_elements, comm);
700 case GLOBALLY_REPLICATED:
701 return Tpetra::createLocalMapWithNode<LO,GO, Node>(num_global_elements, comm);
704 int rank = Teuchos::rank(*comm);
705 size_t my_num_elems = Teuchos::OrdinalTraits<size_t>::zero();
706 if( rank == 0 ) { my_num_elems = num_global_elements; }
708 return rcp(
new Tpetra::Map<LO,GO, Node>(num_global_elements,
709 my_num_elems, indexBase, comm));
711 case CONTIGUOUS_AND_ROOTED:
713 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> > gathermap
714 = getGatherMap<LO,GO,GS,Node>( map );
718 TEUCHOS_TEST_FOR_EXCEPTION(
true,
720 "Control should never reach this point. "
721 "Please contact the Amesos2 developers." );
726 #ifdef HAVE_AMESOS2_EPETRA
731 template <
typename LO,
typename GO,
typename GS,
typename Node>
732 Teuchos::RCP<Tpetra::Map<LO,GO,Node> >
738 int num_my_elements = map.NumMyElements();
739 Teuchos::Array<int> my_global_elements(num_my_elements);
740 map.MyGlobalElements(my_global_elements.getRawPtr());
742 Teuchos::Array<GO> my_gbl_inds_buf;
743 Teuchos::ArrayView<GO> my_gbl_inds;
744 if (! std::is_same<int, GO>::value) {
745 my_gbl_inds_buf.resize (num_my_elements);
746 my_gbl_inds = my_gbl_inds_buf ();
747 for (
int k = 0; k < num_my_elements; ++k) {
748 my_gbl_inds[k] =
static_cast<GO
> (my_global_elements[k]);
752 using Teuchos::av_reinterpret_cast;
753 my_gbl_inds = av_reinterpret_cast<GO> (my_global_elements ());
756 typedef Tpetra::Map<LO,GO,Node> map_t;
757 RCP<map_t> tmap = rcp(
new map_t(Teuchos::OrdinalTraits<GS>::invalid(),
759 as<GO>(map.IndexBase()),
764 template <
typename LO,
typename GO,
typename GS,
typename Node>
765 Teuchos::RCP<Epetra_Map>
770 Teuchos::Array<GO> elements_tmp;
771 elements_tmp = map.getNodeElementList();
772 int num_my_elements = elements_tmp.size();
773 Teuchos::Array<int> my_global_elements(num_my_elements);
774 for (
int i = 0; i < num_my_elements; ++i){
775 my_global_elements[i] = as<int>(elements_tmp[i]);
779 RCP<Epetra_Map> emap = rcp(
new Epetra_Map(-1,
781 my_global_elements.getRawPtr(),
782 as<GO>(map.getIndexBase()),
786 #endif // HAVE_AMESOS2_EPETRA
788 template <
typename Scalar,
789 typename GlobalOrdinal,
790 typename GlobalSizeT>
791 void transpose(Teuchos::ArrayView<Scalar> vals,
792 Teuchos::ArrayView<GlobalOrdinal> indices,
793 Teuchos::ArrayView<GlobalSizeT> ptr,
794 Teuchos::ArrayView<Scalar> trans_vals,
795 Teuchos::ArrayView<GlobalOrdinal> trans_indices,
796 Teuchos::ArrayView<GlobalSizeT> trans_ptr)
804 #ifdef HAVE_AMESOS2_DEBUG
805 typename Teuchos::ArrayView<GlobalOrdinal>::iterator ind_it, ind_begin, ind_end;
806 ind_begin = indices.begin();
807 ind_end = indices.end();
808 size_t min_trans_ptr_size = *std::max_element(ind_begin, ind_end) + 1;
809 TEUCHOS_TEST_FOR_EXCEPTION( Teuchos::as<size_t>(trans_ptr.size()) < min_trans_ptr_size,
810 std::invalid_argument,
811 "Transpose pointer size not large enough." );
812 TEUCHOS_TEST_FOR_EXCEPTION( trans_vals.size() < vals.size(),
813 std::invalid_argument,
814 "Transpose values array not large enough." );
815 TEUCHOS_TEST_FOR_EXCEPTION( trans_indices.size() < indices.size(),
816 std::invalid_argument,
817 "Transpose indices array not large enough." );
819 typename Teuchos::ArrayView<GlobalOrdinal>::iterator ind_it, ind_end;
822 Teuchos::Array<GlobalSizeT> count(trans_ptr.size(), 0);
823 ind_end = indices.end();
824 for( ind_it = indices.begin(); ind_it != ind_end; ++ind_it ){
825 ++(count[(*ind_it) + 1]);
828 typename Teuchos::Array<GlobalSizeT>::iterator cnt_it, cnt_end;
829 cnt_end = count.end();
830 for( cnt_it = count.begin() + 1; cnt_it != cnt_end; ++cnt_it ){
831 *cnt_it = *cnt_it + *(cnt_it - 1);
834 trans_ptr.assign(count);
848 GlobalSizeT size = ptr.size();
849 for( GlobalSizeT i = 0; i < size - 1; ++i ){
850 GlobalOrdinal u = ptr[i];
851 GlobalOrdinal v = ptr[i + 1];
852 for( GlobalOrdinal j = u; j < v; ++j ){
853 GlobalOrdinal k = count[indices[j]];
854 trans_vals[k] = vals[j];
855 trans_indices[k] = i;
856 ++(count[indices[j]]);
862 template <
typename Scalar1,
typename Scalar2>
864 scale(Teuchos::ArrayView<Scalar1> vals,
size_t l,
865 size_t ld, Teuchos::ArrayView<Scalar2> s)
867 size_t vals_size = vals.size();
868 #ifdef HAVE_AMESOS2_DEBUG
869 size_t s_size = s.size();
870 TEUCHOS_TEST_FOR_EXCEPTION( s_size < l,
871 std::invalid_argument,
872 "Scale vector must have length at least that of the vector" );
875 for( i = 0, s_i = 0; i < vals_size; ++i, ++s_i ){
885 template <
typename Scalar1,
typename Scalar2,
class BinaryOp>
887 scale(Teuchos::ArrayView<Scalar1> vals,
size_t l,
888 size_t ld, Teuchos::ArrayView<Scalar2> s,
891 size_t vals_size = vals.size();
892 #ifdef HAVE_AMESOS2_DEBUG
893 size_t s_size = s.size();
894 TEUCHOS_TEST_FOR_EXCEPTION( s_size < l,
895 std::invalid_argument,
896 "Scale vector must have length at least that of the vector" );
899 for( i = 0, s_i = 0; i < vals_size; ++i, ++s_i ){
905 vals[i] = binary_op(vals[i], s[s_i]);
915 #endif // #ifndef AMESOS2_UTIL_HPP
void scale(ArrayView< Scalar1 > vals, size_t l, size_t ld, ArrayView< Scalar2 > s)
Scales a 1-D representation of a multivector.
Similar to get_ccs_helper , but used to get a CRS representation of the given matrix.
Definition: Amesos2_Util.hpp:665
A generic base class for the CRS and CCS helpers.
Definition: Amesos2_Util.hpp:447
EStorage_Ordering
Definition: Amesos2_TypeDecl.hpp:141
void transpose(ArrayView< Scalar > vals, ArrayView< GlobalOrdinal > indices, ArrayView< GlobalSizeT > ptr, ArrayView< Scalar > trans_vals, ArrayView< GlobalOrdinal > trans_indices, ArrayView< GlobalSizeT > trans_ptr)
static void do_get(const Teuchos::Ptr< const Matrix > mat, const ArrayView< S > nzvals, const ArrayView< GO > indices, const ArrayView< GS > pointers, GS &nnz, const Teuchos::Ptr< const Tpetra::Map< typename Matrix::local_ordinal_t, typename Matrix::global_ordinal_t, typename Matrix::node_t > > map, EDistribution distribution, EStorage_Ordering ordering=ARBITRARY)
Definition: Amesos2_Util.hpp:497
const RCP< const Teuchos::Comm< int > > to_teuchos_comm(RCP< const Epetra_Comm > c)
Transform an Epetra_Comm object into a Teuchos::Comm object.
void printLine(Teuchos::FancyOStream &out)
Prints a line of 70 "-"s on std::cout.
Definition: Amesos2_Util.cpp:119
A generic helper class for getting a CCS representation of a Matrix.
Definition: Amesos2_Util.hpp:654
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 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:678
static void do_get(const Teuchos::Ptr< const Matrix > mat, const ArrayView< S > nzvals, const ArrayView< GO > indices, const ArrayView< GS > pointers, GS &nnz, EDistribution distribution, EStorage_Ordering ordering=ARBITRARY)
Definition: Amesos2_Util.hpp:478
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:766
Enum and other types declarations for Amesos2.
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:733
EDistribution
Definition: Amesos2_TypeDecl.hpp:123