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 //
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_CLUSTERED_SPMD_PRODUCT_VECTOR_SPACE_HPP
43 #define THYRA_DEFAULT_CLUSTERED_SPMD_PRODUCT_VECTOR_SPACE_HPP
44 
45 #include "Thyra_DefaultClusteredSpmdProductVectorSpace_decl.hpp"
46 #include "Thyra_SpmdVectorSpaceBase.hpp"
47 #include "Thyra_DefaultClusteredSpmdProductVector.hpp"
48 #include "Thyra_VectorSpaceDefaultBase.hpp"
49 #include "Thyra_VectorStdOps.hpp"
50 #include "Thyra_MultiVectorStdOps.hpp"
51 #include "Thyra_SpmdVectorSpaceUtilities.hpp"
52 #include "Teuchos_implicit_cast.hpp"
53 #include "Teuchos_CommHelpers.hpp"
54 
55 namespace Thyra {
56 
57 // Constructors/Intializers/Accessors
58 
59 template<class Scalar>
61  :clusterRootRank_(-1), isEuclidean_(false), globalDim_(0), clusterSubDim_(-1),
62  clusterOffset_(-1)
63 {}
64 
65 template<class Scalar>
67  const Teuchos::RCP<const Teuchos::Comm<Ordinal> > &intraClusterComm_in
68  ,const int clusterRootRank_in
69  ,const Teuchos::RCP<const Teuchos::Comm<Ordinal> > &interClusterComm_in
70  ,const int numBlocks_in
71  ,const Teuchos::RCP<const VectorSpaceBase<Scalar> > vecSpaces[]
72  ):
73  globalDim_(0),
74  clusterOffset_(-1)
75 {
76  initialize(intraClusterComm_in,clusterRootRank_in,interClusterComm_in,numBlocks_in,vecSpaces);
77 }
78 
79 template<class Scalar>
81  const Teuchos::RCP<const Teuchos::Comm<Ordinal> > &intraClusterComm_in
82  ,const int clusterRootRank_in
83  ,const Teuchos::RCP<const Teuchos::Comm<Ordinal> > &interClusterComm_in
84  ,const int numBlocks_in
85  ,const Teuchos::RCP<const VectorSpaceBase<Scalar> > vecSpaces[]
86  )
87 {
88  // Set state
89  intraClusterComm_ = intraClusterComm_in.assert_not_null();
90  clusterRootRank_ = clusterRootRank_in;
91  interClusterComm_ = interClusterComm_in; // This can be NULL!
92  vecSpaces_.resize(numBlocks_in);
93  isEuclidean_ = true;
94  Ordinal l_clusterSubDim = 0;
95  for( int k = 0; k < numBlocks_in; ++k ) {
96  l_clusterSubDim += vecSpaces[k]->dim();
97  if(!vecSpaces[k]->isEuclidean())
98  isEuclidean_ = false;
99  vecSpaces_[k] = vecSpaces[k];
100  }
101  // We must compute the offsets between clusters and the global dimension by
102  // only involving the root process in each cluster.
103  if(interClusterComm_.get()) {
104  clusterOffset_ = SpmdVectorSpaceUtilities::computeLocalOffset(
105  *interClusterComm_,l_clusterSubDim
106  );
107  globalDim_ = SpmdVectorSpaceUtilities::computeGlobalDim(
108  *interClusterComm_,l_clusterSubDim
109  );
110  }
111  // Here must then broadcast the values to all processes within each cluster.
112  {
113  const Ordinal num = 2;
114  Ordinal buff[num] = { clusterOffset_, globalDim_ };
115  Teuchos::broadcast<Ordinal>(*intraClusterComm_, clusterRootRank_, num, &buff[0]);
116  clusterOffset_ = buff[0];
117  globalDim_ = buff[1];
118 
119  }
120  //
121  clusterSubDim_ = l_clusterSubDim;
122  // ToDo: Do a global communication across all clusters to see if all vector
123  // spaces are all Euclidean. It is unlikely to be the case where all of the
124  // clusters do not have the same vector spaces so I do not think this will
125  // even come up. But just in case, we should keep this in mind!
126 }
127 
128 // Overridden form Teuchos::Describable
129 
130 template<class Scalar>
132 {
133  std::ostringstream oss;
134  oss << "DefaultClusteredSpmdProductVectorSpace{";
135  oss << "numBlocks="<<vecSpaces_.size();
136  oss << ",globalDim="<<globalDim_;
137  oss << ",clusterOffset="<<clusterOffset_;
138  oss << "}";
139  return oss.str();
140 }
141 
142 // Public overridden from VectorSpaceBase
143 
144 template<class Scalar>
146 {
147  return globalDim_;
148 }
149 
150 template<class Scalar>
152  const VectorSpaceBase<Scalar>& vecSpc
153  ) const
154 {
156  if (&vecSpc==this) {
157  return true;
158  }
159  const Ptr<const DCSPVS> dcspvs =
160  Teuchos::ptr_dynamic_cast<const DCSPVS>(Teuchos::ptrFromRef(vecSpc), false);
161  if (is_null(dcspvs)) {
162  return false;
163  }
164  if (vecSpaces_.size() != dcspvs->vecSpaces_.size()) {
165  return false;
166  }
167  const int l_numBlocks = vecSpaces_.size();
168  for( int k = 0; k < l_numBlocks; ++k ) {
169  if (!vecSpaces_[k]->isCompatible(*dcspvs->vecSpaces_[k])) {
170  return false;
171  }
172  }
173  return true;
174 }
175 
176 template<class Scalar>
179 {
180  if(!vecSpaces_.size())
181  return Teuchos::null;
182  return vecSpaces_[0]->smallVecSpcFcty();
183 }
184 
185 template<class Scalar>
187  const VectorBase<Scalar>& x, const VectorBase<Scalar>& y
188  ) const
189 {
190  Teuchos::Tuple<Scalar,1> scalarProds_out;
191  this->scalarProds(x, y, scalarProds_out());
192  return scalarProds_out[0];
193 }
194 
195 template<class Scalar>
198  const ArrayView<Scalar> &scalarProds_out ) const
199 {
201  !isEuclidean_, std::logic_error
202  ,"Error, have not implemented support for none Euclidean scalar products yet!"
203  );
204  return dots(X, Y, scalarProds_out);
205  // ToDo:
206  // * Create DefaultClusteredSpmdProductMultiVector subclass
207  // * Cast X and Y this type
208  // * Accumulate the scalar products across all of the blocks in this cluster
209  // * Accumulate the full scalar products across all of the clusters
210  // using *interClusterComm
211  // * Broadcast the final scalar products to all of the processes in
212  // a cluster using *intraClusterComm
213 }
214 
215 template<class Scalar>
217 {
218  return isEuclidean_;
219 }
220 
221 template<class Scalar>
223  const Range1D& /* rng */, const EViewType /* viewType */, const EStrideType /* strideType */
224  ) const
225 {
226  return false; // ToDo: Figure this out for real!
227 }
228 
229 template<class Scalar>
232 {
234 }
235 
236 // Protected overridden from ProductVectorSpaceBase
237 
238 template<class Scalar>
240 {
241  return vecSpaces_.size();
242 }
243 
244 template<class Scalar>
247 {
249  TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= k && k < implicit_cast<int>(vecSpaces_.size()) ) );
250  return vecSpaces_[k];
251 }
252 
253 // Protected overridden from VectorSpaceBase
254 
255 template<class Scalar>
258 {
259  using Teuchos::rcp;
260  return rcp(new DefaultClusteredSpmdProductVector<Scalar>(rcp(this,false),NULL));
261 }
262 
263 template<class Scalar>
266 {
268  // ToDo: Provide an optimized multi-vector implementation when needed!
269 }
270 
271 } // end namespace Thyra
272 
273 #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)