Applications et modules d’environnement
Introduction
Avant de décrire ce que sont les modules d’environnements, il faut d’abord comprendre comment sont gérés les programmes sur un système POSIX pour comprendre leur utilité sur un cluster HPC.
Si vous ne maîtrisez pas le fonctionnement des applications sur Linux, vous trouverez l’explication ici : Programmes et Variables d’environnement
Qu’est ce qu’un module ?
Un module d’environnement est un fichier de description qui permet de décrire un environnement d’exécution propre à un logiciel donné. C’est-à-dire l’ensemble des variables qui sont nécessaires au bon fonctionnement du programme.
C’est aussi une commande (module) qui permet de faciliter le chargement et le déchargement des applications, compilateurs et/ou frameworks de votre session.
Grâce aux modules, il est possible de gérer les logiciels afin d’utiliser la version adéquate suivant le projet.
L’administrateur du cluster IG vous fournit un ensemble de modules prêt à l’usage et peut vous aider à en créer d’autres suivant vos besoins.
Lmod
Historiquement, le paquet environment-modules était utilisé sur le cluster pour gérer les modules. Ceux-ci étaient écrits en langage Tcl.
Usage
Voir les modules disponibles
La commande module avail permet de lister les modules disponibles sur le serveur. Ceux-ci peuvent changer d’un serveur à l’autre.
Voici la liste des modules présent sur le datamaster :
[demo@datamaster ~]$ module avail
-------------------------------------------------------------------- /opt/lmod-8.4/lmod/lmod/modulefiles --------------------------------------------------------------------
Core/lmod Core/settarg (D)
------------------------------------------------------------------------ /storage/modulefiles -------------------------------------------------------------------------
anaconda3/2019.10 anaconda3/2020.07 (D) go/1.18.2 go/1.18.6 (D)
-------------------------------------------------------------------- /shared/software/modules/all ---------------------------------------------------------------------
Core/M4/1.4.17 lang/Bison/3.0.4-GCCcore-6.4.0 numlib/FFTW/3.3.7-gompi-2018a
Core/M4/1.4.18 (D) lang/Bison/3.0.4 (D) numlib/OpenBLAS/0.2.20-GCC-6.4.0-2.28
Core/help2man/1.47.4 lang/Java/1.8.0_172 numlib/ScaLAPACK/2.0.2-gompi-2018a-OpenBLAS-0.2.20
Core/zlib/1.2.11 lang/Python/3.6.4-foss-2018a system/hwloc/1.11.8-GCCcore-6.4.0
compiler/GCC/6.4.0-2.28 lang/Tcl/8.6.8-GCCcore-6.4.0 toolchain/foss/2018a
compiler/GCCcore/6.4.0 lang/flex/2.6.3 toolchain/gompi/2018a
devel/Autoconf/2.69-GCCcore-6.4.0 lang/flex/2.6.4-GCCcore-6.4.0 (D) tools/XZ/5.2.3-GCCcore-6.4.0
devel/Automake/1.15.1-GCCcore-6.4.0 lib/TensorFlow/1.7.1-foss-2018a-Python-3.6.4-CUDA-9.0 tools/binutils/2.28-GCCcore-6.4.0
devel/Autotools/20170619-GCCcore-6.4.0 lib/TensorFlow/1.7.1-foss-2018a-Python-3.6.4 tools/binutils/2.28 (D)
devel/Bazel/0.11.1-GCCcore-6.4.0 lib/TensorFlow/1.8.0-foss-2018a-Python-3.6.4-CUDA-9.0 (D) tools/bzip2/1.0.6-GCCcore-6.4.0
devel/Bazel/0.12.0-GCCcore-6.4.0 (D) lib/libffi/3.2.1-GCCcore-6.4.0 tools/gettext/0.19.8.1
devel/M4/1.4.17 lib/libreadline/7.0-GCCcore-6.4.0 tools/help2man/1.47.4-GCCcore-6.4.0
devel/M4/1.4.18-GCCcore-6.4.0 lib/libtool/2.4.6-GCCcore-6.4.0 tools/help2man/1.47.4 (D)
devel/M4/1.4.18 (D) lib/zlib/1.2.11-GCCcore-6.4.0 tools/numactl/2.0.11-GCCcore-6.4.0
devel/SQLite/3.21.0-GCCcore-6.4.0 lib/zlib/1.2.11 (D) tools/wheel/0.30.0-foss-2018a-Python-3.6.4
devel/ncurses/6.0-GCCcore-6.4.0 math/GMP/6.1.2-GCCcore-6.4.0 tools/wheel/0.31.0-foss-2018a-Python-3.6.4 (D)
devel/ncurses/6.0 (D) mpi/OpenMPI/2.1.2-GCC-6.4.0-2.28
Where:
(D): Default Module
Use "module spider" to find all possible modules.
Use "module keyword key1 key2 ..." to search for all possible modules matching any of the "keys".
Activer un module
La commande module load charge un module d’environnement.
Voici comment charger Anaconda :
[demo@datamaster ~]$ conda
conda: command not found
[demo@datamaster ~]$ module load anaconda3
[demo@datamaster ~]$ conda env list
# conda environments:
#
data /home_nfs/demo/.conda/envs/data
myownenv /home_nfs/demo/.conda/envs/myownenv
base * /storage/modules/anaconda3/2020.07
Appuyer sur la touche tabulation 2x permet de compléter le nom du module et de proposer les noms disponibles. |
Afficher la liste des modules actifs
La commande module list affiche la liste des modules actifs :
[demo@datamaster ~]$ module list
Currently Loaded Modules:
1) anaconda3/2020.07
Désactiver un module
La commande module unload désactive un module :
[demo@datamaster ~]$ module unload anaconda3
[demo@datamaster ~]$ module list
No modules loaded
Désactiver tout les modules
La commande module purge permet de désactiver tout les modules actifs :
[demo@datamaster ~]$ module load mpi
mpi/OpenMPI mpi/OpenMPI/2.1.2-GCC-6.4.0-2.28
[demo@datamaster ~]$ module load mpi/OpenMPI
[demo@datamaster ~]$ module list
Currently Loaded Modules:
1) compiler/GCCcore/6.4.0 4) tools/numactl/2.0.11-GCCcore-6.4.0
2) tools/binutils/2.28-GCCcore-6.4.0 5) system/hwloc/1.11.8-GCCcore-6.4.0
3) compiler/GCC/6.4.0-2.28 6) mpi/OpenMPI/2.1.2-GCC-6.4.0-2.28
[demo@datamaster ~]$ mpicc
gcc: fatal error: no input files
compilation terminated.
[demo@datamaster ~]$ module purge
[demo@datamaster ~]$ module list
No modules loaded
Sur la première ligne, j’ai appuyé sur tab 2 fois après avoir écrit mpi. |
Rechercher un module
La commande module spider permet de trouver les modules.
Sensible à la casse, peut retourner une liste incomplète. Toujours vérifier avec module avail. |
[demo@datamaster ~]$ module spider mpi
-------------------------------------------------------------------------------
compiler/GCC: compiler/GCC/6.4.0-2.28
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
mpi/OpenMPI: mpi/OpenMPI/2.1.2-GCC-6.4.0-2.28
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
toolchain/gompi: toolchain/gompi/2018a
-------------------------------------------------------------------------------
Écrire son propre fichier module
Si vous avez ajouté un programme dans votre dossier personnel, il est possible de créer un fichier module.
Par exemple, nous avons téléchargé une archive compilée du langage Go et nous l’avons extraite par convention dans le dossier ~/bin/ :
[demo@datamaster ~]$ mkdir ~/bin
[demo@datamaster ~]$ wget https://dl.google.com/go/go1.18.6.linux-amd64.tar.gz
[demo@datamaster ~]$ tar -xf go1.18.6.linux-amd64.tar.gz -C ~/bin/
Nous allons ensuite créer un dossier ~/modulefiles dans lequel nous écrirons nos fichiers modules :
[demo@datamaster ~]$ mkdir -p ~/modulefiles/golang/
[demo@datamaster ~]$ touch modulefiles/golang/1.18.6.lua
[demo@datamaster ~]$ nano modulefiles/golang/1.18.6.lua
Voici le contenu à ajouter avec nano :
help([==[This module sets the PATH variable for golang/1.18.6 ]==])
whatis([==[Description: Go programming language created by Google ]==])
whatis([==[Homepage: https://golang.org ]==])
local goroot = "$HOME/bin/go"
conflict("golang")
setenv("GOROOT", goroot)
prepend_path("PATH", pathJoin(goroot, "bin"))
whatis("Name : Golang 1.18.6")
whatis("Version : 1.18.6")
whatis("Category : Compiler")
whatis("Description : Go environment ")
whatis("URL : https://golang.org/ ")
family("golang")
Plus d’exemples : Modulefile Examples from simple to complex
Une fois sauvegardé, nous pouvons ajouter le dossier ~/modulefiles à la liste des sources de modules avec la commande module use :
[demo@datamaster ~]$ module use ~/modulefiles
[demo@datamaster ~]$ module load golang
[demo@datamaster ~]$ go version
go version go1.18.6 linux/amd64
Si nous voulons désactiver le dossier ~/modulefiles, il suffit d’utiliser la commande module unuse avec le chemin absolu :
[demo@datamaster ~]$ module unload golang
[demo@datamaster ~]$ module unuse ~/modulefiles
Nous pouvons automatiser le chargement du module en ajoutant ces lignes dans le fichier ~/.bashrc :
if [ -f ~/bin/go/bin/go ] && [-d ~/modulefiles/golang ]; then
module use ~/modulefiles
module load golang
fi
Si les dossiers du programmes et du fichier module existent alors le module golang sera activé dès la connexion au cluster.
Les répertoires personnels sont accessibles depuis n’importe quel serveur. Si ces fichiers étaient dans le disque local du serveur datamaster (/scratch/ par exemple), cela ne fonctionnerait que pour ce serveur et pas les autres. |
Exemple de fichier module
Écrit en Lua
help([[
Adds the Julia Programming Language in version 1.7.2 to your environment variables.
]])
local pkgName = myModuleName()
local fullVersion = myModuleVersion()
local version = "1.7.2"
local base = "/usr/local/julia-" .. version
whatis("Name: "..pkgName)
whatis("Version: "..fullVersion)
whatis("Description: Julia is a programming language for scientific programming.")
whatis("URL: https://julialang.org")
whatis("Keyword: language, julia, compiler")
setenv("JULIA_BINDIR", pathJoin(base,"bin")) -- /usr/local/julia-1.7.2/bin
setenv("JULIA_DEPOT_PATH", pathJoin(base, "packages"))
prepend_path("PATH", pathJoin(base,"bin"))
prepend_path("LD_LIBRARY_PATH", pathJoin(base,"lib"))
prepend_path("LD_LIBRARY_PATH", pathJoin(base,"lib/julia"))
prepend_path("CPATH", pathJoin(base,"include"))
Écrit en Tcl
proc ModulesHelp { } {
puts stderr "\tAdds CUDA Toolkit 9.0.176 to your environment variables,"
}
module-whatis "adds CUDA Toolkit 9.0.176 to your environment variables"
set root /usr/local/cuda-9.0
setenv CUDA_HOME $root
prepend-path PATH $root/bin
prepend-path LD_LIBRARY_PATH $root/lib
prepend-path LD_LIBRARY_PATH $root/lib64:/usr/lib/nvidia-440
prepend-path PKG_CONFIG_PATH $root/pkgconfig