Zoltan2
Loading...
Searching...
No Matches
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
13
14#ifndef _ZOLTAN2_XPETRACRSMATRIXADAPTER_HPP_
15#define _ZOLTAN2_XPETRACRSMATRIXADAPTER_HPP_
16
21
22#include <Xpetra_CrsMatrix.hpp>
23
24#include <iostream>
25#include <cassert>
26
27namespace Zoltan2 {
28
30
51
52template <typename User, typename UserCoord=User>
53 class XpetraCrsMatrixAdapter : public MatrixAdapter<User, UserCoord> {
54public:
55
56#ifndef DOXYGEN_SHOULD_SKIP_THIS
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;
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
88
89 void setWeights(const scalar_t *weightVal, int stride, int idx = 0);
90
105
106 void setRowWeights(const scalar_t *weightVal, int stride, int idx = 0);
107
113 void setWeightIsDegree(int idx);
114
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
191private:
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
211template <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
252template <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
270template <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
289template <typename User, typename UserCoord>
291 int idx)
292{
293 if (this->getPrimaryEntityType() == MATRIX_ROW)
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
306template <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
323template <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
347template <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
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > user_t
Definition Metric.cpp:39
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.
enum MatrixEntityType getPrimaryEntityType() const
A PartitioningSolution is a solution to a partitioning problem.
The StridedData class manages lists of weights or coordinates.
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...
void applyPartitioningSolution(const User &in, RCP< User > &out, const PartitioningSolution< Adapter > &solution) const
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
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.
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.
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...
static RCP< User > convertToXpetra(const RCP< User > &a)
Convert the object to its Xpetra wrapped version.