|
Amesos2 - Direct Sparse Solver Interfaces
Version of the Day
|
00001 // @HEADER 00002 // 00003 // *********************************************************************** 00004 // 00005 // Amesos2: Templated Direct Sparse Solver Package 00006 // Copyright 2011 Sandia Corporation 00007 // 00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 00009 // the U.S. Government retains certain rights in this software. 00010 // 00011 // Redistribution and use in source and binary forms, with or without 00012 // modification, are permitted provided that the following conditions are 00013 // met: 00014 // 00015 // 1. Redistributions of source code must retain the above copyright 00016 // notice, this list of conditions and the following disclaimer. 00017 // 00018 // 2. Redistributions in binary form must reproduce the above copyright 00019 // notice, this list of conditions and the following disclaimer in the 00020 // documentation and/or other materials provided with the distribution. 00021 // 00022 // 3. Neither the name of the Corporation nor the names of the 00023 // contributors may be used to endorse or promote products derived from 00024 // this software without specific prior written permission. 00025 // 00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00037 // 00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00039 // 00040 // *********************************************************************** 00041 // 00042 // @HEADER 00043 00053 #ifndef AMESOS2_EPETRA_MULTIVEC_ADAPTER_DEF_HPP 00054 #define AMESOS2_EPETRA_MULTIVEC_ADAPTER_DEF_HPP 00055 00056 #include <Teuchos_as.hpp> 00057 00058 #include <Epetra_SerialComm.h> 00059 #ifdef HAVE_MPI 00060 #include <Epetra_MpiComm.h> 00061 #endif 00062 #include <Epetra_LocalMap.h> 00063 #include <Epetra_Import.h> 00064 #include <Epetra_Export.h> 00065 00066 #include "Amesos2_EpetraMultiVecAdapter_decl.hpp" 00067 #include "Amesos2_Util.hpp" 00068 00069 namespace Amesos2 { 00070 00071 MultiVecAdapter<Epetra_MultiVector>::MultiVecAdapter(const MultiVecAdapter<multivec_t>& adapter) 00072 : mv_(adapter.mv_) 00073 , mv_map_(adapter.mv_map_) 00074 { } 00075 00076 MultiVecAdapter<Epetra_MultiVector>::MultiVecAdapter(const Teuchos::RCP<multivec_t>& m) 00077 : mv_(m) 00078 { 00079 mv_map_ = Teuchos::rcpFromRef(mv_->Map()); 00080 } 00081 00082 00083 bool MultiVecAdapter<Epetra_MultiVector>::isLocallyIndexed() const 00084 { 00085 return !mv_->DistributedGlobal(); 00086 } 00087 00088 bool MultiVecAdapter<Epetra_MultiVector>::isGloballyIndexed() const 00089 { 00090 return mv_->DistributedGlobal(); 00091 } 00092 00093 00094 const Teuchos::RCP<const Teuchos::Comm<int> > 00095 MultiVecAdapter<Epetra_MultiVector>::getComm() const 00096 { 00097 return Util::to_teuchos_comm(Teuchos::rcpFromRef(mv_->Comm())); 00098 } 00099 00100 00101 size_t MultiVecAdapter<Epetra_MultiVector>::getLocalLength() const 00102 { 00103 return Teuchos::as<size_t>(mv_->MyLength()); 00104 } 00105 00106 00107 size_t MultiVecAdapter<Epetra_MultiVector>::getLocalNumVectors() const 00108 { 00109 return Teuchos::as<size_t>(mv_->NumVectors()); 00110 } 00111 00112 00113 MultiVecAdapter<Epetra_MultiVector>::global_size_t 00114 MultiVecAdapter<Epetra_MultiVector>::getGlobalLength() const 00115 { 00116 return Teuchos::as<global_size_t>(mv_->GlobalLength()); 00117 } 00118 00119 00120 size_t MultiVecAdapter<Epetra_MultiVector>::getGlobalNumVectors() const 00121 { 00122 return Teuchos::as<size_t>(mv_->NumVectors()); 00123 } 00124 00125 00126 size_t MultiVecAdapter<Epetra_MultiVector>::getStride() const 00127 { 00128 return Teuchos::as<size_t>(mv_->Stride()); 00129 } 00130 00131 00132 bool MultiVecAdapter<Epetra_MultiVector>::isConstantStride() const 00133 { 00134 return mv_->ConstantStride(); 00135 } 00136 00137 00138 Teuchos::RCP<const Tpetra::Vector<MultiVecAdapter<Epetra_MultiVector>::scalar_t, 00139 MultiVecAdapter<Epetra_MultiVector>::local_ordinal_t, 00140 MultiVecAdapter<Epetra_MultiVector>::global_ordinal_t, 00141 MultiVecAdapter<Epetra_MultiVector>::node_t> > 00142 MultiVecAdapter<Epetra_MultiVector>::getVector( size_t j ) const 00143 { 00144 using Teuchos::RCP; 00145 using Teuchos::rcp; 00146 using Teuchos::ArrayRCP; 00147 using Tpetra::MultiVector; 00148 00149 typedef scalar_t st; 00150 typedef local_ordinal_t lot; 00151 typedef global_ordinal_t got; 00152 typedef node_t nt; 00153 00154 RCP<MultiVector<st,lot,got,nt> > vector = rcp(new MultiVector<st,lot,got,nt>(this->getMap(),1)); 00155 00156 // Copy vector contents into Tpetra multi-vector 00157 ArrayRCP<st> it = vector->getDataNonConst(0); 00158 double* vector_data = mv_->operator[](Teuchos::as<int>(j)); // values from j^th vector 00159 Tpetra::global_size_t size = vector->getGlobalLength(); 00160 00161 for( Tpetra::global_size_t i = 0; i < size; ++i ){ 00162 *it = vector_data[i]; 00163 } 00164 00165 return vector->getVector(j); 00166 } 00167 00168 00169 // Implementation is essentially the same as getVector() 00170 Teuchos::RCP<Tpetra::Vector<MultiVecAdapter<Epetra_MultiVector>::scalar_t, 00171 MultiVecAdapter<Epetra_MultiVector>::local_ordinal_t, 00172 MultiVecAdapter<Epetra_MultiVector>::global_ordinal_t, 00173 MultiVecAdapter<Epetra_MultiVector>::node_t> > 00174 MultiVecAdapter<Epetra_MultiVector>::getVectorNonConst( size_t j ) 00175 { 00176 using Teuchos::RCP; 00177 using Teuchos::rcp; 00178 using Teuchos::ArrayRCP; 00179 using Tpetra::MultiVector; 00180 00181 typedef scalar_t st; 00182 typedef local_ordinal_t lot; 00183 typedef global_ordinal_t got; 00184 typedef node_t nt; 00185 00186 RCP<MultiVector<st,lot,got,nt> > vector = rcp(new MultiVector<st,lot,got,nt>(this->getMap(),1)); 00187 00188 // Copy vector contents into Tpetra multi-vector 00189 ArrayRCP<st> it = vector->getDataNonConst(0); 00190 double* vector_data = mv_->operator[](Teuchos::as<int>(j)); // values from j^th vector 00191 Tpetra::global_size_t size = vector->getGlobalLength(); 00192 00193 for( Tpetra::global_size_t i = 0; i < size; ++i ){ 00194 *it = vector_data[i]; 00195 } 00196 00197 return vector->getVectorNonConst(j); 00198 } 00199 00200 00201 void MultiVecAdapter<Epetra_MultiVector>::get1dCopy( 00202 const Teuchos::ArrayView<MultiVecAdapter<Epetra_MultiVector>::scalar_t>& av, 00203 size_t lda, 00204 Teuchos::Ptr< 00205 const Tpetra::Map<MultiVecAdapter<Epetra_MultiVector>::local_ordinal_t, 00206 MultiVecAdapter<Epetra_MultiVector>::global_ordinal_t, 00207 MultiVecAdapter<Epetra_MultiVector>::node_t> > distribution_map ) const 00208 { 00209 using Teuchos::rcpFromPtr; 00210 using Teuchos::as; 00211 00212 const size_t num_vecs = getGlobalNumVectors(); 00213 00214 #ifdef HAVE_AMESOS2_DEBUG 00215 const size_t requested_vector_length = distribution_map->getNodeNumElements(); 00216 TEUCHOS_TEST_FOR_EXCEPTION( lda < requested_vector_length, 00217 std::invalid_argument, 00218 "Given stride is not large enough for local vector length" ); 00219 TEUCHOS_TEST_FOR_EXCEPTION( as<size_t>(av.size()) < (num_vecs-1) * lda + requested_vector_length, 00220 std::invalid_argument, 00221 "MultiVector storage not large enough given leading dimension " 00222 "and number of vectors" ); 00223 #endif 00224 00225 Epetra_Map e_dist_map 00226 = *Util::tpetra_map_to_epetra_map<local_ordinal_t, 00227 global_ordinal_t, 00228 global_size_t, 00229 node_t>(*distribution_map); 00230 00231 multivec_t redist_mv(e_dist_map, as<int>(num_vecs)); 00232 const Epetra_Import importer(e_dist_map, *mv_map_); // Note, target/source order is reversed in Tpetra 00233 redist_mv.Import(*mv_, importer, Insert); 00234 00235 // Finally, do copy 00236 redist_mv.ExtractCopy(av.getRawPtr(), lda); 00237 } 00238 00239 00240 Teuchos::ArrayRCP<MultiVecAdapter<Epetra_MultiVector>::scalar_t> 00241 MultiVecAdapter<Epetra_MultiVector>::get1dViewNonConst(bool local) 00242 { 00243 // TEUCHOS_TEST_FOR_EXCEPTION( !this->isConstantStride(), 00244 // std::logic_error, 00245 // "get1dViewNonConst() : can only get 1d view if stride is constant"); 00246 00247 // if( local ){ 00248 // TEUCHOS_TEST_FOR_EXCEPTION( 00249 // true, 00250 // std::logic_error, 00251 // "Amesos2::MultiVecAdapter<Epetra_MultiVector> : 1D views not yet supported for local-local Epetra multi-vectors"); 00252 00253 // // localize(); 00254 // // /* Use the global element list returned by 00255 // // * mv_->getMap()->getNodeElementList() to get a subCopy of mv_ which we 00256 // // * assign to l_l_mv_, then return get1dViewNonConst() of l_l_mv_ 00257 // // */ 00258 // // l_l_mv_ = Teuchos::null; 00259 00260 // // Teuchos::Array<GlobalOrdinal> nodeElements_go(mv_->Map().NumMyElements()); 00261 // // mv_->Map().MyGlobalElements(nodeElements_go.getRawPtr()); 00262 // // Teuchos::Array<size_t> nodeElements_st(nodeElements_go.size()); 00263 00264 // // // Convert the node element to a list of size_t type objects 00265 // // typename Teuchos::ArrayView<const GlobalOrdinal>::iterator it_go; 00266 // // Teuchos::Array<size_t>::iterator it_st = nodeElements_st.begin(); 00267 // // for( it_go = nodeElements_go.begin(); it_go != nodeElements_go.end(); ++it_go ){ 00268 // // *(it_st++) = Teuchos::as<size_t>(*it_go); 00269 // // } 00270 00271 // // l_l_mv_ = l_mv_->subViewNonConst(nodeElements_st); 00272 00273 // // return(l_l_mv_->get1dViewNonConst()); 00274 // } else { 00275 // scalar_t* values; 00276 // int lda; 00277 00278 // if( !isLocal() ){ 00279 // this->localize(); 00280 // l_mv_->ExtractView(&values, &lda); 00281 // } else { 00282 // mv_->ExtractView(&values, &lda); 00283 // } 00284 00285 // TEUCHOS_TEST_FOR_EXCEPTION( lda != Teuchos::as<int>(this->getStride()), 00286 // std::logic_error, 00287 // "Stride reported during extraction not consistent with what multivector reports"); 00288 00289 // return Teuchos::arcp(values,0,lda*this->getGlobalNumVectors(),false); 00290 // } 00291 return Teuchos::null; 00292 } 00293 00294 00295 void 00296 MultiVecAdapter<Epetra_MultiVector>::put1dData( 00297 const Teuchos::ArrayView<const MultiVecAdapter<Epetra_MultiVector>::scalar_t>& new_data, 00298 size_t lda, 00299 Teuchos::Ptr< 00300 const Tpetra::Map<MultiVecAdapter<Epetra_MultiVector>::local_ordinal_t, 00301 MultiVecAdapter<Epetra_MultiVector>::global_ordinal_t, 00302 MultiVecAdapter<Epetra_MultiVector>::node_t> > source_map) 00303 { 00304 using Teuchos::rcpFromPtr; 00305 using Teuchos::as; 00306 00307 const size_t num_vecs = getGlobalNumVectors(); 00308 // TODO: check that the following const_cast is safe 00309 double* data_ptr = const_cast<double*>(new_data.getRawPtr()); 00310 const Epetra_BlockMap e_source_map 00311 = *Util::tpetra_map_to_epetra_map<local_ordinal_t,global_ordinal_t,global_size_t,node_t>(*source_map); 00312 const multivec_t source_mv(Copy, e_source_map, data_ptr, as<int>(lda), as<int>(num_vecs)); 00313 const Epetra_Import importer(*mv_map_, e_source_map); 00314 00315 mv_->Import(source_mv, importer, Insert); 00316 } 00317 00318 00319 std::string MultiVecAdapter<Epetra_MultiVector>::description() const 00320 { 00321 std::ostringstream oss; 00322 oss << "Amesos2 adapter wrapping: Epetra_MultiVector"; 00323 return oss.str(); 00324 } 00325 00326 00327 void MultiVecAdapter<Epetra_MultiVector>::describe( 00328 Teuchos::FancyOStream& os, 00329 const Teuchos::EVerbosityLevel verbLevel) const 00330 { 00331 // TODO: implement! 00332 } 00333 00334 00335 Teuchos::RCP<const Tpetra::Map<MultiVecAdapter<Epetra_MultiVector>::local_ordinal_t, 00336 MultiVecAdapter<Epetra_MultiVector>::global_ordinal_t, 00337 MultiVecAdapter<Epetra_MultiVector>::node_t> > 00338 MultiVecAdapter<Epetra_MultiVector>::getMap() const 00339 { 00340 return Util::epetra_map_to_tpetra_map<local_ordinal_t,global_ordinal_t,global_size_t,node_t>(*mv_map_); 00341 } 00342 00343 00344 const char* MultiVecAdapter<Epetra_MultiVector>::name 00345 = "Amesos2 adapter for Epetra_MultiVector"; 00346 00347 00348 } // end namespace Amesos2 00349 00350 #endif // AMESOS2_EPETRA_MULTIVEC_ADAPTER_DEF_HPP
1.7.6.1