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 #include <iostream>
61 #include <cassert>
62 
63 namespace Zoltan2 {
64 
66 
88 template <typename User, typename UserCoord=User>
89  class XpetraCrsMatrixAdapter : public MatrixAdapter<User, UserCoord> {
90 public:
91 
92 #ifndef DOXYGEN_SHOULD_SKIP_THIS
93  using scalar_t = typename InputTraits<User>::scalar_t;
94  using lno_t = typename InputTraits<User>::lno_t;
95  using gno_t = typename InputTraits<User>::gno_t;
96  using part_t = typename InputTraits<User>::part_t;
97  using node_t = typename InputTraits<User>::node_t;
98  using offset_t = typename InputTraits<User>::offset_t;
99  using xmatrix_t = Xpetra::CrsMatrix<scalar_t, lno_t, gno_t, node_t>;
100 
101  using userCoord_t = UserCoord;
102  using user_t = User;
103 #endif
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_->getLocalNumRows();
164  }
165 
166  size_t getLocalNumColumns() const {
167  return matrix_->getLocalNumCols();
168  }
169 
170  size_t getLocalNumEntries() const {
171  return matrix_->getLocalNumEntries();
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_->getLocalElementList();
179  rowIds = rowView.getRawPtr();
180  }
181 
182  void getCRSView(ArrayRCP<const offset_t> &offsets,
183  ArrayRCP<const gno_t> &colIds) const
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  ArrayRCP< const lno_t > localColumnIds;
195  matrix_->getAllValues(offsets,localColumnIds,values);
196  colIds = columnIds_;
197  }
198 
199 
200  int getNumWeightsPerRow() const { return nWeightsPerRow_; }
201 
202  void getRowWeightsView(const scalar_t *&weights, int &stride,
203  int idx = 0) const
204  {
205  if(idx<0 || idx >= nWeightsPerRow_)
206  {
207  std::ostringstream emsg;
208  emsg << __FILE__ << ":" << __LINE__
209  << " Invalid row weight index " << idx << std::endl;
210  throw std::runtime_error(emsg.str());
211  }
212 
213  size_t length;
214  rowWeights_[idx].getStridedList(length, weights, stride);
215  }
216 
217  bool useNumNonzerosAsRowWeight(int idx) const { return numNzWeight_[idx];}
218 
219  template <typename Adapter>
220  void applyPartitioningSolution(const User &in, User *&out,
221  const PartitioningSolution<Adapter> &solution) const;
222 
223  template <typename Adapter>
224  void applyPartitioningSolution(const User &in, RCP<User> &out,
225  const PartitioningSolution<Adapter> &solution) const;
226 
227 private:
228 
229  RCP<const User> inmatrix_;
230  RCP<const xmatrix_t> matrix_;
231  RCP<const Xpetra::Map<lno_t, gno_t, node_t> > rowMap_;
232  RCP<const Xpetra::Map<lno_t, gno_t, node_t> > colMap_;
233  lno_t base_;
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  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_->getLocalNumRows();
266  size_t nnz = matrix_->getLocalNumEntries();
267 
268  // Get ArrayRCP pointers to the structures in the underlying matrix
269  ArrayRCP< const offset_t > offset;
270  ArrayRCP< const lno_t > localColumnIds;
271  ArrayRCP< const scalar_t > values;
272  matrix_->getAllValues(offset,localColumnIds,values);
273  columnIds_.resize(nnz, 0);
274 
275  for(offset_t i = 0; i < offset[nrows]; i++){
276  columnIds_[i] = colMap_->getGlobalElement(localColumnIds[i]);
277  }
278 
279  if (nWeightsPerRow_ > 0){
280  rowWeights_ = arcp(new input_t [nWeightsPerRow_], 0, nWeightsPerRow_, true);
281  numNzWeight_ = arcp(new bool [nWeightsPerRow_], 0, nWeightsPerRow_, true);
282  for (int i=0; i < nWeightsPerRow_; i++)
283  numNzWeight_[i] = false;
284  }
285 }
286 
288 template <typename User, typename UserCoord>
290  const scalar_t *weightVal, int stride, int idx)
291 {
292  if (this->getPrimaryEntityType() == MATRIX_ROW)
293  setRowWeights(weightVal, stride, idx);
294  else {
295  // TODO: Need to allow weights for columns and/or nonzeros
296  std::ostringstream emsg;
297  emsg << __FILE__ << "," << __LINE__
298  << " error: setWeights not yet supported for"
299  << " columns or nonzeros."
300  << std::endl;
301  throw std::runtime_error(emsg.str());
302  }
303 }
304 
306 template <typename User, typename UserCoord>
308  const scalar_t *weightVal, int stride, int idx)
309 {
310  typedef StridedData<lno_t,scalar_t> input_t;
311  if(idx<0 || idx >= nWeightsPerRow_)
312  {
313  std::ostringstream emsg;
314  emsg << __FILE__ << ":" << __LINE__
315  << " Invalid row weight index " << idx << std::endl;
316  throw std::runtime_error(emsg.str());
317  }
318 
319  size_t nvtx = getLocalNumRows();
320  ArrayRCP<const scalar_t> weightV(weightVal, 0, nvtx*stride, false);
321  rowWeights_[idx] = input_t(weightV, stride);
322 }
323 
325 template <typename User, typename UserCoord>
327  int idx)
328 {
329  if (this->getPrimaryEntityType() == MATRIX_ROW)
330  setRowWeightIsNumberOfNonZeros(idx);
331  else {
332  // TODO: Need to allow weights for columns and/or nonzeros
333  std::ostringstream emsg;
334  emsg << __FILE__ << "," << __LINE__
335  << " error: setWeightIsNumberOfNonZeros not yet supported for"
336  << " columns" << std::endl;
337  throw std::runtime_error(emsg.str());
338  }
339 }
340 
342 template <typename User, typename UserCoord>
344  int idx)
345 {
346  if(idx<0 || idx >= nWeightsPerRow_)
347  {
348  std::ostringstream emsg;
349  emsg << __FILE__ << ":" << __LINE__
350  << " Invalid row weight index " << idx << std::endl;
351  throw std::runtime_error(emsg.str());
352  }
353 
354 
355  numNzWeight_[idx] = true;
356 }
357 
359 template <typename User, typename UserCoord>
360  template <typename Adapter>
362  const User &in, User *&out,
363  const PartitioningSolution<Adapter> &solution) const
364 {
365  // Get an import list (rows to be received)
366  size_t numNewRows;
367  ArrayRCP<gno_t> importList;
368  try{
369  numNewRows = Zoltan2::getImportList<Adapter,
371  (solution, this, importList);
372  }
374 
375  // Move the rows, creating a new matrix.
376  RCP<User> outPtr = XpetraTraits<User>::doMigration(in, numNewRows,
377  importList.getRawPtr());
378  out = const_cast<User *>(outPtr.get());
379  outPtr.release();
380 }
381 
383 template <typename User, typename UserCoord>
384  template <typename Adapter>
386  const User &in, RCP<User> &out,
387  const PartitioningSolution<Adapter> &solution) const
388 {
389  // Get an import list (rows to be received)
390  size_t numNewRows;
391  ArrayRCP<gno_t> importList;
392  try{
393  numNewRows = Zoltan2::getImportList<Adapter,
395  (solution, this, importList);
396  }
398 
399  // Move the rows, creating a new matrix.
400  out = XpetraTraits<User>::doMigration(in, numNewRows,
401  importList.getRawPtr());
402 }
403 
404 } //namespace Zoltan2
405 
406 #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:18
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:17
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.