Thyra Version of the Day
Loading...
Searching...
No Matches
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
23namespace 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//
31template<class Scalar>
32class CopyBackSpmdMultiVectorEntries {
33public:
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 }
64private:
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
77template<class Scalar>
79copyBackSpmdMultiVectorEntries(
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// Constructors/initializers/accessors
99
100
101template<class Scalar>
105
106
107template<class Scalar>
109 const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace
110 ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace
111 )
112{
113 initialize(spmdRangeSpace,domainSpace);
114}
115
116
117template<class Scalar>
119 const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace
120 ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace
121 ,const ArrayRCP<Scalar> &localValues
122 ,const Ordinal leadingDim
123 )
124{
125 initialize(spmdRangeSpace,domainSpace,localValues,leadingDim);
126}
127
128
129template<class Scalar>
131 const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace
132 ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace
133 )
134{
135 const Ordinal localSubDim = spmdRangeSpace->localSubDim();
136 ArrayRCP<Scalar> values;
137 if (localSubDim)
138 values = Teuchos::arcp<Scalar>(localSubDim * domainSpace->dim());
139 initialize(spmdRangeSpace, domainSpace, values, localSubDim);
140}
141
142
143template<class Scalar>
145 const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace,
146 const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace,
147 const ArrayRCP<Scalar> &localValues,
148 const Ordinal leadingDim_in
149 )
150{
151 const Ordinal localSubDim = spmdRangeSpace->localSubDim();
152 const Ordinal leadingDim = (leadingDim_in >= 0 ? leadingDim_in : localSubDim);
153#ifdef TEUCHOS_DEBUG
154 TEUCHOS_ASSERT(!is_null(spmdRangeSpace));
155 TEUCHOS_ASSERT(!is_null(domainSpace));
156 if (spmdRangeSpace->dim() && localSubDim) {
157 TEUCHOS_ASSERT(nonnull(localValues));
158 }
159 TEUCHOS_ASSERT_INEQUALITY(leadingDim, >=, spmdRangeSpace->localSubDim());
160#endif
161 spmdRangeSpace_ = spmdRangeSpace;
162 domainSpace_ = domainSpace;
163 localValues_ = localValues;
164 leadingDim_ = leadingDim;
165 this->updateSpmdSpace();
166}
167
168
169template<class Scalar>
171 RCP<const SpmdVectorSpaceBase<Scalar> > *spmdRangeSpace
172 ,RCP<const ScalarProdVectorSpaceBase<Scalar> > *domainSpace
173 ,ArrayRCP<Scalar> *localValues
174 ,Ordinal *leadingDim
175 )
176{
177 if(spmdRangeSpace) *spmdRangeSpace = spmdRangeSpace_;
178 if(domainSpace) *domainSpace = domainSpace_;
179 if(localValues) *localValues = localValues_;
180 if(leadingDim) *leadingDim = leadingDim_;
181
182 spmdRangeSpace_ = Teuchos::null;
183 domainSpace_ = Teuchos::null;
184 localValues_ = Teuchos::null;
185 leadingDim_ = 0;
186
187 this->updateSpmdSpace();
188}
189
190
191template<class Scalar>
194{
195#ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
196 std::cerr << "\nSpmdMultiVectorStd<Scalar>::domainScalarProdVecSpc() const called!\n";
197#endif
198 return domainSpace_;
199}
200
201
202// Overridden protected functions from MultiVectorBase
203
204
205template<class Scalar>
208{
209#ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
210 std::cerr << "\nSpmdMultiVectorStd<Scalar>::col() called!\n";
211#endif
212#ifdef TEUCHOS_DEBUG
213 TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= j && j < this->domain()->dim() ) );
214#endif
215 return Teuchos::rcp(
217 spmdRangeSpace_,
218 localValues_.persistingView(j*leadingDim_,spmdRangeSpace_->localSubDim()),
219 1
220 )
221 );
222 //return Teuchos::rcp(new DefaultVectorMultiVector<Scalar>(subView(Range1D(j,j))));
223}
224
225
226template<class Scalar>
229 const Range1D& col_rng_in
230 ) const
231{
232 const Range1D colRng = this->validateColRange(col_rng_in);
233 return Teuchos::rcp(
235 spmdRangeSpace_,
236 Teuchos::rcp_dynamic_cast<const ScalarProdVectorSpaceBase<Scalar> >(
237 spmdRangeSpace_->smallVecSpcFcty()->createVecSpc(colRng.size())
238 ,true
239 ),
240 localValues_.persistingView(colRng.lbound()*leadingDim_,colRng.size()*spmdRangeSpace_->localSubDim()),
241 leadingDim_
242 )
243 );
244}
245
246
247template<class Scalar>
250 const Range1D& col_rng_in
251 )
252{
253 return Teuchos::rcp_const_cast<MultiVectorBase<Scalar> >(
254 this->contigSubViewImpl(col_rng_in));
255 // Have the nonconst version call the const version. Note that in this case
256 // we just need to take the const off of the returned MultiVectorBase object
257 // because the localValues is already handled as nonconst. This is the
258 // perfect instance where the advice in Item 3 in "Effective C++ 3rd
259 // edition" where Scott Meyers recommends having the nonconst version call
260 // the const version.
261}
262
263
264template<class Scalar>
267 const ArrayView<const int> &cols
268 ) const
269{
270 THYRA_DEBUG_ASSERT_MV_COLS("nonContigSubViewImpl(cols)", cols);
271 const int numCols = cols.size();
272 const ArrayRCP<Scalar> localValuesView = createContiguousCopy(cols);
273 return defaultSpmdMultiVector<Scalar>(
274 spmdRangeSpace_,
275 createSmallScalarProdVectorSpaceBase<Scalar>(spmdRangeSpace_, numCols),
276 localValuesView
277 );
278}
279
280
281template<class Scalar>
284 const ArrayView<const int> &cols )
285{
286 THYRA_DEBUG_ASSERT_MV_COLS("nonContigSubViewImpl(cols)", cols);
287 const int numCols = cols.size();
288 const ArrayRCP<Scalar> localValuesView = createContiguousCopy(cols);
289 const Ordinal localSubDim = spmdRangeSpace_->localSubDim();
291 copyBackSpmdMultiVectorEntries<Scalar>(cols, localValuesView.getConst(),
292 localSubDim, localValues_.create_weak(), leadingDim_);
293 return Teuchos::rcpWithEmbeddedObjPreDestroy(
295 spmdRangeSpace_,
296 createSmallScalarProdVectorSpaceBase<Scalar>(spmdRangeSpace_, numCols),
297 localValuesView),
298 copyBackView
299 );
300}
301
302
303// Overridden protected members from SpmdMultiVectorBase
304
305
306template<class Scalar>
309{
310#ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
311 std::cerr << "\nSpmdMultiVectorStd<Scalar>::spmdSpace() const called!\n";
312#endif
313 return spmdRangeSpace_;
314}
315
316
317template<class Scalar>
319 const Ptr<ArrayRCP<Scalar> > &localValues, const Ptr<Ordinal> &leadingDim
320 )
321{
322#ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
323 std::cerr << "\nSpmdMultiVectorStd<Scalar>::getLocalMultiVectorDataImpl() called!\n";
324#endif
325 *localValues = localValues_;
326 *leadingDim = leadingDim_;
327}
328
329
330template<class Scalar>
332 const Ptr<ArrayRCP<const Scalar> > &localValues, const Ptr<Ordinal> &leadingDim
333 ) const
334{
335#ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
336 std::cerr << "\nSpmdMultiVectorStd<Scalar>::getLocalData() called!\n";
337#endif
338 *localValues = localValues_;
339 *leadingDim = leadingDim_;
340}
341
342
343// private
344
345
346template<class Scalar>
348DefaultSpmdMultiVector<Scalar>::createContiguousCopy(
349 const ArrayView<const int> &cols ) const
350{
351 typedef typename ArrayRCP<Scalar>::const_iterator const_itr_t;
352 typedef typename ArrayRCP<Scalar>::iterator itr_t;
353 const int numCols = cols.size();
354 const Ordinal localSubDim = spmdRangeSpace_->localSubDim();
355 ArrayRCP<Scalar> localValuesView = Teuchos::arcp<Scalar>(numCols*localSubDim);
356 // Copy to contiguous storage column by column
357 const const_itr_t lv = localValues_.begin();
358 const itr_t lvv = localValuesView.begin();
359 for (int k = 0; k < numCols; ++k) {
360 const int col_k = cols[k];
361 const const_itr_t lv_k = lv + leadingDim_*col_k;
362 const itr_t lvv_k = lvv + localSubDim*k;
363 std::copy(lv_k, lv_k+localSubDim, lvv_k);
364 }
365 return localValuesView;
366}
367
368
369} // end namespace Thyra
370
371
372#endif // THYRA_DEFAULT_SPMD_MULTI_VECTOR_DEF_HPP
ArrayRCP< T > create_weak() const
ArrayRCP< const T > getConst() const
const T * const_iterator
iterator begin() const
size_type size() const
Ordinal size() const
Ordinal lbound() const
void getLocalMultiVectorDataImpl(const Ptr< ArrayRCP< const Scalar > > &localValues, const Ptr< Ordinal > &leadingDim) const
RCP< const SpmdVectorSpaceBase< Scalar > > spmdSpaceImpl() const
DefaultSpmdMultiVector()
Construct to uninitialized.
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.
RCP< MultiVectorBase< Scalar > > nonconstNonContigSubViewImpl(const ArrayView< const int > &cols)
RCP< VectorBase< Scalar > > nonconstColImpl(Ordinal j)
RCP< const MultiVectorBase< Scalar > > contigSubViewImpl(const Range1D &colRng) const
void getNonconstLocalMultiVectorDataImpl(const Ptr< ArrayRCP< Scalar > > &localValues, const Ptr< Ordinal > &leadingDim)
RCP< MultiVectorBase< Scalar > > nonconstContigSubViewImpl(const Range1D &colRng)
void initialize(const RCP< const SpmdVectorSpaceBase< Scalar > > &spmdRangeSpace, const RCP< const ScalarProdVectorSpaceBase< Scalar > > &domainSpace)
Initialize only with vector spaces where storage is allocated internally..
RCP< const MultiVectorBase< Scalar > > nonContigSubViewImpl(const ArrayView< const int > &cols) const
RCP< const ScalarProdVectorSpaceBase< Scalar > > domainScalarProdVecSpc() const
Efficient concrete implementation subclass for SPMD vectors.
RCP< const VectorSpaceBase< Scalar > > domain() const
Returns this->domainScalarProdVecSpc().
RCP< const ScalarProdVectorSpaceBase< Scalar > > createSmallScalarProdVectorSpaceBase(const RCP< const VectorSpaceBase< Scalar > > &vs, const Ordinal dim)
Create a small vector space casted to ScalarProdVectorSpaceBase.
Range1D validateColRange(const Range1D &rowCol) const
Validate and resize the column range.
virtual void updateSpmdSpace()
Subclasses should call whenever the structure of the VectorSpaceBase changes.
Base abstract VectorSpaceBase class for all SPMD-based vector spaces.
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
#define TEUCHOS_ASSERT_INEQUALITY(val1, comp, val2)
Teuchos::Range1D Range1D
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)