Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Zoltan2_TpetraRowGraphAdapter.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_TPETRAROWGRAPHADAPTER_HPP_
51 #define _ZOLTAN2_TPETRAROWGRAPHADAPTER_HPP_
52 
53 #include "Kokkos_DualView.hpp"
54 #include "Kokkos_UnorderedMap.hpp"
55 #include <Tpetra_RowGraph.hpp>
56 #include <Zoltan2_GraphAdapter.hpp>
58 #include <Zoltan2_StridedData.hpp>
59 #include <string>
60 
61 namespace Zoltan2 {
62 
84 template <typename User, typename UserCoord = User>
85 class TpetraRowGraphAdapter : public GraphAdapter<User, UserCoord> {
86 
87 public:
88 #ifndef DOXYGEN_SHOULD_SKIP_THIS
89  using scalar_t = typename InputTraits<User>::scalar_t;
90  using offset_t = typename InputTraits<User>::offset_t;
91  using lno_t = typename InputTraits<User>::lno_t;
92  using gno_t = typename InputTraits<User>::gno_t;
93  using part_t = typename InputTraits<User>::part_t;
94  using node_t = typename InputTraits<User>::node_t;
95  using user_t = User;
96  using userCoord_t = UserCoord;
97 
98  using Base = GraphAdapter<User, UserCoord>;
99 #endif
100 
110  TpetraRowGraphAdapter(const RCP<const User> &ingraph, int nVtxWeights = 0,
111  int nEdgeWeights = 0);
112 
125  void setWeights(const scalar_t *val, int stride, int idx);
126 
135  void setWeightsDevice(typename Base::ConstWeightsDeviceView1D val, int idx);
136 
145  void setWeightsHost(typename Base::ConstWeightsHostView1D val, int idx);
146 
162  void setVertexWeights(const scalar_t *val, int stride, int idx);
163 
175  void setVertexWeightsDevice(typename Base::ConstWeightsDeviceView1D val,
176  int idx);
177 
189  void setVertexWeightsHost(typename Base::ConstWeightsHostView1D val, int idx);
190 
196  void setWeightIsDegree(int idx);
197 
203  void setVertexWeightIsDegree(int idx);
204 
227  void setEdgeWeights(const scalar_t *val, int stride, int idx);
228 
234  void setEdgeWeightsDevice(typename Base::ConstWeightsDeviceView1D val,
235  int idx);
236 
242  void setEdgeWeightsHost(typename Base::ConstWeightsHostView1D val, int idx);
243 
245  // The GraphAdapter interface.
247 
248  // TODO: Assuming rows == objects;
249  // TODO: Need to add option for columns or nonzeros?
250  size_t getLocalNumVertices() const override;
251 
252  void getVertexIDsView(const gno_t *&ids) const override;
253 
254  void
255  getVertexIDsDeviceView(typename Base::ConstIdsDeviceView &ids) const override;
256 
257  void
258  getVertexIDsHostView(typename Base::ConstIdsHostView &ids) const override;
259 
260  size_t getLocalNumEdges() const override;
261 
262  void getEdgesView(const offset_t *&offsets,
263  const gno_t *&adjIds) const override;
264 
265  void
266  getEdgesDeviceView(typename Base::ConstOffsetsDeviceView &offsets,
267  typename Base::ConstIdsDeviceView &adjIds) const override;
268 
269  void getEdgesHostView(typename Base::ConstOffsetsHostView &offsets,
270  typename Base::ConstIdsHostView &adjIds) const override;
271 
272  int getNumWeightsPerVertex() const override;
273 
274  void getVertexWeightsView(const scalar_t *&weights, int &stride,
275  int idx) const override;
276 
277  void getVertexWeightsDeviceView(typename Base::WeightsDeviceView1D &weights,
278  int idx = 0) const override;
279 
281  typename Base::WeightsDeviceView &weights) const override;
282 
283  void getVertexWeightsHostView(typename Base::WeightsHostView1D &weights,
284  int idx = 0) const override;
285 
287  typename Base::WeightsHostView &weights) const override;
288 
289  bool useDegreeAsVertexWeight(int idx) const override;
290 
291  int getNumWeightsPerEdge() const override;
292 
293  void getEdgeWeightsView(const scalar_t *&weights, int &stride,
294  int idx) const override;
295 
296  void getEdgeWeightsDeviceView(typename Base::WeightsDeviceView1D &weights,
297  int idx = 0) const override;
298 
300  typename Base::WeightsDeviceView &weights) const override;
301 
302  void getEdgeWeightsHostView(typename Base::WeightsHostView1D &weights,
303  int idx = 0) const override;
304 
306  typename Base::WeightsHostView &weights) const override;
307 
308  template <typename Adapter>
310  const User &in, User *&out,
311  const PartitioningSolution<Adapter> &solution) const;
312 
313  template <typename Adapter>
315  const User &in, RCP<User> &out,
316  const PartitioningSolution<Adapter> &solution) const;
317 
318 protected:
319  // Useb by TpetraCrsGraphAdapter
320  TpetraRowGraphAdapter(int nVtxWgts, int nEdgeWgts,
321  const RCP<const User> &graph)
322  : graph_(graph), nWeightsPerVertex_(nVtxWgts),
323  nWeightsPerEdge_(nEdgeWgts) {}
324 
325  RCP<const User> graph_;
326 
327  typename Base::ConstOffsetsHostView offsHost_;
328  typename Base::ConstIdsHostView adjIdsHost_;
329 
330  typename Base::ConstIdsDeviceView adjIdsDevice_;
331  typename Base::ConstOffsetsDeviceView offsDevice_;
332 
334  ArrayRCP<StridedData<lno_t, scalar_t>> vertexWeights_;
335  typename Base::WeightsDeviceView vertexWeightsDevice_;
336  typename Base::VtxDegreeHostView vertexDegreeWeightsHost_;
337 
339  ArrayRCP<StridedData<lno_t, scalar_t>> edgeWeights_;
340  typename Base::WeightsDeviceView edgeWeightsDevice_;
341 
342  virtual RCP<User> doMigration(const User &from, size_t numLocalRows,
343  const gno_t *myNewRows) const;
344 };
345 
347 // Definitions
349 
350 template <typename User, typename UserCoord>
352  const RCP<const User> &ingraph, int nVtxWgts, int nEdgeWgts)
353  : graph_(ingraph), nWeightsPerVertex_(nVtxWgts),
354  nWeightsPerEdge_(nEdgeWgts), edgeWeights_() {
355  using strided_t = StridedData<lno_t, scalar_t>;
356  using localInds_t = typename User::nonconst_local_inds_host_view_type;
357 
358  const auto nvtx = graph_->getLocalNumRows();
359  const auto nedges = graph_->getLocalNumEntries();
360  // Diff from CrsMatrix
361  const auto maxNumEntries = graph_->getLocalMaxNumRowEntries();
362 
363  // Unfortunately we have to copy the offsets and edge Ids
364  // because edge Ids are not usually stored in vertex id order.
365 
366  adjIdsHost_ = typename Base::ConstIdsHostView("adjIdsHost_", nedges);
367  offsHost_ = typename Base::ConstOffsetsHostView("offsHost_", nvtx + 1);
368 
369  localInds_t nbors("nbors", maxNumEntries);
370 
371  for (size_t v = 0; v < nvtx; v++) {
372  size_t numColInds = 0;
373  graph_->getLocalRowCopy(v, nbors, numColInds); // Diff from CrsGraph
374 
375  offsHost_(v + 1) = offsHost_(v) + numColInds;
376  for (offset_t e = offsHost_(v), i = 0; e < offsHost_(v + 1); e++) {
377  adjIdsHost_(e) = graph_->getColMap()->getGlobalElement(nbors(i++));
378  }
379  }
380 
381  // Since there's no direct getter of offsets and edges in device view,
382  // we have to deep copy here
383  offsDevice_ =
384  Kokkos::create_mirror_view_and_copy(typename Base::device_t(), offsHost_);
385  adjIdsDevice_ = Kokkos::create_mirror_view_and_copy(typename Base::device_t(),
386  adjIdsHost_);
387 
388  if (nWeightsPerVertex_ > 0) {
390  arcp(new strided_t[nWeightsPerVertex_], 0, nWeightsPerVertex_, true);
391 
392  vertexWeightsDevice_ = typename Base::WeightsDeviceView(
393  "vertexWeightsDevice_", nvtx, nWeightsPerVertex_);
394 
395  vertexDegreeWeightsHost_ = typename Base::VtxDegreeHostView(
396  "vertexDegreeWeightsHost_", nWeightsPerVertex_);
397 
398  for (int i = 0; i < nWeightsPerVertex_; ++i) {
399  vertexDegreeWeightsHost_(i) = false;
400  }
401  }
402 
403  if (nWeightsPerEdge_ > 0) {
404  edgeWeights_ =
405  arcp(new strided_t[nWeightsPerEdge_], 0, nWeightsPerEdge_, true);
406 
407  edgeWeightsDevice_ = typename Base::WeightsDeviceView(
408  "nWeightsPerEdge_", graph_->getLocalNumRows(), nWeightsPerEdge_);
409  }
410 }
411 
413 template <typename User, typename UserCoord>
415  const scalar_t *weightVal, int stride, int idx) {
416  if (this->getPrimaryEntityType() == GRAPH_VERTEX)
417  setVertexWeights(weightVal, stride, idx);
418  else
419  setEdgeWeights(weightVal, stride, idx);
420 }
421 
423 template <typename User, typename UserCoord>
425  typename Base::ConstWeightsDeviceView1D val, int idx) {
426  if (this->getPrimaryEntityType() == GRAPH_VERTEX)
427  setVertexWeightsDevice(val, idx);
428  else
429  setEdgeWeightsDevice(val, idx);
430 }
431 
433 template <typename User, typename UserCoord>
435  typename Base::ConstWeightsHostView1D val, int idx) {
436  if (this->getPrimaryEntityType() == GRAPH_VERTEX)
437  setVertexWeightsHost(val, idx);
438  else
439  setEdgeWeightsHost(val, idx);
440 }
441 
443 template <typename User, typename UserCoord>
445  const scalar_t *weightVal, int stride, int idx) {
446  AssertCondition((idx >= 0) and (idx < nWeightsPerVertex_),
447  "Invalid vertex weight index: " + std::to_string(idx));
448 
449  size_t nvtx = getLocalNumVertices();
450  ArrayRCP<const scalar_t> weightV(weightVal, 0, nvtx * stride, false);
451  vertexWeights_[idx] = input_t(weightV, stride);
452 }
453 
455 template <typename User, typename UserCoord>
457  typename Base::ConstWeightsDeviceView1D weights, int idx) {
458 
459  AssertCondition((idx >= 0) and (idx < nWeightsPerVertex_),
460  "Invalid vertex weight index: " + std::to_string(idx));
461 
462  AssertCondition(vertexWeightsDevice_.extent(0) == weights.extent(0),
463  "Invalid sizes!");
464 
465  Kokkos::parallel_for(
466  vertexWeightsDevice_.extent(0), KOKKOS_CLASS_LAMBDA(const int vertexID) {
467  vertexWeightsDevice_(vertexID, idx) = weights(vertexID);
468  });
469 
470  Kokkos::fence();
471 }
472 
474 template <typename User, typename UserCoord>
476  typename Base::ConstWeightsHostView1D weightsHost, int idx) {
477  AssertCondition((idx >= 0) and (idx < nWeightsPerVertex_),
478  "Invalid vertex weight index: " + std::to_string(idx));
479 
480  auto weightsDevice = Kokkos::create_mirror_view_and_copy(
481  typename Base::device_t(), weightsHost);
482 
483  setVertexWeightsDevice(weightsDevice, idx);
484 }
485 
487 template <typename User, typename UserCoord>
489  AssertCondition(this->getPrimaryEntityType() == GRAPH_VERTEX,
490  "setWeightIsNumberOfNonZeros is supported only for vertices");
491 
492  setVertexWeightIsDegree(idx);
493 }
494 
496 template <typename User, typename UserCoord>
498  AssertCondition((idx >= 0) and (idx < nWeightsPerVertex_),
499  "Invalid vertex weight index.");
500 
501  vertexDegreeWeightsHost_(idx) = true;
502 }
503 
505 template <typename User, typename UserCoord>
507  const scalar_t *weightVal, int stride, int idx) {
508  typedef StridedData<lno_t, scalar_t> input_t;
509 
510  AssertCondition((idx >= 0) and (idx < nWeightsPerEdge_),
511  "Invalid edge weight index" + std::to_string(idx));
512 
513  size_t nedges = getLocalNumEdges();
514  ArrayRCP<const scalar_t> weightV(weightVal, 0, nedges * stride, false);
515  edgeWeights_[idx] = input_t(weightV, stride);
516 }
517 
519 template <typename User, typename UserCoord>
521  typename Base::ConstWeightsDeviceView1D weights, int idx) {
522  AssertCondition((idx >= 0) and (idx < nWeightsPerVertex_),
523  "Invalid edge weight index.");
524 
525  AssertCondition(edgeWeightsDevice_.extent(0) == weights.extent(0),
526  "Invalid sizes!");
527 
528  Kokkos::parallel_for(
529  edgeWeightsDevice_.extent(0), KOKKOS_CLASS_LAMBDA(const int vertexID) {
530  edgeWeightsDevice_(vertexID, idx) = weights(vertexID);
531  });
532 
533  Kokkos::fence();
534 }
535 
537 template <typename User, typename UserCoord>
539  typename Base::ConstWeightsHostView1D weightsHost, int idx) {
540  AssertCondition((idx >= 0) and (idx < nWeightsPerVertex_),
541  "Invalid edge weight index.");
542 
543  auto weightsDevice = Kokkos::create_mirror_view_and_copy(
544  typename Base::device_t(), weightsHost);
545 
546  setEdgeWeightsDevice(weightsDevice);
547 }
548 
550 template <typename User, typename UserCoord>
552  return graph_->getLocalNumRows();
553 }
554 
556 template <typename User, typename UserCoord>
558  const gno_t *&ids) const {
559  ids = NULL;
560  if (getLocalNumVertices())
561  ids = graph_->getRowMap()->getLocalElementList().getRawPtr();
562 }
563 
565 template <typename User, typename UserCoord>
567  typename Base::ConstIdsDeviceView &ids) const {
568 
569  // TODO: Making a ConstIdsDeviceView LayoutLeft would proably remove the
570  // need of creating tmpIds
571  auto idsDevice = graph_->getRowMap()->getMyGlobalIndices();
572  auto tmpIds = typename Base::IdsDeviceView("", idsDevice.extent(0));
573 
574  Kokkos::deep_copy(tmpIds, idsDevice);
575 
576  ids = tmpIds;
577 }
578 
580 template <typename User, typename UserCoord>
582  typename Base::ConstIdsHostView &ids) const {
583  // TODO: Making a ConstIdsDeviceView LayoutLeft would proably remove the
584  // need of creating tmpIds
585  auto idsDevice = graph_->getRowMap()->getMyGlobalIndices();
586  auto tmpIds = typename Base::IdsHostView("", idsDevice.extent(0));
587 
588  Kokkos::deep_copy(tmpIds, idsDevice);
589 
590  ids = tmpIds;
591 }
592 
594 template <typename User, typename UserCoord>
596  return graph_->getLocalNumEntries();
597 }
598 
600 template <typename User, typename UserCoord>
602  const offset_t *&offsets, const gno_t *&adjIds) const {
603  offsets = offsHost_.data();
604  adjIds = (getLocalNumEdges() ? adjIdsHost_.data() : NULL);
605 }
606 
608 template <typename User, typename UserCoord>
610  typename Base::ConstOffsetsDeviceView &offsets,
611  typename Base::ConstIdsDeviceView &adjIds) const {
612 
613  offsets = offsDevice_;
614  adjIds = adjIdsDevice_;
615 }
616 
618 template <typename User, typename UserCoord>
620  typename Base::ConstOffsetsHostView &offsets,
621  typename Base::ConstIdsHostView &adjIds) const {
622 
623  auto hostIDs = Kokkos::create_mirror_view(adjIdsDevice_);
624  Kokkos::deep_copy(hostIDs, adjIdsDevice_);
625  adjIds = hostIDs;
626 
627  auto hostOffsets = Kokkos::create_mirror_view(offsDevice_);
628  Kokkos::deep_copy(hostOffsets, offsDevice_);
629  offsets = hostOffsets;
630 }
631 
633 template <typename User, typename UserCoord>
635  return nWeightsPerVertex_;
636 }
637 
639 template <typename User, typename UserCoord>
641  const scalar_t *&weights, int &stride, int idx) const {
642 
643  AssertCondition((idx >= 0) and (idx < nWeightsPerVertex_),
644  "Invalid vertex weight index.");
645 
646  size_t length;
647  vertexWeights_[idx].getStridedList(length, weights, stride);
648 }
649 
651 template <typename User, typename UserCoord>
653  typename Base::WeightsDeviceView1D &weights, int idx) const {
654  AssertCondition((idx >= 0) and (idx < nWeightsPerVertex_),
655  "Invalid vertex weight index.");
656 
657  const auto size = vertexWeightsDevice_.extent(0);
658  weights = typename Base::WeightsDeviceView1D("weights", size);
659 
660  Kokkos::parallel_for(
661  size, KOKKOS_CLASS_LAMBDA(const int id) {
662  weights(id) = vertexWeightsDevice_(id, idx);
663  });
664 
665  Kokkos::fence();
666 }
667 
669 template <typename User, typename UserCoord>
671  typename Base::WeightsDeviceView &weights) const {
672 
673  weights = vertexWeightsDevice_;
674 }
675 
677 template <typename User, typename UserCoord>
679  typename Base::WeightsHostView1D &weights, int idx) const {
680  AssertCondition((idx >= 0) and (idx < nWeightsPerVertex_),
681  "Invalid vertex weight index.");
682 
683  auto weightsDevice = typename Base::WeightsDeviceView1D(
684  "weights", vertexWeightsDevice_.extent(0));
685  getVertexWeightsDeviceView(weightsDevice, idx);
686 
687  weights = Kokkos::create_mirror_view(weightsDevice);
688  Kokkos::deep_copy(weights, weightsDevice);
689 }
690 
692 template <typename User, typename UserCoord>
694  typename Base::WeightsHostView &weights) const {
695 
696  weights = Kokkos::create_mirror_view(vertexWeightsDevice_);
697  Kokkos::deep_copy(weights, vertexWeightsDevice_);
698 }
699 
701 template <typename User, typename UserCoord>
703  int idx) const {
704  return vertexDegreeWeightsHost_(idx);
705 }
706 
708 template <typename User, typename UserCoord>
710  return nWeightsPerEdge_;
711 }
712 
714 template <typename User, typename UserCoord>
716  const scalar_t *&weights, int &stride, int idx) const {
717  AssertCondition((idx >= 0) and (idx < nWeightsPerEdge_),
718  "Invalid edge weight index.");
719 
720  size_t length;
721  edgeWeights_[idx].getStridedList(length, weights, stride);
722 }
723 
725 template <typename User, typename UserCoord>
727  typename Base::WeightsDeviceView1D &weights, int idx) const {
728 
729  weights = Kokkos::subview(edgeWeightsDevice_, Kokkos::ALL, idx);
730 }
731 
733 template <typename User, typename UserCoord>
735  typename Base::WeightsDeviceView &weights) const {
736 
737  weights = edgeWeightsDevice_;
738 }
739 
741 template <typename User, typename UserCoord>
743  typename Base::WeightsHostView1D &weights, int idx) const {
744 
745  auto weightsDevice = Kokkos::subview(edgeWeightsDevice_, Kokkos::ALL, idx);
746  weights = Kokkos::create_mirror_view(weightsDevice);
747  Kokkos::deep_copy(weights, weightsDevice);
748 }
749 
751 template <typename User, typename UserCoord>
753  typename Base::WeightsHostView &weights) const {
754 
755  weights = Kokkos::create_mirror_view(edgeWeightsDevice_);
756  Kokkos::deep_copy(weights, edgeWeightsDevice_);
757 }
758 
760 template <typename User, typename UserCoord>
761 template <typename Adapter>
763  const User &in, User *&out,
764  const PartitioningSolution<Adapter> &solution) const {
765  // Get an import list (rows to be received)
766  size_t numNewVtx;
767  ArrayRCP<gno_t> importList;
768  try {
769  numNewVtx =
770  Zoltan2::getImportList<Adapter, TpetraRowGraphAdapter<User, UserCoord>>(
771  solution, this, importList);
772  }
774 
775  // Move the rows, creating a new graph.
776  RCP<User> outPtr = doMigration(in, numNewVtx, importList.getRawPtr());
777  out = outPtr.get();
778  outPtr.release();
779 }
780 
782 template <typename User, typename UserCoord>
783 template <typename Adapter>
785  const User &in, RCP<User> &out,
786  const PartitioningSolution<Adapter> &solution) const {
787  // Get an import list (rows to be received)
788  size_t numNewVtx;
789  ArrayRCP<gno_t> importList;
790  try {
791  numNewVtx =
792  Zoltan2::getImportList<Adapter, TpetraRowGraphAdapter<User, UserCoord>>(
793  solution, this, importList);
794  }
796 
797  // Move the rows, creating a new graph.
798  out = doMigration(in, numNewVtx, importList.getRawPtr());
799 }
800 
802 template <typename User, typename UserCoord>
804  const User &from, size_t numLocalRows, const gno_t *myNewRows) const {
805  typedef Tpetra::Map<lno_t, gno_t, node_t> map_t;
806  typedef Tpetra::CrsGraph<lno_t, gno_t, node_t> tcrsgraph_t;
807 
808  // We cannot create a Tpetra::RowGraph, unless the underlying type is
809  // something we know (like Tpetra::CrsGraph).
810  // If the underlying type is something different, the user probably doesn't
811  // want a Tpetra::CrsGraph back, so we throw an error.
812 
813  // Try to cast "from" graph to a TPetra::CrsGraph
814  // If that fails we throw an error.
815  // We could cast as a ref which will throw std::bad_cast but with ptr
816  // approach it might be clearer what's going on here
817  const tcrsgraph_t *pCrsGraphSrc = dynamic_cast<const tcrsgraph_t *>(&from);
818 
819  if (!pCrsGraphSrc) {
820  throw std::logic_error("TpetraRowGraphAdapter cannot migrate data for "
821  "your RowGraph; it can migrate data only for "
822  "Tpetra::CrsGraph. "
823  "You can inherit from TpetraRowGraphAdapter and "
824  "implement migration for your RowGraph.");
825  }
826 
827  // source map
828  const RCP<const map_t> &smap = from.getRowMap();
829  int oldNumElts = smap->getLocalNumElements();
830  gno_t numGlobalRows = smap->getGlobalNumElements();
831  gno_t base = smap->getMinAllGlobalIndex();
832 
833  // target map
834  ArrayView<const gno_t> rowList(myNewRows, numLocalRows);
835  const RCP<const Teuchos::Comm<int>> &comm = from.getComm();
836  RCP<const map_t> tmap = rcp(new map_t(numGlobalRows, rowList, base, comm));
837 
838  // importer
839  Tpetra::Import<lno_t, gno_t, node_t> importer(smap, tmap);
840 
841  // number of entries in my new rows
842  typedef Tpetra::Vector<gno_t, lno_t, gno_t, node_t> vector_t;
843  vector_t numOld(smap);
844  vector_t numNew(tmap);
845  for (int lid = 0; lid < oldNumElts; lid++) {
846  numOld.replaceGlobalValue(smap->getGlobalElement(lid),
847  from.getNumEntriesInLocalRow(lid));
848  }
849  numNew.doImport(numOld, importer, Tpetra::INSERT);
850 
851  size_t numElts = tmap->getLocalNumElements();
852  ArrayRCP<const gno_t> nnz;
853  if (numElts > 0)
854  nnz = numNew.getData(0); // hangs if vector len == 0
855 
856  ArrayRCP<const size_t> nnz_size_t;
857 
858  if (numElts && sizeof(gno_t) != sizeof(size_t)) {
859  size_t *vals = new size_t[numElts];
860  nnz_size_t = arcp(vals, 0, numElts, true);
861  for (size_t i = 0; i < numElts; i++) {
862  vals[i] = static_cast<size_t>(nnz[i]);
863  }
864  } else {
865  nnz_size_t = arcp_reinterpret_cast<const size_t>(nnz);
866  }
867 
868  // target graph
869  RCP<tcrsgraph_t> G = rcp(new tcrsgraph_t(tmap, nnz_size_t()));
870 
871  G->doImport(*pCrsGraphSrc, importer, Tpetra::INSERT);
872  G->fillComplete();
873  return Teuchos::rcp_dynamic_cast<User>(G);
874 }
875 
876 } // namespace Zoltan2
877 
878 #endif
TpetraRowGraphAdapter(int nVtxWgts, int nEdgeWgts, const RCP< const User > &graph)
ArrayRCP< StridedData< lno_t, scalar_t > > edgeWeights_
void getVertexIDsHostView(typename Base::ConstIdsHostView &ids) const override
Sets pointers to this process&#39; graph entries.
void setVertexWeightsHost(typename Base::ConstWeightsHostView1D val, int idx)
Provide a host view to vertex weights.
void getEdgeWeightsView(const scalar_t *&weights, int &stride, int idx) const override
Provide a pointer to the edge weights, if any.
Helper functions for Partitioning Problems.
void setWeightIsDegree(int idx)
Specify an index for which the weight should be the degree of the entity.
void getVertexIDsView(const gno_t *&ids) const override
Sets pointers to this process&#39; graph entries.
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
typename InputTraits< User >::scalar_t scalar_t
static void AssertCondition(bool condition, const std::string &message, const char *file=__FILE__, int line=__LINE__)
void getEdgesView(const offset_t *&offsets, const gno_t *&adjIds) const override
Gets adjacency lists for all vertices in a compressed sparse row (CSR) format.
static ArrayRCP< ArrayRCP< zscalar_t > > weights
void getVertexWeightsDeviceView(typename Base::WeightsDeviceView1D &weights, int idx=0) const override
Provide a device view of the vertex weights, if any.
GraphAdapter defines the interface for graph-based user data.
int getNumWeightsPerVertex() const override
Returns the number (0 or greater) of weights per vertex.
typename node_t::device_type device_t
void setVertexWeights(const scalar_t *val, int stride, int idx)
Provide a pointer to vertex weights.
default_part_t part_t
The data type to represent part numbers.
default_offset_t offset_t
The data type to represent offsets.
size_t getLocalNumVertices() const override
Returns the number of vertices on this process.
ArrayRCP< StridedData< lno_t, scalar_t > > vertexWeights_
typename InputTraits< User >::part_t part_t
int getNumWeightsPerEdge() const override
Returns the number (0 or greater) of edge weights.
void getEdgesDeviceView(typename Base::ConstOffsetsDeviceView &offsets, typename Base::ConstIdsDeviceView &adjIds) const override
Gets adjacency lists for all vertices in a compressed sparse row (CSR) format.
void getEdgeWeightsDeviceView(typename Base::WeightsDeviceView1D &weights, int idx=0) const override
Provide a device view of the edge weights, if any.
void setWeightsHost(typename Base::ConstWeightsHostView1D val, int idx)
Provide a host view of weights for the primary entity type.
void getVertexWeightsView(const scalar_t *&weights, int &stride, int idx) const override
Provide a pointer to the vertex weights, if any.
bool useDegreeAsVertexWeight(int idx) const override
Indicate whether vertex weight with index idx should be the global degree of the vertex.
void applyPartitioningSolution(const User &in, User *&out, const PartitioningSolution< Adapter > &solution) const
typename InputTraits< User >::node_t node_t
A PartitioningSolution is a solution to a partitioning problem.
size_t getLocalNumEdges() const override
Returns the number of edges on this process.
void getEdgesHostView(typename Base::ConstOffsetsHostView &offsets, typename Base::ConstIdsHostView &adjIds) const override
Gets adjacency lists for all vertices in a compressed sparse row (CSR) format.
void getVertexWeightsHostView(typename Base::WeightsHostView1D &weights, int idx=0) const override
Provide a host view of the vertex weights, if any.
void getEdgeWeightsHostView(typename Base::WeightsHostView1D &weights, int idx=0) const override
Provide a host view of the edge weights, if any.
typename InputTraits< User >::gno_t gno_t
default_lno_t lno_t
The ordinal type (e.g., int, long, int64_t) that represents local counts and local indices...
Tpetra::Map map_t
Definition: mapRemotes.cpp:16
The StridedData class manages lists of weights or coordinates.
void setEdgeWeightsDevice(typename Base::ConstWeightsDeviceView1D val, int idx)
Provide a device view to edge weights.
void setWeightsDevice(typename Base::ConstWeightsDeviceView1D val, int idx)
Provide a device view of weights for the primary entity type.
map_t::local_ordinal_type lno_t
Definition: mapRemotes.cpp:17
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 getVertexIDsDeviceView(typename Base::ConstIdsDeviceView &ids) const override
Sets pointers to this process&#39; graph entries.
typename InputTraits< User >::offset_t offset_t
void setVertexWeightsDevice(typename Base::ConstWeightsDeviceView1D val, int idx)
Provide a device view to vertex weights.
void setVertexWeightIsDegree(int idx)
Specify an index for which the vertex weight should be the degree of the vertex.
TpetraRowGraphAdapter(const RCP< const User > &ingraph, int nVtxWeights=0, int nEdgeWeights=0)
Constructor for graph with no weights or coordinates.
void setEdgeWeights(const scalar_t *val, int stride, int idx)
Provide a pointer to edge weights.
Defines the GraphAdapter interface.
void setWeights(const scalar_t *val, int stride, int idx)
Provide a pointer to weights for the primary entity type.
virtual RCP< User > doMigration(const User &from, size_t numLocalRows, const gno_t *myNewRows) const
default_scalar_t scalar_t
The data type for weights and coordinates.
void setEdgeWeightsHost(typename Base::ConstWeightsHostView1D val, int idx)
Provide a host view to edge weights.
Provides access for Zoltan2 to Tpetra::RowGraph data.
This file defines the StridedData class.