Amesos2 - Direct Sparse Solver Interfaces  Version of the Day
Amesos2_EpetraRowMatrix_AbstractMatrixAdapter_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 
44 
53 #ifndef AMESOS2_EPETRAROWMATRIX_ABSTRACTMATRIXADAPTER_DEF_HPP
54 #define AMESOS2_EPETRAROWMATRIX_ABSTRACTMATRIXADAPTER_DEF_HPP
55 
56 #include <Epetra_RowMatrix.h>
57 #include <Epetra_Map.h>
58 #include <Epetra_Comm.h>
59 
61 
62 
63 namespace Amesos2 {
64 
65  using Teuchos::RCP;
66  using Teuchos::ArrayView;
67 
68  template <class DerivedMat>
69  AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::AbstractConcreteMatrixAdapter(RCP<DerivedMat> m)
70  : MatrixAdapter<DerivedMat>(m)
71  {
72  // anything else? probs not
73  }
74 
75  // implementation functions
76  template <class DerivedMat>
77  void
78  AbstractConcreteMatrixAdapter<
79  Epetra_RowMatrix,
80  DerivedMat>::getGlobalRowCopy_impl(global_ordinal_t row,
81  const ArrayView<global_ordinal_t>& indices,
82  const ArrayView<scalar_t>& vals,
83  size_t& nnz) const
84  {
85  using Teuchos::as;
86  const int local_row = this->row_map_->getLocalElement(row);
87  bool threw = false;
88 
89  Teuchos::Array<local_ordinal_t> epetra_lcl_inds_buf;
90  Teuchos::ArrayView<local_ordinal_t> epetra_lcl_inds;
91  if (! std::is_same<global_ordinal_t, local_ordinal_t>::value) {
92  int num_ent = 0;
93  int err = 0;
94  try {
95  err = this->mat_->NumMyRowEntries (local_row, num_ent);
96  }
97  catch (int integer_exception) {
98  threw = true;
99  err = integer_exception;
100  }
101  TEUCHOS_TEST_FOR_EXCEPTION
102  (threw && err != 0, std::runtime_error, "Epetra_RowMatrix::"
103  "NumMyRowEntries, called on local row " << local_row << ", threw "
104  "an integer exception " << err << ".");
105  TEUCHOS_TEST_FOR_EXCEPTION
106  (! threw && err != 0, std::runtime_error, "Epetra_RowMatrix returned "
107  "error code " << err << " from NumMyRowEntries for local row "
108  << local_row << ".");
109  epetra_lcl_inds_buf.resize (num_ent);
110  epetra_lcl_inds = epetra_lcl_inds_buf ();
111  }
112  else { // local_ordinal_t == global_ordinal_t
113  using Teuchos::av_reinterpret_cast;
114  epetra_lcl_inds = av_reinterpret_cast<int> (indices);
115  }
116 
117  int nnz_ret = 0;
118  int rowmatrix_return_val = 0;
119  try {
120  rowmatrix_return_val =
121  this->mat_->ExtractMyRowCopy(local_row,
122  as<int>(std::min(epetra_lcl_inds.size(), vals.size())),
123  nnz_ret,
124  vals.getRawPtr(),
125  epetra_lcl_inds.getRawPtr());
126  }
127  catch (int integer_exception) {
128  threw = true;
129  rowmatrix_return_val = integer_exception;
130  }
131  TEUCHOS_TEST_FOR_EXCEPTION
132  (threw && rowmatrix_return_val != 0, std::runtime_error,
133  "Epetra_RowMatrix::ExtractMyRowCopy, called on local row " << local_row
134  << ", threw an integer exception " << rowmatrix_return_val << ".");
135  TEUCHOS_TEST_FOR_EXCEPTION
136  (! threw && rowmatrix_return_val != 0, std::runtime_error,
137  "Epetra_RowMatrix object returned error code "
138  << rowmatrix_return_val << " from ExtractMyRowCopy." );
139  nnz = as<size_t>(nnz_ret);
140 
141  // Epetra_CrsMatrix::ExtractMyRowCopy returns local column
142  // indices, so transform these into global indices
143  for( size_t i = 0; i < nnz; ++i ){
144  indices[i] = this->col_map_->getGlobalElement(epetra_lcl_inds[i]);
145  }
146  }
147 
148  template <class DerivedMat>
149  void
150  AbstractConcreteMatrixAdapter<
151  Epetra_RowMatrix,
152  DerivedMat>::getGlobalColCopy_impl(global_ordinal_t col,
153  const ArrayView<global_ordinal_t>& indices,
154  const ArrayView<scalar_t>& vals,
155  size_t& nnz) const
156  {
157  TEUCHOS_TEST_FOR_EXCEPTION( true,
158  std::runtime_error,
159  "Column access to row-based object not yet supported. "
160  "Please contact the Amesos2 developers." );
161  }
162 
163 
164  template <class DerivedMat>
165  typename AbstractConcreteMatrixAdapter<
166  Epetra_RowMatrix,
167  DerivedMat>::global_size_t
168  AbstractConcreteMatrixAdapter<
169  Epetra_RowMatrix,
170  DerivedMat>::getGlobalNNZ_impl() const
171  {
172  return Teuchos::as<global_size_t>(this->mat_->NumGlobalNonzeros());
173  }
174 
175  template <class DerivedMat>
176  size_t
177  AbstractConcreteMatrixAdapter<
178  Epetra_RowMatrix,
179  DerivedMat>::getLocalNNZ_impl() const
180  {
181  return Teuchos::as<size_t>(this->mat_->NumMyNonzeros());
182  }
183 
184  template <class DerivedMat>
185  typename AbstractConcreteMatrixAdapter<
186  Epetra_RowMatrix,
187  DerivedMat>::global_size_t
188  AbstractConcreteMatrixAdapter<
189  Epetra_RowMatrix,
190  DerivedMat>::getGlobalNumRows_impl() const
191  {
192  return Teuchos::as<global_size_t>(this->mat_->NumGlobalRows());
193  }
194 
195  template <class DerivedMat>
196  typename AbstractConcreteMatrixAdapter<
197  Epetra_RowMatrix,
198  DerivedMat>::global_size_t
199  AbstractConcreteMatrixAdapter<
200  Epetra_RowMatrix,
201  DerivedMat>::getGlobalNumCols_impl() const
202  {
203  return Teuchos::as<global_size_t>(this->mat_->NumGlobalCols());
204  }
205 
206  template <class DerivedMat>
207  size_t
208  AbstractConcreteMatrixAdapter<
209  Epetra_RowMatrix,
210  DerivedMat>::getMaxRowNNZ_impl() const
211  {
212  return Teuchos::as<size_t>(this->mat_->MaxNumEntries());
213  }
214 
215  template <class DerivedMat>
216  size_t
217  AbstractConcreteMatrixAdapter<
218  Epetra_RowMatrix,
219  DerivedMat>::getMaxColNNZ_impl() const
220  {
221  TEUCHOS_TEST_FOR_EXCEPTION( true,
222  std::runtime_error,
223  "Column access to row-based object not yet supported. "
224  "Please contact the Amesos2 developers." );
225  }
226 
227  template <class DerivedMat>
228  size_t
229  AbstractConcreteMatrixAdapter<
230  Epetra_RowMatrix,
231  DerivedMat>::getGlobalRowNNZ_impl(global_ordinal_t row) const
232  {
233  // check whether row is local, then transform to local index
234  Epetra_Map rowmap = this->mat_->RowMatrixRowMap();
235  int gid = Teuchos::as<int>(row);
236  TEUCHOS_TEST_FOR_EXCEPTION( !rowmap.MyGID(gid),
237  std::invalid_argument,
238  "The specified global row id does not belong to me" );
239  int lid = rowmap.LID(gid);
240  int nnz = 0;
241  this->mat_->NumMyRowEntries(lid, nnz);
242  return nnz;
243  }
244 
245  template <class DerivedMat>
246  size_t
247  AbstractConcreteMatrixAdapter<
248  Epetra_RowMatrix,
249  DerivedMat>::getLocalRowNNZ_impl(local_ordinal_t row) const
250  {
251  Epetra_Map rowmap = this->mat_->RowMatrixRowMap();
252  int lid = Teuchos::as<int>(row);
253  TEUCHOS_TEST_FOR_EXCEPTION( !rowmap.MyLID(lid),
254  std::invalid_argument,
255  "The specified local row id does not beloing to me" );
256  int num_entries = 0;
257  this->mat_->NumMyRowEntries(row, num_entries);
258  return num_entries;
259  }
260 
261  template <class DerivedMat>
262  size_t
263  AbstractConcreteMatrixAdapter<
264  Epetra_RowMatrix,
265  DerivedMat>::getGlobalColNNZ_impl(global_ordinal_t col) const
266  {
267  TEUCHOS_TEST_FOR_EXCEPTION( true,
268  std::runtime_error,
269  "Column access to row-based object not yet supported. "
270  "Please contact the Amesos2 developers." );
271  }
272 
273  template <class DerivedMat>
274  size_t
275  AbstractConcreteMatrixAdapter<
276  Epetra_RowMatrix,
277  DerivedMat>::getLocalColNNZ_impl(local_ordinal_t col) const
278  {
279  TEUCHOS_TEST_FOR_EXCEPTION( true,
280  std::runtime_error,
281  "Column access to row-based object not yet supported. "
282  "Please contact the Amesos2 developers." );
283  }
284 
285  template <class DerivedMat>
286  const RCP<const Tpetra::Map<MatrixTraits<Epetra_RowMatrix>::local_ordinal_t,
287  MatrixTraits<Epetra_RowMatrix>::global_ordinal_t,
288  MatrixTraits<Epetra_RowMatrix>::node_t> >
289  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::getMap_impl() const
290  {
291  // Should Map() be used (returns Epetra_BlockMap)
292  /*
293  printf("Amesos2_EpetraRowMatrix_AbstractMatrixAdapter: Epetra does not support a 'getMap()' method. Returning rcp(Teuchos::null). \
294  If your map contains non-contiguous GIDs please use Tpetra instead of Epetra. \n");
295  */
296  return( Teuchos::null );
297  }
298 
299  template <class DerivedMat>
300  const RCP<const Tpetra::Map<MatrixTraits<Epetra_RowMatrix>::local_ordinal_t,
301  MatrixTraits<Epetra_RowMatrix>::global_ordinal_t,
302  MatrixTraits<Epetra_RowMatrix>::node_t> >
303  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::getRowMap_impl() const
304  {
305  // Must transform to a Tpetra::Map
306  const Epetra_Map rowmap = this->mat_->RowMatrixRowMap();
307  return( Util::epetra_map_to_tpetra_map<local_ordinal_t,global_ordinal_t,global_size_t,node_t>(rowmap) );
308  }
309 
310  template <class DerivedMat>
311  const RCP<const Tpetra::Map<MatrixTraits<Epetra_RowMatrix>::local_ordinal_t,
312  MatrixTraits<Epetra_RowMatrix>::global_ordinal_t,
313  MatrixTraits<Epetra_RowMatrix>::node_t> >
314  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::getColMap_impl() const
315  {
316  // Must transform this matrix' Epetra_Map to a Tpetra::Map
317  const Epetra_Map colmap = this->mat_->RowMatrixColMap();
318  return( Util::epetra_map_to_tpetra_map<local_ordinal_t,global_ordinal_t,global_size_t,node_t>(colmap) );
319  }
320 
321  template <class DerivedMat>
322  const RCP<const Teuchos::Comm<int> >
323  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::getComm_impl() const
324  {
325  return Util::to_teuchos_comm(Teuchos::rcpFromRef(this->mat_->Comm()));
326  }
327 
328  template <class DerivedMat>
329  bool
330  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::isLocallyIndexed_impl() const
331  {
332  return this->mat_->IndicesAreLocal();
333  }
334 
335  template <class DerivedMat>
336  bool
337  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::isGloballyIndexed_impl() const
338  {
339  return this->mat_->IndicesAreGlobal();
340  }
341 
342 
343  template <class DerivedMat>
344  RCP<const MatrixAdapter<DerivedMat> >
345  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::get_impl(const Teuchos::Ptr<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > map, EDistribution distribution) const
346  {
347  // Delegate implementation to subclass
348 #ifdef __CUDACC__
349  // NVCC doesn't seem to like the static_cast, even though it is valid
350  return dynamic_cast<ConcreteMatrixAdapter<DerivedMat>*>(this)->get_impl(map, distribution);
351 #else
352  return static_cast<ConcreteMatrixAdapter<DerivedMat>*>(this)->get_impl(map, distribution);
353 #endif
354  }
355 
356  template <class DerivedMat>
357  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>
358  ::super_t::spmtx_ptr_t
359  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::getSparseRowPtr() const
360  {
361  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::super_t::spmtx_ptr_t sp_rowptr = nullptr;
362  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::super_t::spmtx_idx_t sp_colind = nullptr;
363  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::super_t::spmtx_vals_t sp_values = nullptr;
364 
365  this->mat_->ExtractCrsDataPointers(sp_rowptr, sp_colind, sp_values);
366 
367  return sp_rowptr;
368  }
369 
370  template <class DerivedMat>
371  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>
372  ::super_t::spmtx_idx_t
373  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::getSparseColInd() const
374  {
375  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::super_t::spmtx_ptr_t sp_rowptr = nullptr;
376  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::super_t::spmtx_idx_t sp_colind = nullptr;
377  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::super_t::spmtx_vals_t sp_values = nullptr;
378 
379  this->mat_->ExtractCrsDataPointers(sp_rowptr, sp_colind, sp_values);
380 
381  return sp_colind;
382  }
383 
384  template <class DerivedMat>
385  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>
386  ::super_t::spmtx_vals_t
387  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::getSparseValues() const
388  {
389  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::super_t::spmtx_ptr_t sp_rowptr = nullptr;
390  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::super_t::spmtx_idx_t sp_colind = nullptr;
391  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::super_t::spmtx_vals_t sp_values = nullptr;
392 
393  this->mat_->ExtractCrsDataPointers(sp_rowptr, sp_colind, sp_values);
394 
395  return sp_values;
396  }
397 
398 } // end namespace Amesos2
399 
400 #endif // AMESOS2_EPETRAROWMATRIX_ABSTRACTMATRIXADAPTER_DEF_HPP
const RCP< const Teuchos::Comm< int > > to_teuchos_comm(RCP< const Epetra_Comm > c)
Transform an Epetra_Comm object into a Teuchos::Comm object.
Provides the Epetra_RowMatrix abstraction for the concrete Epetra row matric adapters.
EDistribution
Definition: Amesos2_TypeDecl.hpp:123