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>
48 template <
typename User,
typename UserCoord = User>
52 #ifndef DOXYGEN_SHOULD_SKIP_THIS
60 using userCoord_t = UserCoord;
75 int nEdgeWeights = 0);
109 void setWeightsHost(
typename Base::ConstWeightsHostView1D val,
int idx);
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;
314 template <
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);
357 "vertexWeightsDevice_", nvtx, nWeightsPerVertex_);
360 "vertexDegreeWeightsHost_", nWeightsPerVertex_);
377 template <
typename User,
typename UserCoord>
379 const scalar_t *weightVal,
int stride,
int idx) {
381 setVertexWeights(weightVal, stride, idx);
383 setEdgeWeights(weightVal, stride, idx);
387 template <
typename User,
typename UserCoord>
389 typename Base::ConstWeightsDeviceView1D val,
int idx) {
391 setVertexWeightsDevice(val, idx);
393 setEdgeWeightsDevice(val, idx);
397 template <
typename User,
typename UserCoord>
399 typename Base::ConstWeightsHostView1D val,
int idx) {
401 setVertexWeightsHost(val, idx);
403 setEdgeWeightsHost(val, idx);
407 template <
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);
419 template <
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);
438 template <
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(
447 setVertexWeightsDevice(weightsDevice, idx);
451 template <
typename User,
typename UserCoord>
454 "setWeightIsNumberOfNonZeros is supported only for vertices");
456 setVertexWeightIsDegree(idx);
460 template <
typename User,
typename UserCoord>
463 "Invalid vertex weight index.");
465 vertexDegreeWeightsHost_(idx) =
true;
469 template <
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);
483 template <
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);
501 template <
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(
510 setEdgeWeightsDevice(weightsDevice);
514 template <
typename User,
typename UserCoord>
516 return graph_->getLocalNumRows();
520 template <
typename User,
typename UserCoord>
522 const gno_t *&ids)
const {
524 if (getLocalNumVertices())
525 ids = graph_->getRowMap()->getLocalElementList().getRawPtr();
529 template <
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);
544 template <
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);
558 template <
typename User,
typename UserCoord>
560 return graph_->getLocalNumEntries();
564 template <
typename User,
typename UserCoord>
567 offsets = offsHost_.data();
568 adjIds = (getLocalNumEdges() ? adjIdsHost_.data() : NULL);
572 template <
typename User,
typename UserCoord>
574 typename Base::ConstOffsetsDeviceView &offsets,
575 typename Base::ConstIdsDeviceView &adjIds)
const {
577 offsets = offsDevice_;
578 adjIds = adjIdsDevice_;
582 template <
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;
597 template <
typename User,
typename UserCoord>
599 return nWeightsPerVertex_;
603 template <
typename User,
typename UserCoord>
605 const scalar_t *&
weights,
int &stride,
int idx)
const {
608 "Invalid vertex weight index.");
611 vertexWeights_[idx].getStridedList(length, weights, stride);
615 template <
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);
633 template <
typename User,
typename UserCoord>
635 typename Base::WeightsDeviceView &
weights)
const {
637 weights = vertexWeightsDevice_;
641 template <
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);
656 template <
typename User,
typename UserCoord>
658 typename Base::WeightsHostView &
weights)
const {
660 weights = Kokkos::create_mirror_view(vertexWeightsDevice_);
661 Kokkos::deep_copy(weights, vertexWeightsDevice_);
665 template <
typename User,
typename UserCoord>
668 return vertexDegreeWeightsHost_(idx);
672 template <
typename User,
typename UserCoord>
674 return nWeightsPerEdge_;
678 template <
typename User,
typename UserCoord>
680 const scalar_t *&
weights,
int &stride,
int idx)
const {
682 "Invalid edge weight index.");
685 edgeWeights_[idx].getStridedList(length, weights, stride);
689 template <
typename User,
typename UserCoord>
691 typename Base::WeightsDeviceView1D &
weights,
int idx)
const {
693 weights = Kokkos::subview(edgeWeightsDevice_, Kokkos::ALL, idx);
697 template <
typename User,
typename UserCoord>
699 typename Base::WeightsDeviceView &
weights)
const {
701 weights = edgeWeightsDevice_;
705 template <
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);
715 template <
typename User,
typename UserCoord>
717 typename Base::WeightsHostView &
weights)
const {
719 weights = Kokkos::create_mirror_view(edgeWeightsDevice_);
720 Kokkos::deep_copy(weights, edgeWeightsDevice_);
724 template <
typename User,
typename UserCoord>
725 template <
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());
746 template <
typename User,
typename UserCoord>
747 template <
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());
766 template <
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);
TpetraRowGraphAdapter(int nVtxWgts, int nEdgeWgts, const RCP< const User > &graph)
ArrayRCP< StridedData< lno_t, scalar_t > > edgeWeights_
Base::ConstIdsHostView adjIdsHost_
void getVertexIDsHostView(typename Base::ConstIdsHostView &ids) const override
Sets pointers to this process' 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' graph entries.
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
typename InputTraits< User >::scalar_t scalar_t
Base::WeightsDeviceView edgeWeightsDevice_
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.
void getVertexWeightsDeviceView(typename Base::WeightsDeviceView1D &weights, int idx=0) const override
Provide a device view of the vertex weights, if any.
Base::ConstOffsetsDeviceView offsDevice_
GraphAdapter defines the interface for graph-based user data.
int getNumWeightsPerVertex() const override
Returns the number (0 or greater) of weights per vertex.
void setVertexWeights(const scalar_t *val, int stride, int idx)
Provide a pointer to vertex weights.
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
Base::ConstIdsDeviceView adjIdsDevice_
Base::VtxDegreeHostView vertexDegreeWeightsHost_
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
void getVertexIDsDeviceView(typename Base::ConstIdsDeviceView &ids) const override
Sets pointers to this process' 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.
Base::WeightsDeviceView vertexWeightsDevice_
Defines the GraphAdapter interface.
void setWeights(const scalar_t *val, int stride, int idx)
Provide a pointer to weights for the primary entity type.
Base::ConstOffsetsHostView offsHost_
virtual RCP< User > doMigration(const User &from, size_t numLocalRows, const gno_t *myNewRows) const
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.