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_ArrayView.hpp> 60 #include <Teuchos_FancyOStream.hpp> 62 #include <Tpetra_Map.hpp> 63 #include <Tpetra_DistObject_decl.hpp> 64 #include <Tpetra_ComputeGatherMap.hpp> 69 #ifdef HAVE_TPETRA_INST_INT_INT 70 #ifdef HAVE_AMESOS2_EPETRA 71 #include <Epetra_Map.h> 87 using Teuchos::ArrayView;
90 using Meta::if_then_else;
108 template <
typename LO,
typename GO,
typename GS,
typename Node>
109 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
110 getGatherMap(
const Teuchos::RCP<
const Tpetra::Map<LO,GO,Node> > &map );
113 template <
typename LO,
typename GO,
typename GS,
typename Node>
114 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
116 GS num_global_elements,
117 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
119 const Teuchos::RCP<
const Tpetra::Map<LO,GO,Node> >& map = Teuchos::null);
122 #ifdef HAVE_TPETRA_INST_INT_INT 123 #ifdef HAVE_AMESOS2_EPETRA 130 template <
typename LO,
typename GO,
typename GS,
typename Node>
131 RCP<Tpetra::Map<LO,GO,Node> >
132 epetra_map_to_tpetra_map(
const Epetra_BlockMap& map);
139 template <
typename LO,
typename GO,
typename GS,
typename Node>
141 tpetra_map_to_epetra_map(
const Tpetra::Map<LO,GO,Node>& map);
148 const RCP<const Teuchos::Comm<int> > to_teuchos_comm(RCP<const Epetra_Comm> c);
155 const RCP<const Epetra_Comm> to_epetra_comm(RCP<
const Teuchos::Comm<int> > c);
156 #endif // HAVE_AMESOS2_EPETRA 157 #endif // HAVE_TPETRA_INST_INT_INT 164 template <
typename Scalar,
165 typename GlobalOrdinal,
166 typename GlobalSizeT>
168 ArrayView<GlobalOrdinal> indices,
169 ArrayView<GlobalSizeT> ptr,
170 ArrayView<Scalar> trans_vals,
171 ArrayView<GlobalOrdinal> trans_indices,
172 ArrayView<GlobalSizeT> trans_ptr);
187 template <
typename Scalar1,
typename Scalar2>
188 void scale(ArrayView<Scalar1> vals,
size_t l,
189 size_t ld, ArrayView<Scalar2> s);
209 template <
typename Scalar1,
typename Scalar2,
class BinaryOp>
210 void scale(ArrayView<Scalar1> vals,
size_t l,
211 size_t ld, ArrayView<Scalar2> s, BinaryOp binary_op);
215 void printLine( Teuchos::FancyOStream &out );
222 #ifndef DOXYGEN_SHOULD_SKIP_THIS 245 template <
class M,
typename S,
typename GO,
typename GS,
class Op>
246 struct same_gs_helper
248 static void do_get(
const Teuchos::Ptr<const M> mat,
249 const ArrayView<typename M::scalar_t> nzvals,
250 const ArrayView<typename M::global_ordinal_t> indices,
251 const ArrayView<GS> pointers,
254 const Tpetra::Map<
typename M::local_ordinal_t,
255 typename M::global_ordinal_t,
256 typename M::node_t> > map,
260 Op::apply(mat, nzvals, indices, pointers, nnz, map, distribution, ordering);
264 template <
class M,
typename S,
typename GO,
typename GS,
class Op>
265 struct diff_gs_helper
267 static void do_get(
const Teuchos::Ptr<const M> mat,
268 const ArrayView<typename M::scalar_t> nzvals,
269 const ArrayView<typename M::global_ordinal_t> indices,
270 const ArrayView<GS> pointers,
273 const Tpetra::Map<
typename M::local_ordinal_t,
274 typename M::global_ordinal_t,
275 typename M::node_t> > map,
279 typedef typename M::global_size_t mat_gs_t;
280 typename ArrayView<GS>::size_type i, size = pointers.size();
281 Teuchos::Array<mat_gs_t> pointers_tmp(size);
282 mat_gs_t nnz_tmp = 0;
284 Op::apply(mat, nzvals, indices, pointers_tmp, nnz_tmp, map, distribution, ordering);
286 for (i = 0; i < size; ++i){
287 pointers[i] = Teuchos::as<GS>(pointers_tmp[i]);
289 nnz = Teuchos::as<GS>(nnz_tmp);
293 template <
class M,
typename S,
typename GO,
typename GS,
class Op>
294 struct same_go_helper
296 static void do_get(
const Teuchos::Ptr<const M> mat,
297 const ArrayView<typename M::scalar_t> nzvals,
298 const ArrayView<GO> indices,
299 const ArrayView<GS> pointers,
302 const Tpetra::Map<
typename M::local_ordinal_t,
303 typename M::global_ordinal_t,
304 typename M::node_t> > map,
308 typedef typename M::global_size_t mat_gs_t;
309 if_then_else<is_same<GS,mat_gs_t>::value,
310 same_gs_helper<M,S,GO,GS,Op>,
311 diff_gs_helper<M,S,GO,GS,Op> >::type::do_get(mat, nzvals, indices,
313 distribution, ordering);
317 template <
class M,
typename S,
typename GO,
typename GS,
class Op>
318 struct diff_go_helper
320 static void do_get(
const Teuchos::Ptr<const M> mat,
321 const ArrayView<typename M::scalar_t> nzvals,
322 const ArrayView<GO> indices,
323 const ArrayView<GS> pointers,
326 const Tpetra::Map<
typename M::local_ordinal_t,
327 typename M::global_ordinal_t,
328 typename M::node_t> > map,
332 typedef typename M::global_ordinal_t mat_go_t;
333 typedef typename M::global_size_t mat_gs_t;
334 typename ArrayView<GO>::size_type i, size = indices.size();
335 Teuchos::Array<mat_go_t> indices_tmp(size);
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_tmp,
341 distribution, ordering);
343 for (i = 0; i < size; ++i){
344 indices[i] = Teuchos::as<GO>(indices_tmp[i]);
349 template <
class M,
typename S,
typename GO,
typename GS,
class Op>
350 struct same_scalar_helper
352 static void do_get(
const Teuchos::Ptr<const M> mat,
353 const ArrayView<S> nzvals,
354 const ArrayView<GO> indices,
355 const ArrayView<GS> pointers,
358 const Tpetra::Map<
typename M::local_ordinal_t,
359 typename M::global_ordinal_t,
360 typename M::node_t> > map,
364 typedef typename M::global_ordinal_t mat_go_t;
365 if_then_else<is_same<GO,mat_go_t>::value,
366 same_go_helper<M,S,GO,GS,Op>,
367 diff_go_helper<M,S,GO,GS,Op> >::type::do_get(mat, nzvals, indices,
369 distribution, ordering);
373 template <
class M,
typename S,
typename GO,
typename GS,
class Op>
374 struct diff_scalar_helper
376 static void do_get(
const Teuchos::Ptr<const M> mat,
377 const ArrayView<S> nzvals,
378 const ArrayView<GO> indices,
379 const ArrayView<GS> pointers,
382 const Tpetra::Map<
typename M::local_ordinal_t,
383 typename M::global_ordinal_t,
384 typename M::node_t> > map,
388 typedef typename M::scalar_t mat_scalar_t;
389 typedef typename M::global_ordinal_t mat_go_t;
390 typename ArrayView<S>::size_type i, size = nzvals.size();
391 Teuchos::Array<mat_scalar_t> nzvals_tmp(size);
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_tmp, indices,
397 distribution, ordering);
399 for (i = 0; i < size; ++i){
400 nzvals[i] = Teuchos::as<S>(nzvals_tmp[i]);
404 #endif // DOXYGEN_SHOULD_SKIP_THIS 418 template<
class Matrix,
typename S,
typename GO,
typename GS,
class Op>
421 static void do_get(
const Teuchos::Ptr<const Matrix> mat,
422 const ArrayView<S> nzvals,
423 const ArrayView<GO> indices,
424 const ArrayView<GS> pointers,
430 typedef typename Matrix::local_ordinal_t lo_t;
431 typedef typename Matrix::global_ordinal_t go_t;
432 typedef typename Matrix::global_size_t gs_t;
433 typedef typename Matrix::node_t node_t;
435 const Teuchos::RCP<const Tpetra::Map<lo_t,go_t,node_t> > map
436 = getDistributionMap<lo_t,go_t,gs_t,node_t>(distribution,
437 Op::get_dimension(mat),
440 Op::getMapFromMatrix(mat)
443 do_get(mat, nzvals, indices, pointers, nnz, Teuchos::ptrInArg(*map), distribution, ordering);
450 static void do_get(
const Teuchos::Ptr<const Matrix> mat,
451 const ArrayView<S> nzvals,
452 const ArrayView<GO> indices,
453 const ArrayView<GS> pointers,
458 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
459 typename Matrix::global_ordinal_t,
460 typename Matrix::node_t> > map
462 do_get(mat, nzvals, indices, pointers, nnz, Teuchos::ptrInArg(*map), distribution, ordering);
469 static void do_get(
const Teuchos::Ptr<const Matrix> mat,
470 const ArrayView<S> nzvals,
471 const ArrayView<GO> indices,
472 const ArrayView<GS> pointers,
475 const Tpetra::Map<
typename Matrix::local_ordinal_t,
476 typename Matrix::global_ordinal_t,
477 typename Matrix::node_t> > map,
481 typedef typename Matrix::scalar_t mat_scalar;
482 if_then_else<is_same<mat_scalar,S>::value,
483 same_scalar_helper<Matrix,S,GO,GS,Op>,
484 diff_scalar_helper<Matrix,S,GO,GS,Op> >::type::do_get(mat,
488 distribution, ordering);
492 #ifndef DOXYGEN_SHOULD_SKIP_THIS 497 template<
class Matrix>
500 static void apply(
const Teuchos::Ptr<const Matrix> mat,
501 const ArrayView<typename Matrix::scalar_t> nzvals,
502 const ArrayView<typename Matrix::global_ordinal_t> rowind,
503 const ArrayView<typename Matrix::global_size_t> colptr,
504 typename Matrix::global_size_t& nnz,
506 const Tpetra::Map<
typename Matrix::local_ordinal_t,
507 typename Matrix::global_ordinal_t,
508 typename Matrix::node_t> > map,
512 mat->getCcs(nzvals, rowind, colptr, nnz, map, ordering, distribution);
517 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
518 typename Matrix::global_ordinal_t,
519 typename Matrix::node_t> >
520 getMapFromMatrix(
const Teuchos::Ptr<const Matrix> mat)
522 return mat->getMap();
526 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
527 typename Matrix::global_ordinal_t,
528 typename Matrix::node_t> >
529 getMap(
const Teuchos::Ptr<const Matrix> mat)
531 return mat->getColMap();
535 typename Matrix::global_size_t
536 get_dimension(
const Teuchos::Ptr<const Matrix> mat)
538 return mat->getGlobalNumCols();
542 template<
class Matrix>
545 static void apply(
const Teuchos::Ptr<const Matrix> mat,
546 const ArrayView<typename Matrix::scalar_t> nzvals,
547 const ArrayView<typename Matrix::global_ordinal_t> colind,
548 const ArrayView<typename Matrix::global_size_t> rowptr,
549 typename Matrix::global_size_t& nnz,
551 const Tpetra::Map<
typename Matrix::local_ordinal_t,
552 typename Matrix::global_ordinal_t,
553 typename Matrix::node_t> > map,
557 mat->getCrs(nzvals, colind, rowptr, nnz, map, ordering, distribution);
562 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
563 typename Matrix::global_ordinal_t,
564 typename Matrix::node_t> >
565 getMapFromMatrix(
const Teuchos::Ptr<const Matrix> mat)
567 return mat->getMap();
571 const Teuchos::RCP<
const Tpetra::Map<
typename Matrix::local_ordinal_t,
572 typename Matrix::global_ordinal_t,
573 typename Matrix::node_t> >
574 getMap(
const Teuchos::Ptr<const Matrix> mat)
576 return mat->getRowMap();
580 typename Matrix::global_size_t
581 get_dimension(
const Teuchos::Ptr<const Matrix> mat)
583 return mat->getGlobalNumRows();
586 #endif // DOXYGEN_SHOULD_SKIP_THIS 625 template<
class Matrix,
typename S,
typename GO,
typename GS>
636 template<
class Matrix,
typename S,
typename GO,
typename GS>
648 template <
typename LO,
typename GO,
typename GS,
typename Node>
649 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
650 getGatherMap(
const Teuchos::RCP<
const Tpetra::Map<LO,GO,Node> > &map )
653 Teuchos::RCP< const Tpetra::Map<LO,GO,Node> > gather_map = Tpetra::Details::computeGatherMap(map, Teuchos::null);
658 template <
typename LO,
typename GO,
typename GS,
typename Node>
659 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
661 GS num_global_elements,
662 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
664 const Teuchos::RCP<
const Tpetra::Map<LO,GO,Node> >& map)
668 switch( distribution ){
671 return Tpetra::createUniformContigMapWithNode<LO,GO, Node>(num_global_elements, comm);
673 return Tpetra::createLocalMapWithNode<LO,GO, Node>(num_global_elements, comm);
676 int rank = Teuchos::rank(*comm);
677 size_t my_num_elems = Teuchos::OrdinalTraits<size_t>::zero();
678 if( rank == 0 ) { my_num_elems = num_global_elements; }
680 return rcp(
new Tpetra::Map<LO,GO, Node>(num_global_elements,
681 my_num_elems, indexBase, comm));
685 const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> > gathermap
686 = getGatherMap<LO,GO,GS,Node>( map );
690 TEUCHOS_TEST_FOR_EXCEPTION(
true,
692 "Control should never reach this point. " 693 "Please contact the Amesos2 developers." );
698 #ifdef HAVE_TPETRA_INST_INT_INT 699 #ifdef HAVE_AMESOS2_EPETRA 704 template <
typename LO,
typename GO,
typename GS,
typename Node>
705 Teuchos::RCP<Tpetra::Map<LO,GO,Node> >
706 epetra_map_to_tpetra_map(
const Epetra_BlockMap& map)
711 int num_my_elements = map.NumMyElements();
712 Teuchos::Array<int> my_global_elements(num_my_elements);
713 map.MyGlobalElements(my_global_elements.getRawPtr());
715 typedef Tpetra::Map<LO,GO,Node> map_t;
716 RCP<map_t> tmap = rcp(
new map_t(Teuchos::OrdinalTraits<GS>::invalid(),
717 my_global_elements(),
718 as<GO>(map.IndexBase()),
719 to_teuchos_comm(Teuchos::rcpFromRef(map.Comm()))));
723 template <
typename LO,
typename GO,
typename GS,
typename Node>
724 Teuchos::RCP<Epetra_Map>
725 tpetra_map_to_epetra_map(
const Tpetra::Map<LO,GO,Node>& map)
729 Teuchos::Array<GO> elements_tmp;
730 elements_tmp = map.getNodeElementList();
731 int num_my_elements = elements_tmp.size();
732 Teuchos::Array<int> my_global_elements(num_my_elements);
733 for (
int i = 0; i < num_my_elements; ++i){
734 my_global_elements[i] = as<int>(elements_tmp[i]);
738 RCP<Epetra_Map> emap = rcp(
new Epetra_Map(-1,
740 my_global_elements.getRawPtr(),
741 as<GO>(map.getIndexBase()),
742 *to_epetra_comm(map.getComm())));
745 #endif // HAVE_AMESOS2_EPETRA 746 #endif // HAVE_TPETRA_INST_INT_INT 748 template <
typename Scalar,
749 typename GlobalOrdinal,
750 typename GlobalSizeT>
751 void transpose(Teuchos::ArrayView<Scalar> vals,
752 Teuchos::ArrayView<GlobalOrdinal> indices,
753 Teuchos::ArrayView<GlobalSizeT> ptr,
754 Teuchos::ArrayView<Scalar> trans_vals,
755 Teuchos::ArrayView<GlobalOrdinal> trans_indices,
756 Teuchos::ArrayView<GlobalSizeT> trans_ptr)
764 #ifdef HAVE_AMESOS2_DEBUG 765 typename Teuchos::ArrayView<GlobalOrdinal>::iterator ind_it, ind_begin, ind_end;
766 ind_begin = indices.begin();
767 ind_end = indices.end();
768 size_t min_trans_ptr_size = *std::max_element(ind_begin, ind_end) + 1;
769 TEUCHOS_TEST_FOR_EXCEPTION( Teuchos::as<size_t>(trans_ptr.size()) < min_trans_ptr_size,
770 std::invalid_argument,
771 "Transpose pointer size not large enough." );
772 TEUCHOS_TEST_FOR_EXCEPTION( trans_vals.size() < vals.size(),
773 std::invalid_argument,
774 "Transpose values array not large enough." );
775 TEUCHOS_TEST_FOR_EXCEPTION( trans_indices.size() < indices.size(),
776 std::invalid_argument,
777 "Transpose indices array not large enough." );
779 typename Teuchos::ArrayView<GlobalOrdinal>::iterator ind_it, ind_end;
782 Teuchos::Array<GlobalSizeT> count(trans_ptr.size(), 0);
783 ind_end = indices.end();
784 for( ind_it = indices.begin(); ind_it != ind_end; ++ind_it ){
785 ++(count[(*ind_it) + 1]);
788 typename Teuchos::Array<GlobalSizeT>::iterator cnt_it, cnt_end;
789 cnt_end = count.end();
790 for( cnt_it = count.begin() + 1; cnt_it != cnt_end; ++cnt_it ){
791 *cnt_it = *cnt_it + *(cnt_it - 1);
794 trans_ptr.assign(count);
808 GlobalSizeT size = ptr.size();
809 for( GlobalSizeT i = 0; i < size - 1; ++i ){
810 GlobalOrdinal u = ptr[i];
811 GlobalOrdinal v = ptr[i + 1];
812 for( GlobalOrdinal j = u; j < v; ++j ){
813 GlobalOrdinal k = count[indices[j]];
814 trans_vals[k] = vals[j];
815 trans_indices[k] = i;
816 ++(count[indices[j]]);
822 template <
typename Scalar1,
typename Scalar2>
824 scale(Teuchos::ArrayView<Scalar1> vals,
size_t l,
825 size_t ld, Teuchos::ArrayView<Scalar2> s)
827 size_t vals_size = vals.size();
828 #ifdef HAVE_AMESOS2_DEBUG 829 size_t s_size = s.size();
830 TEUCHOS_TEST_FOR_EXCEPTION( s_size < l,
831 std::invalid_argument,
832 "Scale vector must have length at least that of the vector" );
835 for( i = 0, s_i = 0; i < vals_size; ++i, ++s_i ){
845 template <
typename Scalar1,
typename Scalar2,
class BinaryOp>
847 scale(Teuchos::ArrayView<Scalar1> vals,
size_t l,
848 size_t ld, Teuchos::ArrayView<Scalar2> s,
851 size_t vals_size = vals.size();
852 #ifdef HAVE_AMESOS2_DEBUG 853 size_t s_size = s.size();
854 TEUCHOS_TEST_FOR_EXCEPTION( s_size < l,
855 std::invalid_argument,
856 "Scale vector must have length at least that of the vector" );
859 for( i = 0, s_i = 0; i < vals_size; ++i, ++s_i ){
865 vals[i] = binary_op(vals[i], s[s_i]);
875 #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:637
A generic base class for the CRS and CCS helpers.
Definition: Amesos2_Util.hpp:419
Definition: Amesos2_TypeDecl.hpp:143
EStorage_Ordering
Definition: Amesos2_TypeDecl.hpp:141
Definition: Amesos2_TypeDecl.hpp:125
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:469
Definition: Amesos2_AbstractConcreteMatrixAdapter.hpp:48
void printLine(Teuchos::FancyOStream &out)
Prints a line of 70 "-"s on std::cout.
Definition: Amesos2_Util.cpp:123
A generic helper class for getting a CCS representation of a Matrix.
Definition: Amesos2_Util.hpp:626
Definition: Amesos2_TypeDecl.hpp:126
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:650
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:450
Definition: Amesos2_TypeDecl.hpp:124
Enum and other types declarations for Amesos2.
Definition: Amesos2_TypeDecl.hpp:127
EDistribution
Definition: Amesos2_TypeDecl.hpp:123
Definition: Amesos2_TypeDecl.hpp:128