Thyra Version of the Day
Loading...
Searching...
No Matches
Thyra_SpmdVectorDefaultBase_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_SPMD_VECTOR_DEFAULT_BASE_DEF_HPP
43#define THYRA_SPMD_VECTOR_DEFAULT_BASE_DEF_HPP
44
45// disable clang warnings
46#if defined (__clang__) && !defined (__INTEL_COMPILER)
47#pragma clang system_header
48#endif
49
50#include "Thyra_SpmdVectorDefaultBase_decl.hpp"
51#include "Thyra_VectorDefaultBase.hpp"
52#include "Thyra_SpmdVectorSpaceDefaultBase.hpp"
53#include "Thyra_apply_op_helper.hpp"
54#include "Thyra_SpmdLocalDataAccess.hpp"
55#include "RTOpPack_SPMD_apply_op.hpp"
56#include "Teuchos_Workspace.hpp"
57#include "Teuchos_Assert.hpp"
58#include "Teuchos_dyn_cast.hpp"
59#include "Teuchos_Assert.hpp"
60#include "Teuchos_Range1D.hpp"
61
62namespace Thyra {
63
64
65// Public interface functions
66
67
68template<class Scalar>
70 :globalDim_(0)
71 ,localOffset_(-1)
72 ,localSubDim_(0)
73{}
74
75
76template<class Scalar>
78 const Ptr<const Teuchos::Comm<Ordinal> > &comm_in,
80 const ArrayView<const Ptr<const VectorBase<Scalar> > > &vecs,
81 const ArrayView<const Ptr<VectorBase<Scalar> > > &targ_vecs,
82 const Ptr<RTOpPack::ReductTarget> &reduct_obj,
83 const Ordinal global_offset_in
84 ) const
85{
86
87 using Teuchos::null;
90 using Teuchos::rcpFromPtr;
91
92 const int num_vecs = vecs.size();
93 const int num_targ_vecs = targ_vecs.size();
94
96 const SpmdVectorSpaceBase<Scalar> &spmdSpc = *this->spmdSpace();
97
98#ifdef TEUCHOS_DEBUG
100 "SpmdVectorDefaultBase<>::applyOp(...)",*space(),
101 op, vecs, targ_vecs, reduct_obj, global_offset_in);
102#endif
103
105 if (nonnull(comm_in))
106 comm = Teuchos::rcpFromPtr(comm_in);
107 else
108 comm = spmdSpc.getComm();
109
110 // First see if this is a locally replicated vector in which case
111 // we treat this as a local operation only.
112 const bool locallyReplicated = spmdSpc.isLocallyReplicated();
113
114 const Range1D local_rng(localOffset_, localOffset_+localSubDim_-1);
115
116 // Create sub-vector views of all of the *participating* local data
117 Workspace<RTOpPack::ConstSubVectorView<Scalar> > sub_vecs(wss.get(), num_vecs);
118 Workspace<RTOpPack::SubVectorView<Scalar> > sub_targ_vecs(wss.get(), num_targ_vecs);
119 for(int k = 0; k < num_vecs; ++k ) {
120 sub_vecs[k] = getLocalSubVectorView<Scalar>(rcpFromPtr(vecs[k]));
121 sub_vecs[k].setGlobalOffset(localOffset_+global_offset_in);
122 }
123 for(int k = 0; k < num_targ_vecs; ++k ) {
124 sub_targ_vecs[k] = getNonconstLocalSubVectorView<Scalar>(rcpFromPtr(targ_vecs[k]));
125 sub_targ_vecs[k].setGlobalOffset(localOffset_+global_offset_in);
126 }
127
128 // Apply the RTOp operator object (all processors must participate)
129 RTOpPack::SPMD_apply_op(
130 locallyReplicated ? NULL : &*comm, // comm
131 op, // op
132 num_vecs, // num_vecs
133 sub_vecs.getRawPtr(), // sub_vecs
134 num_targ_vecs, // num_targ_vecs
135 sub_targ_vecs.getRawPtr(), // targ_sub_vecs
136 reduct_obj.get() // reduct_obj
137 );
138
139 // Free and commit the local data
140 for (int k = 0; k < num_vecs; ++k ) {
142 }
143 for (int k = 0; k < num_targ_vecs; ++k ) {
144 sub_targ_vecs[k] = RTOpPack::SubVectorView<Scalar>();
145 }
146
147}
148
149
150// Overridden from Teuchos::Describable
151
152
153template<class Scalar>
155{
156 using Teuchos::RCP; using Teuchos::Comm; using Teuchos::null;
157 using Teuchos::typeName;
158 std::ostringstream ostr;
159 ostr<<typeName(*this)<<"{spmdSpace="<<this->spmdSpace()->description()<<"}";
160 return ostr.str();
161}
162
163
164// Overridden public functions from VectorBase
165
166
167template<class Scalar>
170{
171 return this->spmdSpace();
172}
173
174
175// protected
176
177
178// Overridden protected functions from VectorBase
179
180
181template<class Scalar>
183 const RTOpPack::RTOpT<Scalar> &op,
184 const ArrayView<const Ptr<const VectorBase<Scalar> > > &vecs,
185 const ArrayView<const Ptr<VectorBase<Scalar> > > &targ_vecs,
186 const Ptr<RTOpPack::ReductTarget> &reduct_obj,
187 const Ordinal global_offset
188 ) const
189{
190 applyOpImplWithComm( Teuchos::null, op, vecs, targ_vecs, reduct_obj,
191 global_offset);
192}
193
194
195template<class Scalar>
197 const Range1D& rng_in, RTOpPack::ConstSubVectorView<Scalar>* sub_vec
198 ) const
199{
200#ifdef THYRA_DEBUG
201 TEUCHOS_ASSERT(sub_vec);
202#endif
203 if( rng_in == Range1D::INVALID ) {
204 // Just return an null view
206 return;
207 }
208 const bool isFullRng = rng_in.full_range();
209 const Range1D rng = validateRange(rng_in);
210 const bool isLocallyReplicated = this->spmdSpace()->isLocallyReplicated();
211 if (
212 (
213 rng.lbound() < localOffset_
214 ||
215 localOffset_+localSubDim_-1 < rng.ubound()
216 ||
217 isFullRng
218 )
219 &&
220 !isLocallyReplicated
221 )
222 {
223 // rng consists of off-processor elements so use the default implementation!
225 return;
226 }
227 // rng consists of all local data so get it!
228 ArrayRCP<const Scalar>localValues;
229 this->getLocalData(Teuchos::outArg(localValues));
230 sub_vec->initialize(
231 rng.lbound(), // globalOffset
232 rng.size(), // subDim
233 localValues.persistingView(rng.lbound()-localOffset_, rng.size()),
234 1 // stride
235 );
236}
237
238
239template<class Scalar>
242 ) const
243{
244#ifdef TEUCHOS_DEBUG
246 sub_vec==NULL || sub_vec->globalOffset() < 0 || sub_vec->globalOffset() + sub_vec->subDim() > globalDim_
247 ,std::logic_error
248 ,"SpmdVectorDefaultBase<Scalar>::releaseDetachedVectorViewImpl(...) : Error, this sub vector was not gotten from acquireDetachedView(...)!"
249 );
250#endif
251 if(
252 sub_vec->globalOffset() < localOffset_
253 || localOffset_+localSubDim_ < sub_vec->globalOffset()+sub_vec->subDim()
254 )
255 {
256 // Let the default implementation handle it!
258 return;
259 }
260 // Nothing to deallocate!
261 sub_vec->uninitialize();
262}
263
264
265template<class Scalar>
267 const Range1D& rng_in, RTOpPack::SubVectorView<Scalar>* sub_vec
268 )
269{
270#ifdef THYRA_DEBUG
271 TEUCHOS_ASSERT(sub_vec);
272#endif
273 if( rng_in == Range1D::INVALID ) {
274 // Just return an null view
276 return;
277 }
278 const bool isFullRng = rng_in.full_range();
279 const Range1D rng = validateRange(rng_in);
280 const bool isLocallyReplicated = this->spmdSpace()->isLocallyReplicated();
281 if (
282 (
283 rng.lbound() < localOffset_
284 ||
285 localOffset_+localSubDim_-1 < rng.ubound()
286 ||
287 isFullRng
288 )
289 &&
290 !isLocallyReplicated
291 )
292 {
293 // rng consists of off-processor elements so use the default implementation!
295 return;
296 }
297 // rng consists of all local data so get it!
298 ArrayRCP<Scalar> localValues;
299 this->getNonconstLocalData(Teuchos::outArg(localValues));
300 sub_vec->initialize(
301 rng.lbound(), // globalOffset
302 rng.size(), // subDim
303 localValues.persistingView(rng.lbound()-localOffset_, rng.size()),
304 1 // stride
305 );
306}
307
308
309template<class Scalar>
312 )
313{
314#ifdef TEUCHOS_DEBUG
316 sub_vec==NULL || sub_vec->globalOffset() < 0 || sub_vec->globalOffset() + sub_vec->subDim() > globalDim_
317 ,std::logic_error
318 ,"SpmdVectorDefaultBase<Scalar>::commitDetachedView(...) : Error, this sub vector was not gotten from acquireDetachedView(...)!"
319 );
320#endif
321 if(
322 sub_vec->globalOffset() < localOffset_
323 ||
324 localOffset_+localSubDim_ < sub_vec->globalOffset()+sub_vec->subDim()
325 )
326 {
327 // Let the default implementation handle it!
329 return;
330 }
331 sub_vec->uninitialize(); // Nothing to deallocate!
332}
333
334
335// Overridden Protected functions from SpmdMultiVectorBase
336
337
338template<class Scalar>
341{
342 ArrayRCP<Scalar> localValues;
343 this->getNonconstLocalData(Teuchos::outArg(localValues));
345 localOffset_, // globalOffset
346 localSubDim_,
347 0, // colOffset
348 1, // numCols
349 localValues,
350 localSubDim_ // leadingDim
351 );
352}
353
354
355template<class Scalar>
358{
359 using Teuchos::outArg;
360 ArrayRCP<const Scalar> localValues;
361 this->getLocalData(outArg(localValues));
363 localOffset_, // globalOffset
364 localSubDim_,
365 0, // colOffset
366 1, // numCols
367 localValues,
368 localSubDim_ // leadingDim
369 );
370}
371
372
373template<class Scalar>
375 const Ptr<ArrayRCP<Scalar> > &localValues, const Ptr<Ordinal> &leadingDim)
376{
377 this->getNonconstLocalData(localValues);
378 *leadingDim = localValues->size();
379}
380
381
382template<class Scalar>
384 const Ptr<ArrayRCP<const Scalar> > &localValues, const Ptr<Ordinal> &leadingDim) const
385{
386 this->getLocalData(localValues);
387 *leadingDim = localValues->size();
388}
389
390
391// Overridden Protected functions from SpmdVectorBase
392
393
394template<class Scalar>
397{
398 ArrayRCP<Scalar> localValues;
399 this->getNonconstLocalData(Teuchos::outArg(localValues));
401 localOffset_,
402 localSubDim_,
403 localValues,
404 1 // stride
405 );
406}
407
408
409template<class Scalar>
412{
413 ArrayRCP<const Scalar> localValues;
414 this->getLocalData(Teuchos::outArg(localValues));
416 localOffset_, // globalOffset?
417 localSubDim_,
418 localValues,
419 1 // stride
420 );
421}
422
423
424// Protected functions to be used by subclasses
425
426
427template<class Scalar>
429{
430 if(globalDim_ == 0) {
431 const SpmdVectorSpaceBase<Scalar> *l_spmdSpace = this->spmdSpace().get();
432 if(l_spmdSpace) {
433 globalDim_ = l_spmdSpace->dim();
434 localOffset_ = l_spmdSpace->localOffset();
435 localSubDim_ = l_spmdSpace->localSubDim();
436 }
437 else {
438 globalDim_ = 0;
439 localOffset_ = -1;
440 localSubDim_ = 0;
441 }
442 }
443}
444
445
446// private
447
448
449template<class Scalar>
451{
452 const Range1D rng = Teuchos::full_range(rng_in,0,globalDim_-1);
453#ifdef TEUCHOS_DEBUG
455 !(0 <= rng.lbound() && rng.ubound() < globalDim_), std::invalid_argument
456 ,"SpmdVectorDefaultBase<Scalar>::validateRange(...): Error, the range ["
457 <<rng.lbound()<<","<<rng.ubound()<<"] is not "
458 "in the range [0,"<<(globalDim_-1)<<"]!"
459 );
460#endif
461 return rng;
462}
463
464
465#ifdef THYRA_SPMD_VECTOR_BASE_DUMP
466template<class Scalar>
467bool SpmdVectorDefaultBase<Scalar>::show_dump = false;
468#endif // THYRA_SPMD_VECTOR_BASE_DUMP
469
470
471} // end namespace Thyra
472
473
474#endif // THYRA_SPMD_VECTOR_DEFAULT_BASE_DEF_HPP
Ordinal globalOffset() const
void initialize(Ordinal globalOffset_in, Ordinal subDim_in, const ArrayRCP< const Scalar > &values_in, ptrdiff_t stride_in)
void initialize(Ordinal globalOffset_in, Ordinal subDim_in, const ArrayRCP< Scalar > &values_in, ptrdiff_t stride_in)
ArrayRCP< T > persistingView(size_type lowerOffset, size_type size) const
T * get() const
bool full_range() const
Ordinal size() const
Ordinal lbound() const
Ordinal ubound() const
size_t size() const
Base class for SPMD vectors that can provide views of contiguous elements in a process.
RTOpPack::SubMultiVectorView< Scalar > getNonconstLocalSubMultiVectorImpl()
void getLocalMultiVectorDataImpl(const Ptr< ArrayRCP< const Scalar > > &localValues, const Ptr< Ordinal > &leadingDim) const
void applyOpImpl(const RTOpPack::RTOpT< Scalar > &op, const ArrayView< const Ptr< const VectorBase< Scalar > > > &vecs, const ArrayView< const Ptr< VectorBase< Scalar > > > &targ_vecs, const Ptr< RTOpPack::ReductTarget > &reduct_obj, const Ordinal global_offset) const
Calls applyOpImplWithComm(null,op,...).
void acquireNonconstDetachedVectorViewImpl(const Range1D &rng, RTOpPack::SubVectorView< Scalar > *sub_vec)
Implemented through this->getLocalData()
void releaseDetachedVectorViewImpl(RTOpPack::ConstSubVectorView< Scalar > *sub_vec) const
Implemented through this->freeLocalData()
void acquireDetachedVectorViewImpl(const Range1D &rng, RTOpPack::ConstSubVectorView< Scalar > *sub_vec) const
Implemented through this->getLocalData()
void commitNonconstDetachedVectorViewImpl(RTOpPack::SubVectorView< Scalar > *sub_vec)
Implemented through this->commitLocalData()
virtual void updateSpmdSpace()
Subclasses must call this function whenever the structure of the VectorSpaceBase changes.
RTOpPack::ConstSubMultiVectorView< Scalar > getLocalSubMultiVectorImpl() const
void getNonconstLocalMultiVectorDataImpl(const Ptr< ArrayRCP< Scalar > > &localValues, const Ptr< Ordinal > &leadingDim)
virtual void applyOpImplWithComm(const Ptr< const Teuchos::Comm< Ordinal > > &comm, const RTOpPack::RTOpT< Scalar > &op, const ArrayView< const Ptr< const VectorBase< Scalar > > > &vecs, const ArrayView< const Ptr< VectorBase< Scalar > > > &targ_vecs, const Ptr< RTOpPack::ReductTarget > &reduct_obj, const Ordinal global_offset) const
Implementation of applyOpImpl(...) that uses an input Comm.
RTOpPack::SubVectorView< Scalar > getNonconstLocalSubVectorImpl()
Virtual implementation for getNonconstLocalSubVector().
Teuchos::RCP< const VectorSpaceBase< Scalar > > space() const
Returns this->spmdSpace().
RTOpPack::ConstSubVectorView< Scalar > getLocalSubVectorImpl() const
Virtual implementation for getLocalSubVector().
Base abstract VectorSpaceBase class for all SPMD-based vector spaces.
virtual Ordinal localSubDim() const =0
Returns the number of local elements stored on this process.
virtual Teuchos::RCP< const Teuchos::Comm< Ordinal > > getComm() const =0
Returns the SPMD communicator.
virtual bool isLocallyReplicated() const =0
Returns true if vector space is locally replicated space.
virtual Ordinal localOffset() const =0
Returns the offset for the local sub-vector stored on this process.
Abstract interface for finite-dimensional dense vectors.
virtual void acquireNonconstDetachedVectorViewImpl(const Range1D &rng, RTOpPack::SubVectorView< Scalar > *sub_vec)
virtual void acquireDetachedVectorViewImpl(const Range1D &rng, RTOpPack::ConstSubVectorView< Scalar > *sub_vec) const
virtual void releaseDetachedVectorViewImpl(RTOpPack::ConstSubVectorView< Scalar > *sub_vec) const
virtual void commitNonconstDetachedVectorViewImpl(RTOpPack::SubVectorView< Scalar > *sub_vec)
virtual Ordinal dim() const =0
Return the dimension of the vector space.
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
void apply_op_validate_input(const std::string &func_name, const VectorSpaceBase< Scalar > &space, const RTOpPack::RTOpT< Scalar > &op, const ArrayView< const Ptr< const VectorBase< Scalar > > > &vecs, const ArrayView< const Ptr< VectorBase< Scalar > > > &targ_vecs, const Ptr< RTOpPack::ReductTarget > &reduct_obj, const Ordinal global_offset)
Validate the inputs to VectorBase::applyOp().
std::string typeName(const T &t)
T_To & dyn_cast(T_From &from)
TEUCHOSCORE_LIB_DLL_EXPORT Teuchos::RCP< WorkspaceStore > get_default_workspace_store()