14#ifndef _ZOLTAN2_TPETRAROWGRAPHADAPTER_HPP_
15#define _ZOLTAN2_TPETRAROWGRAPHADAPTER_HPP_
17#include "Kokkos_DualView.hpp"
18#include "Kokkos_UnorderedMap.hpp"
19#include <Tpetra_RowGraph.hpp>
48template <
typename User,
typename UserCoord = User>
52#ifndef DOXYGEN_SHOULD_SKIP_THIS
60 using userCoord_t = UserCoord;
75 int nEdgeWeights = 0);
227 const gno_t *&adjIds)
const override;
231 typename Base::ConstIdsDeviceView &adjIds)
const override;
234 typename Base::ConstIdsHostView &adjIds)
const override;
239 int idx)
const override;
242 int idx = 0)
const override;
245 typename Base::WeightsDeviceView &
weights)
const override;
248 int idx = 0)
const override;
251 typename Base::WeightsHostView &
weights)
const override;
258 int idx)
const override;
261 int idx = 0)
const override;
264 typename Base::WeightsDeviceView &
weights)
const override;
267 int idx = 0)
const override;
270 typename Base::WeightsHostView &
weights)
const override;
272 template <
typename Adapter>
274 const User &in, User *&out,
277 template <
typename Adapter>
279 const User &in, RCP<User> &out,
285 const RCP<const User> &graph)
306 virtual RCP<User>
doMigration(
const User &from,
size_t numLocalRows,
307 const gno_t *myNewRows)
const;
314template <
typename User,
typename UserCoord>
316 const RCP<const User> &ingraph,
int nVtxWgts,
int nEdgeWgts)
317 : graph_(ingraph), nWeightsPerVertex_(nVtxWgts),
318 nWeightsPerEdge_(nEdgeWgts), edgeWeights_() {
320 using localInds_t =
typename User::nonconst_local_inds_host_view_type;
322 const auto nvtx =
graph_->getLocalNumRows();
323 const auto nedges =
graph_->getLocalNumEntries();
325 const auto maxNumEntries =
graph_->getLocalMaxNumRowEntries();
330 adjIdsHost_ =
typename Base::ConstIdsHostView(
"adjIdsHost_", nedges);
331 offsHost_ =
typename Base::ConstOffsetsHostView(
"offsHost_", nvtx + 1);
333 localInds_t nbors(
"nbors", maxNumEntries);
335 for (
size_t v = 0; v < nvtx; v++) {
336 size_t numColInds = 0;
337 graph_->getLocalRowCopy(v, nbors, numColInds);
348 Kokkos::create_mirror_view_and_copy(
typename Base::device_t(),
offsHost_);
349 adjIdsDevice_ = Kokkos::create_mirror_view_and_copy(
typename Base::device_t(),
377template <
typename User,
typename UserCoord>
379 const scalar_t *weightVal,
int stride,
int idx) {
381 setVertexWeights(weightVal, stride, idx);
383 setEdgeWeights(weightVal, stride, idx);
387template <
typename User,
typename UserCoord>
389 typename Base::ConstWeightsDeviceView1D val,
int idx) {
391 setVertexWeightsDevice(val, idx);
393 setEdgeWeightsDevice(val, idx);
397template <
typename User,
typename UserCoord>
399 typename Base::ConstWeightsHostView1D val,
int idx) {
401 setVertexWeightsHost(val, idx);
403 setEdgeWeightsHost(val, idx);
407template <
typename User,
typename UserCoord>
409 const scalar_t *weightVal,
int stride,
int idx) {
411 "Invalid vertex weight index: " + std::to_string(idx));
413 size_t nvtx = getLocalNumVertices();
414 ArrayRCP<const scalar_t> weightV(weightVal, 0, nvtx * stride,
false);
415 vertexWeights_[idx] = input_t(weightV, stride);
419template <
typename User,
typename UserCoord>
421 typename Base::ConstWeightsDeviceView1D
weights,
int idx) {
424 "Invalid vertex weight index: " + std::to_string(idx));
429 auto vertexWeightsDevice = this->vertexWeightsDevice_;
430 Kokkos::parallel_for(
431 vertexWeightsDevice.extent(0), KOKKOS_LAMBDA(
const int vertexID) {
432 vertexWeightsDevice(vertexID, idx) =
weights(vertexID);
439template <
typename User,
typename UserCoord>
441 typename Base::ConstWeightsHostView1D weightsHost,
int idx) {
443 "Invalid vertex weight index: " + std::to_string(idx));
445 auto weightsDevice = Kokkos::create_mirror_view_and_copy(
446 typename Base::device_t(), weightsHost);
448 setVertexWeightsDevice(weightsDevice, idx);
452template <
typename User,
typename UserCoord>
455 "setWeightIsNumberOfNonZeros is supported only for vertices");
457 setVertexWeightIsDegree(idx);
461template <
typename User,
typename UserCoord>
464 "Invalid vertex weight index.");
466 vertexDegreeWeightsHost_(idx) =
true;
470template <
typename User,
typename UserCoord>
472 const scalar_t *weightVal,
int stride,
int idx) {
476 "Invalid edge weight index" + std::to_string(idx));
478 size_t nedges = getLocalNumEdges();
479 ArrayRCP<const scalar_t> weightV(weightVal, 0, nedges * stride,
false);
480 edgeWeights_[idx] = input_t(weightV, stride);
484template <
typename User,
typename UserCoord>
486 typename Base::ConstWeightsDeviceView1D
weights,
int idx) {
488 "Invalid edge weight index.");
493 auto edgeWeightsDevice = this->edgeWeightsDevice_;
494 Kokkos::parallel_for(
495 edgeWeightsDevice.extent(0), KOKKOS_LAMBDA(
const int vertexID) {
496 edgeWeightsDevice(vertexID, idx) =
weights(vertexID);
503template <
typename User,
typename UserCoord>
505 typename Base::ConstWeightsHostView1D weightsHost,
int idx) {
507 "Invalid edge weight index.");
509 auto weightsDevice = Kokkos::create_mirror_view_and_copy(
510 typename Base::device_t(), weightsHost);
512 setEdgeWeightsDevice(weightsDevice);
516template <
typename User,
typename UserCoord>
518 return graph_->getLocalNumRows();
522template <
typename User,
typename UserCoord>
524 const gno_t *&ids)
const {
526 if (getLocalNumVertices())
527 ids = graph_->getRowMap()->getLocalElementList().getRawPtr();
531template <
typename User,
typename UserCoord>
533 typename Base::ConstIdsDeviceView &ids)
const {
537 auto idsDevice = graph_->getRowMap()->getMyGlobalIndices();
538 auto tmpIds =
typename Base::IdsDeviceView(
"", idsDevice.extent(0));
540 Kokkos::deep_copy(tmpIds, idsDevice);
546template <
typename User,
typename UserCoord>
548 typename Base::ConstIdsHostView &ids)
const {
551 auto idsDevice = graph_->getRowMap()->getMyGlobalIndices();
552 auto tmpIds =
typename Base::IdsHostView(
"", idsDevice.extent(0));
554 Kokkos::deep_copy(tmpIds, idsDevice);
560template <
typename User,
typename UserCoord>
562 return graph_->getLocalNumEntries();
566template <
typename User,
typename UserCoord>
569 offsets = offsHost_.data();
570 adjIds = (getLocalNumEdges() ? adjIdsHost_.data() : NULL);
574template <
typename User,
typename UserCoord>
576 typename Base::ConstOffsetsDeviceView &offsets,
577 typename Base::ConstIdsDeviceView &adjIds)
const {
579 offsets = offsDevice_;
580 adjIds = adjIdsDevice_;
584template <
typename User,
typename UserCoord>
586 typename Base::ConstOffsetsHostView &offsets,
587 typename Base::ConstIdsHostView &adjIds)
const {
589 auto hostIDs = Kokkos::create_mirror_view(adjIdsDevice_);
590 Kokkos::deep_copy(hostIDs, adjIdsDevice_);
593 auto hostOffsets = Kokkos::create_mirror_view(offsDevice_);
594 Kokkos::deep_copy(hostOffsets, offsDevice_);
595 offsets = hostOffsets;
599template <
typename User,
typename UserCoord>
601 return nWeightsPerVertex_;
605template <
typename User,
typename UserCoord>
610 "Invalid vertex weight index.");
613 vertexWeights_[idx].getStridedList(length,
weights, stride);
617template <
typename User,
typename UserCoord>
619 typename Base::WeightsDeviceView1D &
weights,
int idx)
const {
621 "Invalid vertex weight index.");
623 const auto size = vertexWeightsDevice_.extent(0);
624 weights =
typename Base::WeightsDeviceView1D(
"weights", size);
626 auto vertexWeightsDevice = this->vertexWeightsDevice_;
627 Kokkos::parallel_for(
628 size, KOKKOS_LAMBDA(
const int id) {
629 weights(
id) = vertexWeightsDevice(
id, idx);
636template <
typename User,
typename UserCoord>
638 typename Base::WeightsDeviceView &
weights)
const {
640 weights = vertexWeightsDevice_;
644template <
typename User,
typename UserCoord>
646 typename Base::WeightsHostView1D &
weights,
int idx)
const {
648 "Invalid vertex weight index.");
650 auto weightsDevice =
typename Base::WeightsDeviceView1D(
651 "weights", vertexWeightsDevice_.extent(0));
652 getVertexWeightsDeviceView(weightsDevice, idx);
654 weights = Kokkos::create_mirror_view(weightsDevice);
655 Kokkos::deep_copy(
weights, weightsDevice);
659template <
typename User,
typename UserCoord>
661 typename Base::WeightsHostView &
weights)
const {
663 weights = Kokkos::create_mirror_view(vertexWeightsDevice_);
664 Kokkos::deep_copy(
weights, vertexWeightsDevice_);
668template <
typename User,
typename UserCoord>
671 return vertexDegreeWeightsHost_(idx);
675template <
typename User,
typename UserCoord>
677 return nWeightsPerEdge_;
681template <
typename User,
typename UserCoord>
685 "Invalid edge weight index.");
688 edgeWeights_[idx].getStridedList(length,
weights, stride);
692template <
typename User,
typename UserCoord>
694 typename Base::WeightsDeviceView1D &
weights,
int idx)
const {
696 weights = Kokkos::subview(edgeWeightsDevice_, Kokkos::ALL, idx);
700template <
typename User,
typename UserCoord>
702 typename Base::WeightsDeviceView &
weights)
const {
708template <
typename User,
typename UserCoord>
710 typename Base::WeightsHostView1D &
weights,
int idx)
const {
712 auto weightsDevice = Kokkos::subview(edgeWeightsDevice_, Kokkos::ALL, idx);
713 weights = Kokkos::create_mirror_view(weightsDevice);
714 Kokkos::deep_copy(
weights, weightsDevice);
718template <
typename User,
typename UserCoord>
720 typename Base::WeightsHostView &
weights)
const {
722 weights = Kokkos::create_mirror_view(edgeWeightsDevice_);
723 Kokkos::deep_copy(
weights, edgeWeightsDevice_);
727template <
typename User,
typename UserCoord>
728template <
typename Adapter>
730 const User &in, User *&out,
734 ArrayRCP<gno_t> importList;
737 Zoltan2::getImportList<Adapter, TpetraRowGraphAdapter<User, UserCoord>>(
738 solution,
this, importList);
743 RCP<User> outPtr = doMigration(in, numNewVtx, importList.getRawPtr());
749template <
typename User,
typename UserCoord>
750template <
typename Adapter>
752 const User &in, RCP<User> &out,
756 ArrayRCP<gno_t> importList;
759 Zoltan2::getImportList<Adapter, TpetraRowGraphAdapter<User, UserCoord>>(
760 solution,
this, importList);
765 out = doMigration(in, numNewVtx, importList.getRawPtr());
769template <
typename User,
typename UserCoord>
771 const User &from,
size_t numLocalRows,
const gno_t *myNewRows)
const {
772 typedef Tpetra::Map<lno_t, gno_t, node_t>
map_t;
773 typedef Tpetra::CrsGraph<lno_t, gno_t, node_t> tcrsgraph_t;
784 const tcrsgraph_t *pCrsGraphSrc =
dynamic_cast<const tcrsgraph_t *
>(&from);
787 throw std::logic_error(
"TpetraRowGraphAdapter cannot migrate data for "
788 "your RowGraph; it can migrate data only for "
790 "You can inherit from TpetraRowGraphAdapter and "
791 "implement migration for your RowGraph.");
795 const RCP<const map_t> &smap = from.getRowMap();
796 int oldNumElts = smap->getLocalNumElements();
797 gno_t numGlobalRows = smap->getGlobalNumElements();
798 gno_t base = smap->getMinAllGlobalIndex();
801 ArrayView<const gno_t> rowList(myNewRows, numLocalRows);
802 const RCP<const Teuchos::Comm<int>> &comm = from.getComm();
803 RCP<const map_t> tmap = rcp(
new map_t(numGlobalRows, rowList, base, comm));
806 Tpetra::Import<lno_t, gno_t, node_t> importer(smap, tmap);
809 typedef Tpetra::Vector<gno_t, lno_t, gno_t, node_t> vector_t;
810 vector_t numOld(smap);
811 vector_t numNew(tmap);
812 for (
int lid = 0; lid < oldNumElts; lid++) {
813 numOld.replaceGlobalValue(smap->getGlobalElement(lid),
814 from.getNumEntriesInLocalRow(lid));
816 numNew.doImport(numOld, importer, Tpetra::INSERT);
818 size_t numElts = tmap->getLocalNumElements();
819 ArrayRCP<const gno_t> nnz;
821 nnz = numNew.getData(0);
823 ArrayRCP<const size_t> nnz_size_t;
825 if (numElts &&
sizeof(
gno_t) !=
sizeof(
size_t)) {
826 size_t *vals =
new size_t[numElts];
827 nnz_size_t = arcp(vals, 0, numElts,
true);
828 for (
size_t i = 0; i < numElts; i++) {
829 vals[i] =
static_cast<size_t>(nnz[i]);
832 nnz_size_t = arcp_reinterpret_cast<const size_t>(nnz);
836 RCP<tcrsgraph_t> G = rcp(
new tcrsgraph_t(tmap, nnz_size_t()));
838 G->doImport(*pCrsGraphSrc, importer, Tpetra::INSERT);
840 return Teuchos::rcp_dynamic_cast<User>(G);
#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.
typename InputTraits< User >::node_t node_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 Tpetra::RowGraph data.
void getEdgeWeightsHostView(typename Base::WeightsHostView &weights) const override
Provide a host view of the edge weights, if any.
ArrayRCP< StridedData< lno_t, scalar_t > > vertexWeights_
void setEdgeWeightsHost(typename Base::ConstWeightsHostView1D val, int idx)
Provide a host view to edge weights.
ArrayRCP< StridedData< lno_t, scalar_t > > edgeWeights_
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.
size_t getLocalNumVertices() const override
Returns the number of vertices on this process.
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.
void setEdgeWeights(const scalar_t *val, int stride, int idx)
Provide a pointer to edge weights.
void getVertexWeightsHostView(typename Base::WeightsHostView &weights) const override
Provide a host view of the vertex weights, if any.
void getVertexWeightsView(const scalar_t *&weights, int &stride, int idx) const override
Provide a pointer to the vertex weights, if any.
void getVertexIDsHostView(typename Base::ConstIdsHostView &ids) const override
Sets pointers to this process' graph entries.
TpetraRowGraphAdapter(int nVtxWgts, int nEdgeWgts, const RCP< const User > &graph)
void getVertexWeightsDeviceView(typename Base::WeightsDeviceView &weights) const override
Provide a device view of the vertex weights, if any.
Base::WeightsDeviceView edgeWeightsDevice_
void getVertexWeightsHostView(typename Base::WeightsHostView1D &weights, int idx=0) const override
Provide a host view of the vertex weights, if any.
void getEdgeWeightsDeviceView(typename Base::WeightsDeviceView &weights) const override
Provide a device view of the edge weights, if any.
void applyPartitioningSolution(const User &in, RCP< User > &out, const PartitioningSolution< Adapter > &solution) const
void setWeightIsDegree(int idx)
Specify an index for which the weight should be the degree of the entity.
void setWeightsDevice(typename Base::ConstWeightsDeviceView1D val, int idx)
Provide a device view of weights for the primary entity type.
Base::ConstOffsetsDeviceView offsDevice_
Base::WeightsDeviceView vertexWeightsDevice_
void applyPartitioningSolution(const User &in, User *&out, const PartitioningSolution< Adapter > &solution) const
Base::ConstIdsDeviceView adjIdsDevice_
void getEdgeWeightsView(const scalar_t *&weights, int &stride, int idx) const override
Provide a pointer to the edge weights, if any.
void getVertexWeightsDeviceView(typename Base::WeightsDeviceView1D &weights, int idx=0) const override
Provide a device view of the vertex weights, if any.
void getVertexIDsDeviceView(typename Base::ConstIdsDeviceView &ids) const override
Sets pointers to this process' graph entries.
virtual RCP< User > doMigration(const User &from, size_t numLocalRows, const gno_t *myNewRows) const
Base::ConstOffsetsHostView offsHost_
Base::ConstIdsHostView adjIdsHost_
void getEdgeWeightsHostView(typename Base::WeightsHostView1D &weights, int idx=0) const override
Provide a host 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 setWeights(const scalar_t *val, int stride, int idx)
Provide a pointer to weights for the primary entity type.
void getVertexIDsView(const gno_t *&ids) const override
Sets pointers to this process' graph entries.
void setVertexWeightsDevice(typename Base::ConstWeightsDeviceView1D val, int idx)
Provide a device view to vertex weights.
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.
size_t getLocalNumEdges() const override
Returns the number of edges on this process.
void setVertexWeights(const scalar_t *val, int stride, int idx)
Provide a pointer to vertex weights.
TpetraRowGraphAdapter(const RCP< const User > &ingraph, int nVtxWeights=0, int nEdgeWeights=0)
Constructor for graph with no weights or coordinates.
bool useDegreeAsVertexWeight(int idx) const override
Indicate whether vertex weight with index idx should be the global degree of the vertex.
Base::VtxDegreeHostView vertexDegreeWeightsHost_
void setVertexWeightIsDegree(int idx)
Specify an index for which the vertex weight should be the degree of the vertex.
void setEdgeWeightsDevice(typename Base::ConstWeightsDeviceView1D val, int idx)
Provide a device view to edge weights.
void getEdgeWeightsDeviceView(typename Base::WeightsDeviceView1D &weights, int idx=0) const override
Provide a device view of the edge weights, if any.
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 setVertexWeightsHost(typename Base::ConstWeightsHostView1D val, int idx)
Provide a host view to vertex weights.
map_t::local_ordinal_type lno_t
Created by mbenlioglu on Aug 31, 2020.
static void AssertCondition(bool condition, const std::string &message, const char *file=__FILE__, int line=__LINE__)