14 #ifndef _ZOLTAN2_XPETRACRSMATRIXADAPTER_HPP_
15 #define _ZOLTAN2_XPETRACRSMATRIXADAPTER_HPP_
22 #include <Xpetra_CrsMatrix.hpp>
52 template <
typename User,
typename UserCoord=User>
56 #ifndef DOXYGEN_SHOULD_SKIP_THIS
63 using xmatrix_t = Xpetra::CrsMatrix<scalar_t, lno_t, gno_t, node_t>;
65 using userCoord_t = UserCoord;
79 int nWeightsPerRow=0);
131 return matrix_->getLocalNumRows();
135 return matrix_->getLocalNumCols();
139 return matrix_->getLocalNumEntries();
144 ArrayView<const gno_t> rowView = rowMap_->getLocalElementList();
145 rowIds = rowView.getRawPtr();
150 ArrayView<const gno_t> colView = colMap_->getLocalElementList();
151 colIds = colView.getRawPtr();
154 void getCRSView(ArrayRCP<const offset_t> &offsets, ArrayRCP<const gno_t> &colIds)
const
156 ArrayRCP< const lno_t > localColumnIds;
157 ArrayRCP<const scalar_t> values;
158 matrix_->getAllValues(offsets,localColumnIds,values);
165 ArrayRCP<const gno_t> &colIds,
166 ArrayRCP<const scalar_t> &values)
const {
167 ArrayRCP< const lno_t > localColumnIds;
168 matrix_->getAllValues(offsets,localColumnIds,values);
173 ArrayRCP<const gno_t> &rowIds)
const override {
174 ArrayRCP<const offset_t> crsOffsets;
175 ArrayRCP<const lno_t> crsLocalColumnIds;
176 ArrayRCP<const scalar_t> values;
177 matrix_->getAllValues(crsOffsets, crsLocalColumnIds, values);
179 const auto localRowIds = rowMap_->getLocalElementList();
180 const auto numLocalCols = colMap_->getLocalNumElements();
183 auto determineRow = [&crsOffsets, &localRowIds](
const int columnIdx) {
185 for (
int rowIdx = 0; rowIdx < localRowIds.size(); ++rowIdx) {
186 if (rowIdx < (localRowIds.size() - 1)) {
187 if (static_cast<offset_t>(columnIdx) < crsOffsets[rowIdx + 1]) {
200 std::vector<std::vector<gno_t>> rowIDsPerCol(numLocalCols);
202 for (
int colIdx = 0; colIdx < crsLocalColumnIds.size(); ++colIdx) {
203 const auto colID = crsLocalColumnIds[colIdx];
204 const auto globalRow = rowMap_->getGlobalElement(determineRow(colIdx));
206 rowIDsPerCol[colID].push_back(globalRow);
209 size_t offsetWrite = 0;
210 ArrayRCP<gno_t> ccsRowIds(values.size());
211 ArrayRCP<offset_t> ccsOffsets(colMap_->getLocalNumElements() + 1);
214 for (int64_t colID = 1; colID < ccsOffsets.size(); ++colID) {
215 const auto &rowIDs = rowIDsPerCol[colID - 1];
217 if (not rowIDs.empty()) {
218 std::copy(rowIDs.begin(), rowIDs.end(),
219 ccsRowIds.begin() + offsetWrite);
220 offsetWrite += rowIDs.size();
223 ccsOffsets[colID] = offsetWrite;
226 ccsOffsets[numLocalCols] = crsLocalColumnIds.size();
229 offsets = ccsOffsets;
237 if(idx<0 || idx >= nWeightsPerRow_)
239 std::ostringstream emsg;
240 emsg << __FILE__ <<
":" << __LINE__
241 <<
" Invalid row weight index " << idx << std::endl;
242 throw std::runtime_error(emsg.str());
246 rowWeights_[idx].getStridedList(length, weights, stride);
251 template <
typename Adapter>
255 template <
typename Adapter>
261 RCP<const User> inmatrix_;
262 RCP<const xmatrix_t> matrix_;
263 RCP<const Xpetra::Map<lno_t, gno_t, node_t> > rowMap_;
264 RCP<const Xpetra::Map<lno_t, gno_t, node_t> > colMap_;
266 ArrayRCP<gno_t> columnIds_;
269 ArrayRCP<StridedData<lno_t, scalar_t> > rowWeights_;
270 ArrayRCP<bool> numNzWeight_;
272 bool mayHaveDiagonalEntries;
279 template <
typename User,
typename UserCoord>
281 const RCP<const User> &inmatrix,
int nWeightsPerRow):
282 inmatrix_(inmatrix), matrix_(), rowMap_(), colMap_(),
284 nWeightsPerRow_(nWeightsPerRow), rowWeights_(), numNzWeight_(),
285 mayHaveDiagonalEntries(true)
289 matrix_ = rcp_const_cast<
const xmatrix_t>(
294 rowMap_ = matrix_->getRowMap();
295 colMap_ = matrix_->getColMap();
297 size_t nrows = matrix_->getLocalNumRows();
298 size_t nnz = matrix_->getLocalNumEntries();
301 ArrayRCP< const offset_t > offset;
302 ArrayRCP< const lno_t > localColumnIds;
303 ArrayRCP< const scalar_t > values;
304 matrix_->getAllValues(offset,localColumnIds,values);
305 columnIds_.resize(nnz, 0);
307 for (
offset_t i = 0; i < offset[nrows]; i++) {
308 columnIds_[i] = colMap_->getGlobalElement(localColumnIds[i]);
311 if (nWeightsPerRow_ > 0){
312 rowWeights_ = arcp(
new input_t [nWeightsPerRow_], 0, nWeightsPerRow_,
true);
313 numNzWeight_ = arcp(
new bool [nWeightsPerRow_], 0, nWeightsPerRow_,
true);
314 for (
int i=0; i < nWeightsPerRow_; i++)
315 numNzWeight_[i] =
false;
320 template <
typename User,
typename UserCoord>
322 const scalar_t *weightVal,
int stride,
int idx)
324 if (this->getPrimaryEntityType() ==
MATRIX_ROW)
325 setRowWeights(weightVal, stride, idx);
328 std::ostringstream emsg;
329 emsg << __FILE__ <<
"," << __LINE__
330 <<
" error: setWeights not yet supported for"
331 <<
" columns or nonzeros."
333 throw std::runtime_error(emsg.str());
338 template <
typename User,
typename UserCoord>
340 const scalar_t *weightVal,
int stride,
int idx)
343 if(idx<0 || idx >= nWeightsPerRow_)
345 std::ostringstream emsg;
346 emsg << __FILE__ <<
":" << __LINE__
347 <<
" Invalid row weight index " << idx << std::endl;
348 throw std::runtime_error(emsg.str());
351 size_t nvtx = getLocalNumRows();
352 ArrayRCP<const scalar_t> weightV(weightVal, 0, nvtx*stride,
false);
353 rowWeights_[idx] = input_t(weightV, stride);
357 template <
typename User,
typename UserCoord>
361 if (this->getPrimaryEntityType() ==
MATRIX_ROW)
362 setRowWeightIsNumberOfNonZeros(idx);
365 std::ostringstream emsg;
366 emsg << __FILE__ <<
"," << __LINE__
367 <<
" error: setWeightIsNumberOfNonZeros not yet supported for"
368 <<
" columns" << std::endl;
369 throw std::runtime_error(emsg.str());
374 template <
typename User,
typename UserCoord>
378 if(idx<0 || idx >= nWeightsPerRow_)
380 std::ostringstream emsg;
381 emsg << __FILE__ <<
":" << __LINE__
382 <<
" Invalid row weight index " << idx << std::endl;
383 throw std::runtime_error(emsg.str());
387 numNzWeight_[idx] =
true;
391 template <
typename User,
typename UserCoord>
392 template <
typename Adapter>
394 const User &in, User *&out,
399 ArrayRCP<gno_t> importList;
403 (solution,
this, importList);
409 importList.getRawPtr());
410 out =
const_cast<User *
>(outPtr.get());
415 template <
typename User,
typename UserCoord>
416 template <
typename Adapter>
418 const User &in, RCP<User> &out,
423 ArrayRCP<gno_t> importList;
427 (solution,
this, importList);
433 importList.getRawPtr());
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.
void getColumnIDsView(const gno_t *&colIds) const
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.
map_t::global_ordinal_type gno_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.
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
void getCCSView(ArrayRCP< const offset_t > &offsets, ArrayRCP< const gno_t > &rowIds) const override
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.
The StridedData class manages lists of weights or coordinates.
map_t::local_ordinal_type lno_t
size_t getLocalNumEntries() const
Returns the number of nonzeros on this process.
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...
void getRowIDsView(const gno_t *&rowIds) const
This file defines the StridedData class.
~XpetraCrsMatrixAdapter()
Destructor.