14#include "arcane/aleph/AlephArcane.h"
15#include "arcane/utils/StringList.h"
26AlephKernelSolverInitializeArguments::
27AlephKernelSolverInitializeArguments()
44, m_isParallel(wpm->isParallel())
45, m_rank(wpm->commRank())
47, m_world_size(wpm->commSize())
48, m_there_are_idles(true)
49, m_i_am_an_other(true)
51, m_world_parallel(wpm)
53, m_aleph_vector_idx(0)
55, m_underlying_solver((alephUnderlyingSolver == 0 ? 1 : alephUnderlyingSolver))
56, m_reorder(alephOrdering)
58, m_solver_size(alephNumberOfCores)
60, m_has_been_initialized(false)
85, m_isParallel(sd->parallelMng()->isParallel())
86, m_rank(sd->parallelMng()->commRank())
87, m_size(sd->parallelMng()->commSize())
88, m_world_size(sd->parallelMng()->worldParallelMng()->commSize())
89, m_there_are_idles(m_size != m_world_size)
90, m_i_am_an_other(sd->parallelMng()->worldParallelMng()->commRank() > m_size)
91, m_parallel(sd->parallelMng())
92, m_world_parallel(sd->parallelMng()->worldParallelMng())
94, m_aleph_vector_idx(0)
96, m_underlying_solver((alephUnderlyingSolver == 0 ? 1 : alephUnderlyingSolver))
97, m_reorder(alephOrdering)
99, m_solver_size(alephNumberOfCores)
101, m_has_been_initialized(false)
120, m_isParallel(sd->parallelMng()->isParallel())
121, m_rank(sd->parallelMng()->commRank())
122, m_size(sd->parallelMng()->commSize())
123, m_world_size(sd->parallelMng()->worldParallelMng()->commSize())
124, m_there_are_idles(m_size != m_world_size)
125, m_i_am_an_other(sd->parallelMng()->worldParallelMng()->commRank() > m_size)
126, m_parallel(sd->parallelMng())
127, m_world_parallel(sd->parallelMng()->worldParallelMng())
132, m_aleph_vector_idx(0)
133, m_underlying_solver(alephUnderlyingSolver == 0 ? 1 : alephUnderlyingSolver)
136, m_solver_size(alephNumberOfCores)
138, m_has_been_initialized(false)
140 debug() <<
"\33[1;31m[AlephKernel] New kernel with indexing+init options!\33[0m";
154 debug() <<
"\33[1;31m[AlephKernel] thisParallelMng's size=" << m_size <<
"\33[0m";
155 debug() <<
"\33[1;31m[AlephKernel] worldParallelMng's size=" << m_world_size <<
"\33[0m";
158 debug() <<
"\33[1;31m[AlephKernel] I am an additional site #" << m_rank <<
" among " << m_world_size <<
"\33[0m";
160 debug() <<
"\33[1;31m[AlephKernel] Aleph underlying solver has been set to "
161 << m_underlying_solver <<
"\33[0m";
163 if (m_solver_size == 0) {
164 m_solver_size = m_world_size;
165 debug() <<
"\33[1;31m[AlephKernel] Aleph Number of Cores"
166 <<
" now matches world's number of processors: "
167 << m_solver_size <<
"\33[0m";
169 if (m_solver_size > m_size) {
170 m_solver_size = m_size;
171 debug() <<
"\33[1;31m[AlephKernel] Aleph Number of Cores"
172 <<
" exceeds in size, reverting to " << m_size <<
"\33[0m";
174 if ((m_size % m_solver_size) != 0)
176 debug() <<
"\33[1;31m[AlephKernel] Each solver takes "
177 << m_solver_size <<
" site(s)"
180 if (m_there_are_idles && !m_i_am_an_other) {
182 cfg.
add(m_underlying_solver);
183 cfg.
add(m_solver_size);
184 cfg.
add((m_reorder ==
true) ? 1 : 0);
186 debug() <<
"\33[1;31m[AlephKernel] Sending to others configuration: " << cfg <<
"\33[0m";
187 m_world_parallel->broadcast(cfg.
view(), 0);
197 info(4) <<
"Destroying ~AlephKernel";
205 m_results_queue.clear();
209 m_matrix_queue.clear();
213 delete aq->m_x_vector;
214 delete aq->m_b_vector;
215 delete aq->m_tmp_vector;
218 m_arguments_queue.clear();
224 info(4) <<
"Destroying ~AlephKernel] done";
231initialize(
Integer global_nb_row,
236 if (m_there_are_idles && !m_i_am_an_other) {
237 m_world_parallel->broadcast(UniqueArray<unsigned long>(1, 0xd80dee82l).view(), 0);
238 UniqueArray<Integer> args(0);
239 args.add(global_nb_row);
240 args.add(local_nb_row);
241 m_world_parallel->broadcast(args.view(), 0);
243 debug() <<
"\33[1;31m[initialize] Geometry set to " << global_nb_row
244 <<
" lines, I see " << local_nb_row <<
" of them"
246 m_topology =
new AlephTopology(
traceMng(),
this, global_nb_row, local_nb_row);
247 m_ordering =
new AlephOrdering(
this, global_nb_row, local_nb_row, m_reorder);
248 debug() <<
"\33[1;31m[initialize] done"
250 m_has_been_initialized =
true;
257break_and_return(
void)
259 if (m_there_are_idles && !m_i_am_an_other)
260 m_world_parallel->broadcast(UniqueArray<unsigned long>(1, 0x4b97b15dl).view(), 0);
274 debug() <<
"\33[1;31m[mapranks] mapranks starting @ "
275 << m_solver_index * m_size
276 <<
", m_size=" << m_size
277 <<
", m_solver_size=" << m_solver_size
278 <<
", m_world_size=" << m_world_size <<
"\33[0m";
280 for (
int rnk = m_solver_index * m_size; rnk < (m_solver_index + 1) * m_size; rnk += 1) {
281 const int map = (rnk / (m_size / m_solver_size)) % m_world_size;
282 debug() <<
"\33[1;31m[mapranks] map=" << map <<
"\33[0m";
283 ranks[rnk % m_size] = map;
284 debug() <<
"\33[1;31m[mapranks] mapped solver #" << m_solver_index
285 <<
", core " << rnk % m_size <<
" --> site " << map <<
"\33[0m";
295 for (
int rnk = ranks.
size() - 1; rnk >= 0; rnk -= 1)
296 if (ranks[rnk] == rank)
304Ref<IParallelMng> AlephKernel::
305_createUnderlyingParallelMng(
Integer nb_wanted_sites)
307 info(4) <<
"[createUnderlyingParallelMng] nb_wanted_sites=" << nb_wanted_sites;
308 UniqueArray<Integer> kept_ranks;
309 for (Int32 rank = 0; rank < m_world_size; ++rank) {
310 if (hitranks(rank, m_solver_ranks[m_solver_index]))
311 kept_ranks.add(rank);
313 info(4) <<
"[createUnderlyingParallelMng] Now createSubParallelMng of size=" << kept_ranks.size();
314 Ref<IParallelMng> upm = m_world_parallel->createSubParallelMngRef(kept_ranks.constView());
315 info(4) <<
"[createUnderlyingParallelMng] done: upm=" << upm.get();
324createSolverMatrix(
void)
326 ItacFunction(AlephService);
328 if (isInitialized() ==
false) {
329 debug() <<
"\33[1;31m[createSolverMatrix] has_NOT_been_initialized!\33[0m"
331 return new AlephMatrix(
this);
334 if (m_there_are_idles && !m_i_am_an_other)
335 m_world_parallel->broadcast(UniqueArray<unsigned long>(1, 0xef162166l).view(), 0);
337 debug() <<
"\33[1;31m[createSolverMatrix]\33[0m"
343 debug() <<
"\33[1;31m[createSolverMatrix] UN configured, building Underlying Parallel Managers index="
344 << index() <<
"\33[0m";
346 m_solver_ranks.add(SharedArray<Integer>(m_world_size));
347 m_solver_ranks[m_solver_index].fill(-1);
348 mapranks(m_solver_ranks[m_solver_index]);
350 Ref<IParallelMng> upm = _createUnderlyingParallelMng(m_solver_size);
352 debug() <<
"\33[1;31m[createSolverMatrix] upm->isParallel()=" << upm->isParallel() <<
"\33[0m";
353 debug() <<
"\33[1;31m[createSolverMatrix] upm->commSize()=" << upm->commSize() <<
"\33[0m";
354 debug() <<
"\33[1;31m[createSolverMatrix] upm->commRank()=" << upm->commRank() <<
"\33[0m";
357 debug() <<
"\33[1;31m[createSolverMatrix] upm NULL"
360 m_sub_parallel_mng_queue.add(upm);
361 debug() <<
"\33[1;31m[createSolverMatrix] Queuing new kernel arguments: X, B and Tmp with their topolgy"
365 IAlephTopology* underlying_topology = factory()->GetTopology(
this, index(), topology()->nb_row_size());
368 if (underlying_topology != NULL)
369 underlying_topology->backupAndInitialize();
370 m_arguments_queue.add(
new AlephKernelArguments(
traceMng(),
371 new AlephVector(
this),
372 new AlephVector(
this),
373 new AlephVector(
this),
374 underlying_topology));
377 debug() <<
"\33[1;31m[createSolverMatrix] Creating Tmp vector for this set of arguments"
379 m_arguments_queue.at(m_solver_index)->m_tmp_vector->create();
381 debug() <<
"\33[1;31m[createSolverMatrix] Now queuing the matrix\33[0m";
382 m_matrix_queue.add(
new AlephMatrix(
this));
383 debug() <<
"\33[1;31m[createSolverMatrix] Now queuing the space for the resolution results\33[0m";
384 m_results_queue.add(
new AlephKernelResults());
387 if (getTopologyImplementation(m_solver_index) != NULL)
388 getTopologyImplementation(m_solver_index)->backupAndInitialize();
390 debug() <<
"\33[1;31m[createSolverMatrix] done!\33[0m";
392 return m_matrix_queue[m_solver_index];
407 if (m_has_been_initialized ==
false) {
408 debug() <<
"\33[1;31m[createSolverVector] has_NOT_been_initialized!\33[0m";
411 if (m_there_are_idles && !m_i_am_an_other)
413 m_aleph_vector_idx++;
414 if ((m_aleph_vector_idx % 2) == 0) {
415 debug() <<
"\33[1;31m[createSolverVector] Get " << m_solver_index <<
"th X vector\33[0m";
416 return m_arguments_queue.at(m_solver_index)->m_x_vector;
419 debug() <<
"\33[1;31m[createSolverVector] Get " << m_solver_index <<
"th B vector\33[0m";
420 return m_arguments_queue.at(m_solver_index)->m_b_vector;
437 if (!isInitialized()) {
438 debug() <<
"\33[1;31m[postSolver] Trying to post a solver to an uninitialized kernel!\33[0m";
439 debug() <<
"\33[1;31m[postSolver] Now telling Indexer to do its job!\33[0m";
440 indexing()->nowYouCanBuildTheTopology(fromThisMatrix, fromeThisX, fromThisB);
443 if (m_there_are_idles && !m_i_am_an_other) {
444 m_world_parallel->broadcast(UniqueArray<unsigned long>(1, 0xba9488bel).view(), 0);
445 UniqueArray<Real> real_args(0);
446 real_args.add(params->epsilon());
447 real_args.add(params->alpha());
448 real_args.add(params->minRHSNorm());
449 real_args.add(params->DDMCParameterAmgDiagonalThreshold());
451 UniqueArray<int> bool_args(0);
452 bool_args.add(params->xoUser());
453 bool_args.add(params->checkRealResidue());
454 bool_args.add(params->printRealResidue());
455 bool_args.add(params->debugInfo());
456 bool_args.add(params->convergenceAnalyse());
457 bool_args.add(params->stopErrorStrategy());
458 bool_args.add(params->writeMatrixToFileErrorStrategy());
459 bool_args.add(params->DDMCParameterListingOutput());
460 bool_args.add(params->printCpuTimeResolution());
461 bool_args.add(params->getKeepSolverStructure());
462 bool_args.add(params->getSequentialSolver());
464 UniqueArray<Integer> int_args(0);
465 int_args.add(params->maxIter());
466 int_args.add(params->gamma());
467 int_args.add((
Integer)params->precond());
468 int_args.add((
Integer)params->method());
469 int_args.add((
Integer)params->amgCoarseningMethod());
470 int_args.add(params->getOutputLevel());
471 int_args.add(params->getAmgCycle());
472 int_args.add(params->getAmgSolverIter());
473 int_args.add(params->getAmgSmootherIter());
474 int_args.add((
Integer)params->getAmgSmootherOption());
475 int_args.add((
Integer)params->getAmgCoarseningOption());
476 int_args.add((
Integer)params->getAmgCoarseSolverOption());
477 int_args.add((
Integer)params->getCriteriaStop());
480 m_world_parallel->broadcast(real_args.view(), 0);
481 m_world_parallel->broadcast(bool_args.view(), 0);
482 m_world_parallel->broadcast(int_args.view(), 0);
485 debug() <<
"\33[1;31m[postSolver] Queuing solver " << m_solver_index <<
"\33[0m";
486 debug() <<
"\33[1;31m[postSolver] Backuping its params @" << params <<
"\33[0m";
487 m_arguments_queue.at(m_solver_index)->m_params = params;
490 debug() <<
"\33[1;31m[postSolver] Mis à jour des indices solvers et sites"
493 debug() <<
"\33[1;31m[postSolver] m_solver_index=" << m_solver_index <<
"\33[0m";
508 if (m_there_are_idles && !m_i_am_an_other) {
514 debug() <<
"\33[1;31m[syncSolver] Not solved, launching the work"
520 debug() <<
"\33[1;31m[syncSolver] Syncing " << gid <<
"\33[0m";
521 AlephVector* aleph_vector_x = m_arguments_queue.at(gid)->m_x_vector;
522 aleph_vector_x->reassemble_waitAndFill();
523 m_matrix_queue.at(gid)->reassemble_waitAndFill(m_results_queue.at(gid)->m_nb_iteration,
524 m_results_queue.at(gid)->m_residual_norm);
526 debug() <<
"\33[1;31m[syncSolver] Finishing " << gid <<
"\33[0m";
527 nb_iteration = m_results_queue.at(gid)->m_nb_iteration;
528 residual_norm[0] = m_results_queue.at(gid)->m_residual_norm[0];
529 residual_norm[1] = m_results_queue.at(gid)->m_residual_norm[1];
530 residual_norm[2] = m_results_queue.at(gid)->m_residual_norm[2];
531 residual_norm[3] = m_results_queue.at(gid)->m_residual_norm[3];
533 if (getTopologyImplementation(gid) != NULL)
534 getTopologyImplementation(gid)->restore();
536 debug() <<
"\33[1;31m[syncSolver] Done " << gid <<
"\33[0m";
538 return m_arguments_queue.at(gid)->m_x_vector;
549 debug() <<
"\33[1;31m[workSolver] Now working"
551 for (
int gid = 0; gid < m_solver_index; ++gid) {
553 debug() <<
"\33[1;31m[workSolver] Waiting for assembling " << gid <<
"\33[0m";
554 AlephVector* aleph_vector_x = m_arguments_queue.at(gid)->m_x_vector;
555 AlephVector* aleph_vector_b = m_arguments_queue.at(gid)->m_b_vector;
556 AlephMatrix* aleph_matrix_A = m_matrix_queue.at(gid);
558 aleph_vector_b->assemble_waitAndFill();
559 aleph_vector_x->assemble_waitAndFill();
564 debug() <<
"\33[1;31m[workSolver] NOW CONFIGURED!"
570 for (
int gid = 0; gid < m_solver_index; ++gid) {
572 debug() <<
"\33[1;31m[workSolver] Solving " << gid <<
" ?"
574 if (getTopologyImplementation(gid) != NULL)
575 getTopologyImplementation(gid)->backupAndInitialize();
576 m_matrix_queue.at(gid)->solveNow(m_arguments_queue.at(gid)->m_x_vector,
577 m_arguments_queue.at(gid)->m_b_vector,
578 m_arguments_queue.at(gid)->m_tmp_vector,
579 m_results_queue.at(gid)->m_nb_iteration,
580 m_results_queue.at(gid)->m_residual_norm,
581 m_arguments_queue.at(gid)->m_params);
583 if (getTopologyImplementation(gid) != NULL)
584 getTopologyImplementation(gid)->restore();
587 for (
int gid = 0; gid < m_solver_index; ++gid) {
589 debug() <<
"\33[1;31m[workSolver] Posting re-assembling " << gid <<
"\33[0m";
590 m_arguments_queue.at(gid)->m_x_vector->reassemble();
591 m_matrix_queue.at(gid)->reassemble(m_results_queue.at(gid)->m_nb_iteration,
592 m_results_queue.at(gid)->m_residual_norm);
605 if (!m_sub_domain && !m_i_am_an_other)
606 ARCANE_FATAL(
"[AlephKernel::subDomain]",
"No sub-domain to work on!");
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
AlephKernel(IParallelMng *, Integer, IAlephFactory *, Integer=0, Integer=0, bool=false)
AlephVector * createSolverVector(void)
AlephVector * syncSolver(Integer, Integer &, Real *)
void mapranks(Array< Integer > &)
Matrice d'un système linéaire.
void assemble_waitAndFill()
assemble_waitAndFill attend que les requètes précédemment postées aient été traitées
Gestionnaire de reordering.
Paramètres d'un système linéraire.
Informations sur l'environnement parallèle.
Vecteur d'un système linéaire.
Vue modifiable d'un tableau d'un type T.
constexpr Integer size() const noexcept
Retourne la taille du tableau.
Tableau d'items de types quelconques.
ArrayView< T > view() const
Vue mutable sur ce tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Exception lorsqu'une erreur fatale est survenue.
Interface du gestionnaire de parallélisme pour un sous-domaine.
Interface du gestionnaire d'un sous-domaine.
Interface du gestionnaire de traces.
virtual void flush()=0
Flush tous les flots.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
ITraceMng * traceMng() const
Gestionnaire de trace.
Vecteur 1D de données avec sémantique par valeur (style STL).
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
List< String > StringList
Tableau de chaînes de caractères unicode.
double Real
Type représentant un réel.