Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Zoltan2_XpetraCrsMatrixAdapter.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Zoltan2: A package of combinatorial algorithms for scientific computing
4 //
5 // Copyright 2012 NTESS and the Zoltan2 contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
14 #ifndef _ZOLTAN2_XPETRACRSMATRIXADAPTER_HPP_
15 #define _ZOLTAN2_XPETRACRSMATRIXADAPTER_HPP_
16 
18 #include <Zoltan2_StridedData.hpp>
19 #include <Zoltan2_XpetraTraits.hpp>
21 
22 #include <Xpetra_CrsMatrix.hpp>
23 
24 #include <iostream>
25 #include <cassert>
26 
27 namespace Zoltan2 {
28 
30 
52 template <typename User, typename UserCoord=User>
53  class XpetraCrsMatrixAdapter : public MatrixAdapter<User, UserCoord> {
54 public:
55 
56 #ifndef DOXYGEN_SHOULD_SKIP_THIS
57  using scalar_t = typename InputTraits<User>::scalar_t;
58  using lno_t = typename InputTraits<User>::lno_t;
59  using gno_t = typename InputTraits<User>::gno_t;
60  using part_t = typename InputTraits<User>::part_t;
61  using node_t = typename InputTraits<User>::node_t;
62  using offset_t = typename InputTraits<User>::offset_t;
63  using xmatrix_t = Xpetra::CrsMatrix<scalar_t, lno_t, gno_t, node_t>;
64 
65  using userCoord_t = UserCoord;
66  using user_t = User;
67 #endif
68 
74  XpetraCrsMatrixAdapter(const RCP<const User> &inmatrix,
75  int nWeightsPerRow=0);
76 
89  void setWeights(const scalar_t *weightVal, int stride, int idx = 0);
90 
106  void setRowWeights(const scalar_t *weightVal, int stride, int idx = 0);
107 
113  void setWeightIsDegree(int idx);
114 
120  void setRowWeightIsNumberOfNonZeros(int idx);
121 
123  // The MatrixAdapter interface.
125 
126  size_t getLocalNumRows() const {
127  return matrix_->getLocalNumRows();
128  }
129 
130  size_t getLocalNumColumns() const {
131  return matrix_->getLocalNumCols();
132  }
133 
134  size_t getLocalNumEntries() const {
135  return matrix_->getLocalNumEntries();
136  }
137 
138  bool CRSViewAvailable() const { return true; }
139 
140  void getRowIDsView(const gno_t *&rowIds) const
141  {
142  ArrayView<const gno_t> rowView = rowMap_->getLocalElementList();
143  rowIds = rowView.getRawPtr();
144  }
145 
146  void getCRSView(ArrayRCP<const offset_t> &offsets,
147  ArrayRCP<const gno_t> &colIds) const
148  {
149  ArrayRCP< const lno_t > localColumnIds;
150  ArrayRCP<const scalar_t> values;
151  matrix_->getAllValues(offsets,localColumnIds,values);
152  colIds = columnIds_;
153  }
154 
155  void getCRSView(ArrayRCP<const offset_t> &offsets,
156  ArrayRCP<const gno_t> &colIds,
157  ArrayRCP<const scalar_t> &values) const {
158  ArrayRCP< const lno_t > localColumnIds;
159  matrix_->getAllValues(offsets,localColumnIds,values);
160  colIds = columnIds_;
161  }
162 
163 
164  int getNumWeightsPerRow() const { return nWeightsPerRow_; }
165 
166  void getRowWeightsView(const scalar_t *&weights, int &stride,
167  int idx = 0) const
168  {
169  if(idx<0 || idx >= nWeightsPerRow_)
170  {
171  std::ostringstream emsg;
172  emsg << __FILE__ << ":" << __LINE__
173  << " Invalid row weight index " << idx << std::endl;
174  throw std::runtime_error(emsg.str());
175  }
176 
177  size_t length;
178  rowWeights_[idx].getStridedList(length, weights, stride);
179  }
180 
181  bool useNumNonzerosAsRowWeight(int idx) const { return numNzWeight_[idx];}
182 
183  template <typename Adapter>
184  void applyPartitioningSolution(const User &in, User *&out,
185  const PartitioningSolution<Adapter> &solution) const;
186 
187  template <typename Adapter>
188  void applyPartitioningSolution(const User &in, RCP<User> &out,
189  const PartitioningSolution<Adapter> &solution) const;
190 
191 private:
192 
193  RCP<const User> inmatrix_;
194  RCP<const xmatrix_t> matrix_;
195  RCP<const Xpetra::Map<lno_t, gno_t, node_t> > rowMap_;
196  RCP<const Xpetra::Map<lno_t, gno_t, node_t> > colMap_;
197  lno_t base_;
198  ArrayRCP<gno_t> columnIds_; // TODO: Refactor adapter to localColumnIds_
199 
200  int nWeightsPerRow_;
201  ArrayRCP<StridedData<lno_t, scalar_t> > rowWeights_;
202  ArrayRCP<bool> numNzWeight_;
203 
204  bool mayHaveDiagonalEntries;
205 };
206 
208 // Definitions
210 
211 template <typename User, typename UserCoord>
213  const RCP<const User> &inmatrix, int nWeightsPerRow):
214  inmatrix_(inmatrix), matrix_(), rowMap_(), colMap_(),
215  columnIds_(),
216  nWeightsPerRow_(nWeightsPerRow), rowWeights_(), numNzWeight_(),
217  mayHaveDiagonalEntries(true)
218 {
219  typedef StridedData<lno_t,scalar_t> input_t;
220  try {
221  matrix_ = rcp_const_cast<const xmatrix_t>(
222  XpetraTraits<User>::convertToXpetra(rcp_const_cast<User>(inmatrix)));
223  }
225 
226  rowMap_ = matrix_->getRowMap();
227  colMap_ = matrix_->getColMap();
228 
229  size_t nrows = matrix_->getLocalNumRows();
230  size_t nnz = matrix_->getLocalNumEntries();
231 
232  // Get ArrayRCP pointers to the structures in the underlying matrix
233  ArrayRCP< const offset_t > offset;
234  ArrayRCP< const lno_t > localColumnIds;
235  ArrayRCP< const scalar_t > values;
236  matrix_->getAllValues(offset,localColumnIds,values);
237  columnIds_.resize(nnz, 0);
238 
239  for(offset_t i = 0; i < offset[nrows]; i++){
240  columnIds_[i] = colMap_->getGlobalElement(localColumnIds[i]);
241  }
242 
243  if (nWeightsPerRow_ > 0){
244  rowWeights_ = arcp(new input_t [nWeightsPerRow_], 0, nWeightsPerRow_, true);
245  numNzWeight_ = arcp(new bool [nWeightsPerRow_], 0, nWeightsPerRow_, true);
246  for (int i=0; i < nWeightsPerRow_; i++)
247  numNzWeight_[i] = false;
248  }
249 }
250 
252 template <typename User, typename UserCoord>
254  const scalar_t *weightVal, int stride, int idx)
255 {
256  if (this->getPrimaryEntityType() == MATRIX_ROW)
257  setRowWeights(weightVal, stride, idx);
258  else {
259  // TODO: Need to allow weights for columns and/or nonzeros
260  std::ostringstream emsg;
261  emsg << __FILE__ << "," << __LINE__
262  << " error: setWeights not yet supported for"
263  << " columns or nonzeros."
264  << std::endl;
265  throw std::runtime_error(emsg.str());
266  }
267 }
268 
270 template <typename User, typename UserCoord>
272  const scalar_t *weightVal, int stride, int idx)
273 {
274  typedef StridedData<lno_t,scalar_t> input_t;
275  if(idx<0 || idx >= nWeightsPerRow_)
276  {
277  std::ostringstream emsg;
278  emsg << __FILE__ << ":" << __LINE__
279  << " Invalid row weight index " << idx << std::endl;
280  throw std::runtime_error(emsg.str());
281  }
282 
283  size_t nvtx = getLocalNumRows();
284  ArrayRCP<const scalar_t> weightV(weightVal, 0, nvtx*stride, false);
285  rowWeights_[idx] = input_t(weightV, stride);
286 }
287 
289 template <typename User, typename UserCoord>
291  int idx)
292 {
293  if (this->getPrimaryEntityType() == MATRIX_ROW)
294  setRowWeightIsNumberOfNonZeros(idx);
295  else {
296  // TODO: Need to allow weights for columns and/or nonzeros
297  std::ostringstream emsg;
298  emsg << __FILE__ << "," << __LINE__
299  << " error: setWeightIsNumberOfNonZeros not yet supported for"
300  << " columns" << std::endl;
301  throw std::runtime_error(emsg.str());
302  }
303 }
304 
306 template <typename User, typename UserCoord>
308  int idx)
309 {
310  if(idx<0 || idx >= nWeightsPerRow_)
311  {
312  std::ostringstream emsg;
313  emsg << __FILE__ << ":" << __LINE__
314  << " Invalid row weight index " << idx << std::endl;
315  throw std::runtime_error(emsg.str());
316  }
317 
318 
319  numNzWeight_[idx] = true;
320 }
321 
323 template <typename User, typename UserCoord>
324  template <typename Adapter>
326  const User &in, User *&out,
327  const PartitioningSolution<Adapter> &solution) const
328 {
329  // Get an import list (rows to be received)
330  size_t numNewRows;
331  ArrayRCP<gno_t> importList;
332  try{
333  numNewRows = Zoltan2::getImportList<Adapter,
335  (solution, this, importList);
336  }
338 
339  // Move the rows, creating a new matrix.
340  RCP<User> outPtr = XpetraTraits<User>::doMigration(in, numNewRows,
341  importList.getRawPtr());
342  out = const_cast<User *>(outPtr.get());
343  outPtr.release();
344 }
345 
347 template <typename User, typename UserCoord>
348  template <typename Adapter>
350  const User &in, RCP<User> &out,
351  const PartitioningSolution<Adapter> &solution) const
352 {
353  // Get an import list (rows to be received)
354  size_t numNewRows;
355  ArrayRCP<gno_t> importList;
356  try{
357  numNewRows = Zoltan2::getImportList<Adapter,
359  (solution, this, importList);
360  }
362 
363  // Move the rows, creating a new matrix.
364  out = XpetraTraits<User>::doMigration(in, numNewRows,
365  importList.getRawPtr());
366 }
367 
368 } //namespace Zoltan2
369 
370 #endif
Helper functions for Partitioning Problems.
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
void setRowWeights(const scalar_t *weightVal, int stride, int idx=0)
Specify a weight for each row.
typename InputTraits< User >::scalar_t scalar_t
MatrixAdapter defines the adapter interface for matrices.
static ArrayRCP< ArrayRCP< zscalar_t > > weights
Provides access for Zoltan2 to Xpetra::CrsMatrix data.
void getRowWeightsView(const scalar_t *&weights, int &stride, int idx=0) const
Provide a pointer to the row weights, if any.
default_part_t part_t
The data type to represent part numbers.
default_offset_t offset_t
The data type to represent offsets.
map_t::global_ordinal_type gno_t
Definition: mapRemotes.cpp:27
Xpetra::CrsMatrix< zscalar_t, zlno_t, zgno_t, znode_t > xmatrix_t
static RCP< User > doMigration(const User &from, size_t numLocalRows, const gno_t *myNewRows)
Migrate the object Given a user object and a new row distribution, create and return a new user objec...
typename Zoltan2::InputTraits< ztcrsmatrix_t >::node_t node_t
int getNumWeightsPerRow() const
Returns the number of weights per row (0 or greater). Row weights may be used when partitioning matri...
size_t getLocalNumColumns() const
Returns the number of columns on this process.
void getCRSView(ArrayRCP< const offset_t > &offsets, ArrayRCP< const gno_t > &colIds) const
Traits of Xpetra classes, including migration method.
typename InputTraits< User >::part_t part_t
static RCP< User > convertToXpetra(const RCP< User > &a)
Convert the object to its Xpetra wrapped version.
size_t getImportList(const PartitioningSolution< SolutionAdapter > &solution, const DataAdapter *const data, ArrayRCP< typename DataAdapter::gno_t > &imports)
From a PartitioningSolution, get a list of IDs to be imported. Assumes part numbers in PartitioningSo...
void getCRSView(ArrayRCP< const offset_t > &offsets, ArrayRCP< const gno_t > &colIds, ArrayRCP< const scalar_t > &values) const
A PartitioningSolution is a solution to a partitioning problem.
XpetraCrsMatrixAdapter(const RCP< const User > &inmatrix, int nWeightsPerRow=0)
Constructor.
void setWeightIsDegree(int idx)
Specify an index for which the weight should be the degree of the entity.
size_t getLocalNumRows() const
Returns the number of rows on this process.
default_lno_t lno_t
The ordinal type (e.g., int, long, int64_t) that represents local counts and local indices...
The StridedData class manages lists of weights or coordinates.
map_t::local_ordinal_type lno_t
Definition: mapRemotes.cpp:26
default_gno_t gno_t
The ordinal type (e.g., int, long, int64_t) that can represent global counts and identifiers.
size_t getLocalNumEntries() const
Returns the number of nonzeros on this process.
default_node_t node_t
The Kokkos node type. This is only meaningful for users of Tpetra objects.
typename InputTraits< User >::offset_t offset_t
Defines the MatrixAdapter interface.
void setWeights(const scalar_t *weightVal, int stride, int idx=0)
Specify a weight for each entity of the primaryEntityType.
bool useNumNonzerosAsRowWeight(int idx) const
Indicate whether row weight with index idx should be the global number of nonzeros in the row...
void applyPartitioningSolution(const User &in, User *&out, const PartitioningSolution< Adapter > &solution) const
void setRowWeightIsNumberOfNonZeros(int idx)
Specify an index for which the row weight should be the global number of nonzeros in the row...
bool CRSViewAvailable() const
Indicates whether the MatrixAdapter implements a view of the matrix in compressed sparse row (CRS) fo...
default_scalar_t scalar_t
The data type for weights and coordinates.
void getRowIDsView(const gno_t *&rowIds) const
This file defines the StridedData class.