Thyra Version of the Day
Loading...
Searching...
No Matches
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
55namespace 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//
63template<class Scalar>
64class CopyBackSpmdMultiVectorEntries {
65public:
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 }
96private:
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
109template<class Scalar>
110RCP<CopyBackSpmdMultiVectorEntries<Scalar> >
111copyBackSpmdMultiVectorEntries(
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
131template<class Scalar>
132int DefaultSpmdMultiVector<Scalar>::numSkipCopyBack(0);
133#endif
134
135
136// Constructors/initializers/accessors
137
138
139template<class Scalar>
141 :leadingDim_(0)
142{}
143
144
145template<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
155template<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
167template<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
181template<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
207template<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
229template<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
243template<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
264template<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
285template<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
302template<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
319template<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
344template<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
355template<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
368template<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
384template<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
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. `*.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)