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 //
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_DEFAULT_SPMD_MULTI_VECTOR_DEF_HPP
43 #define THYRA_DEFAULT_SPMD_MULTI_VECTOR_DEF_HPP
44 
45 // Define to make some verbose output
46 //#define THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
47 
48 #include "Thyra_DefaultSpmdMultiVector_decl.hpp"
49 #include "Thyra_SpmdMultiVectorDefaultBase.hpp"
50 #include "Thyra_VectorSpaceFactoryBase.hpp"
51 #include "Thyra_DefaultSpmdVector.hpp"
52 #include "Teuchos_Assert.hpp"
53 
54 
55 namespace Thyra {
56 
57 
58 //
59 // Simple utility class to copy back multi-vector entries
60 //
61 // ToDo: Refactor above to not use raw pointers!
62 //
63 template<class Scalar>
64 class CopyBackSpmdMultiVectorEntries {
65 public:
66  CopyBackSpmdMultiVectorEntries(
67  const ArrayView<const int> &cols,
68  const ArrayRCP<const Scalar> &localValuesView, const Ordinal localSubDim,
69  const ArrayRCP<Scalar> &localValues, const Ordinal leadingDim
70  )
71  : cols_(cols), localValuesView_(localValuesView), localSubDim_(localSubDim),
72  localValues_(localValues), leadingDim_(leadingDim)
73  {}
74  ~CopyBackSpmdMultiVectorEntries()
75  {
76  typedef typename ArrayRCP<const Scalar>::const_iterator const_itr_t;
77  typedef typename ArrayRCP<Scalar>::iterator itr_t;
78  // Copy from contiguous storage column by column
79  if (localValues_.strong_count()) {
80  const int numCols = cols_.size();
81  const const_itr_t lvv = localValuesView_.begin();
82  const itr_t lv = localValues_.begin();
83  for (int k = 0; k < numCols; ++k) {
84  const int col_k = cols_[k];
85  const const_itr_t lvv_k = lvv + localSubDim_*k;
86  const itr_t lv_k = lv + leadingDim_*col_k;
87  std::copy( lvv_k, lvv_k + localSubDim_, lv_k );
88  }
89  }
90 #ifdef THYRA_DEBUG
91  else {
92  ++DefaultSpmdMultiVector<Scalar>::numSkipCopyBack;
93  }
94 #endif // THYRA_DEBUG
95  }
96 private:
97  Array<int> cols_;
98  ArrayRCP<const Scalar> localValuesView_;
99  Ordinal localSubDim_;
100  ArrayRCP<Scalar> localValues_;
101  Ordinal leadingDim_;
102  // Not defined and not to be called
103  CopyBackSpmdMultiVectorEntries();
104  CopyBackSpmdMultiVectorEntries(const CopyBackSpmdMultiVectorEntries&);
105  CopyBackSpmdMultiVectorEntries& operator=(const CopyBackSpmdMultiVectorEntries&);
106 };
107 
108 
109 template<class Scalar>
110 RCP<CopyBackSpmdMultiVectorEntries<Scalar> >
111 copyBackSpmdMultiVectorEntries(
112  const ArrayView<const int> &cols,
113  const ArrayRCP<const Scalar> &localValuesView, const Ordinal localSubDim,
114  const ArrayRCP<Scalar> &localValues, const Ordinal leadingDim
115  )
116 {
117  return Teuchos::rcp(
118  new CopyBackSpmdMultiVectorEntries<Scalar>(
119  cols, localValuesView, localSubDim, localValues, leadingDim
120  )
121  );
122 }
123 
124 
125 //
126 // DefaultSpmdMultiVector
127 //
128 
129 
130 #ifdef THYRA_DEBUG
131 template<class Scalar>
132 int DefaultSpmdMultiVector<Scalar>::numSkipCopyBack(0);
133 #endif
134 
135 
136 // Constructors/initializers/accessors
137 
138 
139 template<class Scalar>
141  :leadingDim_(0)
142 {}
143 
144 
145 template<class Scalar>
147  const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace
148  ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace
149  )
150 {
151  initialize(spmdRangeSpace,domainSpace);
152 }
153 
154 
155 template<class Scalar>
157  const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace
158  ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace
159  ,const ArrayRCP<Scalar> &localValues
160  ,const Ordinal leadingDim
161  )
162 {
163  initialize(spmdRangeSpace,domainSpace,localValues,leadingDim);
164 }
165 
166 
167 template<class Scalar>
169  const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace
170  ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace
171  )
172 {
173  const Ordinal localSubDim = spmdRangeSpace->localSubDim();
174  ArrayRCP<Scalar> values;
175  if (localSubDim)
176  values = Teuchos::arcp<Scalar>(localSubDim * domainSpace->dim());
177  initialize(spmdRangeSpace, domainSpace, values, localSubDim);
178 }
179 
180 
181 template<class Scalar>
183  const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace,
184  const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace,
185  const ArrayRCP<Scalar> &localValues,
186  const Ordinal leadingDim_in
187  )
188 {
189  const Ordinal localSubDim = spmdRangeSpace->localSubDim();
190  const Ordinal leadingDim = (leadingDim_in >= 0 ? leadingDim_in : localSubDim);
191 #ifdef TEUCHOS_DEBUG
192  TEUCHOS_ASSERT(!is_null(spmdRangeSpace));
193  TEUCHOS_ASSERT(!is_null(domainSpace));
194  if (spmdRangeSpace->dim() && localSubDim) {
195  TEUCHOS_ASSERT(nonnull(localValues));
196  }
197  TEUCHOS_ASSERT_INEQUALITY(leadingDim, >=, spmdRangeSpace->localSubDim());
198 #endif
199  spmdRangeSpace_ = spmdRangeSpace;
200  domainSpace_ = domainSpace;
201  localValues_ = localValues;
202  leadingDim_ = leadingDim;
203  this->updateSpmdSpace();
204 }
205 
206 
207 template<class Scalar>
209  RCP<const SpmdVectorSpaceBase<Scalar> > *spmdRangeSpace
210  ,RCP<const ScalarProdVectorSpaceBase<Scalar> > *domainSpace
211  ,ArrayRCP<Scalar> *localValues
212  ,Ordinal *leadingDim
213  )
214 {
215  if(spmdRangeSpace) *spmdRangeSpace = spmdRangeSpace_;
216  if(domainSpace) *domainSpace = domainSpace_;
217  if(localValues) *localValues = localValues_;
218  if(leadingDim) *leadingDim = leadingDim_;
219 
220  spmdRangeSpace_ = Teuchos::null;
221  domainSpace_ = Teuchos::null;
222  localValues_ = Teuchos::null;
223  leadingDim_ = 0;
224 
225  this->updateSpmdSpace();
226 }
227 
228 
229 template<class Scalar>
232 {
233 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
234  std::cerr << "\nSpmdMultiVectorStd<Scalar>::domainScalarProdVecSpc() const called!\n";
235 #endif
236  return domainSpace_;
237 }
238 
239 
240 // Overridden protected functions from MultiVectorBase
241 
242 
243 template<class Scalar>
246 {
247 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
248  std::cerr << "\nSpmdMultiVectorStd<Scalar>::col() called!\n";
249 #endif
250 #ifdef TEUCHOS_DEBUG
251  TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= j && j < this->domain()->dim() ) );
252 #endif
253  return Teuchos::rcp(
255  spmdRangeSpace_,
256  localValues_.persistingView(j*leadingDim_,spmdRangeSpace_->localSubDim()),
257  1
258  )
259  );
260  //return Teuchos::rcp(new DefaultVectorMultiVector<Scalar>(subView(Range1D(j,j))));
261 }
262 
263 
264 template<class Scalar>
267  const Range1D& col_rng_in
268  ) const
269 {
270  const Range1D colRng = this->validateColRange(col_rng_in);
271  return Teuchos::rcp(
273  spmdRangeSpace_,
274  Teuchos::rcp_dynamic_cast<const ScalarProdVectorSpaceBase<Scalar> >(
275  spmdRangeSpace_->smallVecSpcFcty()->createVecSpc(colRng.size())
276  ,true
277  ),
278  localValues_.persistingView(colRng.lbound()*leadingDim_,colRng.size()*spmdRangeSpace_->localSubDim()),
279  leadingDim_
280  )
281  );
282 }
283 
284 
285 template<class Scalar>
288  const Range1D& col_rng_in
289  )
290 {
291  return Teuchos::rcp_const_cast<MultiVectorBase<Scalar> >(
292  this->contigSubViewImpl(col_rng_in));
293  // Have the nonconst version call the const version. Note that in this case
294  // we just need to take the const off of the returned MultiVectorBase object
295  // because the localValues is already handled as nonconst. This is the
296  // perfect instance where the advice in Item 3 in "Effective C++ 3rd
297  // edition" where Scott Meyers recommends having the nonconst version call
298  // the const version.
299 }
300 
301 
302 template<class Scalar>
305  const ArrayView<const int> &cols
306  ) const
307 {
308  THYRA_DEBUG_ASSERT_MV_COLS("nonContigSubViewImpl(cols)", cols);
309  const int numCols = cols.size();
310  const ArrayRCP<Scalar> localValuesView = createContiguousCopy(cols);
311  return defaultSpmdMultiVector<Scalar>(
312  spmdRangeSpace_,
313  createSmallScalarProdVectorSpaceBase<Scalar>(spmdRangeSpace_, numCols),
314  localValuesView
315  );
316 }
317 
318 
319 template<class Scalar>
322  const ArrayView<const int> &cols )
323 {
324  THYRA_DEBUG_ASSERT_MV_COLS("nonContigSubViewImpl(cols)", cols);
325  const int numCols = cols.size();
326  const ArrayRCP<Scalar> localValuesView = createContiguousCopy(cols);
327  const Ordinal localSubDim = spmdRangeSpace_->localSubDim();
329  copyBackSpmdMultiVectorEntries<Scalar>(cols, localValuesView.getConst(),
330  localSubDim, localValues_.create_weak(), leadingDim_);
331  return Teuchos::rcpWithEmbeddedObjPreDestroy(
333  spmdRangeSpace_,
334  createSmallScalarProdVectorSpaceBase<Scalar>(spmdRangeSpace_, numCols),
335  localValuesView),
336  copyBackView
337  );
338 }
339 
340 
341 // Overridden protected members from SpmdMultiVectorBase
342 
343 
344 template<class Scalar>
347 {
348 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
349  std::cerr << "\nSpmdMultiVectorStd<Scalar>::spmdSpace() const called!\n";
350 #endif
351  return spmdRangeSpace_;
352 }
353 
354 
355 template<class Scalar>
357  const Ptr<ArrayRCP<Scalar> > &localValues, const Ptr<Ordinal> &leadingDim
358  )
359 {
360 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
361  std::cerr << "\nSpmdMultiVectorStd<Scalar>::getLocalMultiVectorDataImpl() called!\n";
362 #endif
363  *localValues = localValues_;
364  *leadingDim = leadingDim_;
365 }
366 
367 
368 template<class Scalar>
370  const Ptr<ArrayRCP<const Scalar> > &localValues, const Ptr<Ordinal> &leadingDim
371  ) const
372 {
373 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
374  std::cerr << "\nSpmdMultiVectorStd<Scalar>::getLocalData() called!\n";
375 #endif
376  *localValues = localValues_;
377  *leadingDim = leadingDim_;
378 }
379 
380 
381 // private
382 
383 
384 template<class Scalar>
387  const ArrayView<const int> &cols ) const
388 {
389  typedef typename ArrayRCP<Scalar>::const_iterator const_itr_t;
390  typedef typename ArrayRCP<Scalar>::iterator itr_t;
391  const int numCols = cols.size();
392  const Ordinal localSubDim = spmdRangeSpace_->localSubDim();
393  ArrayRCP<Scalar> localValuesView = Teuchos::arcp<Scalar>(numCols*localSubDim);
394  // Copy to contiguous storage column by column
395  const const_itr_t lv = localValues_.begin();
396  const itr_t lvv = localValuesView.begin();
397  for (int k = 0; k < numCols; ++k) {
398  const int col_k = cols[k];
399  const const_itr_t lv_k = lv + leadingDim_*col_k;
400  const itr_t lvv_k = lvv + localSubDim*k;
401  std::copy(lv_k, lv_k+localSubDim, lvv_k);
402  }
403  return localValuesView;
404 }
405 
406 
407 } // end namespace Thyra
408 
409 
410 #endif // THYRA_DEFAULT_SPMD_MULTI_VECTOR_DEF_HPP
const const Scalar * const_iterator
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