Le Runner est un outil pour automatiser la comparaison de la performance d'algorithmes d'optimisation. Le Runner facilite et accélère les tests pour déterminer l'influence des paramètres algorithmiques sur la performance.
Le code source du Runner dépend des librairies de Nomad 4. Nomad 4 doit donc être installé pour compiler le Runner.
L'outil a été construit pour Nomad 4 mais il est possible de tester d'autres algorithmes : Nomad 3.9 ou d'autres algorithmes (Matlab FMinSearch et Matlab grid NelderMead).
Le Runner contient un grand nombre de problèmes d'optimisation qui sont prédéfinis. On peut choisir quels problèmes sélectionner (taille, contrainte, nature des variables, etc.).
La documentation du Runner est minimale (voir le fichier readme_Runner4.txt). Cette page Wiki a été bâtie à partir de tutoriels faits à des usagers.
La vidéo d'un tutoriel est disponible sur YouTube (attention ça dure 1h30').
N'HÉSITEZ PAS À COLLABORER AVEC VOS PROPRES EXPÉRIENCES DANS LA SECTION EXPÉRIENCES
Nomad 4 version publique : https://github.com/bbopt/nomad.git
Ou Nomad 4 version develop (privée) : https://github.com/bbopt/nomad4dev.git
Runner 4 version privée uniquement : https://github.com/bbopt/Runner4.git
Pour l'instant, ces codes sont “compilables”/utilisables uniquement avec CMake (version > 3.14 ) et Make sur Linux et OSX et Windows (Visual Studio).
Le Runner est efficace lorsqu'utilisé avec MPI. La distribution openMPI fait le travail.
Runner sans MPI: Si les tests nécessitent l'utilisation de OpenMP (tests de parallélisme, utilisation de PSD-Mads…) ou si MPI n'est pas disponible, il est possible de désactiver MPI lors de la compilation du Runner.
Une fois Nomad 4 récupéré de GitHub,
git clone https://github.com/bbopt/nomad
ou git clone https://github.com/bbopt/nomad4dev
Il faut compiler avec CMake :
1- Mise en place:
cmake -DTEST_OPENMP=OFF -S . -B build/release
ou Runner sans MPI: cmake -S . -B build/release
L'option TEST_OPENMP=OFF
permet d'éviter que Nomad utilise OpenMP pour la parallélisation des évaluations. Le Runner va utiliser MPI et on veut éviter une “compétition” entre les deux.
Runner sans MPI: utiliser la deuxième commande pour la mise en place.
2- Compilation:
cmake --build build/release --parallel 4
L'option --parallel 4
sert à compiler plus rapidement sur 4 coeurs. Pour connaître le nombre de coeurs disponibles sur la machine, faire la commande nproc
.
3- Installation:
cmake --install build/release
Le Runner 4 est dans un dépôt privé accessible uniquement aux usagers du groupe BBOPT.
git clone https://github.com/bbopt/runner4
Il faut lancer un script pour configurer les makefiles avant de lancer la compilation.
Supposons que l'on veuille comparer différentes options algorithmiques de Nomad 4.0.2 entre elles, par exemple, avec et sans 'searches'. On va utiliser Nomad 4.0.2 comme version de base pour compiler le Runner. On n'aura pas besoin d'utiliser un autre solveur (par exemple Nomad 3). On configure donc le runner avec cette option :
cd Runner4
./configure --nomad_4_base=/home/user/myGitRep/nomad
(remplacer par le chemin vers le répertoire git de NOMAD).
Cette commande va créer les makefile
pour faire la compilation. Par défaut, le Runner va utiliser MPI. Si MPI n'est pas disponible ou pas correctement installé, la compilation va échouer.
Runner sans MPI: Pour désactiver l'utilisation de MPI, et utiliser OpenMP dans NOMAD:
configure --nomad_4_base=/home/user/myGitRep/nomad --disable-mpi --enable-openmp
(remplacer par le chemin vers le répertoire git de NOMAD).
Les options du configure
sont obtenues en faisant :
./configure --help
On lance la compilation en parallèle (l'option -j
) avec
make -j 4
Une fois la commande complétée avec succès on va trouver l'exécutable runner.mpi
dans le répertoire Runner4/bin
. Runner sans MPI: l'exécutable s'appelle simplement runner
.
La sélection des problèmes d'optimisation s'effectue en éditant le fichier Run/problem_selection
.
Le fichier permet de sélectionner quelles “seeds” tester pour les algorithmes, par exemple :
runner.setNomadRunSeeds(93399, 31710) ;
On peut aussi spécifier le budget d'évaluation.
# Control evaluation budget (limit the number of evaluations for algo run and influences the x axis of data profiles) # put a value < 0 to deactivate runner.setOverallMaxBBEvals( 20000 ); runner.setNbSimplexEvals ( 400 );
Les problèmes disponibles ont des mots clefs associés qui peuvent être utilisés pour sélectionner une série de problèmes, par exemple :
runner.select_problems_by_keyword ( "constrained" );
ou
runner.select_problems_by_keyword ( "orthomads_paper" );
Une fois une série de problèmes sélectionnée on peut en exclure certains, par exemple :
runner.exclude_problems_by_size ( 0 , 9 ); # big problems only
ou préciser quels problèmes conserver :
runner.refine_problems_by_keyword ( "SMOOTH" );
On peut sélectionner les problèmes “à la pièce”, par exemple :
runner.select_problem_by_name ( "ARWHEAD_I0_N10" );
Dans ce cas, on rajoute le problème “ARWHEAD”. Ce problème à plusieurs variantes; dans ce cas, on choisi la variante avec une partie des variables d'entrée spécifiés comme des entiers (I0
) et avec une dimension de 10 (N10
).
Pour connaître les variantes disponibles d'un problème, il faut examiner le code source. Par exemple, on peut examiner le code source de ARWHEAD : Runner4/Run/problems/Arwhead.cpp
. Pour qu'une variante soit disponible, elle doit être instanciée correctement dans le Runner. Cela se fait dans le constructeur de Runner
situé dans code source Runner4/src/Runner.cpp
en faisant un push_back
d'une instance dans _all_pbs
:
# construct list of all problems: _all_pbs.push_back ( new Arwhead ( 10 ) ); _all_pbs.push_back ( new Arwhead ( 20 ) ); _all_pbs.push_back ( new Arwhead ( 10 , FORCE_HALF_INT) ); _all_pbs.push_back ( new Arwhead ( 20 , FORCE_HALF_INT) );
Le choix des algorithmes et de leurs paramètres se fait en choisissant quels fichiers de configuration doivent être testées par le Runner. Il y a un fichier par configuration de test (choix d'un algo avec ses paramètres algorithmiques). Plusieurs exemples de fichiers de configuration se trouvent dans le répertoire Runner4/Run/test_configs
.
Un fichier de configuration comprend au minimum trois arguments avec leurs valeurs :
# The first 3 arguments are mandatory RUNNER 4.0 SOLVER NOMAD 4.0.2 ALGO_LEGEND Mads default
L'argument SOLVER
doit comprendre le nom du solveur. Pour pouvoir utiliser un solveur, il faut avoir correctement configuré et compilé le Runner à cet effet (voir section Installation/Compilation du Runner).
L'argument ALGO_LEGEND
donne l'information qui va apparaitre sur un graphe pour identifier une configuration de test. On peut mettre la description que l'on veut.
Les autres arguments du fichier doivent suivre la syntaxe reconnue par le solveur choisi pour spécifier les paramètres algorithmiques. Par exemple, pour NOMAD 4.0.2, si on souhaite désactiver la recherche basée sur Nelder Mead, on rajoute :
NM_SEARCH no
Si on ne précise rien, il s'agit des options par défaut.
Tous les paramètres reconnus d'un algorithme ne peuvent pas être spécifiés pour une configuration de test (la mécanique pour cette vérification n'est pas expliquée ici). Les paramètres qui sont utilisés pour définir le problème (comme la dimension, les bornes, etc.) ne peuvent pas être mis dans ce fichier. En fait, ils seront rajoutés lors de l'exécution du Runner et le fichier correspondant sera placé dans le répertoire de test (voir plus loin).
Pour exécuter les tests (mode avec MPI) sur les problèmes sélectionnés on doit se placer dans le répertoire Run
et on fait par exemple la commande :
cd Run
mpirun -np 4 ../bin/runner.mpi test_configs/param_mads_4.0.2.txt test_configs/param_mads_4.0.2_nosearch.txt
Runner sans MPI: ../bin/runner test_configs/param_mads_4.0.2.txt test_configs/param_mads_4.0.2_nosearch.txt
Cela va lancer les tests avec 2 configurations de Nomad 4.0.2 utilisant l'algorithme Mads et des paramètres algorithmiques différents. Sur la ligne de commande, mpirun -np 4
signifie qu'il va y avoir 4 processus qui vont être exécutés en parallèle. Un problème avec une seed donnée et une configuration d'algo vont être résolus par un seul processus (les évaluations seront séquentielles). Dépendamment des ressources CPU disponibles, vous pouvez changer le nombre de processus pour mpirun
.
L'exécutable va afficher les problèmes sélectionnés :
selected problems (13) pb #1: [MORE_WILD_23_WATSON_SMOOTH] [n=12] [m=1] [bnds=0] [cstr=0] [trend=0] [int=0] [bin=0] [lib] [f*=4e-06] pb #2: [MORE_WILD_24_WATSON_SMOOTH] [n=12] [m=1] [bnds=0] [cstr=0] [trend=0] [int=0] [bin=0] [lib] [f*=0.001758] ...
On verra ensuite un résumé des configurations
test configurations (2): algo #1 (NOMAD 4.0.2): All attributes have default value algo #2 (NOMAD 4.0.2): [ NM_SEARCH 0 ] [ QUAD_MODEL_SEARCH 0 ] [ SPECULATIVE_SEARCH 0 ]
Il est important de vérifier que les configurations sont bien celles que vous avez choisies. Il est toujours possible d'interrompre l'exécution en faisant CTRL-C
.
Si des runs ont déjà été effectuées, le runner va charger les résultats disponibles et ne re-fera pas les executions. Les tests qui sont détectés sont affichés de la façon suivante :
test executions (52): pb #5, algo #1, seed run #1: found in ./problems/MORE_WILD/tests/1621282407_34280_5_1/: bbe=1815 f=4e-06 fx0=273.248 ffx=273.248 pb #5, algo #1, seed run #2: found in ./problems/MORE_WILD/tests/1621282407_34280_5_1/: bbe=1474 f=7e-06 fx0=273.248 ffx=273.248
Dans cet exemple, le pb #5 a été résolu avec l'algo #1 (voir plus haut) pour les seed #1 et #2. On trouve le premier fichier de résultats dans le répertoire Runner4/Run/problems/MORE_WILD/tests/xxxxxxxxxxxxxxx_5_1
. Les deux derniers chiffres correspondent au numéro du pb et le numéro de l'algo.
Dans le cas ou les runs n'ont pas été exécutées l'affichage va être le suivant :
proc 1/4: pb #1, algo #2 all seed runs OK proc 1/4: pb #2, algo #2 all seed runs OK proc 1/4: pb #3, algo #1 all seed runs OK proc 1/4: pb #3, algo #2 all seed runs OK proc 3/4: pb #1, algo #1 all seed runs OK proc 3/4: pb #4, algo #2 all seed runs OK
Une nouvelle ligne s'affiche quand les exécutions pour toutes les seeds d'un pb et d'un algo sont terminées.
Pour chaque classe de problème (par exemple MORE_WILD ou ROSENBROCK) on va avoir un répertoire de test où est conservé les fichiers résultant d'une exécution. À noter qu'une classe de problème peut contenir plusieurs instances de problème. Par exemple, MORE_WILD consiste en 53 fonctions analytiques qui sont bruitées (ou pas) de 4 façons différentes. Cela donne au total 212 problèmes MORE_WILD.
Le répertoire des tests pour MORE_WILD est Runner4/Run/problems/MORE_WILD/tests
. Pour un problème spécifique donné (dans un sous répertoire) on trouve les fichiers suivants :
stats.93399.txt param.31710.txt param.93399.txt stats.31710.txt
Le fichier de paramètres avec le numéro de seed contient toute l'information requise par le solveur. Par exemple, le fichier param.31710.txt
contient l'information suivante :
# RUNNER 4.0 # SOLVER NOMAD 4.0.2 # ID MORE_WILD_35_BROWN_SMOOTH # Problem parameters DIMENSION 10 BB_INPUT_TYPE ( R R R R R R R R R R ) BB_OUTPUT_TYPE OBJ X0 ( 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 ) # Output parameters TMP_DIR /tmp DISPLAY_STATS bbe ( sol ) obj DISPLAY_DEGREE 0 STATS_FILE stats.31710.txt time bbe %16.16fobj %fbbo %fsol # Added algo parameters MAX_BB_EVAL 4400 SEED 31710
Tel qu'indiqué par l'argument STATS_FILE
, le fichier stats.31710.txt
contient les sorties au format prescrit.
Si le Runner détecte que les problèmes choisis ont déjà été résolus pour le choix d'algo, par défaut, il ne refera pas les runs. Toutefois, en cas de changement dans le code source de l'algo ou d'un problème lors de l'exécution, on peut être amené à vouloir refaire des runs. Il est donc nécessaire de supprimer les runs avant de recommencer. Cela est spécifié dans le fichier Runner4/Run/maintenance_selection
:
# ------------------------------------------ # Perform a cleaning of all test directories # for selected solvers and problems # ------------------------------------------ runner.clean_selected_tests();
Dans ce cas, le Runner va supprimer les répertoires de test sélectionnés (fichiers de configs dans la commande mpirun -np 4 ../bin/runner.mpi
et pb sélectionnés dans Runner4/Run/problem_selection
).
Il est important d'examiner ce fichier avant de lancer le Runner pour éviter d'effacer par accident des répertoires qui ont pris du temps à être obtenus.
Lorsque les runs ont été effectuées avec succès, le Runner va produire des fichiers pour tracer des profils de données (ou profils de performance). La sélection de quels profils produire est faite dans le fichier Runner4/Run/output_configuration
. Pour obtenir un profil de données, on doit préciser le paramètre tau pour la précision de détection d'un problème résolu :
runner.output_data_profile_plain(0.001,"outputs/dp3.txt"); runner.output_data_profile_plain(0.00001,"outputs/dp5.txt");
Dans l'exemple, on a deux fichiers qui sont produits (dp3.txt
et dp5.txt
) pour tau = 1E-3 et tau = 1E-5.
En ayant pdflatex d'installé, on peut tracer les profils de données dans un pdf. Pour cela on doit donner les lignes suivantes (ajuster le path de pdflatex):
runner.output_data_profile_pgfplots("outputs/dp3.txt", "1E-3", "/Library/TeX/texbin/pdflatex","NO"); runner.output_data_profile_pgfplots("outputs/dp5.txt", "1E-5", "/Library/TeX/texbin/pdflatex", "NO");
Si pdflatex n'est pas disponible, des messages d'erreur vont apparaître à la fin de l'exécution de la commande mpirun -np 4 ../bin/runner.mpi …
. L'installation de texlive
ou de texstudio
devrait régler ce problème.
Il est aussi possible de créer des profils de données avec MATLAB :
runner.output_data_profile_matlab ("outputs/output_tp5.txt","1E-5");
Il est possible d'exécuter des tests en parallèle sur plusieurs machines (avec MPI) en utilisant l'option -hosts
ou -hostfile
de mpirun
.
Il est important que l'option TEST_OPENMP
soit désactivée sur Nomad, lorsque vous utilisez Runner avec MPI.
Avant çà, il faut s'assurer sur chaque machine de pouvoir:
ssh nodex
(une fois sur le réseau);top
;
Maintenant, depuis le répertoire /Run
, tapez par exemple:
mpirun -hosts node1,node2,node3 -np 12 ../bin/runner.mpi test_configs/param_mads_4.0.2.txt test_configs/param_mads_4.0.2_nosearch.txt
avec nodex
le nom d'une machine disponible pour lancer vos calculs. Voir la liste incomplète ici.