00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef THYRA_DEFAULT_SPMD_MULTI_VECTOR_BASE_HPP
00030 #define THYRA_DEFAULT_SPMD_MULTI_VECTOR_BASE_HPP
00031
00032
00033
00034
00035 #include "Thyra_DefaultSpmdMultiVectorDecl.hpp"
00036 #include "Thyra_SpmdMultiVectorBase.hpp"
00037 #include "Thyra_DefaultSpmdVector.hpp"
00038 #include "Teuchos_Assert.hpp"
00039
00040 namespace Thyra {
00041
00042
00043
00044
00045
00046 template<class Scalar>
00047 class CopyBackSpmdMultiVectorEntries {
00048 public:
00049 CopyBackSpmdMultiVectorEntries(
00050 const ArrayView<const int> &cols,
00051 const Scalar *localValuesView, const Index localSubDim,
00052 Scalar *localValues,const Index leadingDim
00053 )
00054 :cols_(cols)
00055 ,localValuesView_(localValuesView),localSubDim_(localSubDim)
00056 ,localValues_(localValues),leadingDim_(leadingDim)
00057 {}
00058 ~CopyBackSpmdMultiVectorEntries()
00059 {
00060
00061
00062 const int numCols = cols_.size();
00063 const Scalar *lvv = &*localValuesView_;
00064 Scalar *lv = &*localValues_;
00065 for( int k = 0; k < numCols; ++k ) {
00066 const int col_k = cols_[k];
00067 const Scalar *lvv_k = lvv + localSubDim_*k;
00068 Scalar *lv_k = lv + leadingDim_*col_k;
00069
00070 std::copy( lvv_k, lvv_k + localSubDim_, lv_k );
00071
00072 }
00073
00074 }
00075 private:
00076 Array<int> cols_;
00077 const Scalar *localValuesView_;
00078 Index localSubDim_;
00079 Scalar *localValues_;
00080 Index leadingDim_;
00081
00082 CopyBackSpmdMultiVectorEntries();
00083 CopyBackSpmdMultiVectorEntries(const CopyBackSpmdMultiVectorEntries&);
00084 CopyBackSpmdMultiVectorEntries& operator=(const CopyBackSpmdMultiVectorEntries&);
00085 };
00086
00087
00088
00089
00090
00091
00092
00093 template<class Scalar>
00094 DefaultSpmdMultiVector<Scalar>::DefaultSpmdMultiVector()
00095 :leadingDim_(0)
00096 {}
00097
00098 template<class Scalar>
00099 DefaultSpmdMultiVector<Scalar>::DefaultSpmdMultiVector(
00100 const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace
00101 ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace
00102 )
00103 {
00104 initialize(spmdRangeSpace,domainSpace);
00105 }
00106
00107 template<class Scalar>
00108 DefaultSpmdMultiVector<Scalar>::DefaultSpmdMultiVector(
00109 const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace
00110 ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace
00111 ,const ArrayRCP<Scalar> &localValues
00112 ,const Index leadingDim
00113 )
00114 {
00115 initialize(spmdRangeSpace,domainSpace,localValues,leadingDim);
00116 }
00117
00118 template<class Scalar>
00119 void DefaultSpmdMultiVector<Scalar>::initialize(
00120 const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace
00121 ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace
00122 )
00123 {
00124 const Index localSubDim = spmdRangeSpace->localSubDim();
00125 ArrayRCP<Scalar> values;
00126 if (localSubDim)
00127 values = Teuchos::arcp<Scalar>(localSubDim * domainSpace->dim());
00128 initialize(spmdRangeSpace, domainSpace, values, localSubDim);
00129 }
00130
00131 template<class Scalar>
00132 void DefaultSpmdMultiVector<Scalar>::initialize(
00133 const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace
00134 ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace
00135 ,const ArrayRCP<Scalar> &localValues
00136 ,const Index leadingDim
00137 )
00138 {
00139 #ifdef TEUCHOS_DEBUG
00140 TEUCHOS_ASSERT(!is_null(spmdRangeSpace));
00141 TEUCHOS_ASSERT(!is_null(domainSpace));
00142 if (spmdRangeSpace->dim()) {
00143 TEUCHOS_ASSERT(!is_null(localValues));
00144 }
00145 TEUCHOS_ASSERT_INEQUALITY(leadingDim, >=, spmdRangeSpace->localSubDim());
00146 #endif
00147 spmdRangeSpace_ = spmdRangeSpace;
00148 domainSpace_ = domainSpace;
00149 localValues_ = localValues;
00150 leadingDim_ = leadingDim;
00151 this->updateSpmdSpace();
00152 }
00153
00154 template<class Scalar>
00155 void DefaultSpmdMultiVector<Scalar>::uninitialize(
00156 RCP<const SpmdVectorSpaceBase<Scalar> > *spmdRangeSpace
00157 ,RCP<const ScalarProdVectorSpaceBase<Scalar> > *domainSpace
00158 ,ArrayRCP<Scalar> *localValues
00159 ,Index *leadingDim
00160 )
00161 {
00162 if(spmdRangeSpace) *spmdRangeSpace = spmdRangeSpace_;
00163 if(domainSpace) *domainSpace = domainSpace_;
00164 if(localValues) *localValues = localValues_;
00165 if(leadingDim) *leadingDim = leadingDim_;
00166
00167 spmdRangeSpace_ = Teuchos::null;
00168 domainSpace_ = Teuchos::null;
00169 localValues_ = Teuchos::null;
00170 leadingDim_ = 0;
00171
00172 this->updateSpmdSpace();
00173 }
00174
00175
00176
00177 template<class Scalar>
00178 RCP< const ScalarProdVectorSpaceBase<Scalar> >
00179 DefaultSpmdMultiVector<Scalar>::domainScalarProdVecSpc() const
00180 {
00181 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00182 std::cerr << "\nSpmdMultiVectorStd<Scalar>::domainScalarProdVecSpc() const called!\n";
00183 #endif
00184 return domainSpace_;
00185 }
00186
00187
00188
00189 template<class Scalar>
00190 RCP<VectorBase<Scalar> >
00191 DefaultSpmdMultiVector<Scalar>::nonconstColImpl(Index j)
00192 {
00193 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00194 std::cerr << "\nSpmdMultiVectorStd<Scalar>::col() called!\n";
00195 #endif
00196 #ifdef TEUCHOS_DEBUG
00197 TEST_FOR_EXCEPT( !( 0 <= j && j < this->domain()->dim() ) );
00198 #endif
00199 return Teuchos::rcp(
00200 new DefaultSpmdVector<Scalar>(
00201 spmdRangeSpace_,
00202 localValues_.persistingView(j*leadingDim_,spmdRangeSpace_->localSubDim()),
00203 1
00204 )
00205 );
00206
00207 }
00208
00209 template<class Scalar>
00210 RCP<MultiVectorBase<Scalar> >
00211 DefaultSpmdMultiVector<Scalar>::nonconstContigSubViewImpl(
00212 const Range1D& col_rng_in
00213 )
00214 {
00215 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00216 std::cerr << "\nSpmdMultiVectorStd<Scalar>::subView() called!\n";
00217 #endif
00218 const Range1D colRng = this->validateColRange(col_rng_in);
00219 return Teuchos::rcp(
00220 new DefaultSpmdMultiVector<Scalar>(
00221 spmdRangeSpace_,
00222 Teuchos::rcp_dynamic_cast<const ScalarProdVectorSpaceBase<Scalar> >(
00223 spmdRangeSpace_->smallVecSpcFcty()->createVecSpc(colRng.size())
00224 ,true
00225 ),
00226 localValues_.persistingView(colRng.lbound()*leadingDim_,colRng.size()*spmdRangeSpace_->localSubDim()),
00227 leadingDim_
00228 )
00229 );
00230 }
00231
00232 template<class Scalar>
00233 RCP<const MultiVectorBase<Scalar> >
00234 DefaultSpmdMultiVector<Scalar>::nonContigSubViewImpl(
00235 const ArrayView<const int> &cols
00236 ) const
00237 {
00238 const int numCols = cols.size();
00239 const ArrayRCP<Scalar> localValuesView = createContiguousCopy(cols);
00240 return
00241 Teuchos::rcp(
00242 new DefaultSpmdMultiVector<Scalar>(
00243 spmdRangeSpace_,
00244 Teuchos::rcp_dynamic_cast<const ScalarProdVectorSpaceBase<Scalar> >(
00245 spmdRangeSpace_->smallVecSpcFcty()->createVecSpc(numCols)
00246 ,true),
00247 localValuesView,
00248 spmdRangeSpace_->localSubDim()
00249 )
00250 );
00251 }
00252
00253 template<class Scalar>
00254 RCP<MultiVectorBase<Scalar> >
00255 DefaultSpmdMultiVector<Scalar>::nonconstNonContigSubViewImpl( const ArrayView<const int> &cols )
00256 {
00257 const int numCols = cols.size();
00258 const ArrayRCP<Scalar> localValuesView = createContiguousCopy(cols);
00259 const Index localSubDim = spmdRangeSpace_->localSubDim();
00260 RCP<MultiVectorBase<Scalar> >
00261 view = Teuchos::rcp(
00262 new DefaultSpmdMultiVector<Scalar>(
00263 spmdRangeSpace_,
00264 Teuchos::rcp_dynamic_cast<const ScalarProdVectorSpaceBase<Scalar> >(
00265 spmdRangeSpace_->smallVecSpcFcty()->createVecSpc(numCols)
00266 ,true),
00267 localValuesView,
00268 localSubDim
00269 )
00270 );
00271 RCP<CopyBackSpmdMultiVectorEntries<Scalar> >
00272 copyBackView
00273 = Teuchos::rcp(
00274 new CopyBackSpmdMultiVectorEntries<Scalar>(
00275 cols,&*localValuesView,localSubDim,&*localValues_,leadingDim_
00276 )
00277 );
00278 Teuchos::set_extra_data(copyBackView, "copyBackView",
00279 Teuchos::outArg(view), Teuchos::PRE_DESTROY);
00280 return view;
00281 }
00282
00283
00284
00285 template<class Scalar>
00286 RCP<const SpmdVectorSpaceBase<Scalar> >
00287 DefaultSpmdMultiVector<Scalar>::spmdSpace() const
00288 {
00289 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00290 std::cerr << "\nSpmdMultiVectorStd<Scalar>::spmdSpace() const called!\n";
00291 #endif
00292 return spmdRangeSpace_;
00293 }
00294
00295 template<class Scalar>
00296 void DefaultSpmdMultiVector<Scalar>::getLocalData(
00297 Scalar **localValues, Index *leadingDim
00298 )
00299 {
00300 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00301 std::cerr << "\nSpmdMultiVectorStd<Scalar>::getLocalData() called!\n";
00302 #endif
00303 #ifdef TEUCHOS_DEBUG
00304 TEST_FOR_EXCEPT( localValues==NULL );
00305 TEST_FOR_EXCEPT( leadingDim==NULL );
00306 #endif
00307 *localValues = &*localValues_;
00308 *leadingDim = leadingDim_;
00309 }
00310
00311 template<class Scalar>
00312 void DefaultSpmdMultiVector<Scalar>::commitLocalData( Scalar *localValues )
00313 {
00314 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00315 std::cerr << "\nSpmdMultiVectorStd<Scalar>::commitLocalData() called!\n";
00316 #endif
00317 #ifdef TEUCHOS_DEBUG
00318 TEST_FOR_EXCEPT( localValues!=&*localValues_ );
00319 #endif
00320
00321 }
00322
00323 template<class Scalar>
00324 void DefaultSpmdMultiVector<Scalar>::getLocalData(
00325 const Scalar **localValues, Index *leadingDim
00326 ) const
00327 {
00328 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00329 std::cerr << "\nSpmdMultiVectorStd<Scalar>::getLocalData() called!\n";
00330 #endif
00331 #ifdef TEUCHOS_DEBUG
00332 TEST_FOR_EXCEPT( localValues==NULL );
00333 TEST_FOR_EXCEPT( leadingDim==NULL );
00334 #endif
00335 *localValues = &*localValues_;
00336 *leadingDim = leadingDim_;
00337 }
00338
00339 template<class Scalar>
00340 void DefaultSpmdMultiVector<Scalar>::freeLocalData( const Scalar *localValues ) const
00341 {
00342 #ifdef TEUCHOS_DEBUG
00343 TEST_FOR_EXCEPT( localValues!=&*localValues_ );
00344 #endif
00345 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00346 std::cerr << "\nSpmdMultiVectorStd<Scalar>::commitLocalData() called!\n";
00347 #endif
00348
00349 }
00350
00351
00352
00353 template<class Scalar>
00354 ArrayRCP<Scalar>
00355 DefaultSpmdMultiVector<Scalar>::createContiguousCopy(
00356 const ArrayView<const int> &cols
00357 ) const
00358 {
00359 const int numCols = cols.size();
00360 #ifdef TEUCHOS_DEBUG
00361 const VectorSpaceBase<Scalar> &domain = *domainSpace_;
00362 const Index dimDomain = domain.dim();
00363 const char msg_err[] = "MultiVectorDefaultBase<Scalar>::subView(numCols,cols[]): Error!";
00364 TEST_FOR_EXCEPTION( numCols < 1 || dimDomain < numCols, std::invalid_argument, msg_err );
00365 #endif
00366 const Index localSubDim = spmdRangeSpace_->localSubDim();
00367 ArrayRCP<Scalar> localValuesView = Teuchos::arcp<Scalar>(numCols*localSubDim);
00368
00369 const Scalar *lv = &*localValues_;
00370 Scalar *lvv = &*localValuesView;
00371 for( int k = 0; k < numCols; ++k ) {
00372 const int col_k = cols[k];
00373 #ifdef TEUCHOS_DEBUG
00374 TEST_FOR_EXCEPTION(
00375 !( 0<= col_k && col_k < dimDomain ), std::invalid_argument
00376 ,msg_err << " col["<<k<<"] = " << col_k
00377 << " is not in the range [0,"<<(dimDomain-1)<<"]!"
00378 );
00379 #endif
00380 const Scalar *lv_k = lv + leadingDim_*col_k;
00381 Scalar *lvv_k = lvv + localSubDim*k;
00382 std::copy( lv_k, lv_k + localSubDim, lvv_k );
00383 }
00384 return localValuesView;
00385 }
00386
00387 }
00388
00389 #endif // THYRA_DEFAULT_SPMD_MULTI_VECTOR_BASE_HPP