Zoltan2
Zoltan2_XpetraCrsMatrixAdapter.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Zoltan2: A package of combinatorial algorithms for scientific computing
6 // Copyright 2012 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 Karen Devine (kddevin@sandia.gov)
39 // Erik Boman (egboman@sandia.gov)
40 // Siva Rajamanickam (srajama@sandia.gov)
41 //
42 // ***********************************************************************
43 //
44 // @HEADER
45 
50 #ifndef _ZOLTAN2_XPETRACRSMATRIXADAPTER_HPP_
51 #define _ZOLTAN2_XPETRACRSMATRIXADAPTER_HPP_
52 
54 #include <Zoltan2_StridedData.hpp>
55 #include <Zoltan2_XpetraTraits.hpp>
57 
58 #include <Xpetra_CrsMatrix.hpp>
59 
60 namespace Zoltan2 {
61 
63 
85 template <typename User, typename UserCoord=User>
86  class XpetraCrsMatrixAdapter : public MatrixAdapter<User,UserCoord> {
87 public:
88 
89 #ifndef DOXYGEN_SHOULD_SKIP_THIS
90  typedef typename InputTraits<User>::scalar_t scalar_t;
91  typedef typename InputTraits<User>::lno_t lno_t;
92  typedef typename InputTraits<User>::gno_t gno_t;
93  typedef typename InputTraits<User>::part_t part_t;
94  typedef typename InputTraits<User>::node_t node_t;
95  typedef typename InputTraits<User>::offset_t offset_t;
96  typedef Xpetra::CrsMatrix<scalar_t, lno_t, gno_t, node_t> xmatrix_t;
97  typedef User user_t;
98  typedef UserCoord userCoord_t;
99 #endif
100 
104 
110  XpetraCrsMatrixAdapter(const RCP<const User> &inmatrix,
111  int nWeightsPerRow=0);
112 
125  void setWeights(const scalar_t *weightVal, int stride, int idx = 0);
126 
142  void setRowWeights(const scalar_t *weightVal, int stride, int idx = 0);
143 
149  void setWeightIsDegree(int idx);
150 
156  void setRowWeightIsNumberOfNonZeros(int idx);
157 
159  // The MatrixAdapter interface.
161 
162  size_t getLocalNumRows() const {
163  return matrix_->getNodeNumRows();
164  }
165 
166  size_t getLocalNumColumns() const {
167  return matrix_->getNodeNumCols();
168  }
169 
170  size_t getLocalNumEntries() const {
171  return matrix_->getNodeNumEntries();
172  }
173 
174  bool CRSViewAvailable() const { return true; }
175 
176  void getRowIDsView(const gno_t *&rowIds) const
177  {
178  ArrayView<const gno_t> rowView = rowMap_->getNodeElementList();
179  rowIds = rowView.getRawPtr();
180  }
181 
182  void getCRSView(ArrayRCP<const offset_t> &offsets, ArrayRCP<const gno_t> &colIds) const
183  {
184 
185  ArrayRCP< const lno_t > localColumnIds;
186  ArrayRCP<const scalar_t> values;
187  matrix_->getAllValues(offsets,localColumnIds,values);
188  colIds = columnIds_;
189  }
190 
191  void getCRSView(ArrayRCP<const offset_t> &offsets,
192  ArrayRCP<const gno_t> &colIds,
193  ArrayRCP<const scalar_t> &values) const
194  {
195  ArrayRCP< const lno_t > localColumnIds;
196  matrix_->getAllValues(offsets,localColumnIds,values);
197  colIds = columnIds_;
198  }
199 
200 
201  int getNumWeightsPerRow() const { return nWeightsPerRow_; }
202 
203  void getRowWeightsView(const scalar_t *&weights, int &stride,
204  int idx = 0) const
205  {
206  if(idx<0 || idx >= nWeightsPerRow_)
207  {
208  std::ostringstream emsg;
209  emsg << __FILE__ << ":" << __LINE__
210  << " Invalid row weight index " << idx << std::endl;
211  throw std::runtime_error(emsg.str());
212  }
213 
214  size_t length;
215  rowWeights_[idx].getStridedList(length, weights, stride);
216  }
217 
218  bool useNumNonzerosAsRowWeight(int idx) const { return numNzWeight_[idx];}
219 
220  template <typename Adapter>
221  void applyPartitioningSolution(const User &in, User *&out,
222  const PartitioningSolution<Adapter> &solution) const;
223 
224  template <typename Adapter>
225  void applyPartitioningSolution(const User &in, RCP<User> &out,
226  const PartitioningSolution<Adapter> &solution) const;
227 
228 private:
229 
230  RCP<const User> inmatrix_;
231  RCP<const xmatrix_t> matrix_;
232  RCP<const Xpetra::Map<lno_t, gno_t, node_t> > rowMap_;
233  RCP<const Xpetra::Map<lno_t, gno_t, node_t> > colMap_;
234  lno_t base_;
235  ArrayRCP<gno_t> columnIds_; // TODO: Refactor adapter to localColumnIds_
236 
237  int nWeightsPerRow_;
238  ArrayRCP<StridedData<lno_t, scalar_t> > rowWeights_;
239  ArrayRCP<bool> numNzWeight_;
240 
241  bool mayHaveDiagonalEntries;
242 };
243 
245 // Definitions
247 
248 template <typename User, typename UserCoord>
250  const RCP<const User> &inmatrix, int nWeightsPerRow):
251  inmatrix_(inmatrix), matrix_(), rowMap_(), colMap_(),
252  columnIds_(),
253  nWeightsPerRow_(nWeightsPerRow), rowWeights_(), numNzWeight_(),
254  mayHaveDiagonalEntries(true)
255 {
256  typedef StridedData<lno_t,scalar_t> input_t;
257  try {
258  matrix_ = rcp_const_cast<const xmatrix_t>(
259  XpetraTraits<User>::convertToXpetra(rcp_const_cast<User>(inmatrix)));
260  }
262 
263  rowMap_ = matrix_->getRowMap();
264  colMap_ = matrix_->getColMap();
265 
266  size_t nrows = matrix_->getNodeNumRows();
267  size_t nnz = matrix_->getNodeNumEntries();
268 
269  // Get ArrayRCP pointers to the structures in the underlying matrix
270  ArrayRCP< const offset_t > offset;
271  ArrayRCP< const lno_t > localColumnIds;
272  ArrayRCP< const scalar_t > values;
273  matrix_->getAllValues(offset,localColumnIds,values);
274  columnIds_.resize(nnz, 0);
275 
276  for(offset_t i = 0; i < offset[nrows]; i++) {
277  columnIds_[i] = colMap_->getGlobalElement(localColumnIds[i]);
278  }
279 
280  if (nWeightsPerRow_ > 0){
281  rowWeights_ = arcp(new input_t [nWeightsPerRow_], 0, nWeightsPerRow_, true);
282  numNzWeight_ = arcp(new bool [nWeightsPerRow_], 0, nWeightsPerRow_, true);
283  for (int i=0; i < nWeightsPerRow_; i++)
284  numNzWeight_[i] = false;
285  }
286 }
287 
289 template <typename User, typename UserCoord>
291  const scalar_t *weightVal, int stride, int idx)
292 {
293  if (this->getPrimaryEntityType() == MATRIX_ROW)
294  setRowWeights(weightVal, stride, idx);
295  else {
296  // TODO: Need to allow weights for columns and/or nonzeros
297  std::ostringstream emsg;
298  emsg << __FILE__ << "," << __LINE__
299  << " error: setWeights not yet supported for"
300  << " columns or nonzeros."
301  << std::endl;
302  throw std::runtime_error(emsg.str());
303  }
304 }
305 
307 template <typename User, typename UserCoord>
309  const scalar_t *weightVal, int stride, int idx)
310 {
311  typedef StridedData<lno_t,scalar_t> input_t;
312  if(idx<0 || idx >= nWeightsPerRow_)
313  {
314  std::ostringstream emsg;
315  emsg << __FILE__ << ":" << __LINE__
316  << " Invalid row weight index " << idx << std::endl;
317  throw std::runtime_error(emsg.str());
318  }
319 
320  size_t nvtx = getLocalNumRows();
321  ArrayRCP<const scalar_t> weightV(weightVal, 0, nvtx*stride, false);
322  rowWeights_[idx] = input_t(weightV, stride);
323 }
324 
326 template <typename User, typename UserCoord>
328  int idx)
329 {
330  if (this->getPrimaryEntityType() == MATRIX_ROW)
331  setRowWeightIsNumberOfNonZeros(idx);
332  else {
333  // TODO: Need to allow weights for columns and/or nonzeros
334  std::ostringstream emsg;
335  emsg << __FILE__ << "," << __LINE__
336  << " error: setWeightIsNumberOfNonZeros not yet supported for"
337  << " columns" << std::endl;
338  throw std::runtime_error(emsg.str());
339  }
340 }
341 
343 template <typename User, typename UserCoord>
345  int idx)
346 {
347  if(idx<0 || idx >= nWeightsPerRow_)
348  {
349  std::ostringstream emsg;
350  emsg << __FILE__ << ":" << __LINE__
351  << " Invalid row weight index " << idx << std::endl;
352  throw std::runtime_error(emsg.str());
353  }
354 
355 
356  numNzWeight_[idx] = true;
357 }
358 
360 template <typename User, typename UserCoord>
361  template <typename Adapter>
363  const User &in, User *&out,
364  const PartitioningSolution<Adapter> &solution) const
365 {
366  // Get an import list (rows to be received)
367  size_t numNewRows;
368  ArrayRCP<gno_t> importList;
369  try{
370  numNewRows = Zoltan2::getImportList<Adapter,
372  (solution, this, importList);
373  }
375 
376  // Move the rows, creating a new matrix.
377  RCP<User> outPtr = XpetraTraits<User>::doMigration(in, numNewRows,
378  importList.getRawPtr());
379  out = const_cast<User *>(outPtr.get());
380  outPtr.release();
381 }
382 
384 template <typename User, typename UserCoord>
385  template <typename Adapter>
387  const User &in, RCP<User> &out,
388  const PartitioningSolution<Adapter> &solution) const
389 {
390  // Get an import list (rows to be received)
391  size_t numNewRows;
392  ArrayRCP<gno_t> importList;
393  try{
394  numNewRows = Zoltan2::getImportList<Adapter,
396  (solution, this, importList);
397  }
399 
400  // Move the rows, creating a new matrix.
401  out = XpetraTraits<User>::doMigration(in, numNewRows,
402  importList.getRawPtr());
403 }
404 
405 } //namespace Zoltan2
406 
407 #endif
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > user_t
Definition: Metric.cpp:74
Xpetra::CrsMatrix< zscalar_t, zlno_t, zgno_t, znode_t > xmatrix_t
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
Defines the MatrixAdapter interface.
Helper functions for Partitioning Problems.
This file defines the StridedData class.
Traits of Xpetra classes, including migration method.
InputTraits< User >::node_t node_t
InputTraits< User >::offset_t offset_t
InputTraits< User >::part_t part_t
InputTraits< User >::scalar_t scalar_t
InputTraits< User >::lno_t lno_t
InputTraits< User >::gno_t gno_t
MatrixAdapter defines the adapter interface for matrices.
A PartitioningSolution is a solution to a partitioning problem.
The StridedData class manages lists of weights or coordinates.
Provides access for Zoltan2 to Xpetra::CrsMatrix data.
void applyPartitioningSolution(const User &in, User *&out, const PartitioningSolution< Adapter > &solution) const
bool CRSViewAvailable() const
Indicates whether the MatrixAdapter implements a view of the matrix in compressed sparse row (CRS) fo...
bool useNumNonzerosAsRowWeight(int idx) const
Indicate whether row weight with index idx should be the global number of nonzeros in the row.
void getCRSView(ArrayRCP< const offset_t > &offsets, ArrayRCP< const gno_t > &colIds) const
void getRowIDsView(const gno_t *&rowIds) const
size_t getLocalNumColumns() const
Returns the number of columns on this process.
size_t getLocalNumEntries() const
Returns the number of nonzeros on this process.
void setRowWeights(const scalar_t *weightVal, int stride, int idx=0)
Specify a weight for each row.
size_t getLocalNumRows() const
Returns the number of rows on this process.
int getNumWeightsPerRow() const
Returns the number of weights per row (0 or greater). Row weights may be used when partitioning matri...
void setWeights(const scalar_t *weightVal, int stride, int idx=0)
Specify a weight for each entity of the primaryEntityType.
void getRowWeightsView(const scalar_t *&weights, int &stride, int idx=0) const
Provide a pointer to the row weights, if any.
void getCRSView(ArrayRCP< const offset_t > &offsets, ArrayRCP< const gno_t > &colIds, ArrayRCP< const scalar_t > &values) const
void setWeightIsDegree(int idx)
Specify an index for which the weight should be the degree of the entity.
void setRowWeightIsNumberOfNonZeros(int idx)
Specify an index for which the row weight should be the global number of nonzeros in the row.
XpetraCrsMatrixAdapter(const RCP< const User > &inmatrix, int nWeightsPerRow=0)
Constructor
map_t::local_ordinal_type lno_t
Definition: mapRemotes.cpp:17
map_t::global_ordinal_type gno_t
Definition: mapRemotes.cpp:18
Created by mbenlioglu on Aug 31, 2020.
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...
static ArrayRCP< ArrayRCP< zscalar_t > > weights
default_offset_t offset_t
The data type to represent offsets.
default_gno_t gno_t
The ordinal type (e.g., int, long, int64_t) that can represent global counts and identifiers.
default_node_t node_t
The Kokkos node type. This is only meaningful for users of Tpetra objects.
default_lno_t lno_t
The ordinal type (e.g., int, long, int64_t) that represents local counts and local indices.
default_part_t part_t
The data type to represent part numbers.
default_scalar_t scalar_t
The data type for weights and coordinates.
Defines the traits required for Tpetra, Eptra and Xpetra objects.
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...