====== 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 [[https://nomad-4-user-guide.readthedocs.io|guide de l'utilisateur]] est recommandée. ===== Les dépôts de Nomad ===== Sur GitHub, nos dépôts se trouvent dans le groupe [[https://github.com/bbopt/|bbopt]]. Pour le développement de Nomad 4, nous avons deux dépôts. Le dépôt publique [[https://github.com/bbopt/nomad|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 [[https://github.com/bbopt/nomad4dev|Nomad 4]]. Les **permissions requises** pour contribuer via ce dépôt sont gérés par [[mailto:christophe.tribes@polymtl.ca|Christophe]]. Nomad 3 cède progressivement la place à Nomad 4, mais le dépôt de [[https://github.com/bbopt/NOMAD_3|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 [[https://desktop.github.com/|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.