14#include "arcane/utils/Iostream.h"
15#include "arcane/utils/Ptr.h"
16#include "arcane/utils/StdHeader.h"
17#include "arcane/utils/PlatformUtils.h"
18#include "arcane/utils/List.h"
19#include "arcane/utils/ApplicationInfo.h"
20#include "arcane/utils/NotSupportedException.h"
21#include "arcane/utils/FatalErrorException.h"
22#include "arcane/utils/String.h"
23#include "arcane/utils/ITraceMng.h"
24#include "arcane/utils/OStringStream.h"
25#include "arcane/utils/IMemoryInfo.h"
26#include "arcane/utils/Array.h"
27#include "arcane/utils/IFunctor.h"
28#include "arcane/utils/StringBuilder.h"
29#include "arcane/utils/ScopedPtr.h"
30#include "arcane/utils/ValueConvert.h"
31#include "arcane/utils/IProcessorAffinityService.h"
32#include "arcane/utils/ArgumentException.h"
33#include "arcane/utils/CStringUtils.h"
34#include "arcane/utils/ITraceMngPolicy.h"
35#include "arcane/utils/Property.h"
36#include "arcane/utils/ParameterListPropertyReader.h"
37#include "arcane/utils/CommandLineArguments.h"
38#include "arcane/utils/CriticalSection.h"
40#include "arcane/impl/ArcaneMain.h"
41#include "arcane/impl/ParallelReplication.h"
43#include "arcane/IIOMng.h"
44#include "arcane/ICodeService.h"
45#include "arcane/ISession.h"
46#include "arcane/Timer.h"
47#include "arcane/ISubDomain.h"
48#include "arcane/IApplication.h"
49#include "arcane/ITimeLoopMng.h"
50#include "arcane/ITimeStats.h"
51#include "arcane/SequentialSection.h"
52#include "arcane/IParallelSuperMng.h"
53#include "arcane/ITimeHistoryMng.h"
54#include "arcane/IDirectExecution.h"
55#include "arcane/IDirectSubDomainExecuteFunctor.h"
56#include "arcane/ICaseMng.h"
57#include "arcane/ServiceFinder2.h"
58#include "arcane/SubDomainBuildInfo.h"
59#include "arcane/IParallelMng.h"
60#include "arcane/IMainFactory.h"
61#include "arcane/ApplicationBuildInfo.h"
62#include "arcane/CaseDatasetSource.h"
64#include "arcane/ServiceUtils.h"
66#include "arcane/impl/ExecutionStatsDumper.h"
67#include "arcane/impl/TimeLoopReader.h"
69#include "arcane/accelerator/core/internal/RunnerInternal.h"
87 Int32 m_max_iteration = 0;
88 bool m_is_continue =
false;
110 : m_sub_domain(
nullptr), m_time_stats(
nullptr), m_want_print_stats(
false) {}
120 SubInfo(
const SubInfo&) =
delete;
121 void operator=(
const SubInfo&) =
delete;
127 bool m_want_print_stats;
131 SessionExec(ArcaneMainBatch* arcane_main,
ISession* session,
Int32 nb_local_rank)
132 : m_arcane_main(arcane_main),
135 m_direct_test_name(m_arcane_main->m_direct_test_name),
138 m_sub_infos(nb_local_rank),
139 m_direct_sub_domain_execute_functor(m_arcane_main->_directExecuteFunctor())
141 const CaseDatasetSource& dataset_source = m_arcane_main->applicationBuildInfo().caseDatasetSource();
145 m_sub_infos.fill(
nullptr);
149 for(
Integer i=0, n=m_sub_infos.size(); i<n; ++i )
150 delete m_sub_infos[i];
154 void executeRank(
Int32 local_rank);
158 ArcaneMainBatch* m_arcane_main;
161 String m_direct_test_name;
179 : m_session_exec(session_exec), m_local_rank(local_rank)
185 m_session_exec->executeRank(m_local_rank);
197 void build()
override;
212 String m_direct_exec_name;
213 String m_direct_test_name;
235ArcaneMainBatch(
const ApplicationInfo& exe_info,IMainFactory* main_factory)
236: ArcaneMain(exe_info,main_factory)
238, m_check_case_only(false)
239, m_has_sub_domain_threads(false)
283 bool r = _sequentialParseArgs(args);
292bool ArcaneMainBatch::
297 String us_arcane_opt(
"-arcane_opt");
298 String us_init_only(
"init_only");
299 String us_check_case_only(
"check_case_only");
300 String us_continue(
"continue");
301 String us_max_iteration(
"max_iteration");
302 String us_casename(
"casename");
303 String us_direct_exec(
"direct_exec");
304 String us_direct_test(
"direct_test");
305 String us_direct_mesh(
"direct_mesh");
306 String us_tool_arg(
"tool_arg");
307 String us_direct_exec_mesh_arg(
"direct_exec_mesh_arg");
308 String us_nb_sub_domain(
"nb_sub_domain");
309 String us_nb_replication(
"nb_replication");
310 String us_idle_service(
"idle_service");
320 bool has_case_dataset_content = !(dataset_source.
fileName().empty() && dataset_source.
content().empty());
322 if (nb_arg<2 && !has_case_dataset_content){
323 trace->
info() <<
"Usage: programm input_data ; for more information: program -arcane_opt help";
324 trace->
pfatal() <<
"No input data specified.";
328 StringBuilder tool_args_xml;
329 StringBuilder direct_exec_mesh_args_xml;
332 String nb_sub_domain_str;
333 String nb_replication_str;
335 if (!idle_service_name.null())
338 for(
Integer i=1, s=nb_arg-1; i<s; ++i ){
340 if (args[i]!=us_arcane_opt){
341 unknown_args.add(args[i]);
344 bool is_valid_opt =
false;
349 if (str==us_init_only){
353 else if (str==us_check_case_only){
357 else if (str==us_continue){
361 else if (str==us_max_iteration){
369 trace->
pfatal() <<
"Option 'max_iteration' must specify the number of iterations";
372 else if (str==us_casename){
379 else if (str==us_direct_exec){
382 m_direct_exec_name = args[i];
387 else if (str==us_direct_test){
390 m_direct_test_name = args[i];
395 else if (str==us_tool_arg || str==us_direct_exec_mesh_arg){
406 String to_add = String::format(
"<{0}>{1}</{2}>\n",arg,value,arg);
407 if (str==us_tool_arg)
408 tool_args_xml += to_add;
409 else if (str==us_direct_exec_mesh_arg)
410 direct_exec_mesh_args_xml += to_add;
413 else if (str==us_nb_sub_domain){
416 nb_sub_domain_str = args[i];
421 else if (str==us_nb_replication){
424 nb_replication_str = args[i];
429 else if (str==us_idle_service){
438 trace->
pfatal() <<
"Unknown Arcane option <" << str <<
">\n";
442 bool use_direct_test = (!m_direct_test_name.null());
443 bool use_direct_exec = (!m_direct_exec_name.null());
445 if (use_direct_test){
447 else if (use_direct_exec){
450 tool_mesh = args[nb_arg-1];
461 if (!nb_sub_domain_str.null()){
462 Int32 nb_sub_domain = 0;
463 bool is_bad = builtInGetValue(nb_sub_domain,nb_sub_domain_str);
464 if (is_bad || nb_sub_domain<=0){
465 trace->
pfatal() <<
"Invalid number of subdomains : " << nb_sub_domain;
467 trace->
info() <<
"Use '" << nb_sub_domain <<
"' subdomains";
468 _applicationBuildInfo().setNbProcessusSubDomain(nb_sub_domain);
471 if (!nb_replication_str.null()){
472 Int32 nb_replication = 0;
473 bool is_bad = builtInGetValue(nb_replication,nb_replication_str);
474 if (is_bad || nb_replication<0){
475 trace->
pfatal() <<
"Invalid number of replication : " << nb_replication;
477 trace->
info() <<
"Use replication of subdomains nb_replication=" << nb_replication;
478 _applicationBuildInfo().setNbReplicationSubDomain(nb_replication);
481 if (_applicationBuildInfo().nbReplicationSubDomain()!=0 && _applicationBuildInfo().nbProcessusSubDomain()!=0)
482 trace->
pfatal() <<
"The subdomains number of replication and restriction options are incompatible.";
484 if (!use_direct_test){
485 String case_file = dataset_source.
fileName();
490 trace->
info() <<
"The file `" << case_file <<
"' is not a known file type.";
491 case_file = args[nb_arg-2];
495 trace->
pfatal() <<
"File extension not valid.";
500 if (use_direct_exec){
505 s +=
"<?xml version=\"1.0\"?>\n";
506 s +=
"<case codename=\"ArcaneDriver\" xml:lang=\"en\" codeversion=\"1.0\">";
508 s +=
" <title>DirectExec</title>\n";
509 s +=
" <description>DirectExec</description>\n";
510 s +=
" <timeloop>ArcaneDirectExecutionLoop</timeloop>\n";
514 s += String::format(
" <filename>{0}</filename>\n",tool_mesh);
515 s += direct_exec_mesh_args_xml;
518 s +=
" <arcane-direct-execution>\n";
519 s += String::format(
" <tool name='{0}'>\n",m_direct_exec_name);
522 s +=
" </arcane-direct-execution>\n";
527 trace->
info() <<
"Direct exec xml file=" << s;
536 if (!unknown_args.empty()){
537 trace->
info()<<
"Unknown command line option: " << unknown_args[0];
548struct LaunchThreadInfo
550 ArcaneMainBatch* arcane_main;
551 ArcaneMainBatch::SessionExec* session_exec;
552 IApplication* application;
563_ThreadWrapper(LaunchThreadInfo* lti)
568 bool clean_abort =
false;
569 bool is_master = lti->thread_index == 0;
571 if (r!=0 && !clean_abort){
589 ITraceMng* trace = _application()->traceMng();
598 if (nb_wanted_sub_domain>nb_total_rank)
600 nb_wanted_sub_domain,nb_total_rank);
603 trace->
info() <<
"NB_LOCAL_RANK=" << nb_local_rank;
604 if (nb_local_rank>=1)
606 int return_value = 0;
609 if (dataset_source.
content().empty() && m_direct_test_name.null()){
611 trace->
info() <<
"Reading input data '" << case_file <<
"'";
612 IIOMng* io_mng = _application()->ioMng();
620 m_session_exec =
new SessionExec(
this,m_session,nb_local_rank);
623 for(
Integer i=0; i<nb_local_rank; ++i ){
624 thinfo[i].arcane_main =
this;
625 thinfo[i].session_exec = m_session_exec;
626 thinfo[i].application = _application();
627 thinfo[i].thread_index = i;
630 if (nb_local_rank>1){
632 for(
Integer i=0; i<nb_local_rank; ++i ){
633 gths[i] =
new std::thread(_ThreadWrapper,&thinfo[i]);
635 for(
Integer i=0; i<nb_local_rank; ++i ){
642 m_session_exec->executeRank(0);
657void ArcaneMainBatch::SessionExec::
658executeRank(
Int32 local_rank)
663 auto sub_info =
new SubInfo();
664 m_sub_infos[local_rank] = sub_info;
673 tm->
info() <<
"Binding threads";
679 IParallelSuperMng* psm = _application()->parallelSuperMng();
680 Ref<IParallelMng> world_pm = psm->internalCreateWorldParallelMng(local_rank);
681 sub_info->m_world_parallel_mng = world_pm;
683 if (!m_direct_test_name.null()){
684 _execDirectTest(world_pm.get(),m_direct_test_name,
true);
696 ITraceMng* trace = world_pm->traceMng();
697 String stat_name =
"Rank";
698 stat_name = stat_name + world_pm->commRank();
699 ITimeStats* time_stat = _application()->mainFactory()->createTimeStats(world_pm->timerMng(),trace,stat_name);
700 sub_info->m_time_stats = time_stat;
701 time_stat->beginGatherStats();
702 world_pm->setTimeStats(time_stat);
704 Ref<IParallelMng> pm = world_pm;
705 Ref<IParallelMng> all_replica_pm = pm;
707 const Integer nb_wanted_sub_domain = _application()->applicationBuildInfo().nbProcessusSubDomain();
708 const Integer nb_wanted_replication = _application()->applicationBuildInfo().nbReplicationSubDomain();
710 if (world_pm->isParallel()){
716 if (nb_wanted_replication>1){
717 Int32 comm_size = world_pm->commSize();
718 Int32 nb_sub_part = comm_size / nb_wanted_replication;
719 trace->info() <<
"Using sub-domain replication nb_sub_part=" << nb_sub_part;
720 if ((comm_size % nb_wanted_replication)!=0)
721 ARCANE_FATAL(
"The number of replication '{0}' must be a common factor of the number of allocated cores '{1}",
722 nb_wanted_replication,comm_size);
725 Ref<IParallelMng> replicate_pm;
726 trace->info() <<
"Building replicated parallel mng";
729 for(
Integer i_sd=0; i_sd<nb_sub_part; ++i_sd ){
730 for(
Int32 i=0; i<nb_wanted_replication; ++i ){
731 kept_ranks[i] = i_sd + (i*nb_sub_part);
732 trace->info() <<
"Rank r=" << kept_ranks[i];
734 Ref<IParallelMng> new_pm = world_pm->createSubParallelMngRef(kept_ranks);
736 replicate_pm = new_pm;
737 replicate_pm->setTimeStats(time_stat);
738 trace->info() <<
" Building own replicated parallel mng";
741 trace->info()<<
"!pm";
752 trace->info() <<
"Building sub-domain parallel mng";
755 for(
Integer i_repl=0; i_repl<nb_wanted_replication; ++i_repl ){
756 for(
Int32 i=0; i<nb_sub_part; ++i ){
757 kept_ranks[i] = i + (i_repl*nb_sub_part);
758 trace->info() <<
"Rank r=" << kept_ranks[i];
760 Ref<IParallelMng> new_pm = world_pm->createSubParallelMngRef(kept_ranks);
767 pm = new_pm->sequentialParallelMngRef();
769 trace->info()<<
"pm: setting time_stat & m_rank_parallel_mng for replica rank=" << i_repl;
771 pm->setTimeStats(time_stat);
772 sub_info->m_rank_parallel_mng = new_pm;
773 auto pr =
new ParallelReplication(i_repl,nb_wanted_replication,replicate_pm);
774 pm->setReplication(pr);
777 trace->info()<<
"!pm";
783 else if (nb_wanted_sub_domain!=0){
784 const Int32 nb_sub_part = nb_wanted_sub_domain;
786 for(
Int32 i=0; i<nb_sub_part; ++i )
788 pm = world_pm->createSubParallelMngRef(kept_ranks);
790 trace->info()<<
"pm: setting time_stat & m_rank_parallel_mng";
792 pm->setTimeStats(time_stat);
793 sub_info->m_rank_parallel_mng = pm;
797 trace->info()<<
"!pm";
803 bool print_stats =
false;
804 ISubDomain* sub_domain =
nullptr;
810 trace->info()<<
"The rank doesn't own any subdomain!";
812 trace->info() <<
"No idle service specified"; trace->flush();
815 trace->info()<<
"execDirectTest: "<<
m_properties.m_idle_service_name;
817 _execDirectTest(world_pm.get(),
m_properties.m_idle_service_name,
false);
824 _createAndRunSubDomain(sub_info,pm,all_replica_pm,local_rank);
825 sub_domain = sub_info->m_sub_domain;
826 print_stats = sub_info->m_want_print_stats;
829 time_stat->endGatherStats();
831 if (print_stats && sub_domain){
835 IParallelMng* pm = sub_domain->parallelMng();
840 _printStats(sub_domain,trace,time_stat);
845 world_pm->broadcast(UniqueArray<unsigned long>(1,0xdfeb699fl).view(),0);
851void ArcaneMainBatch::SessionExec::
852_createAndRunSubDomain(SubInfo* sub_info,Ref<IParallelMng> pm,Ref<IParallelMng> all_replica_pm,
Int32 local_rank)
856 SubDomainBuildInfo sdbi(pm,local_rank,all_replica_pm);
857 sdbi.setCaseFileName(m_case_file);
858 sdbi.setCaseContent(m_case_bytes);
859 ISubDomain* sub_domain =
m_code_service->createAndLoadCase(m_session,sdbi);
860 sub_info->m_sub_domain = sub_domain;
862 ITraceMng* trace = _application()->traceMng();
863 ITraceMng* sd_trace = sub_domain->traceMng();
864 ITraceMngPolicy* trace_policy = _application()->getTraceMngPolicy();
868 trace->info() <<
"REPLICATION: rank=" << pm->replication()->replicationRank();
870 if (!pm->replication()->isMasterRank()){
871 trace->info() <<
"Disable output curves for replicates.";
872 sub_domain->timeHistoryMng()->setDumpActive(
false);
882 String cpu_set = pas->cpuSetString();
883 trace->info() <<
" CpuSet=" << cpu_set;
886 if (m_arcane_main->m_check_case_only){
887 trace->info() <<
"Checking the input data";
890 TimeLoopReader stl(_application());
892 stl.registerTimeLoops(sub_domain);
893 stl.setUsedTimeLoop(sub_domain);
895 ICaseMng* cm = sub_domain->caseMng();
896 cm->readOptions(
true);
903 Timer::Action ts_action(sub_domain,
"Init");
904 Timer::Sentry ts(&init_timer);
910 trace->info() <<
"Option 'max_iteration' activated with " <<
m_properties.m_max_iteration;
917 CriticalSection cs(pm->threadMng());
918 ArcaneMain::redirectSignals();
920 int ret_compute_loop = 0;
922 IDirectExecution* direct_exec = sub_domain->directExecution();
923 if (direct_exec && direct_exec->isActive()){
924 trace->info() <<
"Direct execution activated";
925 direct_exec->execute();
927 else if (m_arcane_main->m_init_only){
928 trace->info() <<
"Option 'init_only' activated";
929 sub_info->m_want_print_stats =
true;
932 sub_info->m_want_print_stats =
true;
933 Timer::Action ts_action(sub_domain,
"Loop");
934 Timer::Sentry ts(&loop_timer);
937 trace_policy->setDefaultVerboseLevel(sd_trace,Trace::UNSPECIFIED_VERBOSITY_LEVEL);
938 if (m_direct_sub_domain_execute_functor){
939 m_direct_sub_domain_execute_functor->setSubDomain(sub_domain);
940 m_direct_sub_domain_execute_functor->execute();
941 sub_domain->parallelMng()->barrier();
944 ret_compute_loop = sub_domain->timeLoopMng()->doComputeLoop(
m_properties.m_max_iteration);
945 if (ret_compute_loop<0)
948 m_arcane_main->setErrorCode(8);
952 Real init_time = init_timer.totalTime();
953 Real loop_time = loop_timer.totalTime();
954 trace->info(0) <<
"TotalReel = " << (init_time+loop_time)
955 <<
" secondes (init: "
956 << init_time <<
" loop: " << loop_time <<
" )";
959 Timer::Action ts_action(sub_domain,
"Exit");
960 trace_policy->setDefaultVerboseLevel(sd_trace,Trace::DEFAULT_VERBOSITY_LEVEL);
961 sub_domain->doExitModules();
969void ArcaneMainBatch::SessionExec::
970_printStats(ISubDomain* sub_domain,ITraceMng* trace,ITimeStats* time_stat)
972 ExecutionStatsDumper exec_dumper(trace);
973 exec_dumper.dumpStats(sub_domain,time_stat);
979void ArcaneMainBatch::SessionExec::
980_execDirectTest(IParallelMng* world_pm,
const String& test_name,
bool is_collective)
982 ITraceMng* trace = world_pm->traceMng();
983 trace->info() <<
"Direct test name=" << test_name;
985 ServiceFinder2T<IDirectExecution,IApplication> sf(_application(),_application());
986 Ref<IDirectExecution> exec(sf.createReference(test_name));
988 String msg = String::format(
"Can not find 'IDirectExecution' service name '{0}'",test_name);
990 throw ParallelFatalErrorException(A_FUNCINFO,msg);
992 throw FatalErrorException(A_FUNCINFO,msg);
995 trace->info() <<
"Begin execution of direct service";
998 exec->setParallelMng(world_pm);
1010 _application()->removeSession(m_session);
1012 m_session =
nullptr;
1015 delete m_session_exec;
1016 m_session_exec =
nullptr;
1018 ITraceMng* tm = _application()->traceMng();
1029 m_session->doAbort();
1042template<
typename V>
void ArcaneMainBatchProperties::
1043_applyPropertyVisitor(V& p)
1045 auto b = p.builder();
1047 p << b.addInt32(
"MaxIteration")
1048 .addDescription(
"Maximum number of iteration")
1049 .addCommandLineArgument(
"MaxIteration")
1050 .addGetter([](
auto a) {
return a.x.m_max_iteration; })
1051 .addSetter([](
auto a) { a.x.m_max_iteration = a.v; });
1053 p << b.addBool(
"Continue")
1054 .addDescription(
"True if continue from previous execution (restart)")
1055 .addCommandLineArgument(
"Continue")
1056 .addGetter([](
auto a) {
return a.x.m_is_continue; })
1057 .addSetter([](
auto a) { a.x.m_is_continue = a.v; });
1059 p << b.addString(
"IdleService")
1060 .addDescription(
"Name of the idle service for additionnal cores")
1061 .addCommandLineArgument(
"IdleService")
1062 .addGetter([](
auto a) {
return a.x.m_idle_service_name; })
1063 .addSetter([](
auto a) { a.x.m_idle_service_name = a.v; });
1069ARCANE_REGISTER_PROPERTY_CLASS(ArcaneMainBatchProperties,());
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
static void finalize(ITraceMng *tm)
Finalise l'exécution.
static void stopAllProfiling()
Stoppe toutes les activités de profiling.
CaseDatasetSource & caseDatasetSource()
Source du jeu de données.
Informations sur une application.
Propriétés associées à ArcaneMain.
String m_idle_service_name
Nom du service pour les CPU non utilisés.
void executeFunctor() override
Exécute la méthode associé
Infos par sous-domaine qui doivent être détruites à la fin de l'exécution.
Informations d'exécution pour une session.
Ref< ICodeService > m_code_service
Service du code.
bool m_has_sub_domain_threads
indique si on utilise des threads pour gérer des sous-domaines
UniqueArray< std::byte > m_case_bytes
Contenu du jeu de données du cas sous forme d'un document XML.
String m_case_file
Nom du fichier contenant le cas.
const ArcaneMainBatchProperties m_properties
Propriétés d'exécution.
Exécution en mode batch d'un code.
String m_case_name
Nom du cas.
void doAbort() override
Effectue un abort.
Ref< ICodeService > m_code_service
Service du code.
bool m_init_only
true si on ne fait que l'initialisation.
ArcaneMainBatchProperties m_properties
Session.
void initialize() override
Initialise l'instance. L'instance n'est pas utilisable tant que cette méthode n'a pas été appelée.
int execute() override
Lance l'exécution. Cette méthode ne retourne que lorsqu'on quitte le programme.
bool m_check_case_only
true si on ne fait que vérifier le jeu de données.
void finalize() override
Effectue les dernières opérations avant destruction de l'instance.
bool m_has_sub_domain_threads
indique si on utilise des threads pour gérer des sous-domaines
void build() override
Construit les membres la classe. L'instance n'est pas utilisable tant que cette méthode n'a pas été a...
bool parseArgs(StringList args) override
Analyse les arguments.
const ApplicationInfo & applicationInfo() const override
Informations sur l'éxécutable.
static int callFunctorWithCatchedException(IFunctor *functor, IArcaneMain *amain, bool *clean_abort, bool is_print=true)
Appelle le fonctor functor en récupérant les éventuelles exceptions.
IApplication * application() const override
Application.
void build() override
Construit les membres la classe. L'instance n'est pas utilisable tant que cette méthode n'a pas été a...
const ApplicationBuildInfo & applicationBuildInfo() const override
Informations pour construire l'instance IApplication.
int errorCode() const override
Code d'erreur de l'exécution.
void initialize() override
Initialise l'instance. L'instance n'est pas utilisable tant que cette méthode n'a pas été appelée.
bool parseArgs(StringList args) override
Analyse les arguments.
Exception lorsqu'un argument est invalide.
Source d'un jeu de données d'un cas.
void setFileName(const String &name)
Positionne le nom du fichier du jeu de données.
String fileName() const
Nom du fichier du jeu de données.
void setContent(Span< const std::byte > bytes)
Positionne le contenu du jeu de données.
ByteConstSpan content() const
Contenu du jeu de données.
Integer count() const
Nombre d'éléments de la collection.
Interface de l'application.
virtual IParallelSuperMng * parallelSuperMng()=0
Gestionnaire superviseur du parallélisme.
Interface de la classe de gestion du code.
virtual ITraceMng * traceMng() const =0
Gestionnaire de traces.
Interface d'un fonctor pour exécuter du code directement après la création d'un sous-domaine sans pas...
Interface du gestionnaire des entrées sorties.
virtual bool collectiveRead(const String &filename, ByteArray &bytes)=0
Lecture collective d'un fichier.
Manufacture des classes d'Arcane.
Interface du gestionnaire de parallélisme pour un sous-domaine.
Classe abstraite du superviseur de parallélisme.
virtual void tryAbort()=0
Tente de faire un abort.
virtual Int32 nbLocalSubDomain()=0
Nombre de sous-domaines à créér localement.
virtual Int32 commSize() const =0
Retourne le nombre total de process utilisés.
Interface d'un service de de trace des appels de fonctions.
virtual void bindThread(Int32 cpu)=0
Contraint le thread courant à rester sur le coeur d'indice cpu.
Interface d'une session d'exécution d'un cas.
Interface du gestionnaire d'un sous-domaine.
Interface gérant les statistiques sur les temps d'exécution.
Interface du gestionnaire de traces.
virtual TraceMessage pfatal()=0
Flot pour un message d'erreur fatale parallèle.
virtual TraceMessage info()=0
Flot pour un message d'information.
Exception lorsqu'une erreur fatale 'parallèle' est générée.
Référence à une instance.
Chaîne de caractères unicode.
bool empty() const
Vrai si la chaîne est vide (nulle ou "")
@ TimerReal
Timer utilisant le temps réel.
Vecteur 1D de données avec sémantique par valeur (style STL).
Integer toInteger(const char *str, bool *is_ok=0)
Converti la chaîne str en un entier non signé. Si is_ok n'est pas nul, il vaut true en retour si la c...
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
List< String > StringList
Tableau de chaînes de caractères unicode.
double Real
Type représentant un réel.
std::int32_t Int32
Type entier signé sur 32 bits.