3.4
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
scotchbackend.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*****************************************************************************
4 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
19
26#ifndef DUMUX_SCOTCH_BACKEND_HH
27#define DUMUX_SCOTCH_BACKEND_HH
28
29#include <string>
30#include <vector>
31#include <iostream>
32
33#if HAVE_PTSCOTCH
34#if HAVE_MPI
35#include <mpi.h>
36#endif
37extern "C"
38{
39#include <stdint.h>
40#include <ptscotch.h>
41}
42#else
43#warning "PTSCOTCH was not found on your system. Dumux::ScotchBackend won't do anything."
44#endif
45
46namespace Dumux {
47
54template<class IndexType>
56{
57public:
59 using Graph = std::vector<std::vector<IndexType>>;
60
63 static std::vector<int> computeGPSReordering(const Graph& graph,
64 std::size_t numPasses = 5)
65 {
66 // Create strategy string for Gibbs-Poole-Stockmeyer ordering
67 std::string strategy = "g{pass= " + std::to_string(numPasses) + "}";
68 return computeReordering(graph, strategy);
69 }
70
72 static std::vector<int> computeReordering(const Graph& graph,
73 std::string scotchStrategy = "")
74 {
75 std::vector<int> permutation, inversePermutation;
76 computeReordering(graph, permutation, inversePermutation, scotchStrategy);
77 return permutation;
78 }
79
81 static void computeReordering(const Graph& graph,
82 std::vector<int>& permutation,
83 std::vector<int>& inversePermutation,
84 std::string scotchStrategy = "")
85 {
86#if HAVE_PTSCOTCH
87 // Number of local graph vertices (cells)
88 const SCOTCH_Num vertnbr = graph.size();
89
90 // Data structures for graph input to SCOTCH (add 1 for case that
91 // graph size is zero)
92 std::vector<SCOTCH_Num> verttab;
93 verttab.reserve(vertnbr + 1);
94 std::vector<SCOTCH_Num> edgetab;
95 edgetab.reserve(20*vertnbr);
96
97 // Build local graph input for SCOTCH
98 // (number of graph vertices (cells),
99 // number of edges connecting two vertices)
100 SCOTCH_Num edgenbr = 0;
101 verttab.push_back(0);
102 typename Graph::const_iterator vertex;
103 for (vertex = graph.begin(); vertex != graph.end(); ++vertex)
104 {
105 edgenbr += vertex->size();
106 verttab.push_back(verttab.back() + vertex->size());
107 edgetab.insert(edgetab.end(), vertex->begin(), vertex->end());
108 }
109
110 // Shrink vectors to hopefully recover an unused memory
111 verttab.shrink_to_fit();
112 edgetab.shrink_to_fit();
113
114 // Create SCOTCH graph
115 SCOTCH_Graph scotchGraph;
116
117 // C-style array indexing
118 const SCOTCH_Num baseval = 0;
119
120 // Create SCOTCH graph and initialise
121 if (SCOTCH_graphInit(&scotchGraph) != 0)
122 {
123 std::cerr << "Error initializing SCOTCH graph!" << std::endl;
124 exit(1);
125 }
126
127 // Build SCOTCH graph
128 if (SCOTCH_graphBuild(&scotchGraph, baseval,
129 vertnbr, &verttab[0], &verttab[1], NULL, NULL,
130 edgenbr, &edgetab[0], NULL))
131 {
132 std::cerr << "Error building SCOTCH graph!" << std::endl;
133 exit(1);
134 }
135
136 // Re-ordering strategy
137 SCOTCH_Strat strat;
138 SCOTCH_stratInit(&strat);
139
140 // Set SCOTCH strategy (if provided)
141 if (!scotchStrategy.empty())
142 SCOTCH_stratGraphOrder(&strat, scotchStrategy.c_str());
143
144 // Vector to hold permutation vectors
145 std::vector<SCOTCH_Num> permutationIndices(vertnbr);
146 std::vector<SCOTCH_Num> inversePermutationIndices(vertnbr);
147
148 // Reset SCOTCH random number generator to produce deterministic partitions
149 SCOTCH_randomReset();
150
151 // Compute re-ordering
152 if (SCOTCH_graphOrder(&scotchGraph, &strat, permutationIndices.data(),
153 inversePermutationIndices.data(), NULL, NULL, NULL))
154 {
155 std::cerr << "SCOTCH: Error during reordering graph!" << std::endl;
156 exit(1);
157 }
158
159 // Clean up SCOTCH objects
160 SCOTCH_graphExit(&scotchGraph);
161 SCOTCH_stratExit(&strat);
162
163 // Copy permutation vectors
164 permutation.resize(vertnbr);
165 inversePermutation.resize(vertnbr);
166 std::copy(permutationIndices.begin(), permutationIndices.end(),
167 permutation.begin());
168 std::copy(inversePermutationIndices.begin(), inversePermutationIndices.end(),
169 inversePermutation.begin());
170#endif // HAVE_PTSCOTCH
171 }
172};
173
174} // end namespace Dumux
175
176#endif
Definition: adapt.hh:29
Definition: scotchbackend.hh:56
static std::vector< int > computeReordering(const Graph &graph, std::string scotchStrategy="")
Compute graph re-ordering.
Definition: scotchbackend.hh:72
std::vector< std::vector< IndexType > > Graph
the graph type
Definition: scotchbackend.hh:59
static std::vector< int > computeGPSReordering(const Graph &graph, std::size_t numPasses=5)
Definition: scotchbackend.hh:63
static void computeReordering(const Graph &graph, std::vector< int > &permutation, std::vector< int > &inversePermutation, std::string scotchStrategy="")
Compute graph re-ordering.
Definition: scotchbackend.hh:81