3.5-git
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#include <dune/common/exceptions.hh>
34
35#if HAVE_PTSCOTCH
36#if HAVE_MPI
37#include <mpi.h>
38#endif
39extern "C"
40{
41#include <stdint.h>
42#include <ptscotch.h>
43}
44#else
45#warning "PTSCOTCH was not found on your system. Dumux::ScotchBackend won't do anything."
46#endif
47
48namespace Dumux {
49
50#if HAVE_PTSCOTCH
51
57template<class IndexType = int>
58class ScotchGraph
59{
60public:
62 using Graph = std::vector<std::vector<IndexType>>;
63
64 ScotchGraph(const Graph& graph)
65 {
66 // Number of local graph vertices
67 const SCOTCH_Num numNodes = graph.size();
68
69 // Data structures for graph input to SCOTCH
70 // add 1 for case that graph size is zero
71 vertTab_.reserve(numNodes + 1);
72 edgeTab_.reserve(20*numNodes);
73
74 // Build local graph input for SCOTCH
75 // (number of graph vertices (cells),
76 // number of edges connecting two vertices)
77 SCOTCH_Num numEdges = 0;
78 vertTab_.push_back(0);
79 for (auto vertex = graph.begin(); vertex != graph.end(); ++vertex)
80 {
81 numEdges += vertex->size();
82 vertTab_.push_back(vertTab_.back() + vertex->size());
83 edgeTab_.insert(edgeTab_.end(), vertex->begin(), vertex->end());
84 }
85
86 // Shrink vectors to hopefully recover any unused memory
87 vertTab_.shrink_to_fit();
88 edgeTab_.shrink_to_fit();
89
90 if (SCOTCH_graphInit(&scotchGraph_) != 0)
91 DUNE_THROW(Dune::Exception, "Error initializing SCOTCH graph!");
92
93 // check graph's consistency (recommended before building)
94 if (SCOTCH_graphCheck(&scotchGraph_) != 0)
95 DUNE_THROW(Dune::Exception, "Error within SCOTCH graph's consistency!");
96
97 // build graph
98 const SCOTCH_Num baseValue = 0; // C-style array indexing
99 if (SCOTCH_graphBuild(&scotchGraph_, baseValue, numNodes, vertTab_.data(), vertTab_.data()+1, NULL, NULL, numEdges, edgeTab_.data(), NULL))
100 DUNE_THROW(Dune::Exception, "Error building SCOTCH graph!");
101 }
102
104 ~ScotchGraph()
105 {
106 SCOTCH_graphExit(&scotchGraph_);
107 }
108
110 SCOTCH_Graph* data()
111 { return &scotchGraph_; }
112
113private:
114 SCOTCH_Graph scotchGraph_;
115 // we have to maintain these ourselves to keep the Scotch graph valid
116 std::vector<SCOTCH_Num> vertTab_;
117 std::vector<SCOTCH_Num> edgeTab_;
118};
119
125class ScotchGraphOrderStrategy
126{
127public:
128 ScotchGraphOrderStrategy(const std::string& strategy = "")
129 {
130 if (SCOTCH_stratInit(&strategy_) != 0)
131 DUNE_THROW(Dune::Exception, "Error initializing SCOTCH strategy!");
132
133 // Set SCOTCH strategy (if provided)
134 if (!strategy.empty())
135 SCOTCH_stratGraphOrder(&strategy_, strategy.c_str());
136 }
137
139 ~ScotchGraphOrderStrategy()
140 {
141 SCOTCH_stratExit(&strategy_);
142 }
143
145 SCOTCH_Strat* data()
146 { return &strategy_; }
147
148private:
149 SCOTCH_Strat strategy_;
150};
151
152#endif // HAVE_PTSCOTCH
153
160template<class IndexType>
162{
163public:
165 using Graph = std::vector<std::vector<IndexType>>;
166
169 static std::vector<int> computeGPSReordering(const Graph& graph,
170 std::size_t numPasses = 5)
171 {
172 // Create strategy string for Gibbs-Poole-Stockmeyer ordering
173 std::string strategy = "g{pass= " + std::to_string(numPasses) + "}";
174 return computeReordering(graph, strategy);
175 }
176
178 static std::vector<int> computeReordering(const Graph& graph,
179 std::string scotchStrategy = "")
180 {
181 std::vector<int> permutation, inversePermutation;
182 computeReordering(graph, permutation, inversePermutation, scotchStrategy);
183 return permutation;
184 }
185
187 static void computeReordering(const Graph& graph,
188 std::vector<int>& permutation,
189 std::vector<int>& inversePermutation,
190 std::string scotchStrategy = "")
191 {
192#if HAVE_PTSCOTCH
193 ScotchGraph<IndexType> scotchGraph(graph);
194 ScotchGraphOrderStrategy strategy(scotchStrategy);
195
196 // Vector to hold permutation vectors
197 const auto graphSize = graph.size();
198 std::vector<SCOTCH_Num> permutationIndices(graphSize);
199 std::vector<SCOTCH_Num> inversePermutationIndices(graphSize);
200
201 // Reset SCOTCH random number generator to produce deterministic partitions
202 SCOTCH_randomReset();
203
204 // Compute re-ordering
205 if (SCOTCH_graphOrder(
206 scotchGraph.data(), strategy.data(), permutationIndices.data(),
207 inversePermutationIndices.data(), NULL, NULL, NULL
208 ))
209 DUNE_THROW(Dune::Exception, "Error reordering SCOTCH graph!");
210
211 // Copy permutation vectors
212 permutation.resize(graphSize);
213 inversePermutation.resize(graphSize);
214 std::copy(permutationIndices.begin(), permutationIndices.end(),
215 permutation.begin());
216 std::copy(inversePermutationIndices.begin(), inversePermutationIndices.end(),
217 inversePermutation.begin());
218#endif // HAVE_PTSCOTCH
219 }
220};
221
222} // end namespace Dumux
223
224#endif
Definition: adapt.hh:29
Definition: scotchbackend.hh:162
static std::vector< int > computeReordering(const Graph &graph, std::string scotchStrategy="")
Compute graph re-ordering.
Definition: scotchbackend.hh:178
std::vector< std::vector< IndexType > > Graph
the graph type
Definition: scotchbackend.hh:165
static std::vector< int > computeGPSReordering(const Graph &graph, std::size_t numPasses=5)
Definition: scotchbackend.hh:169
static void computeReordering(const Graph &graph, std::vector< int > &permutation, std::vector< int > &inversePermutation, std::string scotchStrategy="")
Compute graph re-ordering.
Definition: scotchbackend.hh:187