14#include "arcane/utils/StringBuilder.h"
15#include "arcane/utils/Iostream.h"
17#include "arcane/utils/PlatformUtils.h"
18#include "arcane/utils/Convert.h"
19#include "arcane/utils/Array.h"
20#include "arcane/utils/Iostream.h"
21#include "arcane/utils/ScopedPtr.h"
22#include "arcane/utils/NotImplementedException.h"
23#include "arcane/utils/ArgumentException.h"
25#include "arcane/core/ISubDomain.h"
26#include "arcane/core/IParallelMng.h"
28#include "arcane/core/IMeshSubMeshTransition.h"
29#include "arcane/core/ItemGroup.h"
30#include "arcane/core/Service.h"
31#include "arcane/core/Timer.h"
32#include "arcane/core/FactoryService.h"
33#include "arcane/core/ItemPrinter.h"
34#include "arcane/core/IItemFamily.h"
35#include "arcane/core/MeshVariable.h"
36#include "arcane/core/VariableBuildInfo.h"
37#include "arcane/core/CommonVariables.h"
39#include "arcane_internal_config.h"
44#define MPICH_SKIP_MPICXX
45#define OMPI_SKIP_MPICXX
52#include "arcane/std/MeshPartitionerBase.h"
53#include "arcane/std/PTScotchMeshPartitioner_axl.h"
54#include "arcane/std/PartitionConverter.h"
55#include "arcane/std/GraphDistributor.h"
74class PTScotchMeshPartitioner
94PTScotchMeshPartitioner::
95PTScotchMeshPartitioner(
const ServiceBuildInfo& sbi)
96: ArcanePTScotchMeshPartitionerObject(sbi)
106 Int32 nb_part =
mesh()->parallelMng()->commSize();
116 ARCANE_UNUSED(initial_partition);
118 info() <<
"Load balancing with PTScotch\n";
124 bool dumpGraph =
false;
125 bool checkGraph =
false;
127 dumpGraph =
options()->dumpGraph();
128 checkGraph =
options()->checkGraph();
133 throw ArgumentException(A_FUNCINFO,
"partition with nb_part<nb_rank");
136 initConstraints(
false);
143 CellGroup own_cells = mesh()->ownCells();
144 Integer nb_own_cell = nbOwnCellsWithConstraints();
147 UniqueArray<SCOTCH_Num> scotch_vtkdist(nb_rank+1);
149 scotch_vtkdist[0] = 0;
150 for(
Integer i=0; i<nb_rank; ++i ){
151 total_nb_cell += global_nb_own_cell[i];
152 scotch_vtkdist[i+1] =
static_cast<SCOTCH_Num
>(total_nb_cell);
160 Integer nb_max_face_neighbour_cell = 0;
166 const Cell& item = *i_item;
167 if (cellUsedWithConstraints(item)){
168 cell_scotch_uid[item] = mid;
171 nb_max_face_neighbour_cell += item.nbFace();
174 cell_scotch_uid.synchronize();
177 _initUidRef(cell_scotch_uid);
180 cell_scotch_uid.setUsed(
false);
182 SharedArray<SCOTCH_Num> scotch_xadj;
183 scotch_xadj.reserve(nb_own_cell+1);
185 SharedArray<SCOTCH_Num> scotch_adjncy;
186 scotch_adjncy.reserve(nb_max_face_neighbour_cell);
191 UniqueArray<float> edgeWeights;
192 edgeWeights.resize(0);
193 UniqueArray<float>* edgeWeightsPtr = &edgeWeights;
199 const Cell& item = *i_item;
201 if (!cellUsedWithConstraints(item))
204 scotch_xadj.
add(scotch_adjncy.size());
206 getNeighbourCellsUidWithConstraints(item, neighbour_cells, edgeWeightsPtr);
208 for(
Integer z=0; z<neighbour_cells.size(); ++z )
209 scotch_adjncy.add(
static_cast<SCOTCH_Num
>(neighbour_cells[z]));
211 scotch_xadj.add(scotch_adjncy.size());
213 int nparts =
static_cast<int>(nb_part);
216 SharedArray<float> cells_weights;
218 if (nbCellWeight() == 1) {
219 cells_weights = cellsWeightsWithConstraints(1,
true);
223 cells_weights = cellsSizeWithConstraints();
227 PartitionConverter<float,SCOTCH_Num> converter(pm, (
double)SCOTCH_NUMMAX / 2.0, cells_weights);
228 ArrayConverter<float,SCOTCH_Num,PartitionConverter<float,SCOTCH_Num> > scotch_vwgtConvert(cells_weights, converter);
230 ArrayConverter<float,SCOTCH_Num> scotch_vwgtConvert(cells_weights);
232 SharedArray<SCOTCH_Num> scotch_vwgt(scotch_vwgtConvert.array().constView());
238 if (edgeWeights.size() == 0)
240 converter.computeContrib(edgeWeights);
241 ArrayConverter<float,SCOTCH_Num,PartitionConverter<float,SCOTCH_Num> > scotch_ewgtConvert(edgeWeights, converter);
243 ArrayConverter<float,SCOTCH_Num> scotch_ewgtConvert(edgeWeights);
246 SharedArray<SCOTCH_Num> scotch_ewgt((UniqueArray<SCOTCH_Num>)scotch_ewgtConvert.array());
249 MPI_Comm scotch_mpicomm = *(MPI_Comm*)getCommunicator();
250#ifdef ARCANE_PART_DUMP
252 Integer iteration =
mesh()->subDomain()->commonVariables().globalIteration();
253 StringBuilder filename(
"mesh-");
254 filename += iteration;
260 GraphDistributor gd(pm);
261#ifndef SCOTCH_MAPPING
262 gd.initWithOneRankPerNode(
true);
264 gd.initWithMaxRank(1);
268 SharedArray<SCOTCH_Num> scotch_part;
270 scotch_xadj = gd.convert<SCOTCH_Num>(scotch_xadj, &scotch_part,
true);
271 scotch_vwgt = gd.convert<SCOTCH_Num>(scotch_vwgt);
272 scotch_adjncy = gd.convert<SCOTCH_Num>(scotch_adjncy);
273 scotch_ewgt = gd.convert<SCOTCH_Num>(scotch_ewgt);
274 scotch_mpicomm = gd.getCommunicator();
276 if (gd.contribute()) {
279#ifndef SCOTCH_MAPPING
281 retval = SCOTCH_dgraphInit(&graph,scotch_mpicomm);
283 error() <<
"Error in dgraphInit() r=" << retval;
285 info() <<
"Build Scotch graph";
288 SCOTCH_randomReset();
290 retval = SCOTCH_dgraphBuild(&graph,
292 scotch_xadj.size()-1,
293 scotch_xadj.size()-1,
298 scotch_adjncy.size(),
299 scotch_adjncy.size(),
300 scotch_adjncy.data(),
305 error() <<
"Error in dgraphBuild() r=" << retval;
308 Integer iteration =
mesh()->subDomain()->commonVariables().globalIteration();
309 StringBuilder filename(
"graph-");
310 filename += iteration;
314 String name(filename.toString());
315 FILE* ofile = ::fopen(name.localstr(),
"w");
316 SCOTCH_dgraphSave(&graph,ofile);
323 info() <<
"Check Scotch graph";
324 retval = SCOTCH_dgraphCheck(&graph);
326 error() <<
"Error in dgraphCheck() r=" << retval;
329 SCOTCH_Strat strategy;
330 retval = SCOTCH_stratInit(&strategy);
332 error() <<
"Error in SCOTCH_stratInit() r=" << retval;
335 char* strat = (
char*)malloc(
options()->strategy().length()+1);
336 ::strncpy(strat,
options()->strategy().localstr(),
options()->strategy().length()+1);
337 retval = SCOTCH_stratDgraphMap(&strategy, strat);
339 error() <<
"Error in SCOTCH_stratDgraphMap() r=" << retval;
343 info() <<
"Execute 'SCOTCH_dgraphPart'";
344 retval = SCOTCH_dgraphPart(&graph,
347 scotch_part.unguardedBasePointer()
350 SCOTCH_stratExit(&strategy);
351 SCOTCH_dgraphExit(&graph);
353 error() <<
"Error in dgraphPart() r=" << retval;
356 SCOTCH_Arch architecture;
357 info() <<
"Build Scotch graph";
360 SCOTCH_randomReset();
362 retval = SCOTCH_graphBuild(&graph,
364 scotch_xadj.size()-1,
365 scotch_xadj.unguardedBasePointer(),
369 scotch_adjncy.size(),
370 scotch_adjncy.unguardedBasePointer(),
374 error() <<
"Error in graphBuild() r=" << retval;
380 Array<SCOTCH_Num> sizetab(level);
381 Array<SCOTCH_Num> linktab(level);
383 nb_nodes = nb_rank/32;
384 sizetab[0] = nb_nodes;
388 retval =SCOTCH_archTleaf(&architecture, level, sizetab.unguardedBasePointer(), linktab.unguardedBasePointer());
390 error() <<
"Error in archTleaf() r=" << retval;
392 SCOTCH_Strat strategy;
393 retval = SCOTCH_stratInit(&strategy);
395 error() <<
"Error in SCOTCH_stratInit() r=" << retval;
397 retval = SCOTCH_graphMap(&graph, &architecture, &strategy, scotch_part.unguardedBasePointer());
403 info() <<
"PART retval=" << retval;
408 String filename(
"s_part");
410 FILE* ofile = ::fopen(filename.localstr(),
"w");
412 ::fprintf(ofile,
"%d\n", *val);
413 info() <<
"GRAPH SAVED in '" << filename <<
"'";
419 scotch_part = gd.convertBack<SCOTCH_Num>(scotch_part, nb_own_cell);
422 String filename(
"scotch_part");
424 FILE* ofile = ::fopen(filename.localstr(),
"w");
426 ::fprintf(ofile,
"%d\n", *val);
427 info() <<
"GRAPH SAVED in '" << filename <<
"'";
437 const Cell& item = *i_item;
438 if (!cellUsedWithConstraints(item))
441 auto new_owner =
static_cast<Int32>(scotch_part[index]);
443 changeCellOwner(item, cells_new_owner, new_owner);
451 cells_new_owner.synchronize();
465#if ARCANE_DEFAULT_PARTITIONER == PTSCOTCH_DEFAULT_PARTITIONER
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro pour déclarer une interface lors de l'enregistrement d'un service.
ArcanePTScotchMeshPartitionerObject(const Arcane::ServiceBuildInfo &sbi)
Constructeur.
CaseOptionsPTScotchMeshPartitioner * options() const
Options du jeu de données du service.
ArrayIterator< const_pointer > const_iterator
Type de l'itérateur constant sur un élément du tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Interface d'un partitionneur de maillage.
Interface d'un partitionneur de maillage.
virtual IMesh * mesh() const =0
Maillage associé au partitionneur.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual void allGather(ConstArrayView< char > send_buf, ArrayView< char > recv_buf)=0
Effectue un regroupement sur tous les processeurs. Il s'agit d'une opération collective....
@ PNoRestore
Indique que la variable ne doit pas être restaurée.
@ PNoDump
Indique que la variable ne doit pas être sauvegardée.
virtual void dumpObject(String filename="toto")
Dump les informations de repartitionnement sur le disque.
virtual void changeOwnersFromCells()
Positionne les nouveaux propriétaires des noeuds, arêtes et faces à partir des mailles.
Partitionneur de maillage utilisant la bibliothèque PtScotch.
void build() override
Construction de niveau build du service.
void partitionMesh(bool initial_partition) override
Structure contenant les informations pour créer un service.
Propriétés de création d'un service.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage error() const
Flot pour un message d'erreur.
ItemGroupT< Cell > CellGroup
Groupe de mailles.
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro pour enregistrer un service.
MeshVariableScalarRefT< Cell, Integer > VariableCellInteger
Grandeur au centre des mailles de type entier.
ItemVariableScalarRefT< Int32 > VariableItemInt32
Grandeur de type entier 32 bits.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Int32 Integer
Type représentant un entier.
@ ST_SubDomain
Le service s'utilise au niveau du sous-domaine.
@ IK_Cell
Entité de maillage de genre maille.
UniqueArray< Integer > IntegerUniqueArray
Tableau dynamique à une dimension d'entiers.
ConstArrayView< Integer > IntegerConstArrayView
Equivalent C d'un tableau à une dimension d'entiers.
@ Cell
Le maillage est AMR par maille.
std::int32_t Int32
Type entier signé sur 32 bits.