Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Thyra_DefaultSpmdMultiVector_def.hpp
1 // @HEADER
2 // *****************************************************************************
3 // Thyra: Interfaces and Support for Abstract Numerical Algorithms
4 //
5 // Copyright 2004 NTESS and the Thyra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef THYRA_DEFAULT_SPMD_MULTI_VECTOR_DEF_HPP
11 #define THYRA_DEFAULT_SPMD_MULTI_VECTOR_DEF_HPP
12 
13 // Define to make some verbose output
14 //#define THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
15 
16 #include "Thyra_DefaultSpmdMultiVector_decl.hpp"
17 #include "Thyra_SpmdMultiVectorDefaultBase.hpp"
18 #include "Thyra_VectorSpaceFactoryBase.hpp"
19 #include "Thyra_DefaultSpmdVector.hpp"
20 #include "Teuchos_Assert.hpp"
21 
22 
23 namespace Thyra {
24 
25 
26 //
27 // Simple utility class to copy back multi-vector entries
28 //
29 // ToDo: Refactor above to not use raw pointers!
30 //
31 template<class Scalar>
32 class CopyBackSpmdMultiVectorEntries {
33 public:
34  CopyBackSpmdMultiVectorEntries(
35  const ArrayView<const int> &cols,
36  const ArrayRCP<const Scalar> &localValuesView, const Ordinal localSubDim,
37  const ArrayRCP<Scalar> &localValues, const Ordinal leadingDim
38  )
39  : cols_(cols), localValuesView_(localValuesView), localSubDim_(localSubDim),
40  localValues_(localValues), leadingDim_(leadingDim)
41  {}
42  ~CopyBackSpmdMultiVectorEntries()
43  {
44  typedef typename ArrayRCP<const Scalar>::const_iterator const_itr_t;
45  typedef typename ArrayRCP<Scalar>::iterator itr_t;
46  // Copy from contiguous storage column by column
47  if (localValues_.strong_count()) {
48  const int numCols = cols_.size();
49  const const_itr_t lvv = localValuesView_.begin();
50  const itr_t lv = localValues_.begin();
51  for (int k = 0; k < numCols; ++k) {
52  const int col_k = cols_[k];
53  const const_itr_t lvv_k = lvv + localSubDim_*k;
54  const itr_t lv_k = lv + leadingDim_*col_k;
55  std::copy( lvv_k, lvv_k + localSubDim_, lv_k );
56  }
57  }
58 #ifdef THYRA_DEBUG
59  else {
60  ++DefaultSpmdMultiVector<Scalar>::numSkipCopyBack;
61  }
62 #endif // THYRA_DEBUG
63  }
64 private:
65  Array<int> cols_;
66  ArrayRCP<const Scalar> localValuesView_;
67  Ordinal localSubDim_;
68  ArrayRCP<Scalar> localValues_;
69  Ordinal leadingDim_;
70  // Not defined and not to be called
71  CopyBackSpmdMultiVectorEntries();
72  CopyBackSpmdMultiVectorEntries(const CopyBackSpmdMultiVectorEntries&);
73  CopyBackSpmdMultiVectorEntries& operator=(const CopyBackSpmdMultiVectorEntries&);
74 };
75 
76 
77 template<class Scalar>
78 RCP<CopyBackSpmdMultiVectorEntries<Scalar> >
79 copyBackSpmdMultiVectorEntries(
80  const ArrayView<const int> &cols,
81  const ArrayRCP<const Scalar> &localValuesView, const Ordinal localSubDim,
82  const ArrayRCP<Scalar> &localValues, const Ordinal leadingDim
83  )
84 {
85  return Teuchos::rcp(
86  new CopyBackSpmdMultiVectorEntries<Scalar>(
87  cols, localValuesView, localSubDim, localValues, leadingDim
88  )
89  );
90 }
91 
92 
93 //
94 // DefaultSpmdMultiVector
95 //
96 
97 
98 #ifdef THYRA_DEBUG
99 template<class Scalar>
100 int DefaultSpmdMultiVector<Scalar>::numSkipCopyBack(0);
101 #endif
102 
103 
104 // Constructors/initializers/accessors
105 
106 
107 template<class Scalar>
109  :leadingDim_(0)
110 {}
111 
112 
113 template<class Scalar>
115  const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace
116  ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace
117  )
118 {
119  initialize(spmdRangeSpace,domainSpace);
120 }
121 
122 
123 template<class Scalar>
125  const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace
126  ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace
127  ,const ArrayRCP<Scalar> &localValues
128  ,const Ordinal leadingDim
129  )
130 {
131  initialize(spmdRangeSpace,domainSpace,localValues,leadingDim);
132 }
133 
134 
135 template<class Scalar>
137  const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace
138  ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace
139  )
140 {
141  const Ordinal localSubDim = spmdRangeSpace->localSubDim();
142  ArrayRCP<Scalar> values;
143  if (localSubDim)
144  values = Teuchos::arcp<Scalar>(localSubDim * domainSpace->dim());
145  initialize(spmdRangeSpace, domainSpace, values, localSubDim);
146 }
147 
148 
149 template<class Scalar>
151  const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace,
152  const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace,
153  const ArrayRCP<Scalar> &localValues,
154  const Ordinal leadingDim_in
155  )
156 {
157  const Ordinal localSubDim = spmdRangeSpace->localSubDim();
158  const Ordinal leadingDim = (leadingDim_in >= 0 ? leadingDim_in : localSubDim);
159 #ifdef TEUCHOS_DEBUG
160  TEUCHOS_ASSERT(!is_null(spmdRangeSpace));
161  TEUCHOS_ASSERT(!is_null(domainSpace));
162  if (spmdRangeSpace->dim() && localSubDim) {
163  TEUCHOS_ASSERT(nonnull(localValues));
164  }
165  TEUCHOS_ASSERT_INEQUALITY(leadingDim, >=, spmdRangeSpace->localSubDim());
166 #endif
167  spmdRangeSpace_ = spmdRangeSpace;
168  domainSpace_ = domainSpace;
169  localValues_ = localValues;
170  leadingDim_ = leadingDim;
171  this->updateSpmdSpace();
172 }
173 
174 
175 template<class Scalar>
177  RCP<const SpmdVectorSpaceBase<Scalar> > *spmdRangeSpace
178  ,RCP<const ScalarProdVectorSpaceBase<Scalar> > *domainSpace
179  ,ArrayRCP<Scalar> *localValues
180  ,Ordinal *leadingDim
181  )
182 {
183  if(spmdRangeSpace) *spmdRangeSpace = spmdRangeSpace_;
184  if(domainSpace) *domainSpace = domainSpace_;
185  if(localValues) *localValues = localValues_;
186  if(leadingDim) *leadingDim = leadingDim_;
187 
188  spmdRangeSpace_ = Teuchos::null;
189  domainSpace_ = Teuchos::null;
190  localValues_ = Teuchos::null;
191  leadingDim_ = 0;
192 
193  this->updateSpmdSpace();
194 }
195 
196 
197 template<class Scalar>
200 {
201 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
202  std::cerr << "\nSpmdMultiVectorStd<Scalar>::domainScalarProdVecSpc() const called!\n";
203 #endif
204  return domainSpace_;
205 }
206 
207 
208 // Overridden protected functions from MultiVectorBase
209 
210 
211 template<class Scalar>
214 {
215 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
216  std::cerr << "\nSpmdMultiVectorStd<Scalar>::col() called!\n";
217 #endif
218 #ifdef TEUCHOS_DEBUG
219  TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= j && j < this->domain()->dim() ) );
220 #endif
221  return Teuchos::rcp(
223  spmdRangeSpace_,
224  localValues_.persistingView(j*leadingDim_,spmdRangeSpace_->localSubDim()),
225  1
226  )
227  );
228  //return Teuchos::rcp(new DefaultVectorMultiVector<Scalar>(subView(Range1D(j,j))));
229 }
230 
231 
232 template<class Scalar>
235  const Range1D& col_rng_in
236  ) const
237 {
238  const Range1D colRng = this->validateColRange(col_rng_in);
239  return Teuchos::rcp(
241  spmdRangeSpace_,
242  Teuchos::rcp_dynamic_cast<const ScalarProdVectorSpaceBase<Scalar> >(
243  spmdRangeSpace_->smallVecSpcFcty()->createVecSpc(colRng.size())
244  ,true
245  ),
246  localValues_.persistingView(colRng.lbound()*leadingDim_,colRng.size()*spmdRangeSpace_->localSubDim()),
247  leadingDim_
248  )
249  );
250 }
251 
252 
253 template<class Scalar>
256  const Range1D& col_rng_in
257  )
258 {
259  return Teuchos::rcp_const_cast<MultiVectorBase<Scalar> >(
260  this->contigSubViewImpl(col_rng_in));
261  // Have the nonconst version call the const version. Note that in this case
262  // we just need to take the const off of the returned MultiVectorBase object
263  // because the localValues is already handled as nonconst. This is the
264  // perfect instance where the advice in Item 3 in "Effective C++ 3rd
265  // edition" where Scott Meyers recommends having the nonconst version call
266  // the const version.
267 }
268 
269 
270 template<class Scalar>
273  const ArrayView<const int> &cols
274  ) const
275 {
276  THYRA_DEBUG_ASSERT_MV_COLS("nonContigSubViewImpl(cols)", cols);
277  const int numCols = cols.size();
278  const ArrayRCP<Scalar> localValuesView = createContiguousCopy(cols);
279  return defaultSpmdMultiVector<Scalar>(
280  spmdRangeSpace_,
281  createSmallScalarProdVectorSpaceBase<Scalar>(spmdRangeSpace_, numCols),
282  localValuesView
283  );
284 }
285 
286 
287 template<class Scalar>
290  const ArrayView<const int> &cols )
291 {
292  THYRA_DEBUG_ASSERT_MV_COLS("nonContigSubViewImpl(cols)", cols);
293  const int numCols = cols.size();
294  const ArrayRCP<Scalar> localValuesView = createContiguousCopy(cols);
295  const Ordinal localSubDim = spmdRangeSpace_->localSubDim();
297  copyBackSpmdMultiVectorEntries<Scalar>(cols, localValuesView.getConst(),
298  localSubDim, localValues_.create_weak(), leadingDim_);
299  return Teuchos::rcpWithEmbeddedObjPreDestroy(
301  spmdRangeSpace_,
302  createSmallScalarProdVectorSpaceBase<Scalar>(spmdRangeSpace_, numCols),
303  localValuesView),
304  copyBackView
305  );
306 }
307 
308 
309 // Overridden protected members from SpmdMultiVectorBase
310 
311 
312 template<class Scalar>
315 {
316 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
317  std::cerr << "\nSpmdMultiVectorStd<Scalar>::spmdSpace() const called!\n";
318 #endif
319  return spmdRangeSpace_;
320 }
321 
322 
323 template<class Scalar>
325  const Ptr<ArrayRCP<Scalar> > &localValues, const Ptr<Ordinal> &leadingDim
326  )
327 {
328 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
329  std::cerr << "\nSpmdMultiVectorStd<Scalar>::getLocalMultiVectorDataImpl() called!\n";
330 #endif
331  *localValues = localValues_;
332  *leadingDim = leadingDim_;
333 }
334 
335 
336 template<class Scalar>
338  const Ptr<ArrayRCP<const Scalar> > &localValues, const Ptr<Ordinal> &leadingDim
339  ) const
340 {
341 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
342  std::cerr << "\nSpmdMultiVectorStd<Scalar>::getLocalData() called!\n";
343 #endif
344  *localValues = localValues_;
345  *leadingDim = leadingDim_;
346 }
347 
348 
349 // private
350 
351 
352 template<class Scalar>
355  const ArrayView<const int> &cols ) const
356 {
357  typedef typename ArrayRCP<Scalar>::const_iterator const_itr_t;
358  typedef typename ArrayRCP<Scalar>::iterator itr_t;
359  const int numCols = cols.size();
360  const Ordinal localSubDim = spmdRangeSpace_->localSubDim();
361  ArrayRCP<Scalar> localValuesView = Teuchos::arcp<Scalar>(numCols*localSubDim);
362  // Copy to contiguous storage column by column
363  const const_itr_t lv = localValues_.begin();
364  const itr_t lvv = localValuesView.begin();
365  for (int k = 0; k < numCols; ++k) {
366  const int col_k = cols[k];
367  const const_itr_t lv_k = lv + leadingDim_*col_k;
368  const itr_t lvv_k = lvv + localSubDim*k;
369  std::copy(lv_k, lv_k+localSubDim, lvv_k);
370  }
371  return localValuesView;
372 }
373 
374 
375 } // end namespace Thyra
376 
377 
378 #endif // THYRA_DEFAULT_SPMD_MULTI_VECTOR_DEF_HPP
const const Scalar * const_iterator
void initialize(int *argc, char ***argv)
RCP< MultiVectorBase< Scalar > > nonconstContigSubViewImpl(const Range1D &colRng)
ArrayRCP< T > create_weak() const
bool is_null(const boost::shared_ptr< T > &p)
RCP< const SpmdVectorSpaceBase< Scalar > > spmdSpaceImpl() const
#define TEUCHOS_ASSERT_INEQUALITY(val1, comp, val2)
size_type size() const
ArrayRCP< const T > getConst() const
RCP< VectorBase< Scalar > > nonconstColImpl(Ordinal j)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
void getLocalMultiVectorDataImpl(const Ptr< ArrayRCP< const Scalar > > &localValues, const Ptr< Ordinal > &leadingDim) const
Interface for a collection of column vectors called a multi-vector.
void getNonconstLocalMultiVectorDataImpl(const Ptr< ArrayRCP< Scalar > > &localValues, const Ptr< Ordinal > &leadingDim)
Efficient concrete implementation subclass for SPMD vectors.
Ordinal lbound() const
RCP< MultiVectorBase< Scalar > > nonconstNonContigSubViewImpl(const ArrayView< const int > &cols)
bool nonnull(const boost::shared_ptr< T > &p)
RCP< const ScalarProdVectorSpaceBase< Scalar > > domainScalarProdVecSpc() const
void uninitialize(RCP< const SpmdVectorSpaceBase< Scalar > > *spmdRangeSpace=NULL, RCP< const ScalarProdVectorSpaceBase< Scalar > > *domainSpace=NULL, ArrayRCP< Scalar > *localValues=NULL, Ordinal *leadingDim=NULL)
Set to an uninitialized state.
Ordinal size() const
RCP< const MultiVectorBase< Scalar > > nonContigSubViewImpl(const ArrayView< const int > &cols) const
Efficient concrete implementation subclass for SPMD multi-vectors.
DefaultSpmdMultiVector()
Construct to uninitialized.
void initialize(const RCP< const SpmdVectorSpaceBase< Scalar > > &spmdRangeSpace, const RCP< const ScalarProdVectorSpaceBase< Scalar > > &domainSpace)
Initialize only with vector spaces where storage is allocated internally..
#define TEUCHOS_ASSERT(assertion_test)
Base abstract VectorSpaceBase class for all SPMD-based vector spaces.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
iterator begin() const
RCP< const MultiVectorBase< Scalar > > contigSubViewImpl(const Range1D &colRng) const