kahipDecomp.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2017-2019 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "kahipDecomp.H"
30 #include "Time.H"
31 #include "PrecisionAdaptor.H"
32 
33 #include "kaHIP_interface.h"
34 
35 #include <string>
36 #include <map>
37 #include <vector>
38 
39 // Provide a clear error message if we have a severe size mismatch
40 // Allow widening, but not narrowing
41 
42 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
43 
44 namespace Foam
45 {
46  defineTypeNameAndDebug(kahipDecomp, 0);
47 
49  (
50  decompositionMethod,
51  kahipDecomp,
52  dictionary
53  );
54 
56  (
57  decompositionMethod,
58  kahipDecomp,
59  dictionaryRegion
60  );
61 }
62 
63 
64 const Foam::Enum
65 <
67 >
69 ({
70  { kahipDecomp::configs::FAST, "fast" },
71  { kahipDecomp::configs::ECO, "eco" },
72  { kahipDecomp::configs::STRONG, "strong" },
73  { kahipDecomp::configs::FASTSOCIAL, "fast-social" },
74  { kahipDecomp::configs::ECOSOCIAL, "eco-social" },
75  { kahipDecomp::configs::STRONGSOCIAL, "strong-social" },
76 });
77 
78 
79 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
80 
82 (
83  const labelList& adjncy,
84  const labelList& xadj,
85  const List<scalar>& cWeights,
86  labelList& decomp
87 ) const
88 {
89  // Default setup
90  enum configs kahipConfig = configs::FAST;
91  double imbalance = 0.01;
92  int seed = 0;
93  bool verbose = false;
94 
95  #if WM_LABEL_SIZE == 64
96  if (xadj.size()-1 > INT_MAX)
97  {
99  << "Cannot decompose " << (xadj.size()-1) << " cells," << nl
100  << "Exceeded integer limit of " << INT_MAX << nl
101  << exit(FatalError);
102  }
103  #endif
104 
105  int numCells = xadj.size()-1;
106 
107  // Cell weights (so on the vertices of the dual)
108  List<int> cellWeights;
109 
110  // Check for externally provided cellweights and if so initialise weights
111  // Note: min, not gMin since routine runs on master only.
112  const scalar minWeights = min(cWeights);
113 
114  if (!cWeights.empty())
115  {
116  if (minWeights <= 0)
117  {
119  << "Illegal minimum weight " << minWeights
120  << endl;
121  }
122 
123  if (cWeights.size() != numCells)
124  {
126  << "Number of cell weights " << cWeights.size()
127  << " does not equal number of cells " << numCells
128  << exit(FatalError);
129  }
130 
131  // Convert to integers.
132  cellWeights.setSize(cWeights.size());
133  forAll(cellWeights, i)
134  {
135  cellWeights[i] = int(cWeights[i]/minWeights);
136  }
137  }
138 
139  configNames.readIfPresent("config", coeffsDict_, kahipConfig);
140  coeffsDict_.readIfPresent("imbalance", imbalance);
141  coeffsDict_.readIfPresent("verbose", verbose);
142 
143  Info<< "kahipDecomp :"
144  << " config=" << configNames[kahipConfig]
145  << " imbalance=" << imbalance;
146 
147  if (coeffsDict_.readIfPresent("seed", seed))
148  {
149  Info<< " seed=" << seed;
150  }
151 
152  // Additional sizing parameters (testing only)
153  std::map<std::string, std::vector<int>> sizingParams;
154 
155  List<int> labels;
156  if
157  (
158  coeffsDict_.readIfPresent("hierarchy", labels)
159  && !labels.empty()
160  )
161  {
162  std::vector<int> vec;
163  vec.reserve(labels.size()+1);
164 
165  // Verify sizing
166 
167  int n = 1;
168  for (const auto val : labels)
169  {
170  n *= val;
171  vec.push_back(val);
172  }
173 
174  if (n != nDomains_)
175  {
176  // Size mismatch. Try to correct.
177 
178  if (nDomains_ % n)
179  {
181  << "Mismatch in number of processors and "
182  << "hierarchy specified" << flatOutput(labels) << endl;
183 
184  vec.clear();
185  }
186  else
187  {
188  // Evenly divisible, add extra hierarchy level
189  vec.push_back(nDomains_ / n);
190  }
191  }
192 
193  if (!vec.empty())
194  {
195  sizingParams["hierarchy"] = std::move(vec);
196  Info<< " hierarchy=" << flatOutput(labels);
197  }
198  }
199 
200  if
201  (
202  coeffsDict_.readIfPresent("distance", labels)
203  && !labels.empty()
204  )
205  {
206  std::vector<int> vec(labels.size());
207 
208  forAll(labels, i)
209  {
210  vec[i] = labels[i];
211  }
212 
213  sizingParams["distance"] = std::move(vec);
214  Info<< " distance=" << flatOutput(labels);
215  }
216 
217  Info<< endl;
218 
219 
220  // Number of partitions
221  int nParts = nDomains_;
222 
223  // Output: number of cut edges
224  int edgeCut = 0;
225 
226  // Addressing
227  ConstPrecisionAdaptor<int, label, List> xadj_param(xadj);
228  ConstPrecisionAdaptor<int, label, List> adjncy_param(adjncy);
229 
230  // Output: cell -> processor addressing
231  decomp.resize(numCells);
232  PrecisionAdaptor<int, label, List> decomp_param(decomp);
233 
234 
235 #if 0 // WIP: #ifdef KAFFPA_CPP_INTERFACE
236  kaffpa_cpp
237  (
238  &numCells, // num vertices in graph
239  (cellWeights.size() ? cellWeights.begin() : nullptr), // vertex wts
240  xadj_param.constCast().data(), // indexing into adjncy
241  nullptr, // edge wts
242  adjncy_param.constCast().data(), // neighbour info
243  &nParts, // nparts
244  &imbalance, // amount of imbalance allowed
245  !verbose, // suppress output
246  seed, // for random
247  int(kahipConfig),
248  &edgeCut, // [output]
249  decomp_param.ref().data(), // [output]
250  sizingParams
251  );
252 #else
253  kaffpa
254  (
255  &numCells, // num vertices in graph
256  (cellWeights.size() ? cellWeights.begin() : nullptr), // vertex wts
257  xadj_param.constCast().data(), // indexing into adjncy
258  nullptr, // edge wts
259  adjncy_param.constCast().data(), // neighbour info
260  &nParts, // nparts
261  &imbalance, // amount of imbalance allowed
262  !verbose, // suppress output
263  seed, // for random
264  int(kahipConfig),
265  &edgeCut, // [output]
266  decomp_param.ref().data() // [output]
267  );
268 #endif
269 
270  return edgeCut;
271 }
272 
273 
274 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
275 
276 Foam::kahipDecomp::kahipDecomp(const dictionary& decompDict)
277 :
278  metisLikeDecomp(typeName, decompDict, selectionType::NULL_DICT)
279 {}
280 
281 
283 (
284  const dictionary& decompDict,
285  const word& regionName
286 )
287 :
288  metisLikeDecomp(typeName, decompDict, regionName, selectionType::NULL_DICT)
289 {}
290 
291 
292 // ************************************************************************* //
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
Foam::decompositionMethod::nDomains_
label nDomains_
Number of domains for the decomposition.
Definition: decompositionMethod.H:95
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:74
Foam::val
label ListType::const_reference val
Definition: ListOps.H:407
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:51
Foam::metisLikeDecomp::coeffsDict_
const dictionary & coeffsDict_
Coefficients for all derived methods.
Definition: metisLikeDecomp.H:60
PrecisionAdaptor.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::kahipDecomp::decomposeSerial
virtual label decomposeSerial(const labelList &adjncy, const labelList &xadj, const List< scalar > &cellWeights, labelList &decomp) const
Call kahip with options from dictionary.
Definition: dummyKahipDecomp.C:58
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
n
label n
Definition: TABSMDCalcMethod2.H:31
regionName
Foam::word regionName
Definition: createNamedDynamicFvMesh.H:1
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::kahipDecomp::configNames
static const Enum< configs > configNames
The selection names for predefined KaHIP configurations.
Definition: kahipDecomp.H:134
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::kahipDecomp::configs
configs
The predefined KaHIP configuration types.
Definition: kahipDecomp.H:122
Foam::FatalError
error FatalError
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Time.H
Foam::kahipDecomp::configs::FAST
default
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Foam::flatOutput
FlatOutput< Container > flatOutput(const Container &obj, label len=0)
Global flatOutput function.
Definition: FlatOutput.H:85
Foam::Enum::readIfPresent
bool readIfPresent(const word &key, const dictionary &dict, EnumType &val) const
Find an entry if present, and assign to T val.
Definition: Enum.C:271
Foam::kahipDecomp::kahipDecomp
kahipDecomp(const kahipDecomp &)=delete
No copy construct.
kahipDecomp.H
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:294
Foam::dictionary::readIfPresent
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:417