Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
23 namespace Thyra {
24 
25 // Constructors/Intializers/Accessors
26 
27 template<class Scalar>
29  :clusterRootRank_(-1), isEuclidean_(false), globalDim_(0), clusterSubDim_(-1),
30  clusterOffset_(-1)
31 {}
32 
33 template<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 
47 template<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 
98 template<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 
112 template<class Scalar>
114 {
115  return globalDim_;
116 }
117 
118 template<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 
144 template<class Scalar>
147 {
148  if(!vecSpaces_.size())
149  return Teuchos::null;
150  return vecSpaces_[0]->smallVecSpcFcty();
151 }
152 
153 template<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 
163 template<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 
183 template<class Scalar>
185 {
186  return isEuclidean_;
187 }
188 
189 template<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 
197 template<class Scalar>
200 {
202 }
203 
204 // Protected overridden from ProductVectorSpaceBase
205 
206 template<class Scalar>
208 {
209  return vecSpaces_.size();
210 }
211 
212 template<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 
223 template<class Scalar>
226 {
227  using Teuchos::rcp;
228  return rcp(new DefaultClusteredSpmdProductVector<Scalar>(rcp(this,false),NULL));
229 }
230 
231 template<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
bool is_null(const boost::shared_ptr< T > &p)
bool isCompatible(const VectorSpaceBase< Scalar > &vecSpc) const
Scalar scalarProd(const VectorBase< Scalar > &x, const VectorBase< Scalar > &y) const
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
RCP< const VectorSpaceBase< Scalar > > getBlock(const int k) const
Abstract interface for objects that represent a space for vectors.
RCP< const VectorSpaceFactoryBase< Scalar > > smallVecSpcFcty() const
EViewType
Determines if a view is a direct view of data or a detached copy of data.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
Interface for a collection of column vectors called a multi-vector.
RCP< MultiVectorBase< Scalar > > createMembers(int numMembers) const
Concrete implementation of a clustered Spmd-based product vector.
TypeTo implicit_cast(const TypeFrom &t)
Abstract interface for finite-dimensional dense vectors.
RCP< MultiVectorBase< Scalar > > createMembers(int numMembers) 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.
EStrideType
Determine if data is unit stride or non-unit stride.
bool hasInCoreView(const Range1D &rng, const EViewType viewType, const EStrideType strideType) const
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)