Thyra  Version of the Day
Thyra_TpetraMultiVector_def.hpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Thyra: Interfaces and Support for Abstract Numerical Algorithms
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Roscoe A. Bartlett (bartlettra@ornl.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef THYRA_TPETRA_MULTIVECTOR_HPP
43 #define THYRA_TPETRA_MULTIVECTOR_HPP
44 
45 #include "Thyra_TpetraMultiVector_decl.hpp"
46 #include "Thyra_TpetraVectorSpace.hpp"
47 #include "Thyra_TpetraVector.hpp"
48 #include "Teuchos_Assert.hpp"
49 
50 
51 namespace Thyra {
52 
53 
54 // Constructors/initializers/accessors
55 
56 
57 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
59 {}
60 
61 
62 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
64  const RCP<const TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node> > &tpetraVectorSpace,
65  const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace,
66  const RCP<Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > &tpetraMultiVector
67  )
68 {
69  initializeImpl(tpetraVectorSpace, domainSpace, tpetraMultiVector);
70 }
71 
72 
73 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
75  const RCP<const TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node> > &tpetraVectorSpace,
76  const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace,
77  const RCP<const Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > &tpetraMultiVector
78  )
79 {
80  initializeImpl(tpetraVectorSpace, domainSpace, tpetraMultiVector);
81 }
82 
83 
84 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
87 {
88  return tpetraMultiVector_.getNonconstObj();
89 }
90 
91 
92 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
95 {
96  return tpetraMultiVector_;
97 }
98 
99 
100 // Overridden public functions form MultiVectorAdapterBase
101 
102 
103 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
106 {
107  return domainSpace_;
108 }
109 
110 
111 // Overridden protected functions from MultiVectorBase
112 
113 
114 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
115 void
117 {
118  tpetraMultiVector_.getNonconstObj()->putScalar(alpha);
119 }
120 
121 
122 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
125 {
126  auto tmv = this->getConstTpetraMultiVector(Teuchos::rcpFromRef(mv));
127 
128  // If the cast succeeded, call Tpetra directly.
129  // Otherwise, fall back to the RTOp implementation.
130  if (nonnull(tmv)) {
131  tpetraMultiVector_.getNonconstObj()->assign(*tmv);
132  } else {
133  // This version will require/modify the host view of this vector.
134  tpetraMultiVector_.getNonconstObj()->template sync<Kokkos::HostSpace>();
135  tpetraMultiVector_.getNonconstObj()->template modify<Kokkos::HostSpace>();
137  }
138 }
139 
140 
141 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
142 void
144 {
145  tpetraMultiVector_.getNonconstObj()->scale(alpha);
146 }
147 
148 
149 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
151  Scalar alpha,
152  const MultiVectorBase<Scalar>& mv
153  )
154 {
155  auto tmv = this->getConstTpetraMultiVector(Teuchos::rcpFromRef(mv));
156 
157  // If the cast succeeded, call Tpetra directly.
158  // Otherwise, fall back to the RTOp implementation.
159  if (nonnull(tmv)) {
161  tpetraMultiVector_.getNonconstObj()->update(alpha, *tmv, ST::one());
162  } else {
163  // This version will require/modify the host view of this vector.
164  tpetraMultiVector_.getNonconstObj()->template sync<Kokkos::HostSpace>();
165  tpetraMultiVector_.getNonconstObj()->template modify<Kokkos::HostSpace>();
167  }
168 }
169 
170 
171 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
173  const ArrayView<const Scalar>& alpha,
174  const ArrayView<const Ptr<const MultiVectorBase<Scalar> > >& mv,
175  const Scalar& beta
176  )
177 {
178 #ifdef TEUCHOS_DEBUG
179  TEUCHOS_ASSERT_EQUALITY(alpha.size(), mv.size());
180 #endif
181 
182  // Try to cast mv to an array of this type
183  typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TMV;
184  Teuchos::Array<RCP<const TMV> > tmvs(mv.size());
185  RCP<const TMV> tmv;
186  bool allCastsSuccessful = true;
187  {
188  auto mvIter = mv.begin();
189  auto tmvIter = tmvs.begin();
190  for (; mvIter != mv.end(); ++mvIter, ++tmvIter) {
191  tmv = this->getConstTpetraMultiVector(Teuchos::rcpFromPtr(*mvIter));
192  if (nonnull(tmv)) {
193  *tmvIter = tmv;
194  } else {
195  allCastsSuccessful = false;
196  break;
197  }
198  }
199  }
200 
201  // If casts succeeded, or input arrays are size 0, call Tpetra directly.
202  // Otherwise, fall back to the RTOp implementation.
203  auto len = tmvs.size();
204  if (len == 0) {
205  tpetraMultiVector_.getNonconstObj()->scale(beta);
206  } else if (len == 1 && allCastsSuccessful) {
207  tpetraMultiVector_.getNonconstObj()->update(alpha[0], *tmvs[0], beta);
208  } else if (len == 2 && allCastsSuccessful) {
209  tpetraMultiVector_.getNonconstObj()->update(alpha[0], *tmvs[0], alpha[1], *tmvs[1], beta);
210  } else if (allCastsSuccessful) {
212  auto tmvIter = tmvs.begin();
213  auto alphaIter = alpha.begin();
214 
215  // Check if any entry of tmvs aliases this object's wrapped vector.
216  // If so, replace that entry in the array with a copy.
217  tmv = Teuchos::null;
218  for (; tmvIter != tmvs.end(); ++tmvIter) {
219  if (tmvIter->getRawPtr() == tpetraMultiVector_.getConstObj().getRawPtr()) {
220  if (tmv.is_null()) {
221  tmv = Teuchos::rcp(new TMV(*tpetraMultiVector_.getConstObj(), Teuchos::Copy));
222  }
223  *tmvIter = tmv;
224  }
225  }
226  tmvIter = tmvs.begin();
227 
228  // We add two MVs at a time, so only scale if even num MVs,
229  // and additionally do the first addition if odd num MVs.
230  if ((tmvs.size() % 2) == 0) {
231  tpetraMultiVector_.getNonconstObj()->scale(beta);
232  } else {
233  tpetraMultiVector_.getNonconstObj()->update(*alphaIter, *(*tmvIter), beta);
234  ++tmvIter;
235  ++alphaIter;
236  }
237  for (; tmvIter != tmvs.end(); tmvIter+=2, alphaIter+=2) {
238  tpetraMultiVector_.getNonconstObj()->update(
239  *alphaIter, *(*tmvIter), *(alphaIter+1), *(*(tmvIter+1)), ST::one());
240  }
241  } else {
242  // This version will require/modify the host view of this vector.
243  tpetraMultiVector_.getNonconstObj()->template sync<Kokkos::HostSpace>();
244  tpetraMultiVector_.getNonconstObj()->template modify<Kokkos::HostSpace>();
246  }
247 }
248 
249 
250 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
252  const MultiVectorBase<Scalar>& mv,
253  const ArrayView<Scalar>& prods
254  ) const
255 {
256  auto tmv = this->getConstTpetraMultiVector(Teuchos::rcpFromRef(mv));
257 
258  // If the cast succeeded, call Tpetra directly.
259  // Otherwise, fall back to the RTOp implementation.
260  if (nonnull(tmv)) {
261  tpetraMultiVector_.getConstObj()->dot(*tmv, prods);
262  } else {
263  // This version will require/modify the host view of this vector.
264  tpetraMultiVector_.getNonconstObj()->template sync<Kokkos::HostSpace>();
265  tpetraMultiVector_.getNonconstObj()->template modify<Kokkos::HostSpace>();
267  }
268 }
269 
270 
271 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
273  const ArrayView<typename ScalarTraits<Scalar>::magnitudeType>& norms
274  ) const
275 {
276  tpetraMultiVector_.getConstObj()->norm1(norms);
277 }
278 
279 
280 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
282  const ArrayView<typename ScalarTraits<Scalar>::magnitudeType>& norms
283  ) const
284 {
285  tpetraMultiVector_.getConstObj()->norm2(norms);
286 }
287 
288 
289 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
291  const ArrayView<typename ScalarTraits<Scalar>::magnitudeType>& norms
292  ) const
293 {
294  tpetraMultiVector_.getConstObj()->normInf(norms);
295 }
296 
297 
298 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
301 {
302 #ifdef TEUCHOS_DEBUG
303  TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(j, 0, this->domain()->dim());
304 #endif
305  return constTpetraVector<Scalar>(
306  tpetraVectorSpace_,
307  tpetraMultiVector_->getVector(j)
308  );
309 }
310 
311 
312 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
315 {
316 #ifdef TEUCHOS_DEBUG
317  TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(j, 0, this->domain()->dim());
318 #endif
319  return tpetraVector<Scalar>(
320  tpetraVectorSpace_,
321  tpetraMultiVector_.getNonconstObj()->getVectorNonConst(j)
322  );
323 }
324 
325 
326 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
329  const Range1D& col_rng_in
330  ) const
331 {
332 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
333  std::cerr << "\nTpetraMultiVector::subView(Range1D) const called!\n";
334 #endif
335  const Range1D colRng = this->validateColRange(col_rng_in);
336 
338  this->getConstTpetraMultiVector()->subView(colRng);
339 
340  const RCP<const ScalarProdVectorSpaceBase<Scalar> > viewDomainSpace =
341  tpetraVectorSpace<Scalar>(
342  Tpetra::createLocalMapWithNode<LocalOrdinal,GlobalOrdinal>(
343  tpetraView->getNumVectors(),
344  tpetraView->getMap()->getComm(),
345  tpetraView->getMap()->getNode()
346  )
347  );
348 
349  return constTpetraMultiVector(
350  tpetraVectorSpace_,
351  viewDomainSpace,
352  tpetraView
353  );
354 }
355 
356 
357 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
360  const Range1D& col_rng_in
361  )
362 {
363 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
364  std::cerr << "\nTpetraMultiVector::subView(Range1D) called!\n";
365 #endif
366  const Range1D colRng = this->validateColRange(col_rng_in);
367 
369  this->getTpetraMultiVector()->subViewNonConst(colRng);
370 
371  const RCP<const ScalarProdVectorSpaceBase<Scalar> > viewDomainSpace =
372  tpetraVectorSpace<Scalar>(
373  Tpetra::createLocalMapWithNode<LocalOrdinal,GlobalOrdinal>(
374  tpetraView->getNumVectors(),
375  tpetraView->getMap()->getComm(),
376  tpetraView->getMap()->getNode()
377  )
378  );
379 
380  return tpetraMultiVector(
381  tpetraVectorSpace_,
382  viewDomainSpace,
383  tpetraView
384  );
385 }
386 
387 
388 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
391  const ArrayView<const int>& cols_in
392  ) const
393 {
394 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
395  std::cerr << "\nTpetraMultiVector::subView(ArrayView) const called!\n";
396 #endif
397  // Tpetra wants col indices as size_t
398  Array<std::size_t> cols(cols_in.size());
399  for (Array<std::size_t>::size_type i = 0; i < cols.size(); ++i)
400  cols[i] = static_cast<std::size_t>(cols_in[i]);
401 
403  this->getConstTpetraMultiVector()->subView(cols());
404 
405  const RCP<const ScalarProdVectorSpaceBase<Scalar> > viewDomainSpace =
406  tpetraVectorSpace<Scalar>(
407  Tpetra::createLocalMapWithNode<LocalOrdinal,GlobalOrdinal>(
408  tpetraView->getNumVectors(),
409  tpetraView->getMap()->getComm(),
410  tpetraView->getMap()->getNode()
411  )
412  );
413 
414  return constTpetraMultiVector(
415  tpetraVectorSpace_,
416  viewDomainSpace,
417  tpetraView
418  );
419 }
420 
421 
422 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
425  const ArrayView<const int>& cols_in
426  )
427 {
428 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
429  std::cerr << "\nTpetraMultiVector::subView(ArrayView) called!\n";
430 #endif
431  // Tpetra wants col indices as size_t
432  Array<std::size_t> cols(cols_in.size());
433  for (Array<std::size_t>::size_type i = 0; i < cols.size(); ++i)
434  cols[i] = static_cast<std::size_t>(cols_in[i]);
435 
437  this->getTpetraMultiVector()->subViewNonConst(cols());
438 
439  const RCP<const ScalarProdVectorSpaceBase<Scalar> > viewDomainSpace =
440  tpetraVectorSpace<Scalar>(
441  Tpetra::createLocalMapWithNode<LocalOrdinal,GlobalOrdinal>(
442  tpetraView->getNumVectors(),
443  tpetraView->getMap()->getComm(),
444  tpetraView->getMap()->getNode()
445  )
446  );
447 
448  return tpetraMultiVector(
449  tpetraVectorSpace_,
450  viewDomainSpace,
451  tpetraView
452  );
453 }
454 
455 
456 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
459  const RTOpPack::RTOpT<Scalar> &primary_op,
460  const ArrayView<const Ptr<const MultiVectorBase<Scalar> > > &multi_vecs,
461  const ArrayView<const Ptr<MultiVectorBase<Scalar> > > &targ_multi_vecs,
462  const ArrayView<const Ptr<RTOpPack::ReductTarget> > &reduct_objs,
463  const Ordinal primary_global_offset
464  ) const
465 {
467 
468  // Sync any non-target Tpetra MVs to host space
469  for (auto itr = multi_vecs.begin(); itr != multi_vecs.end(); ++itr) {
470  Ptr<const TMV> tmv = Teuchos::ptr_dynamic_cast<const TMV>(*itr);
471  if (nonnull(tmv)) {
472  Teuchos::rcp_const_cast<Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(
473  tmv->getConstTpetraMultiVector())-> template sync<Kokkos::HostSpace>();
474  }
475  }
476 
477  // Sync any target Tpetra MVs and mark modified
478  for (auto itr = targ_multi_vecs.begin(); itr != targ_multi_vecs.end(); ++itr) {
479  Ptr<TMV> tmv = Teuchos::ptr_dynamic_cast<TMV>(*itr);
480  if (nonnull(tmv)) {
481  tmv->getTpetraMultiVector()->template sync<Kokkos::HostSpace>();
482  tmv->getTpetraMultiVector()->template modify<Kokkos::HostSpace>();
483  }
484  }
485 
487  primary_op, multi_vecs, targ_multi_vecs, reduct_objs, primary_global_offset);
488 }
489 
490 
491 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
494  const Range1D &rowRng,
495  const Range1D &colRng,
497  ) const
498 {
499  // Only viewing data, so just sync dual view to host space
500  typedef typename Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TMV;
501  Teuchos::rcp_const_cast<TMV>(
502  tpetraMultiVector_.getConstObj())->template sync<Kokkos::HostSpace>();
503 
505  acquireDetachedMultiVectorViewImpl(rowRng, colRng, sub_mv);
506 }
507 
508 
509 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
512  const Range1D &rowRng,
513  const Range1D &colRng,
515  )
516 {
517  // Sync to host and mark as modified
518  tpetraMultiVector_.getNonconstObj()->template sync<Kokkos::HostSpace>();
519  tpetraMultiVector_.getNonconstObj()->template modify<Kokkos::HostSpace>();
520 
522  acquireNonconstDetachedMultiVectorViewImpl(rowRng, colRng, sub_mv);
523 }
524 
525 
526 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
530  )
531 {
534 
535  // Sync changes from host view to execution space
536  typedef typename Tpetra::MultiVector<
537  Scalar,LocalOrdinal,GlobalOrdinal,Node>::execution_space execution_space;
538  tpetraMultiVector_.getNonconstObj()->template sync<execution_space>();
539 }
540 
541 
542 /* ToDo: Implement these?
543 
544 
545 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
546 RCP<const MultiVectorBase<Scalar> >
547 TpetraMultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>::nonContigSubViewImpl(
548  const ArrayView<const int> &cols
549  ) const
550 {
551  THYRA_DEBUG_ASSERT_MV_COLS("nonContigSubViewImpl(cols)", cols);
552  const int numCols = cols.size();
553  const ArrayRCP<Scalar> localValuesView = createContiguousCopy(cols);
554  return defaultSpmdMultiVector<Scalar>(
555  spmdRangeSpace_,
556  createSmallScalarProdVectorSpaceBase<Scalar>(spmdRangeSpace_, numCols),
557  localValuesView
558  );
559 }
560 
561 
562 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
563 RCP<MultiVectorBase<Scalar> >
564 TpetraMultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>::nonconstNonContigSubViewImpl(
565  const ArrayView<const int> &cols )
566 {
567  THYRA_DEBUG_ASSERT_MV_COLS("nonContigSubViewImpl(cols)", cols);
568  const int numCols = cols.size();
569  const ArrayRCP<Scalar> localValuesView = createContiguousCopy(cols);
570  const Ordinal localSubDim = spmdRangeSpace_->localSubDim();
571  RCP<CopyBackSpmdMultiVectorEntries<Scalar> > copyBackView =
572  copyBackSpmdMultiVectorEntries<Scalar>(cols, localValuesView.getConst(),
573  localSubDim, localValues_.create_weak(), leadingDim_);
574  return Teuchos::rcpWithEmbeddedObjPreDestroy(
575  new TpetraMultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>(
576  spmdRangeSpace_,
577  createSmallScalarProdVectorSpaceBase<Scalar>(spmdRangeSpace_, numCols),
578  localValuesView),
579  copyBackView
580  );
581 }
582 
583 */
584 
585 
586 // Overridden protected members from SpmdMultiVectorBase
587 
588 
589 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
592 {
593  return tpetraVectorSpace_;
594 }
595 
596 
597 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
599  const Ptr<ArrayRCP<Scalar> > &localValues, const Ptr<Ordinal> &leadingDim
600  )
601 {
602  *localValues = tpetraMultiVector_.getNonconstObj()->get1dViewNonConst();
603  *leadingDim = tpetraMultiVector_->getStride();
604 }
605 
606 
607 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
609  const Ptr<ArrayRCP<const Scalar> > &localValues, const Ptr<Ordinal> &leadingDim
610  ) const
611 {
612  *localValues = tpetraMultiVector_->get1dView();
613  *leadingDim = tpetraMultiVector_->getStride();
614 }
615 
616 
617 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
619  const EOpTransp M_trans,
620  const MultiVectorBase<Scalar> &X,
621  const Ptr<MultiVectorBase<Scalar> > &Y,
622  const Scalar alpha,
623  const Scalar beta
624  ) const
625 {
626  // Try to extract Tpetra objects from X and Y
627  typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TMV;
628  Teuchos::RCP<const TMV> X_tpetra = this->getConstTpetraMultiVector(Teuchos::rcpFromRef(X));
629  Teuchos::RCP<TMV> Y_tpetra = this->getTpetraMultiVector(Teuchos::rcpFromPtr(Y));
630 
631  // If the cast succeeded, call Tpetra directly.
632  // Otherwise, fall back to the default implementation.
633  if (nonnull(X_tpetra) && nonnull(Y_tpetra)) {
634  // Sync everything to the execution space
635  typedef typename TMV::execution_space execution_space;
636  Teuchos::rcp_const_cast<TMV>(X_tpetra)->template sync<execution_space>();
637  Y_tpetra->template sync<execution_space>();
638  Teuchos::rcp_const_cast<TMV>(
639  tpetraMultiVector_.getConstObj())->template sync<execution_space>();
640 
642  TEUCHOS_TEST_FOR_EXCEPTION(ST::isComplex && (M_trans == CONJ),
643  std::logic_error,
644  "Error, conjugation without transposition is not allowed for complex scalar types!");
645 
646  Teuchos::ETransp trans = Teuchos::NO_TRANS;
647  switch (M_trans) {
648  case NOTRANS:
649  trans = Teuchos::NO_TRANS;
650  break;
651  case CONJ:
652  trans = Teuchos::NO_TRANS;
653  break;
654  case TRANS:
655  trans = Teuchos::TRANS;
656  break;
657  case CONJTRANS:
658  trans = Teuchos::CONJ_TRANS;
659  break;
660  }
661 
662  Y_tpetra->template modify<execution_space>();
663  Y_tpetra->multiply(trans, Teuchos::NO_TRANS, alpha, *tpetraMultiVector_.getConstObj(), *X_tpetra, beta);
664  } else {
665  Teuchos::rcp_const_cast<TMV>(
666  tpetraMultiVector_.getConstObj())->template sync<Kokkos::HostSpace>();
667  SpmdMultiVectorDefaultBase<Scalar>::euclideanApply(M_trans, X, Y, alpha, beta);
668  }
669 
670 }
671 
672 // private
673 
674 
675 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
676 template<class TpetraMultiVector_t>
678  const RCP<const TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node> > &tpetraVectorSpace,
679  const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace,
680  const RCP<TpetraMultiVector_t> &tpetraMultiVector
681  )
682 {
683 #ifdef THYRA_DEBUG
684  TEUCHOS_ASSERT(nonnull(tpetraVectorSpace));
685  TEUCHOS_ASSERT(nonnull(domainSpace));
686  TEUCHOS_ASSERT(nonnull(tpetraMultiVector));
687  // ToDo: Check to make sure that tpetraMultiVector is compatible with
688  // tpetraVectorSpace.
689 #endif
690  tpetraVectorSpace_ = tpetraVectorSpace;
691  domainSpace_ = domainSpace;
692  tpetraMultiVector_.initialize(tpetraMultiVector);
693  this->updateSpmdSpace();
694 }
695 
696 
697 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
698 RCP<Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
700 getTpetraMultiVector(const RCP<MultiVectorBase<Scalar> >& mv) const
701 {
702  using Teuchos::rcp_dynamic_cast;
705 
706  RCP<TMV> tmv = rcp_dynamic_cast<TMV>(mv);
707  if (nonnull(tmv)) {
708  return tmv->getTpetraMultiVector();
709  }
710 
711  RCP<TV> tv = rcp_dynamic_cast<TV>(mv);
712  if (nonnull(tv)) {
713  return tv->getTpetraVector();
714  }
715 
716  return Teuchos::null;
717 }
718 
719 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
720 RCP<const Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
722 getConstTpetraMultiVector(const RCP<const MultiVectorBase<Scalar> >& mv) const
723 {
724  using Teuchos::rcp_dynamic_cast;
727 
728  RCP<const TMV> tmv = rcp_dynamic_cast<const TMV>(mv);
729  if (nonnull(tmv)) {
730  return tmv->getConstTpetraMultiVector();
731  }
732 
733  RCP<const TV> tv = rcp_dynamic_cast<const TV>(mv);
734  if (nonnull(tv)) {
735  return tv->getConstTpetraVector();
736  }
737 
738  return Teuchos::null;
739 }
740 
741 
742 } // end namespace Thyra
743 
744 
745 #endif // THYRA_TPETRA_MULTIVECTOR_HPP
Thyra::TpetraMultiVector::TpetraMultiVector
TpetraMultiVector()
Construct to uninitialized.
Definition: Thyra_TpetraMultiVector_def.hpp:58
Thyra::SpmdMultiVectorDefaultBase::acquireDetachedMultiVectorViewImpl
void acquireDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
Definition: Thyra_SpmdMultiVectorDefaultBase_def.hpp:232
Teuchos::Array::size
size_type size() const
Thyra::TpetraMultiVector::euclideanApply
virtual void euclideanApply(const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha, const Scalar beta) const
Definition: Thyra_TpetraMultiVector_def.hpp:618
Thyra::TpetraMultiVector::nonconstColImpl
RCP< VectorBase< Scalar > > nonconstColImpl(Ordinal j)
Definition: Thyra_TpetraMultiVector_def.hpp:314
Thyra::EOpTransp
EOpTransp
Enumeration for determining how a linear operator is applied. `*.
Definition: Thyra_OperatorVectorTypes.hpp:160
Thyra::TpetraMultiVector::colImpl
RCP< const VectorBase< Scalar > > colImpl(Ordinal j) const
Definition: Thyra_TpetraMultiVector_def.hpp:300
Thyra::MultiVectorDefaultBase::linearCombinationImpl
virtual void linearCombinationImpl(const ArrayView< const Scalar > &alpha, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &mv, const Scalar &beta)
Default implementation of linear_combination using RTOps.
Definition: Thyra_MultiVectorDefaultBase_def.hpp:147
Thyra::TpetraMultiVector::assignImpl
virtual void assignImpl(Scalar alpha)
Definition: Thyra_TpetraMultiVector_def.hpp:116
Thyra::TpetraMultiVector::getTpetraMultiVector
RCP< Tpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getTpetraMultiVector()
Extract the underlying non-const Tpetra::MultiVector object.
Definition: Thyra_TpetraMultiVector_def.hpp:86
Thyra::TpetraMultiVector::acquireDetachedMultiVectorViewImpl
void acquireDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
Definition: Thyra_TpetraMultiVector_def.hpp:493
Thyra::MultiVectorDefaultBase::assignMultiVecImpl
virtual void assignMultiVecImpl(const MultiVectorBase< Scalar > &mv)
Default implementation of assign(MV) using RTOps.
Definition: Thyra_MultiVectorDefaultBase_def.hpp:104
Thyra::TpetraMultiVector::assignMultiVecImpl
virtual void assignMultiVecImpl(const MultiVectorBase< Scalar > &mv)
Definition: Thyra_TpetraMultiVector_def.hpp:124
TEUCHOS_ASSERT
#define TEUCHOS_ASSERT(assertion_test)
Thyra::MultiVectorDefaultBase::mvMultiReductApplyOpImpl
virtual void mvMultiReductApplyOpImpl(const RTOpPack::RTOpT< Scalar > &primary_op, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &multi_vecs, const ArrayView< const Ptr< MultiVectorBase< Scalar > > > &targ_multi_vecs, const ArrayView< const Ptr< RTOpPack::ReductTarget > > &reduct_objs, const Ordinal primary_global_offset) const
Definition: Thyra_MultiVectorDefaultBase_def.hpp:398
Thyra::TpetraMultiVector
Concrete implementation of Thyra::MultiVector in terms of Tpetra::MultiVector.
Definition: Thyra_TpetraMultiVector_decl.hpp:62
Thyra::TpetraMultiVector::scaleImpl
virtual void scaleImpl(Scalar alpha)
Definition: Thyra_TpetraMultiVector_def.hpp:143
Teuchos::ArrayView
RTOpPack::SubMultiVectorView
Thyra::TpetraMultiVector::dotsImpl
virtual void dotsImpl(const MultiVectorBase< Scalar > &mv, const ArrayView< Scalar > &prods) const
Definition: Thyra_TpetraMultiVector_def.hpp:251
Teuchos::RCP
Thyra::TpetraMultiVector::getNonconstLocalMultiVectorDataImpl
void getNonconstLocalMultiVectorDataImpl(const Ptr< ArrayRCP< Scalar > > &localValues, const Ptr< Ordinal > &leadingDim)
Definition: Thyra_TpetraMultiVector_def.hpp:598
Teuchos::Ptr
Thyra::Ordinal
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
Definition: Thyra_OperatorVectorTypes.hpp:127
TEUCHOS_ASSERT_EQUALITY
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
Teuchos::Array
Teuchos::ArrayView::begin
iterator begin() const
Thyra::TpetraMultiVector::getConstTpetraMultiVector
RCP< const Tpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getConstTpetraMultiVector() const
Extract the underlying const Tpetra::MultiVector object.
Definition: Thyra_TpetraMultiVector_def.hpp:94
Thyra::SpmdMultiVectorDefaultBase::euclideanApply
void euclideanApply(const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha, const Scalar beta) const
Uses GEMM() and Teuchos::reduceAll() to implement.
Definition: Thyra_SpmdMultiVectorDefaultBase_def.hpp:344
Thyra::TpetraMultiVector::getLocalMultiVectorDataImpl
void getLocalMultiVectorDataImpl(const Ptr< ArrayRCP< const Scalar > > &localValues, const Ptr< Ordinal > &leadingDim) const
Definition: Thyra_TpetraMultiVector_def.hpp:608
Thyra::TpetraVector
Concrete Thyra::SpmdVectorBase using Tpetra::Vector.
Definition: Thyra_TpetraVector_decl.hpp:60
Teuchos::Array::begin
iterator begin()
Teuchos::ArrayRCP
Thyra::TpetraMultiVector::linearCombinationImpl
virtual void linearCombinationImpl(const ArrayView< const Scalar > &alpha, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &mv, const Scalar &beta)
Definition: Thyra_TpetraMultiVector_def.hpp:172
Thyra::TpetraMultiVector::acquireNonconstDetachedMultiVectorViewImpl
void acquireNonconstDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
Definition: Thyra_TpetraMultiVector_def.hpp:511
Teuchos::ArrayView::size
size_type size() const
Thyra::CONJTRANS
Use the transposed operator with complex-conjugate clements (same as TRANS for real scalar types).
Definition: Thyra_OperatorVectorTypes.hpp:172
Thyra::MultiVectorBase
Interface for a collection of column vectors called a multi-vector.
Definition: Thyra_MultiVectorBase_decl.hpp:493
Thyra::TpetraMultiVector::nonconstContigSubViewImpl
RCP< MultiVectorBase< Scalar > > nonconstContigSubViewImpl(const Range1D &colRng)
Definition: Thyra_TpetraMultiVector_def.hpp:359
Teuchos::ScalarTraits< Scalar >
TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE
#define TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(index, lower_inclusive, upper_exclusive)
Thyra::TpetraMultiVector::nonconstNonContigSubViewImpl
RCP< MultiVectorBase< Scalar > > nonconstNonContigSubViewImpl(const ArrayView< const int > &cols_in)
Definition: Thyra_TpetraMultiVector_def.hpp:424
Thyra::TpetraMultiVector::commitNonconstDetachedMultiVectorViewImpl
void commitNonconstDetachedMultiVectorViewImpl(RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
Definition: Thyra_TpetraMultiVector_def.hpp:528
Thyra::SpmdMultiVectorDefaultBase::commitNonconstDetachedMultiVectorViewImpl
void commitNonconstDetachedMultiVectorViewImpl(RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
Definition: Thyra_SpmdMultiVectorDefaultBase_def.hpp:322
Thyra::TpetraMultiVector::mvMultiReductApplyOpImpl
virtual void mvMultiReductApplyOpImpl(const RTOpPack::RTOpT< Scalar > &primary_op, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &multi_vecs, const ArrayView< const Ptr< MultiVectorBase< Scalar > > > &targ_multi_vecs, const ArrayView< const Ptr< RTOpPack::ReductTarget > > &reduct_objs, const Ordinal primary_global_offset) const
Definition: Thyra_TpetraMultiVector_def.hpp:458
Thyra::TpetraMultiVector::initialize
void initialize(const RCP< const TpetraVectorSpace< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &tpetraVectorSpace, const RCP< const ScalarProdVectorSpaceBase< Scalar > > &domainSpace, const RCP< Tpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &tpetraMultiVector)
Initialize.
Definition: Thyra_TpetraMultiVector_def.hpp:63
Thyra::ScalarProdVectorSpaceBase
Forward decl.
Definition: Thyra_MultiVectorAdapterBase_decl.hpp:52
Thyra::TpetraMultiVector::nonContigSubViewImpl
RCP< const MultiVectorBase< Scalar > > nonContigSubViewImpl(const ArrayView< const int > &cols_in) const
Definition: Thyra_TpetraMultiVector_def.hpp:390
Thyra::NOTRANS
Use the non-transposed operator.
Definition: Thyra_OperatorVectorTypes.hpp:162
Thyra::TpetraMultiVector::norms1Impl
virtual void norms1Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
Definition: Thyra_TpetraMultiVector_def.hpp:272
Thyra::TpetraMultiVector::constInitialize
void constInitialize(const RCP< const TpetraVectorSpace< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &tpetraVectorSpace, const RCP< const ScalarProdVectorSpaceBase< Scalar > > &domainSpace, const RCP< const Tpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &tpetraMultiVector)
Initialize.
Definition: Thyra_TpetraMultiVector_def.hpp:74
Thyra::TpetraMultiVector::contigSubViewImpl
RCP< const MultiVectorBase< Scalar > > contigSubViewImpl(const Range1D &colRng) const
Definition: Thyra_TpetraMultiVector_def.hpp:328
RTOpPack::RTOpT< Scalar >
Thyra::MultiVectorDefaultBase::updateImpl
virtual void updateImpl(Scalar alpha, const MultiVectorBase< Scalar > &mv)
Default implementation of update using RTOps.
Definition: Thyra_MultiVectorDefaultBase_def.hpp:134
Thyra::TpetraMultiVector::norms2Impl
virtual void norms2Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
Definition: Thyra_TpetraMultiVector_def.hpp:281
nonnull
bool nonnull(const boost::shared_ptr< T > &p)
Thyra::TpetraMultiVector::domainScalarProdVecSpc
RCP< const ScalarProdVectorSpaceBase< Scalar > > domainScalarProdVecSpc() const
Definition: Thyra_TpetraMultiVector_def.hpp:105
Thyra::TpetraMultiVector::spmdSpaceImpl
RCP< const SpmdVectorSpaceBase< Scalar > > spmdSpaceImpl() const
Definition: Thyra_TpetraMultiVector_def.hpp:591
Thyra::TpetraVectorSpace
Concrete implementation of an SPMD vector space for Tpetra.
Definition: Thyra_TpetraVectorSpace_decl.hpp:59
Thyra::MultiVectorDefaultBase::dotsImpl
virtual void dotsImpl(const MultiVectorBase< Scalar > &mv, const ArrayView< Scalar > &prods) const
Default implementation of dots using RTOps.
Definition: Thyra_MultiVectorDefaultBase_def.hpp:221
RTOpPack::ConstSubMultiVectorView
Thyra::TpetraMultiVector::updateImpl
virtual void updateImpl(Scalar alpha, const MultiVectorBase< Scalar > &mv)
Definition: Thyra_TpetraMultiVector_def.hpp:150
Thyra::CONJ
Use the non-transposed operator with complex-conjugate elements (same as NOTRANS for real scalar type...
Definition: Thyra_OperatorVectorTypes.hpp:166
Teuchos::Array::size_type
Ordinal size_type
Teuchos::Range1D
TEUCHOS_TEST_FOR_EXCEPTION
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Thyra::TRANS
Use the transposed operator.
Definition: Thyra_OperatorVectorTypes.hpp:168
Thyra::SpmdMultiVectorDefaultBase::acquireNonconstDetachedMultiVectorViewImpl
void acquireNonconstDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
Definition: Thyra_SpmdMultiVectorDefaultBase_def.hpp:284
Teuchos::ETransp
ETransp
Thyra::TpetraMultiVector::normsInfImpl
virtual void normsInfImpl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
Definition: Thyra_TpetraMultiVector_def.hpp:290