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 // ***********************************************************************
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_XPETRACRSGRAPHADAPTER_HPP_
51 #define _ZOLTAN2_XPETRACRSGRAPHADAPTER_HPP_
52 
53 #include <Zoltan2_GraphAdapter.hpp>
54 #include <Zoltan2_StridedData.hpp>
55 #include <Zoltan2_XpetraTraits.hpp>
57 
58 #include <Xpetra_CrsGraph.hpp>
59 
60 namespace Zoltan2 {
61 
83 template <typename User, typename UserCoord=User>
84  class XpetraCrsGraphAdapter : public GraphAdapter<User,UserCoord> {
85 
86 public:
87 
88 #ifndef DOXYGEN_SHOULD_SKIP_THIS
89  typedef typename InputTraits<User>::scalar_t scalar_t;
90  typedef typename InputTraits<User>::offset_t offset_t;
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;
95  typedef Xpetra::CrsGraph<lno_t, gno_t, node_t> xgraph_t;
96  typedef User user_t;
97  typedef UserCoord userCoord_t;
98 
99  using Base = GraphAdapter<User,UserCoord>;
100 #endif
101 
111  XpetraCrsGraphAdapter(const RCP<const User> &ingraph,
112  int nVtxWeights=0, int nEdgeWeights=0);
113 
126  void setWeights(const scalar_t *val, int stride, int idx);
127  void setWeightsDevice(typename Base::ConstWeightsDeviceView& val, int idx) {}
128  void setWeightsHost(typename Base::ConstWeightsHostView& val, int idx) {}
129 
145  void setVertexWeights(const scalar_t *val, int stride, int idx);
146  void setVertexWeightsDevice(typename Base::ConstWeightsDeviceView& val, int idx);
147  void setVertexWeightsHost(typename Base::ConstWeightsHostView& val, int idx);
148 
154  void setWeightIsDegree(int idx);
155 
161  void setVertexWeightIsDegree(int idx);
162 
185  void setEdgeWeights(const scalar_t *val, int stride, int idx);
186  void setEdgeWeightsDevice(typename Base::ConstWeightsDeviceView& val, int idx);
187  void setEdgeWeightsHost(typename Base::ConstWeightsHostView& val, int idx);
188 
191  RCP<const xgraph_t> getXpetraGraph() const { return graph_; }
192 
195  RCP<const User> getUserGraph() const { return ingraph_; }
196 
198  // The GraphAdapter interface.
200 
201  // TODO: Assuming rows == objects;
202  // TODO: Need to add option for columns or nonzeros?
203  size_t getLocalNumVertices() const override { return graph_->getLocalNumRows(); }
204 
205  void getVertexIDsView(const gno_t *&ids) const override
206  {
207  ids = NULL;
208  if (getLocalNumVertices())
209  ids = graph_->getRowMap()->getLocalElementList().getRawPtr();
210  }
211 
212  size_t getLocalNumEdges() const override { return graph_->getLocalNumEntries(); }
213 
214  void getEdgesView(const offset_t *&offsets, const gno_t *&adjIds) const override
215  {
216  offsets = offs_.getRawPtr();
217  adjIds = (getLocalNumEdges() ? adjids_.getRawPtr() : NULL);
218  }
219 
220  int getNumWeightsPerVertex() const override { return nWeightsPerVertex_;}
221 
222  void getVertexWeightsView(const scalar_t *&weights, int &stride,
223  int idx) const override
224  {
225  if(idx<0 || idx >= nWeightsPerVertex_)
226  {
227  std::ostringstream emsg;
228  emsg << __FILE__ << ":" << __LINE__
229  << " Invalid vertex weight index " << idx << std::endl;
230  throw std::runtime_error(emsg.str());
231  }
232 
233 
234  size_t length;
235  vertexWeights_[idx].getStridedList(length, weights, stride);
236  }
237 
238  bool useDegreeAsVertexWeight(int idx) const override {return vertexDegreeWeight_[idx];}
239 
240  int getNumWeightsPerEdge() const override { return nWeightsPerEdge_;}
241 
242  void getEdgeWeightsView(const scalar_t *&weights, int &stride, int idx) const override
243  {
244  if(idx<0 || idx >= nWeightsPerEdge_)
245  {
246  std::ostringstream emsg;
247  emsg << __FILE__ << ":" << __LINE__
248  << " Invalid edge weight index " << idx << std::endl;
249  throw std::runtime_error(emsg.str());
250  }
251 
252 
253  size_t length;
254  edgeWeights_[idx].getStridedList(length, weights, stride);
255  }
256 
257  template <typename Adapter>
258  void applyPartitioningSolution(const User &in, User *&out,
259  const PartitioningSolution<Adapter> &solution) const;
260 
261  template <typename Adapter>
262  void applyPartitioningSolution(const User &in, RCP<User> &out,
263  const PartitioningSolution<Adapter> &solution) const;
264 
265 private:
266 
267  RCP<const User > ingraph_;
268  RCP<const xgraph_t > graph_;
269  RCP<const Comm<int> > comm_;
270 
271  ArrayRCP<const offset_t> offs_;
272  ArrayRCP<const gno_t> adjids_;
273 
274  int nWeightsPerVertex_;
275  ArrayRCP<StridedData<lno_t, scalar_t> > vertexWeights_;
276  ArrayRCP<bool> vertexDegreeWeight_;
277 
278  int nWeightsPerEdge_;
279  ArrayRCP<StridedData<lno_t, scalar_t> > edgeWeights_;
280 
281  int coordinateDim_;
282  ArrayRCP<StridedData<lno_t, scalar_t> > coords_;
283 
284 };
285 
287 // Definitions
289 
290 template <typename User, typename UserCoord>
292  const RCP<const User> &ingraph, int nVtxWgts, int nEdgeWgts):
293  ingraph_(ingraph), graph_(), comm_() , offs_(), adjids_(),
294  nWeightsPerVertex_(nVtxWgts), vertexWeights_(), vertexDegreeWeight_(),
295  nWeightsPerEdge_(nEdgeWgts), edgeWeights_(),
296  coordinateDim_(0), coords_()
297 {
298  typedef StridedData<lno_t,scalar_t> input_t;
299 
300  try {
301  graph_ = rcp_const_cast<const xgraph_t>(
302  XpetraTraits<User>::convertToXpetra(rcp_const_cast<User>(ingraph)));
303  }
305 
306  comm_ = graph_->getComm();
307  size_t nvtx = graph_->getLocalNumRows();
308  size_t nedges = graph_->getLocalNumEntries();
309 
310  // Unfortunately we have to copy the offsets and edge Ids
311  // because edge Ids are not usually stored in vertex id order.
312 
313  size_t n = nvtx + 1;
314  offset_t *offs = new offset_t [n];
315 
316  if (!offs)
317  {
318  std::cerr << "Error: " << __FILE__ << ", " << __LINE__<< std::endl;
319  std::cerr << n << " objects" << std::endl;
320  throw std::bad_alloc();
321  }
322 
323  gno_t *adjids = NULL;
324  if (nedges)
325  {
326  adjids = new gno_t [nedges];
327 
328  if (!adjids)
329  {
330  std::cerr << "Error: " << __FILE__ << ", " << __LINE__<< std::endl;
331  std::cerr << nedges << " objects" << std::endl;
332  throw std::bad_alloc();
333  }
334  }
335 
336  offs[0] = 0;
337  for (size_t v=0; v < nvtx; v++){
338  ArrayView<const lno_t> nbors;
339  graph_->getLocalRowView(v, nbors);
340  offs[v+1] = offs[v] + nbors.size();
341  for (offset_t e=offs[v], i=0; e < offs[v+1]; e++)
342  adjids[e] = graph_->getColMap()->getGlobalElement(nbors[i++]);
343  }
344 
345  offs_ = arcp(offs, 0, n, true);
346  adjids_ = arcp(adjids, 0, nedges, true);
347 
348  if (nWeightsPerVertex_ > 0) {
349  vertexWeights_ =
350  arcp(new input_t[nWeightsPerVertex_], 0, nWeightsPerVertex_, true);
351  vertexDegreeWeight_ =
352  arcp(new bool[nWeightsPerVertex_], 0, nWeightsPerVertex_, true);
353  for (int i=0; i < nWeightsPerVertex_; i++)
354  vertexDegreeWeight_[i] = false;
355  }
356 
357  if (nWeightsPerEdge_ > 0)
358  edgeWeights_ = arcp(new input_t[nWeightsPerEdge_], 0, nWeightsPerEdge_, true);
359 }
360 
362 template <typename User, typename UserCoord>
364  const scalar_t *weightVal, int stride, int idx)
365 {
366  if (this->getPrimaryEntityType() == GRAPH_VERTEX)
367  setVertexWeights(weightVal, stride, idx);
368  else
369  setEdgeWeights(weightVal, stride, idx);
370 }
371 
373 template <typename User, typename UserCoord>
375  const scalar_t *weightVal, int stride, int idx)
376 {
377  typedef StridedData<lno_t,scalar_t> input_t;
378 
379  if(idx<0 || idx >= nWeightsPerVertex_)
380  {
381  std::ostringstream emsg;
382  emsg << __FILE__ << ":" << __LINE__
383  << " Invalid vertex weight index " << idx << std::endl;
384  throw std::runtime_error(emsg.str());
385  }
386 
387  size_t nvtx = getLocalNumVertices();
388  ArrayRCP<const scalar_t> weightV(weightVal, 0, nvtx*stride, false);
389  vertexWeights_[idx] = input_t(weightV, stride);
390 }
391 
393 template <typename User, typename UserCoord>
395  int idx)
396 {
397  if (this->getPrimaryEntityType() == GRAPH_VERTEX)
398  setVertexWeightIsDegree(idx);
399  else {
400  std::ostringstream emsg;
401  emsg << __FILE__ << "," << __LINE__
402  << " error: setWeightIsNumberOfNonZeros is supported only for"
403  << " vertices" << std::endl;
404  throw std::runtime_error(emsg.str());
405  }
406 }
407 
409 template <typename User, typename UserCoord>
411  int idx)
412 {
413  if(idx<0 || idx >= nWeightsPerVertex_)
414  {
415  std::ostringstream emsg;
416  emsg << __FILE__ << ":" << __LINE__
417  << " Invalid vertex weight index " << idx << std::endl;
418  throw std::runtime_error(emsg.str());
419  }
420 
421  vertexDegreeWeight_[idx] = true;
422 }
423 
425 template <typename User, typename UserCoord>
427  const scalar_t *weightVal, int stride, int idx)
428 {
429  typedef StridedData<lno_t,scalar_t> input_t;
430 
431  if(idx<0 || idx >= nWeightsPerEdge_)
432  {
433  std::ostringstream emsg;
434  emsg << __FILE__ << ":" << __LINE__
435  << " Invalid edge weight index " << idx << std::endl;
436  throw std::runtime_error(emsg.str());
437  }
438 
439  size_t nedges = getLocalNumEdges();
440  ArrayRCP<const scalar_t> weightV(weightVal, 0, nedges*stride, false);
441  edgeWeights_[idx] = input_t(weightV, stride);
442 }
443 
445 template <typename User, typename UserCoord>
446  template<typename Adapter>
448  const User &in, User *&out,
449  const PartitioningSolution<Adapter> &solution) const
450 {
451  // Get an import list (rows to be received)
452  size_t numNewVtx;
453  ArrayRCP<gno_t> importList;
454  try{
455  numNewVtx = Zoltan2::getImportList<Adapter,
457  (solution, this, importList);
458  }
460 
461  // Move the rows, creating a new graph.
462  RCP<User> outPtr = XpetraTraits<User>::doMigration(in, numNewVtx,
463  importList.getRawPtr());
464  out = outPtr.get();
465  outPtr.release();
466 }
467 
469 template <typename User, typename UserCoord>
470  template<typename Adapter>
472  const User &in, RCP<User> &out,
473  const PartitioningSolution<Adapter> &solution) const
474 {
475  // Get an import list (rows to be received)
476  size_t numNewVtx;
477  ArrayRCP<gno_t> importList;
478  try{
479  numNewVtx = Zoltan2::getImportList<Adapter,
481  (solution, this, importList);
482  }
484 
485  // Move the rows, creating a new graph.
486  out = XpetraTraits<User>::doMigration(in, numNewVtx,
487  importList.getRawPtr());
488 }
489 
490 } //namespace Zoltan2
491 
492 #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:18
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:74