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 // ***********************************************************************
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(const offset_t *&offsets, const gno_t *&colIds) const
183  {
184  offsets = offset_.getRawPtr();
185  colIds = columnIds_.getRawPtr();
186  }
187 
188  void getCRSView(const offset_t *&offsets, const gno_t *&colIds,
189  const scalar_t *&values) const
190  {
191  offsets = offset_.getRawPtr();
192  colIds = columnIds_.getRawPtr();
193  values = values_.getRawPtr();
194  }
195 
196 
197  int getNumWeightsPerRow() const { return nWeightsPerRow_; }
198 
199  void getRowWeightsView(const scalar_t *&weights, int &stride,
200  int idx = 0) const
201  {
202  if(idx<0 || idx >= nWeightsPerRow_)
203  {
204  std::ostringstream emsg;
205  emsg << __FILE__ << ":" << __LINE__
206  << " Invalid row weight index " << idx << std::endl;
207  throw std::runtime_error(emsg.str());
208  }
209 
210  size_t length;
211  rowWeights_[idx].getStridedList(length, weights, stride);
212  }
213 
214  bool useNumNonzerosAsRowWeight(int idx) const { return numNzWeight_[idx];}
215 
216  template <typename Adapter>
217  void applyPartitioningSolution(const User &in, User *&out,
218  const PartitioningSolution<Adapter> &solution) const;
219 
220  template <typename Adapter>
221  void applyPartitioningSolution(const User &in, RCP<User> &out,
222  const PartitioningSolution<Adapter> &solution) const;
223 
224 private:
225 
226  RCP<const User> inmatrix_;
227  RCP<const xmatrix_t> matrix_;
228  RCP<const Xpetra::Map<lno_t, gno_t, node_t> > rowMap_;
229  RCP<const Xpetra::Map<lno_t, gno_t, node_t> > colMap_;
230  lno_t base_;
231  ArrayRCP< const offset_t > offset_;
232  ArrayRCP< const lno_t > localColumnIds_;
233  ArrayRCP< const scalar_t > values_;
234  ArrayRCP<gno_t> columnIds_; // TODO: Refactor adapter to localColumnIds_
235 
236  int nWeightsPerRow_;
237  ArrayRCP<StridedData<lno_t, scalar_t> > rowWeights_;
238  ArrayRCP<bool> numNzWeight_;
239 
240  bool mayHaveDiagonalEntries;
241 };
242 
244 // Definitions
246 
247 template <typename User, typename UserCoord>
249  const RCP<const User> &inmatrix, int nWeightsPerRow):
250  inmatrix_(inmatrix), matrix_(), rowMap_(), colMap_(),
251  offset_(), columnIds_(),
252  nWeightsPerRow_(nWeightsPerRow), rowWeights_(), numNzWeight_(),
253  mayHaveDiagonalEntries(true)
254 {
255  typedef StridedData<lno_t,scalar_t> input_t;
256  try {
257  matrix_ = rcp_const_cast<const xmatrix_t>(
258  XpetraTraits<User>::convertToXpetra(rcp_const_cast<User>(inmatrix)));
259  }
261 
262  rowMap_ = matrix_->getRowMap();
263  colMap_ = matrix_->getColMap();
264 
265  size_t nrows = matrix_->getNodeNumRows();
266  size_t nnz = matrix_->getNodeNumEntries();
267 
268  // Get ArrayRCP pointers to the structures in the underlying matrix
269  matrix_->getAllValues(offset_,localColumnIds_,values_);
270  columnIds_.resize(nnz, 0);
271 
272  for(offset_t i = 0; i < offset_[nrows]; i++) {
273  columnIds_[i] = colMap_->getGlobalElement(localColumnIds_[i]);
274  }
275 
276  if (nWeightsPerRow_ > 0){
277  rowWeights_ = arcp(new input_t [nWeightsPerRow_], 0, nWeightsPerRow_, true);
278  numNzWeight_ = arcp(new bool [nWeightsPerRow_], 0, nWeightsPerRow_, true);
279  for (int i=0; i < nWeightsPerRow_; i++)
280  numNzWeight_[i] = false;
281  }
282 }
283 
285 template <typename User, typename UserCoord>
287  const scalar_t *weightVal, int stride, int idx)
288 {
289  if (this->getPrimaryEntityType() == MATRIX_ROW)
290  setRowWeights(weightVal, stride, idx);
291  else {
292  // TODO: Need to allow weights for columns and/or nonzeros
293  std::ostringstream emsg;
294  emsg << __FILE__ << "," << __LINE__
295  << " error: setWeights not yet supported for"
296  << " columns or nonzeros."
297  << std::endl;
298  throw std::runtime_error(emsg.str());
299  }
300 }
301 
303 template <typename User, typename UserCoord>
305  const scalar_t *weightVal, int stride, int idx)
306 {
307  typedef StridedData<lno_t,scalar_t> input_t;
308  if(idx<0 || idx >= nWeightsPerRow_)
309  {
310  std::ostringstream emsg;
311  emsg << __FILE__ << ":" << __LINE__
312  << " Invalid row weight index " << idx << std::endl;
313  throw std::runtime_error(emsg.str());
314  }
315 
316  size_t nvtx = getLocalNumRows();
317  ArrayRCP<const scalar_t> weightV(weightVal, 0, nvtx*stride, false);
318  rowWeights_[idx] = input_t(weightV, stride);
319 }
320 
322 template <typename User, typename UserCoord>
324  int idx)
325 {
326  if (this->getPrimaryEntityType() == MATRIX_ROW)
327  setRowWeightIsNumberOfNonZeros(idx);
328  else {
329  // TODO: Need to allow weights for columns and/or nonzeros
330  std::ostringstream emsg;
331  emsg << __FILE__ << "," << __LINE__
332  << " error: setWeightIsNumberOfNonZeros not yet supported for"
333  << " columns" << std::endl;
334  throw std::runtime_error(emsg.str());
335  }
336 }
337 
339 template <typename User, typename UserCoord>
341  int idx)
342 {
343  if(idx<0 || idx >= nWeightsPerRow_)
344  {
345  std::ostringstream emsg;
346  emsg << __FILE__ << ":" << __LINE__
347  << " Invalid row weight index " << idx << std::endl;
348  throw std::runtime_error(emsg.str());
349  }
350 
351 
352  numNzWeight_[idx] = true;
353 }
354 
356 template <typename User, typename UserCoord>
357  template <typename Adapter>
359  const User &in, User *&out,
360  const PartitioningSolution<Adapter> &solution) const
361 {
362  // Get an import list (rows to be received)
363  size_t numNewRows;
364  ArrayRCP<gno_t> importList;
365  try{
366  numNewRows = Zoltan2::getImportList<Adapter,
368  (solution, this, importList);
369  }
371 
372  // Move the rows, creating a new matrix.
373  RCP<User> outPtr = XpetraTraits<User>::doMigration(in, numNewRows,
374  importList.getRawPtr());
375  out = const_cast<User *>(outPtr.get());
376  outPtr.release();
377 }
378 
380 template <typename User, typename UserCoord>
381  template <typename Adapter>
383  const User &in, RCP<User> &out,
384  const PartitioningSolution<Adapter> &solution) const
385 {
386  // Get an import list (rows to be received)
387  size_t numNewRows;
388  ArrayRCP<gno_t> importList;
389  try{
390  numNewRows = Zoltan2::getImportList<Adapter,
392  (solution, this, importList);
393  }
395 
396  // Move the rows, creating a new matrix.
397  out = XpetraTraits<User>::doMigration(in, numNewRows,
398  importList.getRawPtr());
399 }
400 
401 } //namespace Zoltan2
402 
403 #endif
InputTraits< User >::scalar_t scalar_t
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.
MatrixAdapter defines the adapter interface for matrices.
InputTraits< User >::gno_t gno_t
Provides access for Zoltan2 to Xpetra::CrsMatrix data.
void getRowWeightsView(const scalar_t *&weights, int &stride, int idx=0) const
default_part_t part_t
The data type to represent part numbers.
default_offset_t offset_t
The data type to represent offsets.
Xpetra::CrsMatrix< zscalar_t, zlno_t, zgno_t, znode_t > xmatrix_t
InputTraits< User >::lno_t lno_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...
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.
static ArrayRCP< ArrayRCP< zscalar_t > > weights
Traits of Xpetra classes, including migration method.
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...
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.
void getCRSView(const offset_t *&offsets, const gno_t *&colIds) const
InputTraits< User >::part_t part_t
void getCRSView(const offset_t *&offsets, const gno_t *&colIds, const scalar_t *&values) const
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.
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...
InputTraits< User >::offset_t offset_t
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.
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > user_t
Definition: Metric.cpp:74