Zoltan2
Loading...
Searching...
No Matches
Zoltan2_XpetraCrsGraphAdapter.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
14#ifndef _ZOLTAN2_XPETRACRSGRAPHADAPTER_HPP_
15#define _ZOLTAN2_XPETRACRSGRAPHADAPTER_HPP_
16
21
22#include <Xpetra_CrsGraph.hpp>
23
24namespace Zoltan2 {
25
47template <typename User, typename UserCoord=User>
48 class XpetraCrsGraphAdapter : public GraphAdapter<User,UserCoord> {
49
50public:
51
52#ifndef DOXYGEN_SHOULD_SKIP_THIS
55 typedef typename InputTraits<User>::lno_t lno_t;
56 typedef typename InputTraits<User>::gno_t gno_t;
57 typedef typename InputTraits<User>::part_t part_t;
58 typedef typename InputTraits<User>::node_t node_t;
59 typedef Xpetra::CrsGraph<lno_t, gno_t, node_t> xgraph_t;
60 typedef User user_t;
61 typedef UserCoord userCoord_t;
62
64#endif
65
75 XpetraCrsGraphAdapter(const RCP<const User> &ingraph,
76 int nVtxWeights=0, int nEdgeWeights=0);
77
90 void setWeights(const scalar_t *val, int stride, int idx);
91 void setWeightsDevice(typename Base::ConstWeightsDeviceView& val, int idx) {}
92 void setWeightsHost(typename Base::ConstWeightsHostView& val, int idx) {}
93
109 void setVertexWeights(const scalar_t *val, int stride, int idx);
110 void setVertexWeightsDevice(typename Base::ConstWeightsDeviceView& val, int idx);
111 void setVertexWeightsHost(typename Base::ConstWeightsHostView& val, int idx);
112
118 void setWeightIsDegree(int idx);
119
125 void setVertexWeightIsDegree(int idx);
126
149 void setEdgeWeights(const scalar_t *val, int stride, int idx);
150 void setEdgeWeightsDevice(typename Base::ConstWeightsDeviceView& val, int idx);
151 void setEdgeWeightsHost(typename Base::ConstWeightsHostView& val, int idx);
152
155 RCP<const xgraph_t> getXpetraGraph() const { return graph_; }
156
159 RCP<const User> getUserGraph() const { return ingraph_; }
160
162 // The GraphAdapter interface.
164
165 // TODO: Assuming rows == objects;
166 // TODO: Need to add option for columns or nonzeros?
167 size_t getLocalNumVertices() const override { return graph_->getLocalNumRows(); }
168
169 void getVertexIDsView(const gno_t *&ids) const override
170 {
171 ids = NULL;
173 ids = graph_->getRowMap()->getLocalElementList().getRawPtr();
174 }
175
176 size_t getLocalNumEdges() const override { return graph_->getLocalNumEntries(); }
177
178 void getEdgesView(const offset_t *&offsets, const gno_t *&adjIds) const override
179 {
180 offsets = offs_.getRawPtr();
181 adjIds = (getLocalNumEdges() ? adjids_.getRawPtr() : NULL);
182 }
183
184 int getNumWeightsPerVertex() const override { return nWeightsPerVertex_;}
185
186 void getVertexWeightsView(const scalar_t *&weights, int &stride,
187 int idx) const override
188 {
189 if(idx<0 || idx >= nWeightsPerVertex_)
190 {
191 std::ostringstream emsg;
192 emsg << __FILE__ << ":" << __LINE__
193 << " Invalid vertex weight index " << idx << std::endl;
194 throw std::runtime_error(emsg.str());
195 }
196
197
198 size_t length;
199 vertexWeights_[idx].getStridedList(length, weights, stride);
200 }
201
202 bool useDegreeAsVertexWeight(int idx) const override {return vertexDegreeWeight_[idx];}
203
204 int getNumWeightsPerEdge() const override { return nWeightsPerEdge_;}
205
206 void getEdgeWeightsView(const scalar_t *&weights, int &stride, int idx) const override
207 {
208 if(idx<0 || idx >= nWeightsPerEdge_)
209 {
210 std::ostringstream emsg;
211 emsg << __FILE__ << ":" << __LINE__
212 << " Invalid edge weight index " << idx << std::endl;
213 throw std::runtime_error(emsg.str());
214 }
215
216
217 size_t length;
218 edgeWeights_[idx].getStridedList(length, weights, stride);
219 }
220
221 template <typename Adapter>
222 void applyPartitioningSolution(const User &in, User *&out,
223 const PartitioningSolution<Adapter> &solution) const;
224
225 template <typename Adapter>
226 void applyPartitioningSolution(const User &in, RCP<User> &out,
227 const PartitioningSolution<Adapter> &solution) const;
228
229private:
230
231 RCP<const User > ingraph_;
232 RCP<const xgraph_t > graph_;
233 RCP<const Comm<int> > comm_;
234
235 ArrayRCP<const offset_t> offs_;
236 ArrayRCP<const gno_t> adjids_;
237
238 int nWeightsPerVertex_;
239 ArrayRCP<StridedData<lno_t, scalar_t> > vertexWeights_;
240 ArrayRCP<bool> vertexDegreeWeight_;
241
242 int nWeightsPerEdge_;
243 ArrayRCP<StridedData<lno_t, scalar_t> > edgeWeights_;
244
245 int coordinateDim_;
246 ArrayRCP<StridedData<lno_t, scalar_t> > coords_;
247
248};
249
251// Definitions
253
254template <typename User, typename UserCoord>
256 const RCP<const User> &ingraph, int nVtxWgts, int nEdgeWgts):
257 ingraph_(ingraph), graph_(), comm_() , offs_(), adjids_(),
258 nWeightsPerVertex_(nVtxWgts), vertexWeights_(), vertexDegreeWeight_(),
259 nWeightsPerEdge_(nEdgeWgts), edgeWeights_(),
260 coordinateDim_(0), coords_()
261{
262 typedef StridedData<lno_t,scalar_t> input_t;
263
264 try {
265 graph_ = rcp_const_cast<const xgraph_t>(
266 XpetraTraits<User>::convertToXpetra(rcp_const_cast<User>(ingraph)));
267 }
269
270 comm_ = graph_->getComm();
271 size_t nvtx = graph_->getLocalNumRows();
272 size_t nedges = graph_->getLocalNumEntries();
273
274 // Unfortunately we have to copy the offsets and edge Ids
275 // because edge Ids are not usually stored in vertex id order.
276
277 size_t n = nvtx + 1;
278 offset_t *offs = new offset_t [n];
279
280 if (!offs)
281 {
282 std::cerr << "Error: " << __FILE__ << ", " << __LINE__<< std::endl;
283 std::cerr << n << " objects" << std::endl;
284 throw std::bad_alloc();
285 }
286
287 gno_t *adjids = NULL;
288 if (nedges)
289 {
290 adjids = new gno_t [nedges];
291
292 if (!adjids)
293 {
294 std::cerr << "Error: " << __FILE__ << ", " << __LINE__<< std::endl;
295 std::cerr << nedges << " objects" << std::endl;
296 throw std::bad_alloc();
297 }
298 }
299
300 offs[0] = 0;
301 for (size_t v=0; v < nvtx; v++){
302 ArrayView<const lno_t> nbors;
303 graph_->getLocalRowView(v, nbors);
304 offs[v+1] = offs[v] + nbors.size();
305 for (offset_t e=offs[v], i=0; e < offs[v+1]; e++)
306 adjids[e] = graph_->getColMap()->getGlobalElement(nbors[i++]);
307 }
308
309 offs_ = arcp(offs, 0, n, true);
310 adjids_ = arcp(adjids, 0, nedges, true);
311
312 if (nWeightsPerVertex_ > 0) {
313 vertexWeights_ =
314 arcp(new input_t[nWeightsPerVertex_], 0, nWeightsPerVertex_, true);
315 vertexDegreeWeight_ =
316 arcp(new bool[nWeightsPerVertex_], 0, nWeightsPerVertex_, true);
317 for (int i=0; i < nWeightsPerVertex_; i++)
318 vertexDegreeWeight_[i] = false;
319 }
320
321 if (nWeightsPerEdge_ > 0)
322 edgeWeights_ = arcp(new input_t[nWeightsPerEdge_], 0, nWeightsPerEdge_, true);
323}
324
326template <typename User, typename UserCoord>
328 const scalar_t *weightVal, int stride, int idx)
329{
330 if (this->getPrimaryEntityType() == GRAPH_VERTEX)
331 setVertexWeights(weightVal, stride, idx);
332 else
333 setEdgeWeights(weightVal, stride, idx);
334}
335
337template <typename User, typename UserCoord>
339 const scalar_t *weightVal, int stride, int idx)
340{
341 typedef StridedData<lno_t,scalar_t> input_t;
342
343 if(idx<0 || idx >= nWeightsPerVertex_)
344 {
345 std::ostringstream emsg;
346 emsg << __FILE__ << ":" << __LINE__
347 << " Invalid vertex weight index " << idx << std::endl;
348 throw std::runtime_error(emsg.str());
349 }
350
351 size_t nvtx = getLocalNumVertices();
352 ArrayRCP<const scalar_t> weightV(weightVal, 0, nvtx*stride, false);
353 vertexWeights_[idx] = input_t(weightV, stride);
354}
355
357template <typename User, typename UserCoord>
359 int idx)
360{
361 if (this->getPrimaryEntityType() == GRAPH_VERTEX)
362 setVertexWeightIsDegree(idx);
363 else {
364 std::ostringstream emsg;
365 emsg << __FILE__ << "," << __LINE__
366 << " error: setWeightIsNumberOfNonZeros is supported only for"
367 << " vertices" << std::endl;
368 throw std::runtime_error(emsg.str());
369 }
370}
371
373template <typename User, typename UserCoord>
375 int idx)
376{
377 if(idx<0 || idx >= nWeightsPerVertex_)
378 {
379 std::ostringstream emsg;
380 emsg << __FILE__ << ":" << __LINE__
381 << " Invalid vertex weight index " << idx << std::endl;
382 throw std::runtime_error(emsg.str());
383 }
384
385 vertexDegreeWeight_[idx] = true;
386}
387
389template <typename User, typename UserCoord>
391 const scalar_t *weightVal, int stride, int idx)
392{
393 typedef StridedData<lno_t,scalar_t> input_t;
394
395 if(idx<0 || idx >= nWeightsPerEdge_)
396 {
397 std::ostringstream emsg;
398 emsg << __FILE__ << ":" << __LINE__
399 << " Invalid edge weight index " << idx << std::endl;
400 throw std::runtime_error(emsg.str());
401 }
402
403 size_t nedges = getLocalNumEdges();
404 ArrayRCP<const scalar_t> weightV(weightVal, 0, nedges*stride, false);
405 edgeWeights_[idx] = input_t(weightV, stride);
406}
407
409template <typename User, typename UserCoord>
410 template<typename Adapter>
412 const User &in, User *&out,
413 const PartitioningSolution<Adapter> &solution) const
414{
415 // Get an import list (rows to be received)
416 size_t numNewVtx;
417 ArrayRCP<gno_t> importList;
418 try{
419 numNewVtx = Zoltan2::getImportList<Adapter,
421 (solution, this, importList);
422 }
424
425 // Move the rows, creating a new graph.
426 RCP<User> outPtr = XpetraTraits<User>::doMigration(in, numNewVtx,
427 importList.getRawPtr());
428 out = outPtr.get();
429 outPtr.release();
430}
431
433template <typename User, typename UserCoord>
434 template<typename Adapter>
436 const User &in, RCP<User> &out,
437 const PartitioningSolution<Adapter> &solution) const
438{
439 // Get an import list (rows to be received)
440 size_t numNewVtx;
441 ArrayRCP<gno_t> importList;
442 try{
443 numNewVtx = Zoltan2::getImportList<Adapter,
445 (solution, this, importList);
446 }
448
449 // Move the rows, creating a new graph.
450 out = XpetraTraits<User>::doMigration(in, numNewVtx,
451 importList.getRawPtr());
452}
453
454} //namespace Zoltan2
455
456#endif
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > user_t
Definition Metric.cpp:39
Xpetra::CrsGraph< zlno_t, zgno_t, znode_t > xgraph_t
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
Defines the GraphAdapter interface.
Helper functions for Partitioning Problems.
This file defines the StridedData class.
Traits of Xpetra classes, including migration method.
typename InputTraits< User >::node_t node_t
typename InputTraits< User >::lno_t lno_t
typename InputTraits< User >::scalar_t scalar_t
typename InputTraits< User >::gno_t gno_t
typename InputTraits< User >::offset_t offset_t
typename InputTraits< User >::part_t part_t
GraphAdapter defines the interface for graph-based user data.
A PartitioningSolution is a solution to a partitioning problem.
The StridedData class manages lists of weights or coordinates.
Provides access for Zoltan2 to Xpetra::CrsGraph data.
RCP< const xgraph_t > getXpetraGraph() const
Access to Xpetra-wrapped user's graph.
bool useDegreeAsVertexWeight(int idx) const override
Indicate whether vertex weight with index idx should be the global degree of the vertex.
void setWeightIsDegree(int idx)
Specify an index for which the weight should be the degree of the entity.
void setWeights(const scalar_t *val, int stride, int idx)
Provide a pointer to weights for the primary entity type.
void setWeightsDevice(typename Base::ConstWeightsDeviceView &val, int idx)
void setWeightsHost(typename Base::ConstWeightsHostView &val, int idx)
void setVertexWeightsHost(typename Base::ConstWeightsHostView &val, int idx)
size_t getLocalNumEdges() const override
Returns the number of edges on this process.
void setEdgeWeightsHost(typename Base::ConstWeightsHostView &val, int idx)
void setVertexWeightIsDegree(int idx)
Specify an index for which the vertex weight should be the degree of the vertex.
void applyPartitioningSolution(const User &in, User *&out, const PartitioningSolution< Adapter > &solution) const
void setVertexWeights(const scalar_t *val, int stride, int idx)
Provide a pointer to vertex weights.
void setEdgeWeights(const scalar_t *val, int stride, int idx)
Provide a pointer to edge weights.
size_t getLocalNumVertices() const override
Returns the number of vertices on this process.
void setVertexWeightsDevice(typename Base::ConstWeightsDeviceView &val, int idx)
void getEdgeWeightsView(const scalar_t *&weights, int &stride, int idx) const override
Provide a pointer to the edge weights, if any.
XpetraCrsGraphAdapter(const RCP< const User > &ingraph, int nVtxWeights=0, int nEdgeWeights=0)
Constructor for graph with no weights or coordinates.
void getEdgesView(const offset_t *&offsets, const gno_t *&adjIds) const override
void getVertexWeightsView(const scalar_t *&weights, int &stride, int idx) const override
Provide a pointer to the vertex weights, if any.
RCP< const User > getUserGraph() const
Access to user's graph.
int getNumWeightsPerEdge() const override
Returns the number (0 or greater) of edge weights.
int getNumWeightsPerVertex() const override
Returns the number (0 or greater) of weights per vertex.
void setEdgeWeightsDevice(typename Base::ConstWeightsDeviceView &val, int idx)
void getVertexIDsView(const gno_t *&ids) const override
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...