Développement collaboratif
Chaque personne qui contribue au développement de Nomad est amené à modifier le code source, rajouter des exemples, tester le bon fonctionnement du code et documenter les modifications. Les améliorations apportées doivent être rendues disponibles et validées.
Ce qui suit décrit succinctement l'utilisation de GitHub et Git pour la gestion et le partage des modifications. Le rajout de fichiers de code et d'exemple dans la procédure de compilation avec CMake est présenté par la suite.
Une compréhension minimale de l'utilisation de Nomad est requise. Pour débuter avec Nomad, la lecture du guide de l'utilisateur est recommandée.
Les dépôts de Nomad
Sur GitHub, nos dépôts se trouvent dans le groupe bbopt.
Pour le développement de Nomad 4, nous avons deux dépôts. Le dépôt publique Nomad 4 est réservés aux utilisateurs pour télécharger le code et reporter des problèmes.
Au sein de groupe il est recommandé d'utiliser le dépôt privé de Nomad 4. Les permissions requises pour contribuer via ce dépôt sont gérés par Christophe.
Nomad 3 cède progressivement la place à Nomad 4, mais le dépôt de Nomad 3 est toujours disponible.
Opérations de base avec l'application GitHub Desktop
Il est possible d'utiliser uniquement les commandes dans un shell lors des opérations en lien avec le développement logiciel. Pour se simplifier la vie et ne pas avoir à mémoriser ces commandes, l'application GitHub Desktop est un bon choix.
Une fois rentré les informations du compte, on peut “cloner” le dépôt sur le disque local. Dans ce qui suit, on va considérer que c'est le dépôt privé bbopt/nomad4dev qui est utilisé.
Par défaut, on se retrouve dans la branche develop locale. C'est cette branche qui sera utilisée pour mettre à jour la branche develop sur le dépôt publique GitHub de Nomad (c-a-d, sur les serveurs de GitHub). Une fois figée, la branche develop sera utilisée lors de la création d'une version numérotée (tag) pour les usagers.
Avant de commencer à modifier le code, on doit créer une branche à partir de develop. Le nom de la branche doit refléter le type de modifications. Si on souhaite rajouter une fonctionnalité, on peut nommer sa branche feat/mySuper….. On veut un nom parlant mais pas trop long. Il faut garder en tête que l'on pourra créer plusieurs branches et passer de l'une à l'autre au besoin.
Une branche qui vise à fixer un bug pourra être nommée fix/aBug….. Une branche qui vise à compléter la documentation pourra être nommée doc/about…..
Les modifications apportées seront visibles dans GitHub Desktop (fichiers modifiés et lignes modifiées dans un fichier sélectionné). Il est préférable de “commiter” ces modifications à petite échelle. Ce n'est pas une bonne pratique d'attendre d'avoir fait un grand nombre de modifications avant de “commiter”. En effet, il est souhaitable de documenter toutes modifications en quelques mots, pas à pas.
Les modifications locales que l'on fait au cours d'une journée des travail peuvent être poussées (“push”) vers le dépôt GitHub. Il est possible de travailler à plusieurs sur une même branche. Dans ce cas, il faut aussi régulièrement faire un “pull” pour être à jour. Pousser les modifications vers GitHub permet de plus facilement synchroniser le code lorsque l'on travaille sur plusieurs machines à différents moments.
Une fois satisfait des apports au code, il faut “merger” la branche develop locale sur la branche develop de GitHub. Il est recommandé de procéder suivant les étapes suivantes :
- Fusionner (“merge”) la branche develop de GitHub vers la branche de travail locale. Cet étape peut être faite à plusieurs moments durant le développement afin que la branche de travail soit à jour avec les nouveaux développements et les bugs fixés. Pour procéder, dans GitHub Desktop, on bascule dans la branche develop, on fait un “fetch” et un “pull” au besoin pour mettre à jour le code. On bascule à nouveau dans la branche de travail locale et on utilise la fonction “Merge Into Current Branch”. Cette étape peut requérir de régler des conflits entre les deux versions.
- Tester les modifications apportées à la branche de travail locale (tests de base, tests unitaires, tests d'implémentation et tests de performance).
- Utiliser la fonction “Create a Pull Request” de GitHub Desktop. Cela créé un “Pull Request” sur le dépôt GitHub. Dans l'interface Web de GitHub, on doit documenter ce “Pull Request” afin qu'il soit révisé. On peut aussi visualiser les modifications apportées à chaque fichier. Quelques petits détails peuvent être réglés à ce moment là. On édite le fichier localement et on pousse les modifications vers GitHub, sans annuler le “Pull Request”.
- Au besoin, procéder localement aux modifications requises par la personne en charge de réviser (“reviewer”) le code modifié et pousser les modifications vers GitHub. Dans GitHub, lorsque tout est satisfaisant (code, documentation et tests), le code sera fusionné par l'admin (Christophe). La branche de travail sera aussi supprimée.
- Mettre à jour la branche develop locale sur nos machines (fetch et pull). On peut aussi effacer la branche de travail locale.
CMake -- Ajout d'un exemple
Une série d'exemples sont fournis avec le code source de Nomad. Ces exemples sont compilés et installés en même temps que Nomad par CMake. Ces exemples sont inclus dans les tests de base gérés avec CMake.
Le développement de code source et la compilation peuvent être gérés dans un environnement de développement intégré (IDE) comme Visual Studio ou XCode. Toutefois, tout rajout doit aussi pouvoir être compilé avec CMake sur la ligne de commande d'un shell.
Dans ce qui suit, on considère le rajout d'un exemple en mode batch. La procédure est très semblable pour un exemple en mode librairie.
Les exemples simples en mode batch se trouvent dans le répertoire $NOMAD_HOME/examples/basic/batch.
Pour rajouter un exemple, on peut copier un répertoire d'example existant. Supposons, que le répertoire copié se nomad exampleTop. Typiquement, ce répertoire contient les fichiers suivants :
- CMakeLists.txt
- param.txt
- bb.cpp
Le fichier param.txt contient la définition de la boîte noire, du problème d'optimisation et des paramètres algorithmiques. La boîte noire est codée dans le fichier bb.cpp et doit être compilée avant d'être utilisée. La compilation de la boîte noire et l'exécution d'un test sur ce problème sont gérées dans le fichier CMakeLists.txt.
Le contenu du fichier CMakeLists.txt doit être adapté. Dans ce qui suit, les éléments en gras, sont à modifier.
set(CMAKE_EXECUTABLE_SUFFIX .exe)
add_executable(bbTop.exe bb.cpp )
set_target_properties(bbTop.exe PROPERTIES SUFFIX “”)
# installing executables and libraries
install(TARGETS bbTop.exe RUNTIME DESTINATION ${CMAKE_CURRENT_SOURCE_DIR} )
# Add a test for this example
message(STATUS “ Add example batch TOP”)
# Test run in working directory AFTER install of bbTop.exe executable
add_test(NAME ExampleBBTOPBasicBatch COMMAND ${CMAKE_INSTALL_PREFIX}/bin/nomad param.txt WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} )
IMPORTANT : le nom de l'exécutable doit être unique dans tout le projet CMake de Nomad.
Le code source pour l'évaluation de la boîte noire dans bb.cpp doit aussi être modifié. Une boîte noire peut sortir plusieurs valeurs pour la fonction coût et les contraintes. L'ordre de sortie est important et doit correspondre à l'ordre qui figure dans le paramètre BB_OUTPUT_TYPE défini dans le fichier param.txt. Ce paramètre défini aussi comment les sorties de contrainte sont gérés (PB pour barrière progressive, EB pour barrière extrème).
Le contenu du fichier param.txt doit être adapté au problème considéré. En particulier, le paramètre BB_EXE doit correspondre au nom de l'exécutable.
Il faut modifier un autre fichier CMakeLists.txt pour que ce nouveau problème soit pris en compte lors de la compilation de Nomad par CMake dans le répertoire $NOMAD_HOME.
Dans le fichier $NOMAD_HOME/examples/CMakeLists.txt on doit rajouter la ligne suivante :
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/basic/batch/exampleTop)
CMake -- Ajout d'un fichier source
Lorsqu'un fichier source est rajouté au code de Nomad, il faut adapter le fichier CMakeLists.txt qui se trouve dans le répertoire $NOMAD_HOME/src.
Ce fichier est structuré suivant les fonctions principales de Nomad (Cache, Attributs, Algos, …). On distingue aussi si il s'agit d'un fichier de source (cpp) ou d'un fichier d'en-tête (hpp).
Par exemple, le contenu associé à l'algorithme Latin Hypercube est le suivant :
#
# LH
#
set(LH_HEADERS
Algos/LatinHypercubeSampling/LH.hpp
)
set(LH_SOURCES
Algos/LatinHypercubeSampling/LH.cpp
)
Si on ajoute un fichier à un algo existant, il suffit de rajouter des lignes dans les commandes set pour l'aogo considéré.
Pour un nouvel algo, on peut copier le contenu d'un algo existant et l'adapter à nos besoins.
Exécution des tests sur les exemples
Durant le processus de développement, il est impératif de tester l'effet des modifications apportées.
On peut commencer par exécuter un test sur l'exemple utilisant une nouvelle fonctionnalité. Si l'exemple a bien été intégré dans le projet CMake, on peut compiler, installer et faire rouler les tests avec les commandes CMake suivantes (OSX ou Linux) :
cd $NOMAD_HOME
cmake -S. -B build/release
cmake -build build/release
cd build/release
ctest
Les commandes doivent être adaptées dans le cas de Windows. Pour OSX et Linux, la compilation et les tests peuvent être faits en mode parallèle en rajoutant –parallel xx aux commandes.
Lors de l'exécution de la commande cmake -S . -B build/release, on doit vérifier que le nouvel exemple est bien considéré.
La commande ctest affiche le déroulement des tests. Plus d'information est disponible dans le répertoire $NOMAD_HOME/build/release/Testing/Temporary.
Exécution des tests unitaires
Les codes sources des tests unitaires se trouvent dans $NOMAD_HOME/internal/unit_tests/. Pour configurer, compiler et exécuter les tests unitaires, on exécute les commandes CMake suivantes (OSX ou Linux) :
cd $NOMAD_HOME
cmake -DBUILD_TESTS=ON -S . -B build/release
cmake -build build/release
cd build/release
ctest
Il faut investiguer les causes d'un échec sur des tests unitaires.