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)) {
172 distMap = distribution_map->template clone<Node> (distribution_map->getNode ());
175 exporter_ = rcp (
new export_type (this->getMap (), distMap));
178 distMap = exporter_->getTargetMap ();
181 multivec_t redist_mv (distMap, num_vecs);
184 redist_mv.doExport (*mv_, *exporter_, Tpetra::REPLACE);
186 if ( distribution != CONTIGUOUS_AND_ROOTED ) {
189 redist_mv.get1dCopy (av, lda);
194 typedef typename multivec_t::dual_view_type dual_view_type;
195 typedef typename dual_view_type::host_mirror_space host_execution_space;
196 redist_mv.template sync < host_execution_space > ();
198 auto contig_local_view_2d = redist_mv.template getLocalView<host_execution_space>();
199 if ( redist_mv.isConstantStride() ) {
200 for (
size_t j = 0; j < num_vecs; ++j) {
201 auto av_j = av(lda*j, lda);
202 for (
size_t i = 0; i < lda; ++i ) {
203 av_j[i] = contig_local_view_2d(i,j);
212 const size_t lclNumRows = redist_mv.getLocalLength();
213 for (
size_t j = 0; j < redist_mv.getNumVectors(); ++j) {
214 auto av_j = av(lda*j, lclNumRows);
215 auto X_lcl_j_2d = redist_mv.template getLocalView<host_execution_space> ();
216 auto X_lcl_j_1d = Kokkos::subview (X_lcl_j_2d, Kokkos::ALL (), j);
218 using val_type =
typename decltype( X_lcl_j_1d )::value_type;
219 Kokkos::View<val_type*, Kokkos::HostSpace> umavj ( const_cast< val_type* > ( reinterpret_cast<const val_type*> ( av_j.getRawPtr () ) ), av_j.size () );
220 Kokkos::deep_copy (umavj, X_lcl_j_1d);
227 template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
class Node >
228 Teuchos::ArrayRCP<Scalar>
233 Node> >::get1dViewNonConst (
bool local)
239 TEUCHOS_TEST_FOR_EXCEPTION(
240 true, std::logic_error,
"Amesos2::MultiVecAdapter::get1dViewNonConst: " 294 template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
class Node>
300 Node> >::put1dData(
const Teuchos::ArrayView<const scalar_t>& new_data,
303 const Tpetra::Map<LocalOrdinal,
309 typedef Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node> map_type;
311 TEUCHOS_TEST_FOR_EXCEPTION(
312 source_map.getRawPtr () == NULL, std::invalid_argument,
313 "Amesos2::MultiVecAdapter::put1dData: source_map argument is null.");
314 TEUCHOS_TEST_FOR_EXCEPTION(
315 mv_.is_null (), std::logic_error,
316 "Amesos2::MultiVecAdapter::put1dData: the internal MultiVector mv_ is null.");
318 TEUCHOS_TEST_FOR_EXCEPTION(
319 this->getMap ().is_null (), std::logic_error,
320 "Amesos2::MultiVecAdapter::put1dData: this->getMap() returns null.");
322 const size_t num_vecs = getGlobalNumVectors ();
325 if ( num_vecs == 1 && this->getComm()->getRank() == 0 && this->getComm()->getSize() == 1 ) {
326 typedef typename multivec_t::dual_view_type::host_mirror_space host_execution_space;
328 auto mv_view_to_modify_2d = mv_->template getLocalView<host_execution_space>();
329 for (
size_t i = 0; i < lda; ++i ) {
330 mv_view_to_modify_2d(i,0) = new_data[i];
338 RCP<const map_type> srcMap;
339 if (importer_.is_null () ||
340 ! importer_->getSourceMap ()->isSameAs (* source_map) ||
341 ! importer_->getTargetMap ()->isSameAs (* (this->getMap ()))) {
350 srcMap = source_map->template clone<Node> (source_map->getNode ());
351 importer_ = rcp (
new import_type (srcMap, this->getMap ()));
354 srcMap = importer_->getSourceMap ();
357 if ( distribution != CONTIGUOUS_AND_ROOTED ) {
360 const multivec_t source_mv (srcMap, new_data, lda, num_vecs);
361 mv_->doImport (source_mv, *importer_, Tpetra::REPLACE);
364 multivec_t redist_mv (srcMap, num_vecs);
365 typedef typename multivec_t::dual_view_type dual_view_type;
366 typedef typename dual_view_type::host_mirror_space host_execution_space;
367 redist_mv.template modify< host_execution_space > ();
369 if ( redist_mv.isConstantStride() ) {
370 auto contig_local_view_2d = redist_mv.template getLocalView<host_execution_space>();
371 for (
size_t j = 0; j < num_vecs; ++j) {
372 auto av_j = new_data(lda*j, lda);
373 for (
size_t i = 0; i < lda; ++i ) {
374 contig_local_view_2d(i,j) = av_j[i];
383 const size_t lclNumRows = redist_mv.getLocalLength();
384 for (
size_t j = 0; j < redist_mv.getNumVectors(); ++j) {
385 auto av_j = new_data(lda*j, lclNumRows);
386 auto X_lcl_j_2d = redist_mv.template getLocalView<host_execution_space> ();
387 auto X_lcl_j_1d = Kokkos::subview (X_lcl_j_2d, Kokkos::ALL (), j);
389 using val_type =
typename decltype( X_lcl_j_1d )::value_type;
390 Kokkos::View<val_type*, Kokkos::HostSpace> umavj ( const_cast< val_type* > ( reinterpret_cast<const val_type*> ( av_j.getRawPtr () ) ), av_j.size () );
391 Kokkos::deep_copy (umavj, X_lcl_j_1d);
395 typedef typename multivec_t::node_type::memory_space memory_space;
396 redist_mv.template sync <memory_space> ();
398 mv_->doImport (redist_mv, *importer_, Tpetra::REPLACE);
405 template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
class Node >
411 Node> >::description()
const 413 std::ostringstream oss;
414 oss <<
"Amesos2 adapter wrapping: ";
415 oss << mv_->description();
420 template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
class Node >
426 Node> >::describe (Teuchos::FancyOStream& os,
427 const Teuchos::EVerbosityLevel verbLevel)
const 429 mv_->describe (os, verbLevel);
433 template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
class Node >
434 const char* MultiVecAdapter<
438 Node> >::name =
"Amesos2 adapter for Tpetra::MultiVector";
442 #endif // AMESOS2_TPETRA_MULTIVEC_ADAPTER_DEF_HPP Definition: Amesos2_AbstractConcreteMatrixAdapter.hpp:48
Amesos2::MultiVecAdapter specialization for the Tpetra::MultiVector class.
EDistribution
Definition: Amesos2_TypeDecl.hpp:123