Amesos2 - Direct Sparse Solver Interfaces  Version of the Day
Amesos2_EpetraMultiVecAdapter_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Amesos2: Templated Direct Sparse Solver Package
6 // Copyright 2011 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39 //
40 // ***********************************************************************
41 //
42 // @HEADER
43 
53 #ifndef AMESOS2_EPETRA_MULTIVEC_ADAPTER_DEF_HPP
54 #define AMESOS2_EPETRA_MULTIVEC_ADAPTER_DEF_HPP
55 
56 #include <Teuchos_as.hpp>
57 
58 #include <Epetra_SerialComm.h>
59 #ifdef HAVE_MPI
60 #include <Epetra_MpiComm.h>
61 #endif
62 #include <Epetra_LocalMap.h>
63 #include <Epetra_Import.h>
64 #include <Epetra_Export.h>
65 
67 #include "Amesos2_Util.hpp"
68 
69 namespace Amesos2 {
70 
72  : mv_(adapter.mv_)
73  , mv_map_(adapter.mv_map_)
74 { }
75 
76 MultiVecAdapter<Epetra_MultiVector>::MultiVecAdapter(const Teuchos::RCP<multivec_t>& m)
77  : mv_(m)
78 {
79  mv_map_ = Teuchos::rcpFromRef(mv_->Map());
80 }
81 
82 
84 {
85  return !mv_->DistributedGlobal();
86 }
87 
89 {
90  return mv_->DistributedGlobal();
91 }
92 
93 
94 const Teuchos::RCP<const Teuchos::Comm<int> >
96 {
97  return Util::to_teuchos_comm(Teuchos::rcpFromRef(mv_->Comm()));
98 }
99 
100 
102 {
103  return Teuchos::as<size_t>(mv_->MyLength());
104 }
105 
106 
108 {
109  return Teuchos::as<size_t>(mv_->NumVectors());
110 }
111 
112 
115 {
116  return Teuchos::as<global_size_t>(mv_->GlobalLength());
117 }
118 
119 
121 {
122  return Teuchos::as<size_t>(mv_->NumVectors());
123 }
124 
125 
127 {
128  return Teuchos::as<size_t>(mv_->Stride());
129 }
130 
131 
133 {
134  return mv_->ConstantStride();
135 }
136 
137 
138 Teuchos::RCP<const Tpetra::Vector<MultiVecAdapter<Epetra_MultiVector>::scalar_t,
143 {
144  using Teuchos::RCP;
145  using Teuchos::rcp;
146  using Teuchos::ArrayRCP;
147  using Tpetra::MultiVector;
148 
149  typedef scalar_t st;
150  typedef local_ordinal_t lot;
151  typedef global_ordinal_t got;
152  typedef node_t nt;
153 
154  RCP<MultiVector<st,lot,got,nt> > vector = rcp(new MultiVector<st,lot,got,nt>(this->getMap(),1));
155 
156  // Copy vector contents into Tpetra multi-vector
157  ArrayRCP<st> it = vector->getDataNonConst(0);
158  double* vector_data = mv_->operator[](Teuchos::as<int>(j)); // values from j^th vector
159  Tpetra::global_size_t size = vector->getGlobalLength();
160 
161  for( Tpetra::global_size_t i = 0; i < size; ++i ){
162  *it = vector_data[i];
163  }
164 
165  return vector->getVector(j);
166 }
167 
168 
169 // Implementation is essentially the same as getVector()
170 Teuchos::RCP<Tpetra::Vector<MultiVecAdapter<Epetra_MultiVector>::scalar_t,
171  MultiVecAdapter<Epetra_MultiVector>::local_ordinal_t,
172  MultiVecAdapter<Epetra_MultiVector>::global_ordinal_t,
175 {
176  using Teuchos::RCP;
177  using Teuchos::rcp;
178  using Teuchos::ArrayRCP;
179  using Tpetra::MultiVector;
180 
181  typedef scalar_t st;
182  typedef local_ordinal_t lot;
183  typedef global_ordinal_t got;
184  typedef node_t nt;
185 
186  RCP<MultiVector<st,lot,got,nt> > vector = rcp(new MultiVector<st,lot,got,nt>(this->getMap(),1));
187 
188  // Copy vector contents into Tpetra multi-vector
189  ArrayRCP<st> it = vector->getDataNonConst(0);
190  double* vector_data = mv_->operator[](Teuchos::as<int>(j)); // values from j^th vector
191  Tpetra::global_size_t size = vector->getGlobalLength();
192 
193  for( Tpetra::global_size_t i = 0; i < size; ++i ){
194  *it = vector_data[i];
195  }
196 
197  return vector->getVectorNonConst(j);
198 }
199 
200 
202  const Teuchos::ArrayView<MultiVecAdapter<Epetra_MultiVector>::scalar_t>& av,
203  size_t lda,
204  Teuchos::Ptr<
205  const Tpetra::Map<MultiVecAdapter<Epetra_MultiVector>::local_ordinal_t,
206  MultiVecAdapter<Epetra_MultiVector>::global_ordinal_t,
207  MultiVecAdapter<Epetra_MultiVector>::node_t> > distribution_map ) const
208 {
209  using Teuchos::rcpFromPtr;
210  using Teuchos::as;
211 
212  const size_t num_vecs = getGlobalNumVectors();
213 
214 #ifdef HAVE_AMESOS2_DEBUG
215  const size_t requested_vector_length = distribution_map->getNodeNumElements();
216  TEUCHOS_TEST_FOR_EXCEPTION( lda < requested_vector_length,
217  std::invalid_argument,
218  "Given stride is not large enough for local vector length" );
219  TEUCHOS_TEST_FOR_EXCEPTION( as<size_t>(av.size()) < (num_vecs-1) * lda + requested_vector_length,
220  std::invalid_argument,
221  "MultiVector storage not large enough given leading dimension "
222  "and number of vectors" );
223 #endif
224 
225  Epetra_Map e_dist_map
226  = *Util::tpetra_map_to_epetra_map<local_ordinal_t,
227  global_ordinal_t,
228  global_size_t,
229  node_t>(*distribution_map);
230 
231  multivec_t redist_mv(e_dist_map, as<int>(num_vecs));
232  const Epetra_Import importer(e_dist_map, *mv_map_); // Note, target/source order is reversed in Tpetra
233  redist_mv.Import(*mv_, importer, Insert);
234 
235  // Finally, do copy
236  redist_mv.ExtractCopy(av.getRawPtr(), lda);
237 }
238 
239 
240 Teuchos::ArrayRCP<MultiVecAdapter<Epetra_MultiVector>::scalar_t>
242 {
243  ((void) local);
244  // TEUCHOS_TEST_FOR_EXCEPTION( !this->isConstantStride(),
245  // std::logic_error,
246  // "get1dViewNonConst() : can only get 1d view if stride is constant");
247 
248  // if( local ){
249  // TEUCHOS_TEST_FOR_EXCEPTION(
250  // true,
251  // std::logic_error,
252  // "Amesos2::MultiVecAdapter<Epetra_MultiVector> : 1D views not yet supported for local-local Epetra multi-vectors");
253 
254  // // localize();
255  // // /* Use the global element list returned by
256  // // * mv_->getMap()->getNodeElementList() to get a subCopy of mv_ which we
257  // // * assign to l_l_mv_, then return get1dViewNonConst() of l_l_mv_
258  // // */
259  // // l_l_mv_ = Teuchos::null;
260 
261  // // Teuchos::Array<GlobalOrdinal> nodeElements_go(mv_->Map().NumMyElements());
262  // // mv_->Map().MyGlobalElements(nodeElements_go.getRawPtr());
263  // // Teuchos::Array<size_t> nodeElements_st(nodeElements_go.size());
264 
265  // // // Convert the node element to a list of size_t type objects
266  // // typename Teuchos::ArrayView<const GlobalOrdinal>::iterator it_go;
267  // // Teuchos::Array<size_t>::iterator it_st = nodeElements_st.begin();
268  // // for( it_go = nodeElements_go.begin(); it_go != nodeElements_go.end(); ++it_go ){
269  // // *(it_st++) = Teuchos::as<size_t>(*it_go);
270  // // }
271 
272  // // l_l_mv_ = l_mv_->subViewNonConst(nodeElements_st);
273 
274  // // return(l_l_mv_->get1dViewNonConst());
275  // } else {
276  // scalar_t* values;
277  // int lda;
278 
279  // if( !isLocal() ){
280  // this->localize();
281  // l_mv_->ExtractView(&values, &lda);
282  // } else {
283  // mv_->ExtractView(&values, &lda);
284  // }
285 
286  // TEUCHOS_TEST_FOR_EXCEPTION( lda != Teuchos::as<int>(this->getStride()),
287  // std::logic_error,
288  // "Stride reported during extraction not consistent with what multivector reports");
289 
290  // return Teuchos::arcp(values,0,lda*this->getGlobalNumVectors(),false);
291  // }
292  return Teuchos::null;
293 }
294 
295 
296 void
298  const Teuchos::ArrayView<const MultiVecAdapter<Epetra_MultiVector>::scalar_t>& new_data,
299  size_t lda,
300  Teuchos::Ptr<
301  const Tpetra::Map<MultiVecAdapter<Epetra_MultiVector>::local_ordinal_t,
302  MultiVecAdapter<Epetra_MultiVector>::global_ordinal_t,
304 {
305  using Teuchos::rcpFromPtr;
306  using Teuchos::as;
307 
308  const size_t num_vecs = getGlobalNumVectors();
309  // TODO: check that the following const_cast is safe
310  double* data_ptr = const_cast<double*>(new_data.getRawPtr());
311  const Epetra_BlockMap e_source_map
312  = *Util::tpetra_map_to_epetra_map<local_ordinal_t,global_ordinal_t,global_size_t,node_t>(*source_map);
313  const multivec_t source_mv(Copy, e_source_map, data_ptr, as<int>(lda), as<int>(num_vecs));
314  const Epetra_Import importer(*mv_map_, e_source_map);
315 
316  mv_->Import(source_mv, importer, Insert);
317 }
318 
319 
321 {
322  std::ostringstream oss;
323  oss << "Amesos2 adapter wrapping: Epetra_MultiVector";
324  return oss.str();
325 }
326 
327 
329  Teuchos::FancyOStream& os,
330  const Teuchos::EVerbosityLevel verbLevel) const
331 {
332  // TODO: implement!
333  if(verbLevel != Teuchos::VERB_NONE)
334  {
335  os << "TODO: implement! ";
336  }
337 }
338 
339 
340 Teuchos::RCP<const Tpetra::Map<MultiVecAdapter<Epetra_MultiVector>::local_ordinal_t,
341  MultiVecAdapter<Epetra_MultiVector>::global_ordinal_t,
344 {
345  return Util::epetra_map_to_tpetra_map<local_ordinal_t,global_ordinal_t,global_size_t,node_t>(*mv_map_);
346 }
347 
348 
350 = "Amesos2 adapter for Epetra_MultiVector";
351 
352 
353 } // end namespace Amesos2
354 
355 #endif // AMESOS2_EPETRA_MULTIVEC_ADAPTER_DEF_HPP
Utility functions for Amesos2.
Definition: Amesos2_AbstractConcreteMatrixAdapter.hpp:48
Amesos2::MultiVecAdapter specialization for the Epetra_MultiVector class.
A templated MultiVector class adapter for Amesos2.
Definition: Amesos2_MultiVecAdapter_decl.hpp:175