69 ArrayView<const gno_t> edgeIds;
70 ArrayView<const offset_t> offsets;
71 ArrayView<StridedData<lno_t, scalar_t> > wgts;
74 const size_t nVtx = model->getLocalNumVertices();
75 model->getEdgeList(edgeIds, offsets, wgts);
76 const int numWeightsPerEdge = model->getNumWeightsPerEdge();
77 if (numWeightsPerEdge > 1){
78 throw std::runtime_error(
"Multiple weights not supported.");
83 cout <<
"Debug: Local graph from getLocalEdgeList" << endl;
84 cout <<
"rank " << comm->getRank() <<
": nVtx= " << nVtx << endl;
85 cout <<
"rank " << comm->getRank() <<
": edgeIds: " << edgeIds << endl;
86 cout <<
"rank " << comm->getRank() <<
": offsets: " << offsets << endl;
89 bool symmetrize = pl->get(
"symmetrize",
false);
90 using local_graph_type = KokkosSparse::StaticCrsGraph<const gno_t, Kokkos::LayoutLeft, Kokkos::HostSpace, void, const offset_t>;
92 typename local_graph_type::row_map_type::non_const_type symRowmap;
93 typename local_graph_type::entries_type::non_const_type symEntries;
95 Kokkos::View<const gno_t *, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged>> edgeIdsKokkos(edgeIds.data(), edgeIds.size());
96 Kokkos::View<const offset_t *, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged>> offsetsKokkos(offsets.data(), offsets.size());
98 local_graph_type localGraph(edgeIdsKokkos, offsetsKokkos);
100 KokkosKernels::Impl::symmetrize_graph_symbolic_hashmap<
typename local_graph_type::row_map_type,
typename local_graph_type::entries_type,
101 typename local_graph_type::row_map_type::non_const_type,
typename local_graph_type::entries_type::non_const_type,
102 Kokkos::Serial>(localGraph.numRows(), localGraph.row_map, localGraph.entries, symRowmap, symEntries);
103 edgeIds = Kokkos::Compat::getConstArrayView(symEntries);
104 offsets = Kokkos::Compat::getConstArrayView(symRowmap);
108 const ArrayRCP<lno_t> invPerm = solution->getPermutationRCP(
true);
109 const ArrayRCP<lno_t> tmpPerm(invPerm.size());
113 if (offsets[nVtx] == 0) {
114 for (
size_t i = 0; i < nVtx; ++i) {
117 solution->setHaveInverse(
true);
122 Tpetra::global_size_t
INVALID = Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid();
123 for (
size_t i = 0; i < nVtx; ++i) {
133 Teuchos::Array<std::pair<gno_t, offset_t> > children;
135 while (count < nVtx) {
139 while ((next < nVtx) && (
static_cast<Tpetra::global_size_t
>(invPerm[next]) !=
INVALID)) next++;
143 std::string root_method = pl->get(
"root_method",
"pseudoperipheral");
144 if (root_method == std::string(
"first"))
146 else if (root_method == std::string(
"smallest_degree"))
147 root = findSmallestDegree(next, nVtx, edgeIds, offsets);
148 else if (root_method == std::string(
"pseudoperipheral"))
149 root = findPseudoPeripheral(next, nVtx, edgeIds, offsets);
152 throw std::runtime_error(
"invalid root_method");
158 invPerm[root] = count++;
159 tmpPerm[invPerm[root]] = root;
169 for (
offset_t ptr = offsets[v]; ptr < offsets[v+1]; ++ptr){
170 gno_t child = edgeIds[ptr];
171 if (
static_cast<Tpetra::global_size_t
>(invPerm[child]) ==
INVALID){
173 std::pair<gno_t,offset_t> newchild;
174 newchild.first = child;
175 newchild.second = offsets[child+1] - offsets[child];
176 children.push_back(newchild);
184 typename Teuchos::Array<std::pair<gno_t,offset_t> >::iterator it = children.begin ();
185 for ( ; it != children.end(); ++it){
187 gno_t child = it->first;
188 invPerm[child] = count++;
189 tmpPerm[invPerm[child]] = child;
202 for (
size_t i=0; i < nVtx/2; ++i) {
209 invPerm[tmpPerm[nVtx-1-i]] = i;
210 invPerm[temp] = nVtx-1-i;
215 for (
size_t i = 0; i < nVtx; ++i) {
216 if (
static_cast<Tpetra::global_size_t
>(invPerm[i]) ==
INVALID) {
217 throw std::runtime_error(
"An invalid permutation index had been detected in the RCM solution. This can occur if RCM is run on a non-symmetric matrix without setting \"symmetrize\"=\"true\".");
221 solution->setHaveInverse(
true);