53 #ifndef AMESOS2_TPETRA_MULTIVEC_ADAPTER_DEF_HPP 
   54 #define AMESOS2_TPETRA_MULTIVEC_ADAPTER_DEF_HPP 
   56 #include <type_traits> 
   62   using Tpetra::MultiVector;
 
   64   template <
typename Scalar, 
typename LocalOrdinal, 
typename GlobalOrdinal, 
class Node >
 
   69                 Node> >::MultiVecAdapter( 
const Teuchos::RCP<multivec_t>& m )
 
   74   template <
typename Scalar, 
typename LocalOrdinal, 
typename GlobalOrdinal, 
class Node >
 
   75   typename MultiVecAdapter<
 
   79                 Node> >::multivec_t::impl_scalar_type *
 
   84                 Node> >::getMVPointer_impl()
 const 
   86   TEUCHOS_TEST_FOR_EXCEPTION( this->getGlobalNumVectors() != 1,
 
   87           std::invalid_argument,
 
   88           "Amesos2_TpetraMultiVectorAdapter: getMVPointer_impl should only be called for case with a single vector and single MPI process" );
 
   90     typedef typename multivec_t::dual_view_type dual_view_type;
 
   91     typedef typename dual_view_type::host_mirror_space host_execution_space;
 
   92     mv_->template sync<host_execution_space> ();
 
   93     auto contig_local_view_2d = mv_->template getLocalView<host_execution_space>();
 
   94     auto contig_local_view_1d = Kokkos::subview (contig_local_view_2d, Kokkos::ALL (), 0);
 
   95     return contig_local_view_1d.data();
 
  106   template <
typename Scalar, 
typename LocalOrdinal, 
typename GlobalOrdinal, 
class Node >
 
  112                 Node> >::get1dCopy(
const Teuchos::ArrayView<scalar_t>& av,
 
  115                                      const Tpetra::Map<LocalOrdinal,
 
  117                                                        Node> > distribution_map,
 
  122     typedef Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node> map_type;
 
  123     const size_t num_vecs = getGlobalNumVectors ();
 
  125     TEUCHOS_TEST_FOR_EXCEPTION(
 
  126       distribution_map.getRawPtr () == NULL, std::invalid_argument,
 
  127       "Amesos2::MultiVecAdapter::get1dCopy: distribution_map argument is null.");
 
  128     TEUCHOS_TEST_FOR_EXCEPTION(
 
  129       mv_.is_null (), std::logic_error,
 
  130       "Amesos2::MultiVecAdapter::get1dCopy: mv_ is null.");
 
  132     TEUCHOS_TEST_FOR_EXCEPTION(
 
  133       this->getMap ().is_null (), std::logic_error,
 
  134       "Amesos2::MultiVecAdapter::get1dCopy: this->getMap() returns null.");
 
  136 #ifdef HAVE_AMESOS2_DEBUG 
  137     const size_t requested_vector_length = distribution_map->getNodeNumElements ();
 
  138     TEUCHOS_TEST_FOR_EXCEPTION(
 
  139       lda < requested_vector_length, std::invalid_argument,
 
  140       "Amesos2::MultiVecAdapter::get1dCopy: On process " <<
 
  141       distribution_map->getComm ()->getRank () << 
" of the distribution Map's " 
  142       "communicator, the given stride lda = " << lda << 
" is not large enough " 
  143       "for the local vector length " << requested_vector_length << 
".");
 
  144     TEUCHOS_TEST_FOR_EXCEPTION(
 
  145       as<size_t> (av.size ()) < as<size_t> ((num_vecs - 1) * lda + requested_vector_length),
 
  146       std::invalid_argument, 
"Amesos2::MultiVector::get1dCopy: MultiVector " 
  147       "storage not large enough given leading dimension and number of vectors." );
 
  148 #endif // HAVE_AMESOS2_DEBUG 
  151     if ( num_vecs == 1 && this->getComm()->getRank() == 0 && this->getComm()->getSize() == 1 ) {
 
  152       mv_->get1dCopy (av, lda);
 
  159       RCP<const map_type> distMap;
 
  160       if (exporter_.is_null () ||
 
  161           ! exporter_->getSourceMap ()->isSameAs (* (this->getMap ())) ||
 
  162           ! exporter_->getTargetMap ()->isSameAs (* distribution_map)) {
 
  168         distMap = rcp(
new map_type(*distribution_map));
 
  170         exporter_ = rcp (
new export_type (this->getMap (), distMap));
 
  173         distMap = exporter_->getTargetMap ();
 
  176       multivec_t redist_mv (distMap, num_vecs);
 
  179       redist_mv.doExport (*mv_, *exporter_, Tpetra::REPLACE);
 
  181       if ( distribution != CONTIGUOUS_AND_ROOTED ) {
 
  184         redist_mv.get1dCopy (av, lda);
 
  189         typedef typename multivec_t::dual_view_type dual_view_type;
 
  190         typedef typename dual_view_type::host_mirror_space host_execution_space;
 
  191         redist_mv.template sync < host_execution_space > ();
 
  193         auto contig_local_view_2d = redist_mv.template getLocalView<host_execution_space>();
 
  194         if ( redist_mv.isConstantStride() ) {
 
  195           for ( 
size_t j = 0; j < num_vecs; ++j) {
 
  196             auto av_j = av(lda*j, lda);
 
  197             for ( 
size_t i = 0; i < lda; ++i ) {
 
  198               av_j[i] = contig_local_view_2d(i,j); 
 
  207           const size_t lclNumRows = redist_mv.getLocalLength();
 
  208           for (
size_t j = 0; j < redist_mv.getNumVectors(); ++j) {
 
  209             auto av_j = av(lda*j, lclNumRows);
 
  210             auto X_lcl_j_2d = redist_mv.template getLocalView<host_execution_space> ();
 
  211             auto X_lcl_j_1d = Kokkos::subview (X_lcl_j_2d, Kokkos::ALL (), j);
 
  213             using val_type = 
typename decltype( X_lcl_j_1d )::value_type;
 
  214             Kokkos::View<val_type*, Kokkos::HostSpace> umavj ( const_cast< val_type* > ( reinterpret_cast<const val_type*> ( av_j.getRawPtr () ) ), av_j.size () );
 
  215             Kokkos::deep_copy (umavj, X_lcl_j_1d);
 
  222   template <
typename Scalar, 
typename LocalOrdinal, 
typename GlobalOrdinal, 
class Node >
 
  223   Teuchos::ArrayRCP<Scalar>
 
  228                 Node> >::get1dViewNonConst (
bool local)
 
  234     TEUCHOS_TEST_FOR_EXCEPTION(
 
  235       true, std::logic_error, 
"Amesos2::MultiVecAdapter::get1dViewNonConst: " 
  289   template <
typename Scalar, 
typename LocalOrdinal, 
typename GlobalOrdinal, 
class Node>
 
  295                 Node> >::put1dData(
const Teuchos::ArrayView<const scalar_t>& new_data,
 
  298                                      const Tpetra::Map<LocalOrdinal,
 
  304     typedef Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node> map_type;
 
  306     TEUCHOS_TEST_FOR_EXCEPTION(
 
  307       source_map.getRawPtr () == NULL, std::invalid_argument,
 
  308       "Amesos2::MultiVecAdapter::put1dData: source_map argument is null.");
 
  309     TEUCHOS_TEST_FOR_EXCEPTION(
 
  310       mv_.is_null (), std::logic_error,
 
  311       "Amesos2::MultiVecAdapter::put1dData: the internal MultiVector mv_ is null.");
 
  313     TEUCHOS_TEST_FOR_EXCEPTION(
 
  314       this->getMap ().is_null (), std::logic_error,
 
  315       "Amesos2::MultiVecAdapter::put1dData: this->getMap() returns null.");
 
  317     const size_t num_vecs = getGlobalNumVectors ();
 
  320     if ( num_vecs == 1 && this->getComm()->getRank() == 0 && this->getComm()->getSize() == 1 ) {
 
  321       typedef typename multivec_t::dual_view_type::host_mirror_space host_execution_space;
 
  323       auto mv_view_to_modify_2d = mv_->template getLocalView<host_execution_space>();
 
  324       for ( 
size_t i = 0; i < lda; ++i ) {
 
  325         mv_view_to_modify_2d(i,0) = new_data[i]; 
 
  333       RCP<const map_type> srcMap;
 
  334       if (importer_.is_null () ||
 
  335           ! importer_->getSourceMap ()->isSameAs (* source_map) ||
 
  336           ! importer_->getTargetMap ()->isSameAs (* (this->getMap ()))) {
 
  342         srcMap = rcp(
new map_type(*source_map));
 
  343         importer_ = rcp (
new import_type (srcMap, this->getMap ()));
 
  346         srcMap = importer_->getSourceMap ();
 
  349       if ( distribution != CONTIGUOUS_AND_ROOTED ) {
 
  352         const multivec_t source_mv (srcMap, new_data, lda, num_vecs);
 
  353         mv_->doImport (source_mv, *importer_, Tpetra::REPLACE);
 
  356         multivec_t redist_mv (srcMap, num_vecs); 
 
  357         typedef typename multivec_t::dual_view_type dual_view_type;
 
  358         typedef typename dual_view_type::host_mirror_space host_execution_space;
 
  359         redist_mv.template modify< host_execution_space > ();
 
  361         if ( redist_mv.isConstantStride() ) {
 
  362           auto contig_local_view_2d = redist_mv.template getLocalView<host_execution_space>();
 
  363           for ( 
size_t j = 0; j < num_vecs; ++j) {
 
  364             auto av_j = new_data(lda*j, lda);
 
  365             for ( 
size_t i = 0; i < lda; ++i ) {
 
  366               contig_local_view_2d(i,j) = av_j[i];
 
  375           const size_t lclNumRows = redist_mv.getLocalLength();
 
  376           for (
size_t j = 0; j < redist_mv.getNumVectors(); ++j) {
 
  377             auto av_j = new_data(lda*j, lclNumRows);
 
  378             auto X_lcl_j_2d = redist_mv.template getLocalView<host_execution_space> ();
 
  379             auto X_lcl_j_1d = Kokkos::subview (X_lcl_j_2d, Kokkos::ALL (), j);
 
  381             using val_type = 
typename decltype( X_lcl_j_1d )::value_type;
 
  382             Kokkos::View<val_type*, Kokkos::HostSpace> umavj ( const_cast< val_type* > ( reinterpret_cast<const val_type*> ( av_j.getRawPtr () ) ), av_j.size () );
 
  383             Kokkos::deep_copy (umavj, X_lcl_j_1d);
 
  387         typedef typename multivec_t::node_type::memory_space memory_space;
 
  388         redist_mv.template sync <memory_space> ();
 
  390         mv_->doImport (redist_mv, *importer_, Tpetra::REPLACE);
 
  397   template <
typename Scalar, 
typename LocalOrdinal, 
typename GlobalOrdinal, 
class Node >
 
  403                 Node> >::description()
 const 
  405     std::ostringstream oss;
 
  406     oss << 
"Amesos2 adapter wrapping: ";
 
  407     oss << mv_->description();
 
  412   template <
typename Scalar, 
typename LocalOrdinal, 
typename GlobalOrdinal, 
class Node >
 
  418                 Node> >::describe (Teuchos::FancyOStream& os,
 
  419                                    const Teuchos::EVerbosityLevel verbLevel)
 const 
  421     mv_->describe (os, verbLevel);
 
  425   template <
typename Scalar, 
typename LocalOrdinal, 
typename GlobalOrdinal, 
class Node >
 
  426   const char* MultiVecAdapter<
 
  430                 Node> >::name = 
"Amesos2 adapter for Tpetra::MultiVector";
 
  434 #endif // AMESOS2_TPETRA_MULTIVEC_ADAPTER_DEF_HPP 
Amesos2::MultiVecAdapter specialization for the Tpetra::MultiVector class. 
EDistribution
Definition: Amesos2_TypeDecl.hpp:123