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>
78RCP<CopyBackSpmdMultiVectorEntries<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#ifdef THYRA_DEBUG
99template<class Scalar>
100int DefaultSpmdMultiVector<Scalar>::numSkipCopyBack(0);
101#endif
102
103
104// Constructors/initializers/accessors
105
106
107template<class Scalar>
111
112
113template<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
123template<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
135template<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
149template<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
175template<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
197template<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
211template<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
232template<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
253template<class Scalar>
256 const Range1D& col_rng_in
257 )
258{
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
270template<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
287template<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
312template<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
323template<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
336template<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
352template<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
ArrayRCP< const T > getConst() const
const T * const_iterator
iterator begin() const
size_type size() const
Ordinal size() const
Ordinal lbound() const
Efficient concrete implementation subclass for SPMD multi-vectors.
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.
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::Ordinal Ordinal
Type for the dimension of a vector space. `*.
T_To & dyn_cast(T_From &from)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)