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  template<typename KV_GO, typename KV_S>
166  void
167  AbstractConcreteMatrixAdapter<
168  Epetra_RowMatrix,
169  DerivedMat>::getGlobalRowCopy_kokkos_view_impl(global_ordinal_t row,
170  KV_GO & indices,
171  KV_S & vals,
172  size_t& nnz) const
173  {
174  using index_t = typename KV_GO::value_type;
175  using value_t = typename KV_S::value_type;
176  ArrayView<value_t> vals_array (vals.data(), vals.extent(0));
177  ArrayView<index_t> indices_array (indices.data(), indices.extent(0));
178 
179  this->getGlobalRowCopy_impl(row, indices_array, vals_array, nnz);
180  }
181 
182 
183 
184  template <class DerivedMat>
185  typename AbstractConcreteMatrixAdapter<
186  Epetra_RowMatrix,
187  DerivedMat>::global_size_t
188  AbstractConcreteMatrixAdapter<
189  Epetra_RowMatrix,
190  DerivedMat>::getGlobalNNZ_impl() const
191  {
192  return Teuchos::as<global_size_t>(this->mat_->NumGlobalNonzeros());
193  }
194 
195  template <class DerivedMat>
196  size_t
197  AbstractConcreteMatrixAdapter<
198  Epetra_RowMatrix,
199  DerivedMat>::getLocalNNZ_impl() const
200  {
201  return Teuchos::as<size_t>(this->mat_->NumMyNonzeros());
202  }
203 
204  template <class DerivedMat>
205  typename AbstractConcreteMatrixAdapter<
206  Epetra_RowMatrix,
207  DerivedMat>::global_size_t
208  AbstractConcreteMatrixAdapter<
209  Epetra_RowMatrix,
210  DerivedMat>::getGlobalNumRows_impl() const
211  {
212  return Teuchos::as<global_size_t>(this->mat_->NumGlobalRows());
213  }
214 
215  template <class DerivedMat>
216  typename AbstractConcreteMatrixAdapter<
217  Epetra_RowMatrix,
218  DerivedMat>::global_size_t
219  AbstractConcreteMatrixAdapter<
220  Epetra_RowMatrix,
221  DerivedMat>::getGlobalNumCols_impl() const
222  {
223  return Teuchos::as<global_size_t>(this->mat_->NumGlobalCols());
224  }
225 
226  template <class DerivedMat>
227  size_t
228  AbstractConcreteMatrixAdapter<
229  Epetra_RowMatrix,
230  DerivedMat>::getMaxRowNNZ_impl() const
231  {
232  return Teuchos::as<size_t>(this->mat_->MaxNumEntries());
233  }
234 
235  template <class DerivedMat>
236  size_t
237  AbstractConcreteMatrixAdapter<
238  Epetra_RowMatrix,
239  DerivedMat>::getMaxColNNZ_impl() const
240  {
241  TEUCHOS_TEST_FOR_EXCEPTION( true,
242  std::runtime_error,
243  "Column access to row-based object not yet supported. "
244  "Please contact the Amesos2 developers." );
245  }
246 
247  template <class DerivedMat>
248  size_t
249  AbstractConcreteMatrixAdapter<
250  Epetra_RowMatrix,
251  DerivedMat>::getGlobalRowNNZ_impl(global_ordinal_t row) const
252  {
253  // check whether row is local, then transform to local index
254  Epetra_Map rowmap = this->mat_->RowMatrixRowMap();
255  int gid = Teuchos::as<int>(row);
256  TEUCHOS_TEST_FOR_EXCEPTION( !rowmap.MyGID(gid),
257  std::invalid_argument,
258  "The specified global row id does not belong to me" );
259  int lid = rowmap.LID(gid);
260  int nnz = 0;
261  this->mat_->NumMyRowEntries(lid, nnz);
262  return nnz;
263  }
264 
265  template <class DerivedMat>
266  size_t
267  AbstractConcreteMatrixAdapter<
268  Epetra_RowMatrix,
269  DerivedMat>::getLocalRowNNZ_impl(local_ordinal_t row) const
270  {
271  Epetra_Map rowmap = this->mat_->RowMatrixRowMap();
272  int lid = Teuchos::as<int>(row);
273  TEUCHOS_TEST_FOR_EXCEPTION( !rowmap.MyLID(lid),
274  std::invalid_argument,
275  "The specified local row id does not beloing to me" );
276  int num_entries = 0;
277  this->mat_->NumMyRowEntries(row, num_entries);
278  return num_entries;
279  }
280 
281  template <class DerivedMat>
282  size_t
283  AbstractConcreteMatrixAdapter<
284  Epetra_RowMatrix,
285  DerivedMat>::getGlobalColNNZ_impl(global_ordinal_t col) const
286  {
287  TEUCHOS_TEST_FOR_EXCEPTION( true,
288  std::runtime_error,
289  "Column access to row-based object not yet supported. "
290  "Please contact the Amesos2 developers." );
291  }
292 
293  template <class DerivedMat>
294  size_t
295  AbstractConcreteMatrixAdapter<
296  Epetra_RowMatrix,
297  DerivedMat>::getLocalColNNZ_impl(local_ordinal_t col) const
298  {
299  TEUCHOS_TEST_FOR_EXCEPTION( true,
300  std::runtime_error,
301  "Column access to row-based object not yet supported. "
302  "Please contact the Amesos2 developers." );
303  }
304 
305  template <class DerivedMat>
306  const RCP<const Tpetra::Map<MatrixTraits<Epetra_RowMatrix>::local_ordinal_t,
307  MatrixTraits<Epetra_RowMatrix>::global_ordinal_t,
308  MatrixTraits<Epetra_RowMatrix>::node_t> >
309  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::getMap_impl() const
310  {
311  // Should Map() be used (returns Epetra_BlockMap)
312  /*
313  printf("Amesos2_EpetraRowMatrix_AbstractMatrixAdapter: Epetra does not support a 'getMap()' method. Returning rcp(Teuchos::null). \
314  If your map contains non-contiguous GIDs please use Tpetra instead of Epetra. \n");
315  */
316  return( Teuchos::null );
317  }
318 
319  template <class DerivedMat>
320  const RCP<const Tpetra::Map<MatrixTraits<Epetra_RowMatrix>::local_ordinal_t,
321  MatrixTraits<Epetra_RowMatrix>::global_ordinal_t,
322  MatrixTraits<Epetra_RowMatrix>::node_t> >
323  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::getRowMap_impl() const
324  {
325  // Must transform to a Tpetra::Map
326  const Epetra_Map rowmap = this->mat_->RowMatrixRowMap();
327  return( Util::epetra_map_to_tpetra_map<local_ordinal_t,global_ordinal_t,global_size_t,node_t>(rowmap) );
328  }
329 
330  template <class DerivedMat>
331  const RCP<const Tpetra::Map<MatrixTraits<Epetra_RowMatrix>::local_ordinal_t,
332  MatrixTraits<Epetra_RowMatrix>::global_ordinal_t,
333  MatrixTraits<Epetra_RowMatrix>::node_t> >
334  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::getColMap_impl() const
335  {
336  // Must transform this matrix' Epetra_Map to a Tpetra::Map
337  const Epetra_Map colmap = this->mat_->RowMatrixColMap();
338  return( Util::epetra_map_to_tpetra_map<local_ordinal_t,global_ordinal_t,global_size_t,node_t>(colmap) );
339  }
340 
341  template <class DerivedMat>
342  const RCP<const Teuchos::Comm<int> >
343  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::getComm_impl() const
344  {
345  return Util::to_teuchos_comm(Teuchos::rcpFromRef(this->mat_->Comm()));
346  }
347 
348  template <class DerivedMat>
349  bool
350  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::isLocallyIndexed_impl() const
351  {
352  return this->mat_->IndicesAreLocal();
353  }
354 
355  template <class DerivedMat>
356  bool
357  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::isGloballyIndexed_impl() const
358  {
359  return this->mat_->IndicesAreGlobal();
360  }
361 
362 
363  template <class DerivedMat>
364  RCP<const MatrixAdapter<DerivedMat> >
365  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::get_impl(const Teuchos::Ptr<const Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> > map, EDistribution distribution) const
366  {
367  // Delegate implementation to subclass
368 #ifdef __CUDACC__
369  // NVCC doesn't seem to like the static_cast, even though it is valid
370  return dynamic_cast<ConcreteMatrixAdapter<DerivedMat>*>(this)->get_impl(map, distribution);
371 #else
372  return static_cast<ConcreteMatrixAdapter<DerivedMat>*>(this)->get_impl(map, distribution);
373 #endif
374  }
375 
376  template <class DerivedMat>
377  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>
378  ::spmtx_ptr_t
379  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::getSparseRowPtr() const
380  {
381  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::spmtx_ptr_t sp_rowptr = nullptr;
382  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::spmtx_idx_t sp_colind = nullptr;
383  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::spmtx_val_t sp_values = nullptr;
384 
385  this->mat_->ExtractCrsDataPointers(sp_rowptr, sp_colind, sp_values);
386 
387  return sp_rowptr;
388  }
389 
390  template <class DerivedMat>
391  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>
392  ::spmtx_idx_t
393  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::getSparseColInd() const
394  {
395  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::spmtx_ptr_t sp_rowptr = nullptr;
396  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::spmtx_idx_t sp_colind = nullptr;
397  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::spmtx_val_t sp_values = nullptr;
398 
399  this->mat_->ExtractCrsDataPointers(sp_rowptr, sp_colind, sp_values);
400 
401  return sp_colind;
402  }
403 
404  template <class DerivedMat>
405  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>
406  ::spmtx_val_t
407  AbstractConcreteMatrixAdapter<Epetra_RowMatrix, DerivedMat>::getSparseValues() const
408  {
409  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::spmtx_ptr_t sp_rowptr = nullptr;
410  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::spmtx_idx_t sp_colind = nullptr;
411  typename AbstractConcreteMatrixAdapter<Epetra_RowMatrix,DerivedMat>::spmtx_val_t sp_values = nullptr;
412 
413  this->mat_->ExtractCrsDataPointers(sp_rowptr, sp_colind, sp_values);
414 
415  return sp_values;
416  }
417 
418 } // end namespace Amesos2
419 
420 #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