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
46template <typename User, typename UserCoord=User>
47 class XpetraCrsGraphAdapter : public GraphAdapter<User,UserCoord> {
48
49public:
50
51#ifndef DOXYGEN_SHOULD_SKIP_THIS
54 typedef typename InputTraits<User>::lno_t lno_t;
55 typedef typename InputTraits<User>::gno_t gno_t;
56 typedef typename InputTraits<User>::part_t part_t;
57 typedef typename InputTraits<User>::node_t node_t;
58 typedef Xpetra::CrsGraph<lno_t, gno_t, node_t> xgraph_t;
59 typedef User user_t;
60 typedef UserCoord userCoord_t;
61
63#endif
64
74 XpetraCrsGraphAdapter(const RCP<const User> &ingraph,
75 int nVtxWeights=0, int nEdgeWeights=0);
76
89 void setWeights(const scalar_t *val, int stride, int idx);
90 void setWeightsDevice(typename Base::ConstWeightsDeviceView& val, int idx) {}
91 void setWeightsHost(typename Base::ConstWeightsHostView& val, int idx) {}
92
108 void setVertexWeights(const scalar_t *val, int stride, int idx);
109 void setVertexWeightsDevice(typename Base::ConstWeightsDeviceView& val, int idx);
110 void setVertexWeightsHost(typename Base::ConstWeightsHostView& val, int idx);
111
117 void setWeightIsDegree(int idx);
118
124 void setVertexWeightIsDegree(int idx);
125
148 void setEdgeWeights(const scalar_t *val, int stride, int idx);
149 void setEdgeWeightsDevice(typename Base::ConstWeightsDeviceView& val, int idx);
150 void setEdgeWeightsHost(typename Base::ConstWeightsHostView& val, int idx);
151
154 RCP<const xgraph_t> getXpetraGraph() const { return graph_; }
155
158 RCP<const User> getUserGraph() const { return ingraph_; }
159
161 // The GraphAdapter interface.
163
164 // TODO: Assuming rows == objects;
165 // TODO: Need to add option for columns or nonzeros?
166 size_t getLocalNumVertices() const override { return graph_->getLocalNumRows(); }
167
168 void getVertexIDsView(const gno_t *&ids) const override
169 {
170 ids = NULL;
172 ids = graph_->getRowMap()->getLocalElementList().getRawPtr();
173 }
174
175 size_t getLocalNumEdges() const override { return graph_->getLocalNumEntries(); }
176
177 void getEdgesView(const offset_t *&offsets, const gno_t *&adjIds) const override
178 {
179 offsets = offs_.getRawPtr();
180 adjIds = (getLocalNumEdges() ? adjids_.getRawPtr() : NULL);
181 }
182
183 int getNumWeightsPerVertex() const override { return nWeightsPerVertex_;}
184
185 void getVertexWeightsView(const scalar_t *&weights, int &stride,
186 int idx) const override
187 {
188 if(idx<0 || idx >= nWeightsPerVertex_)
189 {
190 std::ostringstream emsg;
191 emsg << __FILE__ << ":" << __LINE__
192 << " Invalid vertex weight index " << idx << std::endl;
193 throw std::runtime_error(emsg.str());
194 }
195
196
197 size_t length;
198 vertexWeights_[idx].getStridedList(length, weights, stride);
199 }
200
201 bool useDegreeAsVertexWeight(int idx) const override {return vertexDegreeWeight_[idx];}
202
203 int getNumWeightsPerEdge() const override { return nWeightsPerEdge_;}
204
205 void getEdgeWeightsView(const scalar_t *&weights, int &stride, int idx) const override
206 {
207 if(idx<0 || idx >= nWeightsPerEdge_)
208 {
209 std::ostringstream emsg;
210 emsg << __FILE__ << ":" << __LINE__
211 << " Invalid edge weight index " << idx << std::endl;
212 throw std::runtime_error(emsg.str());
213 }
214
215
216 size_t length;
217 edgeWeights_[idx].getStridedList(length, weights, stride);
218 }
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 > ingraph_;
231 RCP<const xgraph_t > graph_;
232 RCP<const Comm<int> > comm_;
233
234 ArrayRCP<const offset_t> offs_;
235 ArrayRCP<const gno_t> adjids_;
236
237 int nWeightsPerVertex_;
238 ArrayRCP<StridedData<lno_t, scalar_t> > vertexWeights_;
239 ArrayRCP<bool> vertexDegreeWeight_;
240
241 int nWeightsPerEdge_;
242 ArrayRCP<StridedData<lno_t, scalar_t> > edgeWeights_;
243
244 int coordinateDim_;
245 ArrayRCP<StridedData<lno_t, scalar_t> > coords_;
246
247};
248
250// Definitions
252
253template <typename User, typename UserCoord>
255 const RCP<const User> &ingraph, int nVtxWgts, int nEdgeWgts):
256 ingraph_(ingraph), graph_(), comm_() , offs_(), adjids_(),
257 nWeightsPerVertex_(nVtxWgts), vertexWeights_(), vertexDegreeWeight_(),
258 nWeightsPerEdge_(nEdgeWgts), edgeWeights_(),
259 coordinateDim_(0), coords_()
260{
261 typedef StridedData<lno_t,scalar_t> input_t;
262
263 try {
264 graph_ = rcp_const_cast<const xgraph_t>(
265 XpetraTraits<User>::convertToXpetra(rcp_const_cast<User>(ingraph)));
266 }
268
269 comm_ = graph_->getComm();
270 size_t nvtx = graph_->getLocalNumRows();
271 size_t nedges = graph_->getLocalNumEntries();
272
273 // Unfortunately we have to copy the offsets and edge Ids
274 // because edge Ids are not usually stored in vertex id order.
275
276 size_t n = nvtx + 1;
277 offset_t *offs = new offset_t [n];
278
279 if (!offs)
280 {
281 std::cerr << "Error: " << __FILE__ << ", " << __LINE__<< std::endl;
282 std::cerr << n << " objects" << std::endl;
283 throw std::bad_alloc();
284 }
285
286 gno_t *adjids = NULL;
287 if (nedges)
288 {
289 adjids = new gno_t [nedges];
290
291 if (!adjids)
292 {
293 std::cerr << "Error: " << __FILE__ << ", " << __LINE__<< std::endl;
294 std::cerr << nedges << " objects" << std::endl;
295 throw std::bad_alloc();
296 }
297 }
298
299 offs[0] = 0;
300 for (size_t v=0; v < nvtx; v++){
301 ArrayView<const lno_t> nbors;
302 graph_->getLocalRowView(v, nbors);
303 offs[v+1] = offs[v] + nbors.size();
304 for (offset_t e=offs[v], i=0; e < offs[v+1]; e++)
305 adjids[e] = graph_->getColMap()->getGlobalElement(nbors[i++]);
306 }
307
308 offs_ = arcp(offs, 0, n, true);
309 adjids_ = arcp(adjids, 0, nedges, true);
310
311 if (nWeightsPerVertex_ > 0) {
312 vertexWeights_ =
313 arcp(new input_t[nWeightsPerVertex_], 0, nWeightsPerVertex_, true);
314 vertexDegreeWeight_ =
315 arcp(new bool[nWeightsPerVertex_], 0, nWeightsPerVertex_, true);
316 for (int i=0; i < nWeightsPerVertex_; i++)
317 vertexDegreeWeight_[i] = false;
318 }
319
320 if (nWeightsPerEdge_ > 0)
321 edgeWeights_ = arcp(new input_t[nWeightsPerEdge_], 0, nWeightsPerEdge_, true);
322}
323
325template <typename User, typename UserCoord>
327 const scalar_t *weightVal, int stride, int idx)
328{
329 if (this->getPrimaryEntityType() == GRAPH_VERTEX)
330 setVertexWeights(weightVal, stride, idx);
331 else
332 setEdgeWeights(weightVal, stride, idx);
333}
334
336template <typename User, typename UserCoord>
338 const scalar_t *weightVal, int stride, int idx)
339{
340 typedef StridedData<lno_t,scalar_t> input_t;
341
342 if(idx<0 || idx >= nWeightsPerVertex_)
343 {
344 std::ostringstream emsg;
345 emsg << __FILE__ << ":" << __LINE__
346 << " Invalid vertex weight index " << idx << std::endl;
347 throw std::runtime_error(emsg.str());
348 }
349
350 size_t nvtx = getLocalNumVertices();
351 ArrayRCP<const scalar_t> weightV(weightVal, 0, nvtx*stride, false);
352 vertexWeights_[idx] = input_t(weightV, stride);
353}
354
356template <typename User, typename UserCoord>
358 int idx)
359{
360 if (this->getPrimaryEntityType() == GRAPH_VERTEX)
361 setVertexWeightIsDegree(idx);
362 else {
363 std::ostringstream emsg;
364 emsg << __FILE__ << "," << __LINE__
365 << " error: setWeightIsNumberOfNonZeros is supported only for"
366 << " vertices" << std::endl;
367 throw std::runtime_error(emsg.str());
368 }
369}
370
372template <typename User, typename UserCoord>
374 int idx)
375{
376 if(idx<0 || idx >= nWeightsPerVertex_)
377 {
378 std::ostringstream emsg;
379 emsg << __FILE__ << ":" << __LINE__
380 << " Invalid vertex weight index " << idx << std::endl;
381 throw std::runtime_error(emsg.str());
382 }
383
384 vertexDegreeWeight_[idx] = true;
385}
386
388template <typename User, typename UserCoord>
390 const scalar_t *weightVal, int stride, int idx)
391{
392 typedef StridedData<lno_t,scalar_t> input_t;
393
394 if(idx<0 || idx >= nWeightsPerEdge_)
395 {
396 std::ostringstream emsg;
397 emsg << __FILE__ << ":" << __LINE__
398 << " Invalid edge weight index " << idx << std::endl;
399 throw std::runtime_error(emsg.str());
400 }
401
402 size_t nedges = getLocalNumEdges();
403 ArrayRCP<const scalar_t> weightV(weightVal, 0, nedges*stride, false);
404 edgeWeights_[idx] = input_t(weightV, stride);
405}
406
408template <typename User, typename UserCoord>
409 template<typename Adapter>
411 const User &in, User *&out,
412 const PartitioningSolution<Adapter> &solution) const
413{
414 // Get an import list (rows to be received)
415 size_t numNewVtx;
416 ArrayRCP<gno_t> importList;
417 try{
418 numNewVtx = Zoltan2::getImportList<Adapter,
420 (solution, this, importList);
421 }
423
424 // Move the rows, creating a new graph.
425 RCP<User> outPtr = XpetraTraits<User>::doMigration(in, numNewVtx,
426 importList.getRawPtr());
427 out = outPtr.get();
428 outPtr.release();
429}
430
432template <typename User, typename UserCoord>
433 template<typename Adapter>
435 const User &in, RCP<User> &out,
436 const PartitioningSolution<Adapter> &solution) const
437{
438 // Get an import list (rows to be received)
439 size_t numNewVtx;
440 ArrayRCP<gno_t> importList;
441 try{
442 numNewVtx = Zoltan2::getImportList<Adapter,
444 (solution, this, importList);
445 }
447
448 // Move the rows, creating a new graph.
449 out = XpetraTraits<User>::doMigration(in, numNewVtx,
450 importList.getRawPtr());
451}
452
453} //namespace Zoltan2
454
455#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...