|
Thyra Package Browser (Single Doxygen Collection) Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Thyra: Interfaces and Support for Abstract Numerical Algorithms 00005 // Copyright (2004) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 00029 #ifndef THYRA_DEFAULT_CLUSTERED_SPMD_PRODUCT_VECTOR_SPACE_HPP 00030 #define THYRA_DEFAULT_CLUSTERED_SPMD_PRODUCT_VECTOR_SPACE_HPP 00031 00032 #include "Thyra_DefaultClusteredSpmdProductVectorSpace_decl.hpp" 00033 #include "Thyra_SpmdVectorSpaceBase.hpp" 00034 #include "Thyra_DefaultClusteredSpmdProductVector.hpp" 00035 #include "Thyra_VectorSpaceDefaultBase.hpp" 00036 #include "Thyra_VectorStdOps.hpp" 00037 #include "Thyra_MultiVectorStdOps.hpp" 00038 #include "Thyra_SpmdVectorSpaceUtilities.hpp" 00039 #include "Teuchos_implicit_cast.hpp" 00040 #include "Teuchos_CommHelpers.hpp" 00041 00042 namespace Thyra { 00043 00044 // Constructors/Intializers/Accessors 00045 00046 template<class Scalar> 00047 DefaultClusteredSpmdProductVectorSpace<Scalar>::DefaultClusteredSpmdProductVectorSpace() 00048 :isEuclidean_(false),globalDim_(0),clusterSubDim_(-1),clusterOffset_(-1) 00049 {} 00050 00051 template<class Scalar> 00052 DefaultClusteredSpmdProductVectorSpace<Scalar>::DefaultClusteredSpmdProductVectorSpace( 00053 const Teuchos::RCP<const Teuchos::Comm<Ordinal> > &intraClusterComm_in 00054 ,const int clusterRootRank_in 00055 ,const Teuchos::RCP<const Teuchos::Comm<Ordinal> > &interClusterComm_in 00056 ,const int numBlocks_in 00057 ,const Teuchos::RCP<const VectorSpaceBase<Scalar> > vecSpaces[] 00058 ) 00059 { 00060 initialize(intraClusterComm_in,clusterRootRank_in,interClusterComm_in,numBlocks_in,vecSpaces); 00061 } 00062 00063 template<class Scalar> 00064 void DefaultClusteredSpmdProductVectorSpace<Scalar>::initialize( 00065 const Teuchos::RCP<const Teuchos::Comm<Ordinal> > &intraClusterComm_in 00066 ,const int clusterRootRank_in 00067 ,const Teuchos::RCP<const Teuchos::Comm<Ordinal> > &interClusterComm_in 00068 ,const int numBlocks_in 00069 ,const Teuchos::RCP<const VectorSpaceBase<Scalar> > vecSpaces[] 00070 ) 00071 { 00072 // Set state 00073 intraClusterComm_ = intraClusterComm_in.assert_not_null(); 00074 clusterRootRank_ = clusterRootRank_in; 00075 interClusterComm_ = interClusterComm_in; // This can be NULL! 00076 vecSpaces_.resize(numBlocks_in); 00077 isEuclidean_ = true; 00078 Ordinal l_clusterSubDim = 0; 00079 for( int k = 0; k < numBlocks_in; ++k ) { 00080 l_clusterSubDim += vecSpaces[k]->dim(); 00081 if(!vecSpaces[k]->isEuclidean()) 00082 isEuclidean_ = false; 00083 vecSpaces_[k] = vecSpaces[k]; 00084 } 00085 // We must compute the offsets between clusters and the global dimension by 00086 // only involving the root process in each cluster. 00087 if(interClusterComm_.get()) { 00088 clusterOffset_ = SpmdVectorSpaceUtilities::computeLocalOffset( 00089 *interClusterComm_,l_clusterSubDim 00090 ); 00091 globalDim_ = SpmdVectorSpaceUtilities::computeGlobalDim( 00092 *interClusterComm_,l_clusterSubDim 00093 ); 00094 } 00095 // Here must then broadcast the values to all processes within each cluster. 00096 { 00097 const Ordinal num = 2; 00098 Ordinal buff[num] = { clusterOffset_, globalDim_ }; 00099 Teuchos::broadcast<Ordinal>(*intraClusterComm_, clusterRootRank_, num, &buff[0]); 00100 clusterOffset_ = buff[0]; 00101 globalDim_ = buff[1]; 00102 00103 } 00104 // 00105 clusterSubDim_ = l_clusterSubDim; 00106 // ToDo: Do a global communication across all clusters to see if all vector 00107 // spaces are all Euclidean. It is unlikely to be the case where all of the 00108 // clusters do not have the same vector spaces so I do not think this will 00109 // even come up. But just in case, we should keep this in mind! 00110 } 00111 00112 // Overridden form Teuchos::Describable 00113 00114 template<class Scalar> 00115 std::string DefaultClusteredSpmdProductVectorSpace<Scalar>::description() const 00116 { 00117 std::ostringstream oss; 00118 oss << "DefaultClusteredSpmdProductVectorSpace{"; 00119 oss << "numBlocks="<<vecSpaces_.size(); 00120 oss << ",globalDim="<<globalDim_; 00121 oss << ",clusterOffset="<<clusterOffset_; 00122 oss << "}"; 00123 return oss.str(); 00124 } 00125 00126 // Public overridden from VectorSpaceBase 00127 00128 template<class Scalar> 00129 Ordinal DefaultClusteredSpmdProductVectorSpace<Scalar>::dim() const 00130 { 00131 return globalDim_; 00132 } 00133 00134 template<class Scalar> 00135 bool DefaultClusteredSpmdProductVectorSpace<Scalar>::isCompatible( 00136 const VectorSpaceBase<Scalar>& vecSpc 00137 ) const 00138 { 00139 if( &vecSpc == this ) 00140 return true; 00141 // For now, I will just do the dynamic cast but in the future, we could get 00142 // more sophisticated. 00143 TEST_FOR_EXCEPT(true); 00144 return false; 00145 } 00146 00147 template<class Scalar> 00148 Teuchos::RCP< const VectorSpaceFactoryBase<Scalar> > 00149 DefaultClusteredSpmdProductVectorSpace<Scalar>::smallVecSpcFcty() const 00150 { 00151 if(!vecSpaces_.size()) 00152 return Teuchos::null; 00153 return vecSpaces_[0]->smallVecSpcFcty(); 00154 } 00155 00156 template<class Scalar> 00157 Scalar DefaultClusteredSpmdProductVectorSpace<Scalar>::scalarProd( 00158 const VectorBase<Scalar>& x, const VectorBase<Scalar>& y 00159 ) const 00160 { 00161 Scalar scalarProds_out[1]; 00162 this->scalarProds(x, y, &scalarProds_out[0]); 00163 return scalarProds_out[0]; 00164 } 00165 00166 template<class Scalar> 00167 void DefaultClusteredSpmdProductVectorSpace<Scalar>::scalarProdsImpl( 00168 const MultiVectorBase<Scalar>& X, const MultiVectorBase<Scalar>& Y, 00169 const ArrayView<Scalar> &scalarProds_out ) const 00170 { 00171 TEST_FOR_EXCEPTION( 00172 !isEuclidean_, std::logic_error 00173 ,"Error, have not implemented support for none Euclidean scalar products yet!" 00174 ); 00175 return dots(X, Y, scalarProds_out); 00176 // ToDo: 00177 // * Create DefaultClusteredSpmdProductMultiVector subclass 00178 // * Cast X and Y this type 00179 // * Accumulate the scalar products across all of the blocks in this cluster 00180 // * Accumulate the full scalar products across all of the clusters 00181 // using *interClusterComm 00182 // * Broadcast the final scalar products to all of the processes in 00183 // a cluster using *intraClusterComm 00184 } 00185 00186 template<class Scalar> 00187 bool DefaultClusteredSpmdProductVectorSpace<Scalar>::isEuclidean() const 00188 { 00189 return isEuclidean_; 00190 } 00191 00192 template<class Scalar> 00193 bool DefaultClusteredSpmdProductVectorSpace<Scalar>::hasInCoreView( 00194 const Range1D& rng, const EViewType viewType, const EStrideType strideType 00195 ) const 00196 { 00197 return false; // ToDo: Figure this out for real! 00198 } 00199 00200 template<class Scalar> 00201 Teuchos::RCP< const VectorSpaceBase<Scalar> > 00202 DefaultClusteredSpmdProductVectorSpace<Scalar>::clone() const 00203 { 00204 return Teuchos::rcp(new DefaultClusteredSpmdProductVectorSpace<Scalar>(*this)); 00205 } 00206 00207 // Protected overridden from ProductVectorSpaceBase 00208 00209 template<class Scalar> 00210 int DefaultClusteredSpmdProductVectorSpace<Scalar>::numBlocks() const 00211 { 00212 return vecSpaces_.size(); 00213 } 00214 00215 template<class Scalar> 00216 Teuchos::RCP<const VectorSpaceBase<Scalar> > 00217 DefaultClusteredSpmdProductVectorSpace<Scalar>::getBlock(const int k) const 00218 { 00219 using Teuchos::implicit_cast; 00220 TEST_FOR_EXCEPT( !( 0 <= k && k < implicit_cast<int>(vecSpaces_.size()) ) ); 00221 return vecSpaces_[k]; 00222 } 00223 00224 // Protected overridden from VectorSpaceBase 00225 00226 template<class Scalar> 00227 Teuchos::RCP<VectorBase<Scalar> > 00228 DefaultClusteredSpmdProductVectorSpace<Scalar>::createMember() const 00229 { 00230 using Teuchos::rcp; 00231 return rcp(new DefaultClusteredSpmdProductVector<Scalar>(rcp(this,false),NULL)); 00232 } 00233 00234 template<class Scalar> 00235 Teuchos::RCP<MultiVectorBase<Scalar> > 00236 DefaultClusteredSpmdProductVectorSpace<Scalar>::createMembers(int numMembers) const 00237 { 00238 return VectorSpaceDefaultBase<Scalar>::createMembers(numMembers); 00239 // ToDo: Provide an optimized multi-vector implementation when needed! 00240 } 00241 00242 } // end namespace Thyra 00243 00244 #endif // THYRA_DEFAULT_CLUSTERED_SPMD_PRODUCT_VECTOR_SPACE_HPP
1.7.4