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
63namespace 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
Provides the Epetra_RowMatrix abstraction for the concrete Epetra row matric adapters.