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 Kokkos::parallel_for(
430 vertexWeightsDevice_.extent(0), KOKKOS_CLASS_LAMBDA(
const int vertexID) {
431 vertexWeightsDevice_(vertexID, idx) =
weights(vertexID);
438template <
typename User,
typename UserCoord>
440 typename Base::ConstWeightsHostView1D weightsHost,
int idx) {
442 "Invalid vertex weight index: " + std::to_string(idx));
444 auto weightsDevice = Kokkos::create_mirror_view_and_copy(
445 typename Base::device_t(), weightsHost);
447 setVertexWeightsDevice(weightsDevice, idx);
451template <
typename User,
typename UserCoord>
454 "setWeightIsNumberOfNonZeros is supported only for vertices");
456 setVertexWeightIsDegree(idx);
460template <
typename User,
typename UserCoord>
463 "Invalid vertex weight index.");
465 vertexDegreeWeightsHost_(idx) =
true;
469template <
typename User,
typename UserCoord>
471 const scalar_t *weightVal,
int stride,
int idx) {
475 "Invalid edge weight index" + std::to_string(idx));
477 size_t nedges = getLocalNumEdges();
478 ArrayRCP<const scalar_t> weightV(weightVal, 0, nedges * stride,
false);
479 edgeWeights_[idx] = input_t(weightV, stride);
483template <
typename User,
typename UserCoord>
485 typename Base::ConstWeightsDeviceView1D
weights,
int idx) {
487 "Invalid edge weight index.");
492 Kokkos::parallel_for(
493 edgeWeightsDevice_.extent(0), KOKKOS_CLASS_LAMBDA(
const int vertexID) {
494 edgeWeightsDevice_(vertexID, idx) =
weights(vertexID);
501template <
typename User,
typename UserCoord>
503 typename Base::ConstWeightsHostView1D weightsHost,
int idx) {
505 "Invalid edge weight index.");
507 auto weightsDevice = Kokkos::create_mirror_view_and_copy(
508 typename Base::device_t(), weightsHost);
510 setEdgeWeightsDevice(weightsDevice);
514template <
typename User,
typename UserCoord>
516 return graph_->getLocalNumRows();
520template <
typename User,
typename UserCoord>
522 const gno_t *&ids)
const {
524 if (getLocalNumVertices())
525 ids = graph_->getRowMap()->getLocalElementList().getRawPtr();
529template <
typename User,
typename UserCoord>
531 typename Base::ConstIdsDeviceView &ids)
const {
535 auto idsDevice = graph_->getRowMap()->getMyGlobalIndices();
536 auto tmpIds =
typename Base::IdsDeviceView(
"", idsDevice.extent(0));
538 Kokkos::deep_copy(tmpIds, idsDevice);
544template <
typename User,
typename UserCoord>
546 typename Base::ConstIdsHostView &ids)
const {
549 auto idsDevice = graph_->getRowMap()->getMyGlobalIndices();
550 auto tmpIds =
typename Base::IdsHostView(
"", idsDevice.extent(0));
552 Kokkos::deep_copy(tmpIds, idsDevice);
558template <
typename User,
typename UserCoord>
560 return graph_->getLocalNumEntries();
564template <
typename User,
typename UserCoord>
567 offsets = offsHost_.data();
568 adjIds = (getLocalNumEdges() ? adjIdsHost_.data() : NULL);
572template <
typename User,
typename UserCoord>
574 typename Base::ConstOffsetsDeviceView &offsets,
575 typename Base::ConstIdsDeviceView &adjIds)
const {
577 offsets = offsDevice_;
578 adjIds = adjIdsDevice_;
582template <
typename User,
typename UserCoord>
584 typename Base::ConstOffsetsHostView &offsets,
585 typename Base::ConstIdsHostView &adjIds)
const {
587 auto hostIDs = Kokkos::create_mirror_view(adjIdsDevice_);
588 Kokkos::deep_copy(hostIDs, adjIdsDevice_);
591 auto hostOffsets = Kokkos::create_mirror_view(offsDevice_);
592 Kokkos::deep_copy(hostOffsets, offsDevice_);
593 offsets = hostOffsets;
597template <
typename User,
typename UserCoord>
599 return nWeightsPerVertex_;
603template <
typename User,
typename UserCoord>
608 "Invalid vertex weight index.");
611 vertexWeights_[idx].getStridedList(length,
weights, stride);
615template <
typename User,
typename UserCoord>
617 typename Base::WeightsDeviceView1D &
weights,
int idx)
const {
619 "Invalid vertex weight index.");
621 const auto size = vertexWeightsDevice_.extent(0);
622 weights =
typename Base::WeightsDeviceView1D(
"weights", size);
624 Kokkos::parallel_for(
625 size, KOKKOS_CLASS_LAMBDA(
const int id) {
626 weights(
id) = vertexWeightsDevice_(
id, idx);
633template <
typename User,
typename UserCoord>
635 typename Base::WeightsDeviceView &
weights)
const {
637 weights = vertexWeightsDevice_;
641template <
typename User,
typename UserCoord>
643 typename Base::WeightsHostView1D &
weights,
int idx)
const {
645 "Invalid vertex weight index.");
647 auto weightsDevice =
typename Base::WeightsDeviceView1D(
648 "weights", vertexWeightsDevice_.extent(0));
649 getVertexWeightsDeviceView(weightsDevice, idx);
651 weights = Kokkos::create_mirror_view(weightsDevice);
652 Kokkos::deep_copy(
weights, weightsDevice);
656template <
typename User,
typename UserCoord>
658 typename Base::WeightsHostView &
weights)
const {
660 weights = Kokkos::create_mirror_view(vertexWeightsDevice_);
661 Kokkos::deep_copy(
weights, vertexWeightsDevice_);
665template <
typename User,
typename UserCoord>
668 return vertexDegreeWeightsHost_(idx);
672template <
typename User,
typename UserCoord>
674 return nWeightsPerEdge_;
678template <
typename User,
typename UserCoord>
682 "Invalid edge weight index.");
685 edgeWeights_[idx].getStridedList(length,
weights, stride);
689template <
typename User,
typename UserCoord>
691 typename Base::WeightsDeviceView1D &
weights,
int idx)
const {
693 weights = Kokkos::subview(edgeWeightsDevice_, Kokkos::ALL, idx);
697template <
typename User,
typename UserCoord>
699 typename Base::WeightsDeviceView &
weights)
const {
705template <
typename User,
typename UserCoord>
707 typename Base::WeightsHostView1D &
weights,
int idx)
const {
709 auto weightsDevice = Kokkos::subview(edgeWeightsDevice_, Kokkos::ALL, idx);
710 weights = Kokkos::create_mirror_view(weightsDevice);
711 Kokkos::deep_copy(
weights, weightsDevice);
715template <
typename User,
typename UserCoord>
717 typename Base::WeightsHostView &
weights)
const {
719 weights = Kokkos::create_mirror_view(edgeWeightsDevice_);
720 Kokkos::deep_copy(
weights, edgeWeightsDevice_);
724template <
typename User,
typename UserCoord>
725template <
typename Adapter>
727 const User &in, User *&out,
731 ArrayRCP<gno_t> importList;
734 Zoltan2::getImportList<Adapter, TpetraRowGraphAdapter<User, UserCoord>>(
735 solution,
this, importList);
740 RCP<User> outPtr = doMigration(in, numNewVtx, importList.getRawPtr());
746template <
typename User,
typename UserCoord>
747template <
typename Adapter>
749 const User &in, RCP<User> &out,
753 ArrayRCP<gno_t> importList;
756 Zoltan2::getImportList<Adapter, TpetraRowGraphAdapter<User, UserCoord>>(
757 solution,
this, importList);
762 out = doMigration(in, numNewVtx, importList.getRawPtr());
766template <
typename User,
typename UserCoord>
768 const User &from,
size_t numLocalRows,
const gno_t *myNewRows)
const {
769 typedef Tpetra::Map<lno_t, gno_t, node_t>
map_t;
770 typedef Tpetra::CrsGraph<lno_t, gno_t, node_t> tcrsgraph_t;
781 const tcrsgraph_t *pCrsGraphSrc =
dynamic_cast<const tcrsgraph_t *
>(&from);
784 throw std::logic_error(
"TpetraRowGraphAdapter cannot migrate data for "
785 "your RowGraph; it can migrate data only for "
787 "You can inherit from TpetraRowGraphAdapter and "
788 "implement migration for your RowGraph.");
792 const RCP<const map_t> &smap = from.getRowMap();
793 int oldNumElts = smap->getLocalNumElements();
794 gno_t numGlobalRows = smap->getGlobalNumElements();
795 gno_t base = smap->getMinAllGlobalIndex();
798 ArrayView<const gno_t> rowList(myNewRows, numLocalRows);
799 const RCP<const Teuchos::Comm<int>> &comm = from.getComm();
800 RCP<const map_t> tmap = rcp(
new map_t(numGlobalRows, rowList, base, comm));
803 Tpetra::Import<lno_t, gno_t, node_t> importer(smap, tmap);
806 typedef Tpetra::Vector<gno_t, lno_t, gno_t, node_t> vector_t;
807 vector_t numOld(smap);
808 vector_t numNew(tmap);
809 for (
int lid = 0; lid < oldNumElts; lid++) {
810 numOld.replaceGlobalValue(smap->getGlobalElement(lid),
811 from.getNumEntriesInLocalRow(lid));
813 numNew.doImport(numOld, importer, Tpetra::INSERT);
815 size_t numElts = tmap->getLocalNumElements();
816 ArrayRCP<const gno_t> nnz;
818 nnz = numNew.getData(0);
820 ArrayRCP<const size_t> nnz_size_t;
822 if (numElts &&
sizeof(
gno_t) !=
sizeof(
size_t)) {
823 size_t *vals =
new size_t[numElts];
824 nnz_size_t = arcp(vals, 0, numElts,
true);
825 for (
size_t i = 0; i < numElts; i++) {
826 vals[i] =
static_cast<size_t>(nnz[i]);
829 nnz_size_t = arcp_reinterpret_cast<const size_t>(nnz);
833 RCP<tcrsgraph_t> G = rcp(
new tcrsgraph_t(tmap, nnz_size_t()));
835 G->doImport(*pCrsGraphSrc, importer, Tpetra::INSERT);
837 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__)