Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 
17 #include <Zoltan2_GraphAdapter.hpp>
18 #include <Zoltan2_StridedData.hpp>
19 #include <Zoltan2_XpetraTraits.hpp>
21 
22 #include <Xpetra_CrsGraph.hpp>
23 
24 namespace Zoltan2 {
25 
47 template <typename User, typename UserCoord=User>
48  class XpetraCrsGraphAdapter : public GraphAdapter<User,UserCoord> {
49 
50 public:
51 
52 #ifndef DOXYGEN_SHOULD_SKIP_THIS
53  typedef typename InputTraits<User>::scalar_t scalar_t;
54  typedef typename InputTraits<User>::offset_t offset_t;
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 
63  using Base = GraphAdapter<User,UserCoord>;
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;
172  if (getLocalNumVertices())
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 
229 private:
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 
254 template <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 
326 template <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 
337 template <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 
357 template <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 
373 template <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 
389 template <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 
409 template <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 
433 template <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
Helper functions for Partitioning Problems.
RCP< const xgraph_t > getXpetraGraph() const
Access to Xpetra-wrapped user&#39;s graph.
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
typename InputTraits< User >::scalar_t scalar_t
void setVertexWeightsHost(typename Base::ConstWeightsHostView &val, int idx)
static ArrayRCP< ArrayRCP< zscalar_t > > weights
GraphAdapter defines the interface for graph-based user data.
void setWeightsHost(typename Base::ConstWeightsHostView &val, int idx)
void setWeights(const scalar_t *val, int stride, int idx)
Provide a pointer to weights for the primary entity type.
default_part_t part_t
The data type to represent part numbers.
default_offset_t offset_t
The data type to represent offsets.
map_t::global_ordinal_type gno_t
Definition: mapRemotes.cpp:27
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...
Provides access for Zoltan2 to Xpetra::CrsGraph data.
Xpetra::CrsGraph< zlno_t, zgno_t, znode_t > xgraph_t
Traits of Xpetra classes, including migration method.
size_t getLocalNumVertices() const override
Returns the number of vertices on this process.
typename InputTraits< User >::part_t part_t
RCP< const User > getUserGraph() const
Access to user&#39;s graph.
static RCP< User > convertToXpetra(const RCP< User > &a)
Convert the object to its Xpetra wrapped version.
void getVertexWeightsView(const scalar_t *&weights, int &stride, int idx) const override
Provide a pointer to the vertex weights, if any.
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...
XpetraCrsGraphAdapter(const RCP< const User > &ingraph, int nVtxWeights=0, int nEdgeWeights=0)
Constructor for graph with no weights or coordinates.
typename InputTraits< User >::node_t node_t
A PartitioningSolution is a solution to a partitioning problem.
int getNumWeightsPerEdge() const override
Returns the number (0 or greater) of edge weights.
size_t getLocalNumEdges() const override
Returns the number of edges on this process.
typename InputTraits< User >::gno_t gno_t
void setVertexWeightsDevice(typename Base::ConstWeightsDeviceView &val, int idx)
default_lno_t lno_t
The ordinal type (e.g., int, long, int64_t) that represents local counts and local indices...
void setWeightIsDegree(int idx)
Specify an index for which the weight should be the degree of the entity.
The StridedData class manages lists of weights or coordinates.
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.
void setEdgeWeights(const scalar_t *val, int stride, int idx)
Provide a pointer to edge weights.
void getVertexIDsView(const gno_t *&ids) const override
typename InputTraits< User >::offset_t offset_t
void getEdgeWeightsView(const scalar_t *&weights, int &stride, int idx) const override
Provide a pointer to the edge weights, if any.
void getEdgesView(const offset_t *&offsets, const gno_t *&adjIds) const override
int getNumWeightsPerVertex() const override
Returns the number (0 or greater) of weights per vertex.
Defines the GraphAdapter interface.
void setVertexWeightIsDegree(int idx)
Specify an index for which the vertex weight should be the degree of the vertex.
typename InputTraits< User >::lno_t lno_t
void setVertexWeights(const scalar_t *val, int stride, int idx)
Provide a pointer to vertex weights.
void applyPartitioningSolution(const User &in, User *&out, const PartitioningSolution< Adapter > &solution) const
default_scalar_t scalar_t
The data type for weights and coordinates.
void setEdgeWeightsDevice(typename Base::ConstWeightsDeviceView &val, int idx)
bool useDegreeAsVertexWeight(int idx) const override
Indicate whether vertex weight with index idx should be the global degree of the vertex.
void setEdgeWeightsHost(typename Base::ConstWeightsHostView &val, int idx)
void setWeightsDevice(typename Base::ConstWeightsDeviceView &val, int idx)
This file defines the StridedData class.
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > user_t
Definition: Metric.cpp:39