Thyra Version of the Day
Loading...
Searching...
No Matches
Thyra_DefaultClusteredSpmdProductVectorSpace_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_CLUSTERED_SPMD_PRODUCT_VECTOR_SPACE_HPP
11#define THYRA_DEFAULT_CLUSTERED_SPMD_PRODUCT_VECTOR_SPACE_HPP
12
13#include "Thyra_DefaultClusteredSpmdProductVectorSpace_decl.hpp"
14#include "Thyra_SpmdVectorSpaceBase.hpp"
15#include "Thyra_DefaultClusteredSpmdProductVector.hpp"
16#include "Thyra_VectorSpaceDefaultBase.hpp"
17#include "Thyra_VectorStdOps.hpp"
18#include "Thyra_MultiVectorStdOps.hpp"
19#include "Thyra_SpmdVectorSpaceUtilities.hpp"
20#include "Teuchos_implicit_cast.hpp"
21#include "Teuchos_CommHelpers.hpp"
22
23namespace Thyra {
24
25// Constructors/Intializers/Accessors
26
27template<class Scalar>
29 :clusterRootRank_(-1), isEuclidean_(false), globalDim_(0), clusterSubDim_(-1),
30 clusterOffset_(-1)
31{}
32
33template<class Scalar>
35 const Teuchos::RCP<const Teuchos::Comm<Ordinal> > &intraClusterComm_in
36 ,const int clusterRootRank_in
37 ,const Teuchos::RCP<const Teuchos::Comm<Ordinal> > &interClusterComm_in
38 ,const int numBlocks_in
39 ,const Teuchos::RCP<const VectorSpaceBase<Scalar> > vecSpaces[]
40 ):
41 globalDim_(0),
42 clusterOffset_(-1)
43{
44 initialize(intraClusterComm_in,clusterRootRank_in,interClusterComm_in,numBlocks_in,vecSpaces);
45}
46
47template<class Scalar>
49 const Teuchos::RCP<const Teuchos::Comm<Ordinal> > &intraClusterComm_in
50 ,const int clusterRootRank_in
51 ,const Teuchos::RCP<const Teuchos::Comm<Ordinal> > &interClusterComm_in
52 ,const int numBlocks_in
53 ,const Teuchos::RCP<const VectorSpaceBase<Scalar> > vecSpaces[]
54 )
55{
56 // Set state
57 intraClusterComm_ = intraClusterComm_in.assert_not_null();
58 clusterRootRank_ = clusterRootRank_in;
59 interClusterComm_ = interClusterComm_in; // This can be NULL!
60 vecSpaces_.resize(numBlocks_in);
61 isEuclidean_ = true;
62 Ordinal l_clusterSubDim = 0;
63 for( int k = 0; k < numBlocks_in; ++k ) {
64 l_clusterSubDim += vecSpaces[k]->dim();
65 if(!vecSpaces[k]->isEuclidean())
66 isEuclidean_ = false;
67 vecSpaces_[k] = vecSpaces[k];
68 }
69 // We must compute the offsets between clusters and the global dimension by
70 // only involving the root process in each cluster.
71 if(interClusterComm_.get()) {
72 clusterOffset_ = SpmdVectorSpaceUtilities::computeLocalOffset(
73 *interClusterComm_,l_clusterSubDim
74 );
75 globalDim_ = SpmdVectorSpaceUtilities::computeGlobalDim(
76 *interClusterComm_,l_clusterSubDim
77 );
78 }
79 // Here must then broadcast the values to all processes within each cluster.
80 {
81 const Ordinal num = 2;
82 Ordinal buff[num] = { clusterOffset_, globalDim_ };
83 Teuchos::broadcast<Ordinal>(*intraClusterComm_, clusterRootRank_, num, &buff[0]);
84 clusterOffset_ = buff[0];
85 globalDim_ = buff[1];
86
87 }
88 //
89 clusterSubDim_ = l_clusterSubDim;
90 // ToDo: Do a global communication across all clusters to see if all vector
91 // spaces are all Euclidean. It is unlikely to be the case where all of the
92 // clusters do not have the same vector spaces so I do not think this will
93 // even come up. But just in case, we should keep this in mind!
94}
95
96// Overridden form Teuchos::Describable
97
98template<class Scalar>
100{
101 std::ostringstream oss;
102 oss << "DefaultClusteredSpmdProductVectorSpace{";
103 oss << "numBlocks="<<vecSpaces_.size();
104 oss << ",globalDim="<<globalDim_;
105 oss << ",clusterOffset="<<clusterOffset_;
106 oss << "}";
107 return oss.str();
108}
109
110// Public overridden from VectorSpaceBase
111
112template<class Scalar>
114{
115 return globalDim_;
116}
117
118template<class Scalar>
120 const VectorSpaceBase<Scalar>& vecSpc
121 ) const
122{
124 if (&vecSpc==this) {
125 return true;
126 }
127 const Ptr<const DCSPVS> dcspvs =
128 Teuchos::ptr_dynamic_cast<const DCSPVS>(Teuchos::ptrFromRef(vecSpc), false);
129 if (is_null(dcspvs)) {
130 return false;
131 }
132 if (vecSpaces_.size() != dcspvs->vecSpaces_.size()) {
133 return false;
134 }
135 const int l_numBlocks = vecSpaces_.size();
136 for( int k = 0; k < l_numBlocks; ++k ) {
137 if (!vecSpaces_[k]->isCompatible(*dcspvs->vecSpaces_[k])) {
138 return false;
139 }
140 }
141 return true;
142}
143
144template<class Scalar>
147{
148 if(!vecSpaces_.size())
149 return Teuchos::null;
150 return vecSpaces_[0]->smallVecSpcFcty();
151}
152
153template<class Scalar>
155 const VectorBase<Scalar>& x, const VectorBase<Scalar>& y
156 ) const
157{
158 Teuchos::Tuple<Scalar,1> scalarProds_out;
159 this->scalarProds(x, y, scalarProds_out());
160 return scalarProds_out[0];
161}
162
163template<class Scalar>
166 const ArrayView<Scalar> &scalarProds_out ) const
167{
169 !isEuclidean_, std::logic_error
170 ,"Error, have not implemented support for none Euclidean scalar products yet!"
171 );
172 return dots(X, Y, scalarProds_out);
173 // ToDo:
174 // * Create DefaultClusteredSpmdProductMultiVector subclass
175 // * Cast X and Y this type
176 // * Accumulate the scalar products across all of the blocks in this cluster
177 // * Accumulate the full scalar products across all of the clusters
178 // using *interClusterComm
179 // * Broadcast the final scalar products to all of the processes in
180 // a cluster using *intraClusterComm
181}
182
183template<class Scalar>
185{
186 return isEuclidean_;
187}
188
189template<class Scalar>
191 const Range1D& /* rng */, const EViewType /* viewType */, const EStrideType /* strideType */
192 ) const
193{
194 return false; // ToDo: Figure this out for real!
195}
196
197template<class Scalar>
203
204// Protected overridden from ProductVectorSpaceBase
205
206template<class Scalar>
208{
209 return vecSpaces_.size();
210}
211
212template<class Scalar>
215{
217 TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= k && k < implicit_cast<int>(vecSpaces_.size()) ) );
218 return vecSpaces_[k];
219}
220
221// Protected overridden from VectorSpaceBase
222
223template<class Scalar>
230
231template<class Scalar>
234{
236 // ToDo: Provide an optimized multi-vector implementation when needed!
237}
238
239} // end namespace Thyra
240
241#endif // THYRA_DEFAULT_CLUSTERED_SPMD_PRODUCT_VECTOR_SPACE_HPP
void scalarProdsImpl(const MultiVectorBase< Scalar > &X, const MultiVectorBase< Scalar > &Y, const ArrayView< Scalar > &scalarProds) const
RCP< const VectorSpaceFactoryBase< Scalar > > smallVecSpcFcty() const
void initialize(const RCP< const Teuchos::Comm< Ordinal > > &intraClusterComm, const int clusterRootRank, const RCP< const Teuchos::Comm< Ordinal > > &interClusterComm, const int numBlocks, const RCP< const VectorSpaceBase< Scalar > > vecSpaces[])
Initalize.
Scalar scalarProd(const VectorBase< Scalar > &x, const VectorBase< Scalar > &y) const
RCP< const VectorSpaceBase< Scalar > > getBlock(const int k) const
bool hasInCoreView(const Range1D &rng, const EViewType viewType, const EStrideType strideType) const
RCP< MultiVectorBase< Scalar > > createMembers(int numMembers) const
Concrete implementation of a clustered Spmd-based product vector.
Interface for a collection of column vectors called a multi-vector.
Abstract interface for finite-dimensional dense vectors.
Abstract interface for objects that represent a space for vectors.
RCP< MultiVectorBase< Scalar > > createMembers(int numMembers) const
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
EStrideType
Determine if data is unit stride or non-unit stride.
EViewType
Determines if a view is a direct view of data or a detached copy of data.
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
TypeTo implicit_cast(const TypeFrom &t)
T_To & dyn_cast(T_From &from)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)