|
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_SPMD_MULTI_VECTOR_DEF_HPP 00030 #define THYRA_DEFAULT_SPMD_MULTI_VECTOR_DEF_HPP 00031 00032 // Define to make some verbose output 00033 //#define THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT 00034 00035 #include "Thyra_DefaultSpmdMultiVector_decl.hpp" 00036 #include "Thyra_SpmdMultiVectorBase.hpp" 00037 #include "Thyra_VectorSpaceFactoryBase.hpp" 00038 #include "Thyra_DefaultSpmdVector.hpp" 00039 #include "Teuchos_Assert.hpp" 00040 00041 00042 namespace Thyra { 00043 00044 00045 // 00046 // Simple utility class to copy back multi-vector entries 00047 // 00048 // ToDo: Refactor above to not use raw pointers! 00049 // 00050 template<class Scalar> 00051 class CopyBackSpmdMultiVectorEntries { 00052 public: 00053 CopyBackSpmdMultiVectorEntries( 00054 const ArrayView<const int> &cols, 00055 const ArrayRCP<const Scalar> &localValuesView, const Ordinal localSubDim, 00056 const ArrayRCP<Scalar> &localValues, const Ordinal leadingDim 00057 ) 00058 : cols_(cols), localValuesView_(localValuesView), localSubDim_(localSubDim), 00059 localValues_(localValues), leadingDim_(leadingDim) 00060 {} 00061 ~CopyBackSpmdMultiVectorEntries() 00062 { 00063 typedef typename ArrayRCP<const Scalar>::const_iterator const_itr_t; 00064 typedef typename ArrayRCP<Scalar>::iterator itr_t; 00065 // Copy from contiguous storage column by column 00066 if (localValues_.strong_count()) { 00067 const int numCols = cols_.size(); 00068 const const_itr_t lvv = localValuesView_.begin(); 00069 const itr_t lv = localValues_.begin(); 00070 for (int k = 0; k < numCols; ++k) { 00071 const int col_k = cols_[k]; 00072 const const_itr_t lvv_k = lvv + localSubDim_*k; 00073 const itr_t lv_k = lv + leadingDim_*col_k; 00074 std::copy( lvv_k, lvv_k + localSubDim_, lv_k ); 00075 } 00076 } 00077 #ifdef THYRA_DEBUG 00078 else { 00079 ++DefaultSpmdMultiVector<Scalar>::numSkipCopyBack; 00080 } 00081 #endif // THYRA_DEBUG 00082 } 00083 private: 00084 Array<int> cols_; 00085 ArrayRCP<const Scalar> localValuesView_; 00086 Ordinal localSubDim_; 00087 ArrayRCP<Scalar> localValues_; 00088 Ordinal leadingDim_; 00089 // Not defined and not to be called 00090 CopyBackSpmdMultiVectorEntries(); 00091 CopyBackSpmdMultiVectorEntries(const CopyBackSpmdMultiVectorEntries&); 00092 CopyBackSpmdMultiVectorEntries& operator=(const CopyBackSpmdMultiVectorEntries&); 00093 }; 00094 00095 00096 template<class Scalar> 00097 RCP<CopyBackSpmdMultiVectorEntries<Scalar> > 00098 copyBackSpmdMultiVectorEntries( 00099 const ArrayView<const int> &cols, 00100 const ArrayRCP<const Scalar> &localValuesView, const Ordinal localSubDim, 00101 const ArrayRCP<Scalar> &localValues, const Ordinal leadingDim 00102 ) 00103 { 00104 return Teuchos::rcp( 00105 new CopyBackSpmdMultiVectorEntries<Scalar>( 00106 cols, localValuesView, localSubDim, localValues, leadingDim 00107 ) 00108 ); 00109 } 00110 00111 00112 // 00113 // DefaultSpmdMultiVector 00114 // 00115 00116 00117 #ifdef THYRA_DEBUG 00118 template<class Scalar> 00119 int DefaultSpmdMultiVector<Scalar>::numSkipCopyBack(0); 00120 #endif 00121 00122 00123 // Constructors/initializers/accessors 00124 00125 00126 template<class Scalar> 00127 DefaultSpmdMultiVector<Scalar>::DefaultSpmdMultiVector() 00128 :leadingDim_(0) 00129 {} 00130 00131 00132 template<class Scalar> 00133 DefaultSpmdMultiVector<Scalar>::DefaultSpmdMultiVector( 00134 const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace 00135 ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace 00136 ) 00137 { 00138 initialize(spmdRangeSpace,domainSpace); 00139 } 00140 00141 00142 template<class Scalar> 00143 DefaultSpmdMultiVector<Scalar>::DefaultSpmdMultiVector( 00144 const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace 00145 ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace 00146 ,const ArrayRCP<Scalar> &localValues 00147 ,const Ordinal leadingDim 00148 ) 00149 { 00150 initialize(spmdRangeSpace,domainSpace,localValues,leadingDim); 00151 } 00152 00153 00154 template<class Scalar> 00155 void DefaultSpmdMultiVector<Scalar>::initialize( 00156 const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace 00157 ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace 00158 ) 00159 { 00160 const Ordinal localSubDim = spmdRangeSpace->localSubDim(); 00161 ArrayRCP<Scalar> values; 00162 if (localSubDim) 00163 values = Teuchos::arcp<Scalar>(localSubDim * domainSpace->dim()); 00164 initialize(spmdRangeSpace, domainSpace, values, localSubDim); 00165 } 00166 00167 00168 template<class Scalar> 00169 void DefaultSpmdMultiVector<Scalar>::initialize( 00170 const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace, 00171 const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace, 00172 const ArrayRCP<Scalar> &localValues, 00173 const Ordinal leadingDim_in 00174 ) 00175 { 00176 const Ordinal leadingDim = 00177 (leadingDim_in >= 0 ? leadingDim_in : spmdRangeSpace->localSubDim()); 00178 #ifdef TEUCHOS_DEBUG 00179 TEUCHOS_ASSERT(!is_null(spmdRangeSpace)); 00180 TEUCHOS_ASSERT(!is_null(domainSpace)); 00181 if (spmdRangeSpace->dim()) { 00182 TEUCHOS_ASSERT(!is_null(localValues)); 00183 } 00184 TEUCHOS_ASSERT_INEQUALITY(leadingDim, >=, spmdRangeSpace->localSubDim()); 00185 #endif 00186 spmdRangeSpace_ = spmdRangeSpace; 00187 domainSpace_ = domainSpace; 00188 localValues_ = localValues; 00189 leadingDim_ = leadingDim; 00190 this->updateSpmdSpace(); 00191 } 00192 00193 00194 template<class Scalar> 00195 void DefaultSpmdMultiVector<Scalar>::uninitialize( 00196 RCP<const SpmdVectorSpaceBase<Scalar> > *spmdRangeSpace 00197 ,RCP<const ScalarProdVectorSpaceBase<Scalar> > *domainSpace 00198 ,ArrayRCP<Scalar> *localValues 00199 ,Ordinal *leadingDim 00200 ) 00201 { 00202 if(spmdRangeSpace) *spmdRangeSpace = spmdRangeSpace_; 00203 if(domainSpace) *domainSpace = domainSpace_; 00204 if(localValues) *localValues = localValues_; 00205 if(leadingDim) *leadingDim = leadingDim_; 00206 00207 spmdRangeSpace_ = Teuchos::null; 00208 domainSpace_ = Teuchos::null; 00209 localValues_ = Teuchos::null; 00210 leadingDim_ = 0; 00211 00212 this->updateSpmdSpace(); 00213 } 00214 00215 00216 template<class Scalar> 00217 RCP< const ScalarProdVectorSpaceBase<Scalar> > 00218 DefaultSpmdMultiVector<Scalar>::domainScalarProdVecSpc() const 00219 { 00220 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT 00221 std::cerr << "\nSpmdMultiVectorStd<Scalar>::domainScalarProdVecSpc() const called!\n"; 00222 #endif 00223 return domainSpace_; 00224 } 00225 00226 00227 // Overridden public functions from SpmdMultiVectorBase 00228 00229 00230 template<class Scalar> 00231 RCP<const SpmdVectorSpaceBase<Scalar> > 00232 DefaultSpmdMultiVector<Scalar>::spmdSpace() const 00233 { 00234 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT 00235 std::cerr << "\nSpmdMultiVectorStd<Scalar>::spmdSpace() const called!\n"; 00236 #endif 00237 return spmdRangeSpace_; 00238 } 00239 00240 00241 // Overridden protected functions from MultiVectorBase 00242 00243 00244 template<class Scalar> 00245 RCP<VectorBase<Scalar> > 00246 DefaultSpmdMultiVector<Scalar>::nonconstColImpl(Ordinal j) 00247 { 00248 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT 00249 std::cerr << "\nSpmdMultiVectorStd<Scalar>::col() called!\n"; 00250 #endif 00251 #ifdef TEUCHOS_DEBUG 00252 TEST_FOR_EXCEPT( !( 0 <= j && j < this->domain()->dim() ) ); 00253 #endif 00254 return Teuchos::rcp( 00255 new DefaultSpmdVector<Scalar>( 00256 spmdRangeSpace_, 00257 localValues_.persistingView(j*leadingDim_,spmdRangeSpace_->localSubDim()), 00258 1 00259 ) 00260 ); 00261 //return Teuchos::rcp(new DefaultVectorMultiVector<Scalar>(subView(Range1D(j,j)))); 00262 } 00263 00264 00265 template<class Scalar> 00266 RCP<const MultiVectorBase<Scalar> > 00267 DefaultSpmdMultiVector<Scalar>::contigSubViewImpl( 00268 const Range1D& col_rng_in 00269 ) const 00270 { 00271 const Range1D colRng = this->validateColRange(col_rng_in); 00272 return Teuchos::rcp( 00273 new DefaultSpmdMultiVector<Scalar>( 00274 spmdRangeSpace_, 00275 Teuchos::rcp_dynamic_cast<const ScalarProdVectorSpaceBase<Scalar> >( 00276 spmdRangeSpace_->smallVecSpcFcty()->createVecSpc(colRng.size()) 00277 ,true 00278 ), 00279 localValues_.persistingView(colRng.lbound()*leadingDim_,colRng.size()*spmdRangeSpace_->localSubDim()), 00280 leadingDim_ 00281 ) 00282 ); 00283 } 00284 00285 00286 template<class Scalar> 00287 RCP<MultiVectorBase<Scalar> > 00288 DefaultSpmdMultiVector<Scalar>::nonconstContigSubViewImpl( 00289 const Range1D& col_rng_in 00290 ) 00291 { 00292 return Teuchos::rcp_const_cast<MultiVectorBase<Scalar> >( 00293 this->contigSubViewImpl(col_rng_in)); 00294 // Have the nonconst version call the const version. Note that in this case 00295 // we just need to take the const off of the returned MultiVectorBase object 00296 // because the localValues is already handled as nonconst. This is the 00297 // perfect instance where the advice in Item 3 in "Effective C++ 3rd 00298 // edition" where Scott Meyers recommends having the nonconst version call 00299 // the const version. 00300 } 00301 00302 00303 template<class Scalar> 00304 RCP<const MultiVectorBase<Scalar> > 00305 DefaultSpmdMultiVector<Scalar>::nonContigSubViewImpl( 00306 const ArrayView<const int> &cols 00307 ) const 00308 { 00309 THYRA_DEBUG_ASSERT_MV_COLS("nonContigSubViewImpl(cols)", cols); 00310 const int numCols = cols.size(); 00311 const ArrayRCP<Scalar> localValuesView = createContiguousCopy(cols); 00312 return defaultSpmdMultiVector<Scalar>( 00313 spmdRangeSpace_, 00314 createSmallScalarProdVectorSpaceBase<Scalar>(spmdRangeSpace_, numCols), 00315 localValuesView 00316 ); 00317 } 00318 00319 00320 template<class Scalar> 00321 RCP<MultiVectorBase<Scalar> > 00322 DefaultSpmdMultiVector<Scalar>::nonconstNonContigSubViewImpl( 00323 const ArrayView<const int> &cols ) 00324 { 00325 THYRA_DEBUG_ASSERT_MV_COLS("nonContigSubViewImpl(cols)", cols); 00326 const int numCols = cols.size(); 00327 const ArrayRCP<Scalar> localValuesView = createContiguousCopy(cols); 00328 const Ordinal localSubDim = spmdRangeSpace_->localSubDim(); 00329 RCP<CopyBackSpmdMultiVectorEntries<Scalar> > copyBackView = 00330 copyBackSpmdMultiVectorEntries<Scalar>(cols, localValuesView.getConst(), 00331 localSubDim, localValues_.create_weak(), leadingDim_); 00332 return Teuchos::rcpWithEmbeddedObjPreDestroy( 00333 new DefaultSpmdMultiVector<Scalar>( 00334 spmdRangeSpace_, 00335 createSmallScalarProdVectorSpaceBase<Scalar>(spmdRangeSpace_, numCols), 00336 localValuesView), 00337 copyBackView 00338 ); 00339 } 00340 00341 00342 // Overridden protected members from SpmdMultiVectorBase 00343 00344 00345 template<class Scalar> 00346 void DefaultSpmdMultiVector<Scalar>::getNonconstLocalDataImpl( 00347 const Ptr<ArrayRCP<Scalar> > &localValues, const Ptr<Ordinal> &leadingDim 00348 ) 00349 { 00350 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT 00351 std::cerr << "\nSpmdMultiVectorStd<Scalar>::getLocalDataImpl() called!\n"; 00352 #endif 00353 *localValues = localValues_; 00354 *leadingDim = leadingDim_; 00355 } 00356 00357 00358 template<class Scalar> 00359 void DefaultSpmdMultiVector<Scalar>::getLocalDataImpl( 00360 const Ptr<ArrayRCP<const Scalar> > &localValues, const Ptr<Ordinal> &leadingDim 00361 ) const 00362 { 00363 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT 00364 std::cerr << "\nSpmdMultiVectorStd<Scalar>::getLocalData() called!\n"; 00365 #endif 00366 *localValues = localValues_; 00367 *leadingDim = leadingDim_; 00368 } 00369 00370 00371 // private 00372 00373 00374 template<class Scalar> 00375 ArrayRCP<Scalar> 00376 DefaultSpmdMultiVector<Scalar>::createContiguousCopy( 00377 const ArrayView<const int> &cols ) const 00378 { 00379 typedef typename ArrayRCP<Scalar>::const_iterator const_itr_t; 00380 typedef typename ArrayRCP<Scalar>::iterator itr_t; 00381 const int numCols = cols.size(); 00382 const Ordinal localSubDim = spmdRangeSpace_->localSubDim(); 00383 ArrayRCP<Scalar> localValuesView = Teuchos::arcp<Scalar>(numCols*localSubDim); 00384 // Copy to contiguous storage column by column 00385 const const_itr_t lv = localValues_.begin(); 00386 const itr_t lvv = localValuesView.begin(); 00387 for (int k = 0; k < numCols; ++k) { 00388 const int col_k = cols[k]; 00389 const const_itr_t lv_k = lv + leadingDim_*col_k; 00390 const itr_t lvv_k = lvv + localSubDim*k; 00391 std::copy(lv_k, lv_k+localSubDim, lvv_k); 00392 } 00393 return localValuesView; 00394 } 00395 00396 00397 } // end namespace Thyra 00398 00399 00400 #endif // THYRA_DEFAULT_SPMD_MULTI_VECTOR_DEF_HPP
1.7.4