Zoltan2
Loading...
Searching...
No Matches
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
57
58#include <Xpetra_CrsMatrix.hpp>
59
60namespace Zoltan2 {
61
63
85template <typename User, typename UserCoord=User>
86 class XpetraCrsMatrixAdapter : public MatrixAdapter<User,UserCoord> {
87public:
88
89#ifndef DOXYGEN_SHOULD_SKIP_THIS
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;
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_->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, 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
228private:
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
248template <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_->getLocalNumRows();
267 size_t nnz = matrix_->getLocalNumEntries();
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
289template <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
307template <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
326template <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
343template <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
360template <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,
371 XpetraCrsMatrixAdapter<User,UserCoord> >
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
384template <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,
395 XpetraCrsMatrixAdapter<User,UserCoord> >
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.
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
map_t::global_ordinal_type gno_t
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...