41 const RCP<const typename Adapter::base_adapter_t> &adapter__,
42 const RCP<Teuchos::ParameterList> &pl__,
43 const RCP<
const Teuchos::Comm<int> > &comm__,
44 RCP<const Environment> &env__,
46 ) : adapter(adapter__), pl(pl__), comm(comm__), env(env__), graphFlags(graphFlags__)
57#ifndef HAVE_ZOLTAN2_METIS
59 throw std::runtime_error(
60 "BUILD ERROR: Metis requested but not compiled into Zoltan2.\n"
61 "Please set CMake flag Zoltan2_ENABLE_METIS:BOOL=ON.");
63 typedef typename Adapter::gno_t
gno_t;
64 typedef typename Adapter::lno_t
lno_t;
65 typedef typename Adapter::offset_t offset_t;
66 typedef typename Adapter::scalar_t
scalar_t;
72 const size_t nVtx = model->getLocalNumVertices();
73 const size_t nNnz = model->getLocalNumEdges();
74 lno_t *perm = (
lno_t *) (solution->getPermutationRCP().getRawPtr());
76 if (nVtx > 0 && nNnz > 0) {
77 ArrayView<const gno_t> edgeIds;
78 ArrayView<const offset_t> offsets;
79 ArrayView<StridedData<lno_t, scalar_t> > wgts;
80 model->getEdgeList(edgeIds, offsets, wgts);
83 using Zoltan2OffsetView =
typename Kokkos::View<offset_t*, Kokkos::HostSpace>;
84 using Zoltan2EdgeView =
typename Kokkos::View<gno_t*, Kokkos::HostSpace>;
85 Zoltan2OffsetView zoltan2_rowptr (
const_cast<offset_t*
>(offsets.data()), nVtx+1);
86 Zoltan2EdgeView zoltan2_colidx (
const_cast<gno_t*
>(edgeIds.data()), nNnz);
88 using MetisIdxView =
typename Kokkos::View<idx_t*, Kokkos::HostSpace>;
89 MetisIdxView metis_rowptr;
90 MetisIdxView metis_colidx;
92 const bool doSymmetrize =
93 pl.is_null() ? true : pl->get<
bool>(
"symmetrize",
true);
97 KokkosKernels::Impl::symmetrize_graph_symbolic_hashmap<
98 Zoltan2OffsetView, Zoltan2EdgeView, MetisIdxView, MetisIdxView, Kokkos::HostSpace::execution_space>
99 (nVtx, zoltan2_rowptr, zoltan2_colidx, metis_rowptr, metis_colidx);
103 metis_rowptr = MetisIdxView(
"metis_rowptr", nVtx+1);
104 metis_colidx = MetisIdxView(
"metis_colidx", nNnz);
106 for (
size_t i = 0; i < nVtx+1; ++i)
109 for (
size_t k = 0; k < nNnz; ++k)
117 idx_t nnz = metis_rowptr(0);
119 for (idx_t i = 0; i < metis_nVtx; i++) {
120 for (idx_t k = old_nnz; k < metis_rowptr(i+1); k++) {
121 if (metis_colidx(k) != i) {
122 metis_colidx(nnz) = metis_colidx(k);
126 old_nnz = metis_rowptr(i+1);
127 metis_rowptr(i+1) = nnz;
131 idx_t *metis_perm =
new idx_t[nVtx];
132 idx_t *metis_iperm =
new idx_t[nVtx];
135 int info = METIS_NodeND(&metis_nVtx, metis_rowptr.data(), metis_colidx.data(),
136 NULL, NULL, metis_perm, metis_iperm);
137 if (METIS_OK != info) {
138 throw std::runtime_error(
"METIS_NodeND returned info = " + std::to_string(info));
142 for (
size_t i = 0; i < nVtx; i++)
145 delete [] metis_iperm;
146 delete [] metis_perm;
148 for (
size_t i = 0; i < nVtx; i++)
152 solution->setHavePerm(
true);