Thyra Version of the Day
Loading...
Searching...
No Matches
Thyra_SpmdVectorDefaultBase_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_SPMD_VECTOR_DEFAULT_BASE_DEF_HPP
11#define THYRA_SPMD_VECTOR_DEFAULT_BASE_DEF_HPP
12
13// disable clang warnings
14#if defined (__clang__) && !defined (__INTEL_COMPILER)
15#pragma clang system_header
16#endif
17
18#include "Thyra_SpmdVectorDefaultBase_decl.hpp"
19#include "Thyra_VectorDefaultBase.hpp"
20#include "Thyra_SpmdVectorSpaceDefaultBase.hpp"
21#include "Thyra_apply_op_helper.hpp"
22#include "Thyra_SpmdLocalDataAccess.hpp"
23#include "RTOpPack_SPMD_apply_op.hpp"
24#include "Teuchos_Workspace.hpp"
25#include "Teuchos_Assert.hpp"
26#include "Teuchos_dyn_cast.hpp"
27#include "Teuchos_Assert.hpp"
28#include "Teuchos_Range1D.hpp"
29
30namespace Thyra {
31
32
33// Public interface functions
34
35
36template<class Scalar>
38 :globalDim_(0)
39 ,localOffset_(-1)
40 ,localSubDim_(0)
41{}
42
43
44template<class Scalar>
46 const Ptr<const Teuchos::Comm<Ordinal> > &comm_in,
48 const ArrayView<const Ptr<const VectorBase<Scalar> > > &vecs,
49 const ArrayView<const Ptr<VectorBase<Scalar> > > &targ_vecs,
50 const Ptr<RTOpPack::ReductTarget> &reduct_obj,
51 const Ordinal global_offset_in
52 ) const
53{
54
55 using Teuchos::null;
58 using Teuchos::rcpFromPtr;
59
60 const int num_vecs = vecs.size();
61 const int num_targ_vecs = targ_vecs.size();
62
64 const SpmdVectorSpaceBase<Scalar> &spmdSpc = *this->spmdSpace();
65
66#ifdef TEUCHOS_DEBUG
68 "SpmdVectorDefaultBase<>::applyOp(...)",*space(),
69 op, vecs, targ_vecs, reduct_obj, global_offset_in);
70#endif
71
73 if (nonnull(comm_in))
74 comm = Teuchos::rcpFromPtr(comm_in);
75 else
76 comm = spmdSpc.getComm();
77
78 // First see if this is a locally replicated vector in which case
79 // we treat this as a local operation only.
80 const bool locallyReplicated = spmdSpc.isLocallyReplicated();
81
82 const Range1D local_rng(localOffset_, localOffset_+localSubDim_-1);
83
84 // Create sub-vector views of all of the *participating* local data
85 Workspace<RTOpPack::ConstSubVectorView<Scalar> > sub_vecs(wss.get(), num_vecs);
86 Workspace<RTOpPack::SubVectorView<Scalar> > sub_targ_vecs(wss.get(), num_targ_vecs);
87 for(int k = 0; k < num_vecs; ++k ) {
88 sub_vecs[k] = getLocalSubVectorView<Scalar>(rcpFromPtr(vecs[k]));
89 sub_vecs[k].setGlobalOffset(localOffset_+global_offset_in);
90 }
91 for(int k = 0; k < num_targ_vecs; ++k ) {
92 sub_targ_vecs[k] = getNonconstLocalSubVectorView<Scalar>(rcpFromPtr(targ_vecs[k]));
93 sub_targ_vecs[k].setGlobalOffset(localOffset_+global_offset_in);
94 }
95
96 // Apply the RTOp operator object (all processors must participate)
97 RTOpPack::SPMD_apply_op(
98 locallyReplicated ? NULL : &*comm, // comm
99 op, // op
100 num_vecs, // num_vecs
101 sub_vecs.getRawPtr(), // sub_vecs
102 num_targ_vecs, // num_targ_vecs
103 sub_targ_vecs.getRawPtr(), // targ_sub_vecs
104 reduct_obj.get() // reduct_obj
105 );
106
107 // Free and commit the local data
108 for (int k = 0; k < num_vecs; ++k ) {
110 }
111 for (int k = 0; k < num_targ_vecs; ++k ) {
112 sub_targ_vecs[k] = RTOpPack::SubVectorView<Scalar>();
113 }
114
115}
116
117
118// Overridden from Teuchos::Describable
119
120
121template<class Scalar>
123{
124 using Teuchos::RCP; using Teuchos::Comm; using Teuchos::null;
125 using Teuchos::typeName;
126 std::ostringstream ostr;
127 ostr<<typeName(*this)<<"{spmdSpace="<<this->spmdSpace()->description()<<"}";
128 return ostr.str();
129}
130
131
132// Overridden public functions from VectorBase
133
134
135template<class Scalar>
138{
139 return this->spmdSpace();
140}
141
142
143// protected
144
145
146// Overridden protected functions from VectorBase
147
148
149template<class Scalar>
151 const RTOpPack::RTOpT<Scalar> &op,
152 const ArrayView<const Ptr<const VectorBase<Scalar> > > &vecs,
153 const ArrayView<const Ptr<VectorBase<Scalar> > > &targ_vecs,
154 const Ptr<RTOpPack::ReductTarget> &reduct_obj,
155 const Ordinal global_offset
156 ) const
157{
158 applyOpImplWithComm( Teuchos::null, op, vecs, targ_vecs, reduct_obj,
159 global_offset);
160}
161
162
163template<class Scalar>
165 const Range1D& rng_in, RTOpPack::ConstSubVectorView<Scalar>* sub_vec
166 ) const
167{
168#ifdef THYRA_DEBUG
169 TEUCHOS_ASSERT(sub_vec);
170#endif
171 if( rng_in == Range1D::INVALID ) {
172 // Just return an null view
174 return;
175 }
176 const bool isFullRng = rng_in.full_range();
177 const Range1D rng = validateRange(rng_in);
178 const bool isLocallyReplicated = this->spmdSpace()->isLocallyReplicated();
179 if (
180 (
181 rng.lbound() < localOffset_
182 ||
183 localOffset_+localSubDim_-1 < rng.ubound()
184 ||
185 isFullRng
186 )
187 &&
188 !isLocallyReplicated
189 )
190 {
191 // rng consists of off-processor elements so use the default implementation!
193 return;
194 }
195 // rng consists of all local data so get it!
196 ArrayRCP<const Scalar>localValues;
197 this->getLocalData(Teuchos::outArg(localValues));
198 sub_vec->initialize(
199 rng.lbound(), // globalOffset
200 rng.size(), // subDim
201 localValues.persistingView(rng.lbound()-localOffset_, rng.size()),
202 1 // stride
203 );
204}
205
206
207template<class Scalar>
210 ) const
211{
212#ifdef TEUCHOS_DEBUG
214 sub_vec==NULL || sub_vec->globalOffset() < 0 || sub_vec->globalOffset() + sub_vec->subDim() > globalDim_
215 ,std::logic_error
216 ,"SpmdVectorDefaultBase<Scalar>::releaseDetachedVectorViewImpl(...) : Error, this sub vector was not gotten from acquireDetachedView(...)!"
217 );
218#endif
219 if(
220 sub_vec->globalOffset() < localOffset_
221 || localOffset_+localSubDim_ < sub_vec->globalOffset()+sub_vec->subDim()
222 )
223 {
224 // Let the default implementation handle it!
226 return;
227 }
228 // Nothing to deallocate!
229 sub_vec->uninitialize();
230}
231
232
233template<class Scalar>
235 const Range1D& rng_in, RTOpPack::SubVectorView<Scalar>* sub_vec
236 )
237{
238#ifdef THYRA_DEBUG
239 TEUCHOS_ASSERT(sub_vec);
240#endif
241 if( rng_in == Range1D::INVALID ) {
242 // Just return an null view
244 return;
245 }
246 const bool isFullRng = rng_in.full_range();
247 const Range1D rng = validateRange(rng_in);
248 const bool isLocallyReplicated = this->spmdSpace()->isLocallyReplicated();
249 if (
250 (
251 rng.lbound() < localOffset_
252 ||
253 localOffset_+localSubDim_-1 < rng.ubound()
254 ||
255 isFullRng
256 )
257 &&
258 !isLocallyReplicated
259 )
260 {
261 // rng consists of off-processor elements so use the default implementation!
263 return;
264 }
265 // rng consists of all local data so get it!
266 ArrayRCP<Scalar> localValues;
267 this->getNonconstLocalData(Teuchos::outArg(localValues));
268 sub_vec->initialize(
269 rng.lbound(), // globalOffset
270 rng.size(), // subDim
271 localValues.persistingView(rng.lbound()-localOffset_, rng.size()),
272 1 // stride
273 );
274}
275
276
277template<class Scalar>
280 )
281{
282#ifdef TEUCHOS_DEBUG
284 sub_vec==NULL || sub_vec->globalOffset() < 0 || sub_vec->globalOffset() + sub_vec->subDim() > globalDim_
285 ,std::logic_error
286 ,"SpmdVectorDefaultBase<Scalar>::commitDetachedView(...) : Error, this sub vector was not gotten from acquireDetachedView(...)!"
287 );
288#endif
289 if(
290 sub_vec->globalOffset() < localOffset_
291 ||
292 localOffset_+localSubDim_ < sub_vec->globalOffset()+sub_vec->subDim()
293 )
294 {
295 // Let the default implementation handle it!
297 return;
298 }
299 sub_vec->uninitialize(); // Nothing to deallocate!
300}
301
302
303// Overridden Protected functions from SpmdMultiVectorBase
304
305
306template<class Scalar>
309{
310 ArrayRCP<Scalar> localValues;
311 this->getNonconstLocalData(Teuchos::outArg(localValues));
313 localOffset_, // globalOffset
314 localSubDim_,
315 0, // colOffset
316 1, // numCols
317 localValues,
318 localSubDim_ // leadingDim
319 );
320}
321
322
323template<class Scalar>
326{
327 using Teuchos::outArg;
328 ArrayRCP<const Scalar> localValues;
329 this->getLocalData(outArg(localValues));
331 localOffset_, // globalOffset
332 localSubDim_,
333 0, // colOffset
334 1, // numCols
335 localValues,
336 localSubDim_ // leadingDim
337 );
338}
339
340
341template<class Scalar>
343 const Ptr<ArrayRCP<Scalar> > &localValues, const Ptr<Ordinal> &leadingDim)
344{
345 this->getNonconstLocalData(localValues);
346 *leadingDim = localValues->size();
347}
348
349
350template<class Scalar>
352 const Ptr<ArrayRCP<const Scalar> > &localValues, const Ptr<Ordinal> &leadingDim) const
353{
354 this->getLocalData(localValues);
355 *leadingDim = localValues->size();
356}
357
358
359// Overridden Protected functions from SpmdVectorBase
360
361
362template<class Scalar>
365{
366 ArrayRCP<Scalar> localValues;
367 this->getNonconstLocalData(Teuchos::outArg(localValues));
369 localOffset_,
370 localSubDim_,
371 localValues,
372 1 // stride
373 );
374}
375
376
377template<class Scalar>
380{
381 ArrayRCP<const Scalar> localValues;
382 this->getLocalData(Teuchos::outArg(localValues));
384 localOffset_, // globalOffset?
385 localSubDim_,
386 localValues,
387 1 // stride
388 );
389}
390
391
392// Protected functions to be used by subclasses
393
394
395template<class Scalar>
397{
398 if(globalDim_ == 0) {
399 const SpmdVectorSpaceBase<Scalar> *l_spmdSpace = this->spmdSpace().get();
400 if(l_spmdSpace) {
401 globalDim_ = l_spmdSpace->dim();
402 localOffset_ = l_spmdSpace->localOffset();
403 localSubDim_ = l_spmdSpace->localSubDim();
404 }
405 else {
406 globalDim_ = 0;
407 localOffset_ = -1;
408 localSubDim_ = 0;
409 }
410 }
411}
412
413
414// private
415
416
417template<class Scalar>
419{
420 const Range1D rng = Teuchos::full_range(rng_in,0,globalDim_-1);
421#ifdef TEUCHOS_DEBUG
423 !(0 <= rng.lbound() && rng.ubound() < globalDim_), std::invalid_argument
424 ,"SpmdVectorDefaultBase<Scalar>::validateRange(...): Error, the range ["
425 <<rng.lbound()<<","<<rng.ubound()<<"] is not "
426 "in the range [0,"<<(globalDim_-1)<<"]!"
427 );
428#endif
429 return rng;
430}
431
432
433#ifdef THYRA_SPMD_VECTOR_BASE_DUMP
434template<class Scalar>
435bool SpmdVectorDefaultBase<Scalar>::show_dump = false;
436#endif // THYRA_SPMD_VECTOR_BASE_DUMP
437
438
439} // end namespace Thyra
440
441
442#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
const Ptr< T > ptr() 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()