53 #ifndef AMESOS2_TPETRA_MULTIVEC_ADAPTER_DEF_HPP 54 #define AMESOS2_TPETRA_MULTIVEC_ADAPTER_DEF_HPP 61 using Tpetra::MultiVector;
63 template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
class Node >
68 Node> >::MultiVecAdapter(
const Teuchos::RCP<multivec_t>& m )
73 template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
class Node >
74 typename MultiVecAdapter<
78 Node> >::multivec_t::impl_scalar_type *
83 Node> >::getMVPointer_impl()
const 85 TEUCHOS_TEST_FOR_EXCEPTION( this->getGlobalNumVectors() != 1,
86 std::invalid_argument,
87 "Amesos2_TpetraMultiVectorAdapter: getMVPointer_impl should only be called for case with a single vector and single MPI process" );
89 typedef typename multivec_t::dual_view_type dual_view_type;
90 typedef typename dual_view_type::host_mirror_space host_execution_space;
91 mv_->template sync<host_execution_space> ();
92 auto contig_local_view_2d = mv_->template getLocalView<host_execution_space>();
93 auto contig_local_view_1d = Kokkos::subview (contig_local_view_2d, Kokkos::ALL (), 0);
94 return contig_local_view_1d.data();
105 template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
class Node >
111 Node> >::get1dCopy(
const Teuchos::ArrayView<scalar_t>& av,
114 const Tpetra::Map<LocalOrdinal,
116 Node> > distribution_map,
121 typedef Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node> map_type;
122 const size_t num_vecs = getGlobalNumVectors ();
124 TEUCHOS_TEST_FOR_EXCEPTION(
125 distribution_map.getRawPtr () == NULL, std::invalid_argument,
126 "Amesos2::MultiVecAdapter::get1dCopy: distribution_map argument is null.");
127 TEUCHOS_TEST_FOR_EXCEPTION(
128 mv_.is_null (), std::logic_error,
129 "Amesos2::MultiVecAdapter::get1dCopy: mv_ is null.");
131 TEUCHOS_TEST_FOR_EXCEPTION(
132 this->getMap ().is_null (), std::logic_error,
133 "Amesos2::MultiVecAdapter::get1dCopy: this->getMap() returns null.");
135 #ifdef HAVE_AMESOS2_DEBUG 136 const size_t requested_vector_length = distribution_map->getNodeNumElements ();
137 TEUCHOS_TEST_FOR_EXCEPTION(
138 lda < requested_vector_length, std::invalid_argument,
139 "Amesos2::MultiVecAdapter::get1dCopy: On process " <<
140 distribution_map->getComm ()->getRank () <<
" of the distribution Map's " 141 "communicator, the given stride lda = " << lda <<
" is not large enough " 142 "for the local vector length " << requested_vector_length <<
".");
143 TEUCHOS_TEST_FOR_EXCEPTION(
144 as<size_t> (av.size ()) < as<size_t> ((num_vecs - 1) * lda + requested_vector_length),
145 std::invalid_argument,
"Amesos2::MultiVector::get1dCopy: MultiVector " 146 "storage not large enough given leading dimension and number of vectors." );
147 #endif // HAVE_AMESOS2_DEBUG 150 if ( num_vecs == 1 && this->getComm()->getRank() == 0 && this->getComm()->getSize() == 1 ) {
151 mv_->get1dCopy (av, lda);
158 RCP<const map_type> distMap;
159 if (exporter_.is_null () ||
160 ! exporter_->getSourceMap ()->isSameAs (* (this->getMap ())) ||
161 ! exporter_->getTargetMap ()->isSameAs (* distribution_map)) {
171 distMap = distribution_map->template clone<Node> (distribution_map->getNode ());
174 exporter_ = rcp (
new export_type (this->getMap (), distMap));
177 distMap = exporter_->getTargetMap ();
180 multivec_t redist_mv (distMap, num_vecs);
183 redist_mv.doExport (*mv_, *exporter_, Tpetra::REPLACE);
185 if ( distribution != CONTIGUOUS_AND_ROOTED ) {
188 redist_mv.get1dCopy (av, lda);
193 typedef typename multivec_t::dual_view_type dual_view_type;
194 typedef typename dual_view_type::host_mirror_space host_execution_space;
195 redist_mv.template sync < host_execution_space > ();
197 auto contig_local_view_2d = redist_mv.template getLocalView<host_execution_space>();
198 if ( redist_mv.isConstantStride() ) {
199 for (
size_t j = 0; j < num_vecs; ++j) {
200 auto av_j = av(lda*j, lda);
201 for (
size_t i = 0; i < lda; ++i ) {
202 av_j[i] = contig_local_view_2d(i,j);
211 const size_t lclNumRows = redist_mv.getLocalLength();
212 for (
size_t j = 0; j < redist_mv.getNumVectors(); ++j) {
213 auto av_j = av(lda*j, lclNumRows);
214 auto X_j = redist_mv.getVector(j);
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);
217 for (
size_t i = 0; i < lclNumRows; ++i ) {
218 av_j[i] = X_lcl_j_1d(i);
223 auto global_contiguous_size = distMap->getGlobalNumElements();
224 auto local_contiguous_size = (distMap->getComm()->getRank() == 0) ? global_contiguous_size : 0;
225 RCP<const map_type> contigMap = rcp(
new map_type(global_contiguous_size, local_contiguous_size, 0, distMap->getComm() ));
227 typedef Tpetra::Export<local_ordinal_t, global_ordinal_t, node_t> contiguous_export_t;
228 RCP<contiguous_export_t> contig_exporter = rcp(
new contiguous_export_t(redist_mv.getMap(), contigMap) );
229 multivec_t contig_mv( contigMap, num_vecs);
230 contig_mv.doExport(redist_mv, *contig_exporter, Tpetra::INSERT);
235 template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
class Node >
236 Teuchos::ArrayRCP<Scalar>
241 Node> >::get1dViewNonConst (
bool local)
247 TEUCHOS_TEST_FOR_EXCEPTION(
248 true, std::logic_error,
"Amesos2::MultiVecAdapter::get1dViewNonConst: " 302 template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
class Node>
308 Node> >::put1dData(
const Teuchos::ArrayView<const scalar_t>& new_data,
311 const Tpetra::Map<LocalOrdinal,
317 typedef Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node> map_type;
319 TEUCHOS_TEST_FOR_EXCEPTION(
320 source_map.getRawPtr () == NULL, std::invalid_argument,
321 "Amesos2::MultiVecAdapter::put1dData: source_map argument is null.");
322 TEUCHOS_TEST_FOR_EXCEPTION(
323 mv_.is_null (), std::logic_error,
324 "Amesos2::MultiVecAdapter::put1dData: the internal MultiVector mv_ is null.");
326 TEUCHOS_TEST_FOR_EXCEPTION(
327 this->getMap ().is_null (), std::logic_error,
328 "Amesos2::MultiVecAdapter::put1dData: this->getMap() returns null.");
330 const size_t num_vecs = getGlobalNumVectors ();
333 if ( num_vecs == 1 && this->getComm()->getRank() == 0 && this->getComm()->getSize() == 1 ) {
334 typedef typename multivec_t::dual_view_type::host_mirror_space host_execution_space;
336 auto mv_view_to_modify_2d = mv_->template getLocalView<host_execution_space>();
337 for (
size_t i = 0; i < lda; ++i ) {
338 mv_view_to_modify_2d(i,0) = new_data[i];
346 RCP<const map_type> srcMap;
347 if (importer_.is_null () ||
348 ! importer_->getSourceMap ()->isSameAs (* source_map) ||
349 ! importer_->getTargetMap ()->isSameAs (* (this->getMap ()))) {
358 srcMap = source_map->template clone<Node> (source_map->getNode ());
359 importer_ = rcp (
new import_type (srcMap, this->getMap ()));
362 srcMap = importer_->getSourceMap ();
365 multivec_t redist_mv (srcMap, num_vecs);
367 if ( distribution != CONTIGUOUS_AND_ROOTED ) {
370 const multivec_t source_mv (srcMap, new_data, lda, num_vecs);
371 mv_->doImport (source_mv, *importer_, Tpetra::REPLACE);
374 typedef typename multivec_t::dual_view_type dual_view_type;
375 typedef typename dual_view_type::host_mirror_space host_execution_space;
376 redist_mv.template modify< host_execution_space > ();
378 if ( redist_mv.isConstantStride() ) {
379 auto contig_local_view_2d = redist_mv.template getLocalView<host_execution_space>();
380 for (
size_t j = 0; j < num_vecs; ++j) {
381 auto av_j = new_data(lda*j, lda);
382 for (
size_t i = 0; i < lda; ++i ) {
383 contig_local_view_2d(i,j) = av_j[i];
392 const size_t lclNumRows = redist_mv.getLocalLength();
393 for (
size_t j = 0; j < redist_mv.getNumVectors(); ++j) {
394 auto av_j = new_data(lda*j, lclNumRows);
395 auto X_j = redist_mv.getVector(j);
396 auto X_lcl_j_2d = redist_mv.template getLocalView<host_execution_space> ();
397 auto X_lcl_j_1d = Kokkos::subview (X_lcl_j_2d, Kokkos::ALL (), j);
398 for (
size_t i = 0; i < lclNumRows; ++i ) {
399 X_lcl_j_1d(i) = av_j[i];
404 typedef typename multivec_t::node_type::memory_space memory_space;
405 redist_mv.template sync <memory_space> ();
407 mv_->doImport (redist_mv, *importer_, Tpetra::REPLACE);
414 template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
class Node >
420 Node> >::description()
const 422 std::ostringstream oss;
423 oss <<
"Amesos2 adapter wrapping: ";
424 oss << mv_->description();
429 template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
class Node >
435 Node> >::describe (Teuchos::FancyOStream& os,
436 const Teuchos::EVerbosityLevel verbLevel)
const 438 mv_->describe (os, verbLevel);
442 template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
class Node >
443 const char* MultiVecAdapter<
447 Node> >::name =
"Amesos2 adapter for Tpetra::MultiVector";
451 #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