10 #ifndef _ZOLTAN2_ALGRCM_HPP_
11 #define _ZOLTAN2_ALGRCM_HPP_
19 #include <KokkosKernels_Utils.hpp>
20 #include <KokkosCompat_View.hpp>
29 template <
typename Adapter>
34 const RCP<const typename Adapter::base_adapter_t> adapter;
35 const RCP<Teuchos::ParameterList> pl;
36 const RCP<const Teuchos::Comm<int> > comm;
37 RCP<const Environment> env;
48 const RCP<const typename Adapter::base_adapter_t> &adapter__,
49 const RCP<Teuchos::ParameterList> &pl__,
50 const RCP<
const Teuchos::Comm<int> > &comm__,
51 RCP<const Environment> &env__,
53 ) : adapter(adapter__), pl(pl__), comm(comm__), env(env__), graphFlags(graphFlags__)
59 throw std::logic_error(
"AlgRCM does not yet support global ordering.");
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 device = Kokkos::Device<Kokkos::Serial, Kokkos::HostSpace>;
91 using local_graph_type = KokkosSparse::StaticCrsGraph<const gno_t, Kokkos::LayoutLeft, Kokkos::HostSpace, void, const offset_t>;
93 typename local_graph_type::row_map_type::non_const_type symRowmap;
94 typename local_graph_type::entries_type::non_const_type symEntries;
96 Kokkos::View<const gno_t *, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged>> edgeIdsKokkos(edgeIds.data(), edgeIds.size());
97 Kokkos::View<const offset_t *, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged>> offsetsKokkos(offsets.data(), offsets.size());
99 local_graph_type localGraph(edgeIdsKokkos, offsetsKokkos);
101 KokkosKernels::Impl::symmetrize_graph_symbolic_hashmap<
typename local_graph_type::row_map_type,
typename local_graph_type::entries_type,
102 typename local_graph_type::row_map_type::non_const_type,
typename local_graph_type::entries_type::non_const_type,
103 Kokkos::Serial>(localGraph.numRows(), localGraph.row_map, localGraph.entries, symRowmap, symEntries);
104 edgeIds = Kokkos::Compat::getConstArrayView(symEntries);
105 offsets = Kokkos::Compat::getConstArrayView(symRowmap);
109 const ArrayRCP<lno_t> invPerm = solution->getPermutationRCP(
true);
110 const ArrayRCP<lno_t> tmpPerm(invPerm.size());
114 if (offsets[nVtx] == 0) {
115 for (
size_t i = 0; i < nVtx; ++i) {
118 solution->setHaveInverse(
true);
124 for (
size_t i = 0; i < nVtx; ++i) {
134 Teuchos::Array<std::pair<gno_t, offset_t> > children;
136 while (count < nVtx) {
140 while ((next < nVtx) && (static_cast<Tpetra::global_size_t>(invPerm[next]) != INVALID)) next++;
144 std::string root_method = pl->get(
"root_method",
"pseudoperipheral");
145 if (root_method == std::string(
"first"))
147 else if (root_method == std::string(
"smallest_degree"))
148 root = findSmallestDegree(next, nVtx, edgeIds, offsets);
149 else if (root_method == std::string(
"pseudoperipheral"))
150 root = findPseudoPeripheral(next, nVtx, edgeIds, offsets);
153 throw std::runtime_error(
"invalid root_method");
159 invPerm[
root] = count++;
170 for (
offset_t ptr = offsets[v]; ptr < offsets[v+1]; ++ptr){
171 gno_t child = edgeIds[ptr];
172 if (static_cast<Tpetra::global_size_t>(invPerm[child]) == INVALID){
174 std::pair<gno_t,offset_t> newchild;
175 newchild.first = child;
176 newchild.second = offsets[child+1] - offsets[child];
177 children.push_back(newchild);
185 typename Teuchos::Array<std::pair<gno_t,offset_t> >::iterator it = children.begin ();
186 for ( ; it != children.end(); ++it){
188 gno_t child = it->first;
189 invPerm[child] = count++;
190 tmpPerm[invPerm[child]] = child;
203 for (
size_t i=0; i < nVtx/2; ++i) {
210 invPerm[tmpPerm[nVtx-1-i]] = i;
211 invPerm[temp] = nVtx-1-i;
216 for (
size_t i = 0; i < nVtx; ++i) {
217 if (static_cast<Tpetra::global_size_t>(invPerm[i]) == INVALID) {
218 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\".");
222 solution->setHaveInverse(
true);
228 gno_t findSmallestDegree(
231 ArrayView<const gno_t> edgeIds,
232 ArrayView<const offset_t> offsets)
235 Teuchos::Array<bool> mark(nVtx);
239 gno_t smallestVertex = 0;
242 for (
int i=0; i<nVtx; i++)
252 offset_t deg = offsets[v+1] - offsets[v];
253 if (deg < smallestDegree){
254 smallestDegree = deg;
258 for (
offset_t ptr = offsets[v]; ptr < offsets[v+1]; ++ptr){
259 gno_t child = edgeIds[ptr];
266 return smallestVertex;
270 gno_t findPseudoPeripheral(
273 ArrayView<const gno_t> edgeIds,
274 ArrayView<const offset_t> offsets)
277 Teuchos::Array<bool> mark(nVtx);
280 const int numBFS = 2;
281 for (
int bfs=0; bfs<numBFS; bfs++){
283 for (
int i=0; i<nVtx; i++)
292 for (
offset_t ptr = offsets[v]; ptr < offsets[v+1]; ++ptr){
293 gno_t child = edgeIds[ptr];
int localOrder(const RCP< LocalOrderingSolution< lno_t > > &solution)
Ordering method.
AlgRCM(const RCP< const typename Adapter::base_adapter_t > &adapter__, const RCP< Teuchos::ParameterList > &pl__, const RCP< const Teuchos::Comm< int > > &comm__, RCP< const Environment > &env__, const modelFlag_t &graphFlags__)
std::bitset< NUM_MODEL_FLAGS > modelFlag_t
map_t::global_ordinal_type gno_t
Defines the OrderingSolution class.
Adapter::offset_t offset_t
Algorithm defines the base class for all algorithms.
map_t::local_ordinal_type lno_t
int globalOrder(const RCP< GlobalOrderingSolution< gno_t > > &)
Ordering method.
Sort vector of pairs (key, value) by value.
Adapter::scalar_t scalar_t
GraphModel defines the interface required for graph models.
Tpetra::global_size_t global_size_t
Defines the GraphModel interface.
void sort(Teuchos::Array< std::pair< key_t, value_t > > &listofPairs, bool inc=true)