Utiliser le gestionnaire de paquets NIX sur les serveurs de calcul GRICAD

Ressources externes

Introduction

NixOS est une distribution Linux qui permet la création d’environnements reproductibles et l’installation locale de paquet. Les paquets (NixPkgs) peuvent être utilisés avec n’importe quelle distribution Linux ou MacOS et permettent à un utilisateur sans privilèges particuliers d’installer les paquets de son choix. Il s’agit d’une application très intéressante dans un contexte HPC où les utilisateurs peuvent avoir besoin de nombreuses bibliothèques, parfois dans des versions différentes. Nix permet également le développement dans un environnement à la fois isolé, et reproductible. Les environnements créés peuvent être facilement et efficacement partagés entre utilisateurs.

Le guide de quickstart donne les étapes à suivre pour la configuration de Nix sur un ordinateur Linux ou MacOS. Il est possible de partager le même environnement entre votre ordinateur personnel et les hôtes Gricad, ce qui est une fonctionnalité très intéressante pour le développement!

Principes de Nix

En quelques mots, Nix est un gestionnaire de paquets utilisant le langage fonctionnel nix pour écrire des expressions nix afin de créer des dérivations qui résultent généralement en une instance de paquet.

  • Nix est le gestionnaire de paquet
  • Nixpkgs est le repository contenant toutes les expressions nix
  • NixOS est le système d’exploitation utilisant les nixpkgs (l’utilisation de NixOS n’est pas obligatoire, nous ne l’utilisons pas sur les hôtes de calcul de Gricad)

Nix stocke les paquets dans le Nix store, qui se situe dans le dossier /nix/store, où chaque paquet a son sous-répertoire contenant un hash dans son nom, tel que :

/nix/store/b6gvzjyb2pg0kjfwrjmg1vfhh54ad73z-firefox-33.1

Toutes les dépendances des paquets sont liées dans les binaires (avec une forte utilisation du runpath/RPATH). L’utilisateur peut directement utiliser un binaire depuis son chemin ou installer les paquets dans son profil nix qui est pointé grâce à la variable d’environnement PATH. Quand un paquet est insallé dans le profil d’un utilisateur, il n’est en fait que lié grâce à plusieurs liens symboliques vers le répertoire home.

Avertissements

  • N’utilisez pas Nix avec un autre environnement (c’est à dire, ne chargez pas en même temps Nix et /applis/ciment/v2/env.bash). Dans un contexte Nix, vous n’aurez plus besoin de la commande “module”.
  • L’installation de paquets (opérations nix-env) peut être faite uniquement depuis les noeuds de connexion (non pas depuis les noeuds de calcul). Une fois installés, les paquets sont bien entendu disponibles depuis tous les noeuds.
  • Il est très probable que vous trouviez d’anciennes documentations parlant de la commande “nix-channel”. Utilisez à la place la variable d’environnement NIX_PATH.

References

Ce guide n’est qu’un focus sur des exemples et des configurations spécifiques au cluster GRICAD. Vous trouverez bien plus de cas d’usage de Nix en suivant les liens :

Activation de Nix

source /applis/site/nix.sh

(Vous pouvez écrire cette commande dans votre fichier ~/.bashrc ou au début de votre script de soumission de job).

Cette commande crée un ensemble de variables et configure la variable d’environnement PATH pour qu’elle pointe vers votre profil Nix :

  • $PATH : ~/nix-profile/bin est ajouté au début
  • $NIX_PATH : canal nix actuel (version du dépôt nixpkgs)
  • $NIX_USER_PROFILE_DIR : le chemin racine de vos profils. Faites attention, la création d’un profil à l’exterieur de ce répertoire est autorisée, mais le ramasse-miettes n’a pas connaissance des paquets installés dans ce profil, il risque donc de les supprimer !

Lors de la première activation, les dossiers et fichiers suivants sont également initialisés :

  • ~/.nix-profile : lien vers le profil actuel
  • ~/.config/nixpkgs/config.nix : un environnement Nix préconfiguré fourni par GRICAD, afin de faciliter la personnalisation de certains outils tels que Python ou R
  • .config/nix_channel : fourni et utilisé par le script nix.sh lui-même, il stocke le canal actuellement utilisé, qui sera utilisé pour configurer la variable NIX_PATH

Il est possible de sourcer ce script avec une option permettant de demander l’utilisation d’un autre canal parmi une liste de canaux recommandés par GRICAD (le choix est persistant) :

   --unstable : Active le canal le plus récent (mais qui sera instable)
   --stable: Active le dernier canal stable
   --old: Active le canal obsolète

Executer echo $NIX_PATH permet d’obtenir le canal actuellement utilisé par votre environnement.

Profils

Un profil est simplement un répertoire contenant les liens symboliques d’un ensemble de paquets.

  • Créer (ou basculer vers) un profil utilisateur:
nix-env --switch-profile $NIX_USER_PROFILE_DIR/test_profile

Il est ensuite possible d’installer des paquets dans ce profil

  • Obtenir le profil actuel:
ls -l ~/.nix-profile
  • Votre chemin contient également les profils Nix par défaut qui peuvent donner des outils utilisables pour le système entier. Par exemple, les commandes nix, qui sont les commandes iRods actuellement utilisées (ils, iput, iget,…)
$ which ils
/nix/var/nix/profiles/default/bin/ils

Installation de paquets

Utilisation basique

  • Recherchez un package (exemple avec le paquet hello)
nix search nixpkgs hello

Il est également possible de chercher des paquets depuis le site web de Nix https://search.nixos.org/packages

  • Installer le paquet hello
$ nix profile install nixpkgs#hello
$ hello
Hello, world!
  • Installer le paquet ponysay, depuis l’ancien canal nixos-23.11 (tous les canaux disponibles sont listés sous https://channels.nixos.org/)
nix profile install nixpkgs/nixos-23.11#ponysay

Notez que le canal (toutes les expressions nixpkgs disponibles) est téléchargé et décompressé, si ce n’est déjà fait, dans un cache local. Ensuite, si le paquet et ses dépendances ne sont pas déjà disponibles dans le nix store, tout est téléchargé. Il est possible qu’un paquet ne soit pas disponible en paquet binaire, auquel cas, celui-ci sera automatiquement compilé.

  • Lister tous les paquets installés dans le profil actuel
$ nix profile list
Index:              0
Flake attribute:    legacyPackages.x86_64-linux.hello
Original flake URL: flake:nixpkgs
Locked flake URL:   github:NixOS/nixpkgs/6a39c6e495eefabc935d8ddf66aa45d85b85fa3f
Store paths:        /nix/store/y4qpcibkj767szhjb58i2sidmz8m24hb-hello-2.12.1

Index:              1
Flake attribute:    legacyPackages.x86_64-linux.ponysay
Original flake URL: flake:nixpkgs/nixos-23.11
Locked flake URL:   github:NixOS/nixpkgs/205fd4226592cc83fd4c0885a3e4c9c400efabb5
  • Mettre à niveau le paquet hello (ne fonctionne que pour les paquets installés sans une version donnée verrouillée -> donc avec nixpkgs#hello mais pas nixpkgs/nixos-23.11#hello)
nix profile upgrade 0
  • Si le paquet hello mis à niveau ne fonctionne pas comme prévu, il est possible de revenir à la version qui était disponible avant la mise à niveau :
nix profile rollback
  • Supprimer un paquet
nix profile remove legacyPackages.x86_64-linux.hello

Paquets depuis un dépôt NUR

NUR est un meta-dépôt de dépôts d’utilisateurs, permettant aux utilisateurs de partager des paquets personnalisés en dehors de Nixpkgs. GRICAD donne accès à son propre dépôt NUR qui est préconfiguré dans votre environnement Nix. Il contient généralement des versions préliminaires de paquets actuellement en cours de test avant leur intégration officielle dans Nixpkgs, ou des paquets avec des personnalisations locales spécifiques. Il contient également des paquets qui ne peuvent pas être distribués comme les compilateurs Intel. Pour ces paquets, les sources sont disponibles uniquement localement et les builds/installation des paquets sont impossibles en dehors de GRICAD.

Rechercher des paquets dans le dépôt NUR/GRICAD :

nix search nur#repos.gricad 'obitools'

Installer un paquet NUR/GRICAD :

nix profile install nur#repos.gricad.obitools3

Il est possible de contribuer aux paquets NUR de GRICAD. Vous pouvez simplement réaliser une requête de pull ici : https://github.com/Gricad/nur-packages

Applications vs Bibliothèques

Il est imortant de savoir qu’un paquet Nix peut être une application (un ensemble de binaires) ou une bibliothèque. Cependant, à l’intérieur d’un profil, vous ne devriez qu’installer des applications destinées aux utilisateurs finaux. Par exemple, il n’est pas recommandé d’installer un compilateur ou une bibliothèque de développement. Si vous avez besoin de compiler un programme, vous aurez probablement besoin de créer un nouveau paquet ou au moins utiliser nix shell (que nous verrons après).

  • Pour les paquets d’interpréteurs comme Python ou R, rendez vous à la section “Paquets spécifiques”.

  • Si vous avez besoin de compiler un logiciel, n’essayez pas d’installer des compilateurs pour le moment. Allez plutôt dans la section “Compilation…”

A propos des versions des paquets

Si vous le souhaitez, vous pouvez passer cette section qui n’est pas obligatoire pour la compréhension de l’usage de Nix sur les clusters GRICAD.

Comme nous l’avons vu précédemment, les canaux sont des versions stables (à l’exception du canal unstable) du dépôt nixpkgs. Ils permettent d’obtenir facilement une version plus ancienne d’un paquet. Une fois installé, un paquet n’a plus de lien avec le canal d’origine, mais il reste dans le store tant qu’il n’est utilisé par aucun profil. Cela signifie que l’on peut installer plusieurs versions d’un même paquet dans différents profils et avoir accès à n’importe quelle version, même si le paquet ne provient pas d’un canal stable.

À titre d’exemple, il est même possible d’installer un paquet en appelant directement son chemin d’accès dans le magasin. Il peut s’agir d’un élément que vous avez enregistré dans un fichier texte ou qui vous a été fourni par un autre utilisateur qui souhaite que vous testiez exactement la même version des binaires :

$ readlink $(which ponysay)
/nix/store/39nrz4ky69qxzciss59h9izx04lz4r13-ponysay-3.0.2/bin/ponysay

## Another user or you in another profile:
$ nix-env --switch-profile $NIX_USER_PROFILE_DIR/ponysay_ok
$ nix-env -i /nix/store/39nrz4ky69qxzciss59h9izx04lz4r13-ponysay-3.0.2

Ou vous pouvez directement appeler le binaire d’une version donnée

/nix/store/39nrz4ky69qxzciss59h9izx04lz4r13-ponysay-3.0.2/bin/ponysay --help

Flakes Nix

Flakes est une fonctionnalité à venir, qui est encore expérimentale, mais qui est tout de même fonctionnelle et recommandée. Cette fonctionnalité cherche à améliorer la reproductibilité, la composabilité et l’utilisabilité dans un ecosystème Nix. Vous pouvez trouver une introduction en suivant le lien https://www.tweag.io/blog/2020-05-25-flakes

Par défaut, cette fonctionnalité est activée sur les plateformes de calcul.

Les sections suivantes “Python packages”, “R packages”, “Nix shell”,… de cette documentation sont quasiment rendues obsolètes par flakes. Il est maintenant plus simple de télécharger un échantillon flake, de l’éditer et de l’utiliser. Voici une liste d’échantillons testés sur nos plateformes :

De tels flakes peuvent être utilisés comme environnements devel, appels d’interpreteurs directs ou installation de profil. Il vous suffit de télécharger le fichier flake.nix dans un répertoire vide, de le modifier si vous souhaitez le personnaliser (vérifiez les commentaires), et de le faire tourner. Flake créera un fichier flake.lock pour s’assurer que l’environnement reste inchangé, à moins que vous ne le mettiez à niveau. Grâce à cela, vos jobs sont indépendants de mises à niveau éventuelles du système hôte.

Voici un example de l’installation de Python avec des paquets dans un profil Nix :

# Create a new empty profile
nix-env --switch-profile $NIX_USER_PROFILE_DIR/MyPython

# Create an empty directory and get inside
mkdir MyPython
cd MyPython

# Get a sample working flake for python
wget https://raw.githubusercontent.com/bzizou/sysadmin/refs/heads/master/nix_environments/python3_pinned-flake/flake.nix

# Edit the file `flake.nix`
# You can customize it. In this example, you can replace the part under "HERE goes the Python packages list"
# by a list of already available packages. But you can also add non-standard packages that you would normally
# install with pip. Check the part "HERE goes the custom python packages definitions". You'll see that in
# this example, we compile a new fixed version of pip, under the "mypip" package.

# Install your environned python into your profile:
nix profile install

# Check:
nix profile list

# Run python and check that pip version is the same as given into the flake.nix file
python
>>> import pip
>>> print(pip.__version__)

Paquets Python

Comme précisé précédemment, il s’agit d’une ancienne documentation. L’utilisation de flakes est maintenant recomandée. Référez vous à Nix flakes.

Nix donne accès à Python ainsi qu’à de nombreux modules Python en paquets. Cependant, à cause de ses dépendances, un module Python ne peut pas être installé tout seul, mais doit l’être dans un environnement Python configuré. L’environnement GRICAD Nix est livré avec un fichier préconfiguré pour faciliter cette tâche.

Premièrement, il vous faut modifier le fichier de configuration nixpkgs afin de personnaliser votre liste de paquets Python :

vi ~/.config/nixpkgs/config.nix

Dans ce fichier, vous trouverez la section commençant par "# Python environment" et vous pouvez personnaliser la liste de paquets :

    # Python environment
    pythonEnv = pkgs.python3.withPackages (ps: with ps; [

          #################################################
          # You can list your python packages below and
          # install a python environement with:
          #      nix-env -f "<nixpkgs>" -iA pythonEnv
          #################################################
          numpy ipython virtualenv pip notebook

Ensuite, réalisez l’installation de l’environnement Python dans votre profil avec la commande :

nix-env -f "<nixpkgs>" -iA pythonEnv

Vous devriez ensuite voir python-env en paquet dans votre profil :

$ nix-env -q
python3-3.8.11-env

Si vous avez besoin d’une version spécifique de Python, vous pouvez changer la ligne pythonEnv = , par exemple :

## Latest Python 2:
    pythonEnv = pkgs.python2.withPackages (ps: with ps; [
## Python 3.7:
    pythonEnv = pkgs.python37.withPackages (ps: with ps; [

Installation des bibliothèques Python non disponible par Nix

Vous pourriez avoir besoin d’autres paquets Python qui ne sont pas disponibles dans Nix. Il vous faut alors créer un virtualenv et utiliser pip à l’intérieur. Vérifiez que vous avez installé un python-env (voir section ci-dessus) avec pip dans la liste de paquets, ensuite :

  • Créez un dossier pour votre environnement virtuel Python :
mkdir virtualenv
cd virtualenv
  • Créez un virtualenv test
python -m venv test
  • Chargez le virtualenv (faites le également pour le runtime)
source test/bin/activate
  • Installez ensuite les paquets avec pip
pip install <some_package>
  • Si vous avez des problèmes pendant le runtime avec des bibliothèques dynamiques non trouvées, vous pouvez essayer d’exporter les environnements de bibliothèque avant de faire tourner votre application Python :
export LD_LIBRARY_PATH=$(nix eval --raw nixpkgs.stdenv.cc.cc.lib)/lib

Ou avec nix >= 2.8 :

export LD_LIBRARY_PATH=$(nix --extra-experimental-features nix-command eval --impure --raw --expr 'with import <nixpkgs> {}; stdenv.cc.cc.lib')/lib
  • Vous devrez peut-être également fournir certaines dépendances de compilation. Voici un exemple avec HDF et le paquet colmet :
python -m venv colmet
source colmet/bin/activate
nix-env -iA hdf5
export HDF5_DIR=~.nix-profile
pip install colmet
## If your python module does not work with an environment variable, you can specify the external dependency installation PATH through a pip option as follows:
pip install --global-option=build_ext --global-option="-I/$HOME/.nix-profile/include" --global-option="-L/$HOME/.nix-profile/lib" colmet

Paquets R

La documentation officielle contient une section R

Comme précisé précédemment, il s’agit d’une ancienne documentation. L’utilisation de flakes est maintenant recomandée. Référez vous à Nix flakes.

Modules CRAN

Tous les modules CRAN sont disponibles dans la distribution Nixpkgs en tant que paquets. Vous pouvez vérifier la liste des librairies R disponibles avec la commande suivante :

$ nix-env -qaP -A rPackages

N’installez pas directement de modules R en paquets R dans votre environnement Nix. Ils seraient inutilisables en l’état. Ils doivent plutôt être installés ensemble pour pouvoir se trouver. Votre environnement GRICAD est pré-configuré avec un échantillon d’environnement R. Vous pouvez le personnaliner avant d’installer rEnv en ajoutant les modules nécessaires dans la section “# R environment” de .config/nixpkgs/config.nix :

## Open .config/nixpkgs/config.nix
vi .config/nixpkgs/config.nix
## Add the list of needed modules, with the name provided in the "-qaP -A rPackages" query
## For example:
   packageOverrides = pkgs: {

     # R environnement
     rEnv = pkgs.rWrapper.override {
       packages = with pkgs.rPackages; [

           #################################################
           # You can list your R packages below and intall
           # an R environement with:
           #      nix-env -f "<nixpkgs>" -iA rEnv
           #################################################
           optimx
           snow
           phylobase
           devtools
       ];
     };

Vous pouvez maintenant installer votre interpreteur d’environnement R :

nix-env -iA rEnv

Modules R depuis github

Dans les exemples de la section précédente, vous pouvez ajouter un module depuis Github avec buildRPackage (exemple avec lwgeom) :

   packageOverrides = pkgs: {

     # R environnement
     rEnv = pkgs.rWrapper.override {
       packages = with pkgs.rPackages; [

           #################################################
           # You can list your R packages below and intall
           # an R environement with:
           #      nix-env -f "<nixpkgs>" -iA rEnv
           #################################################
           optimx
           snow
           phylobase
           devtools
            (buildRPackage {
               name = "lwgeom";
               src = pkgs.fetchFromGitHub {
                 owner = "r-spatial";
                 repo = "lwgeom";
                 rev = "be10a443b17f361b73eae07ec11bbf31aa49fc87";
                 sha256 = "0nx8l8iqnjgv97rh9qd6z8zwh1b2l5w3fjk9xl7h6j1130pci0x0";
               };
            propagatedBuildInputs = with pkgs ; [ sqlite proj Rcpp units sf pkgconfig geos ];
            })
       ];
     };

Puis, comme vu dans la section précédente, installez votre environnement :

nix-env -iA rEnv

Les bibliothèques R nécessaires seront automatiquement créées !

Installing a R module locally

  • Créez un répertoire dans votre home, dans lequel vous stockerez les modules locaux, par exemple :
mkdir ~/my_r_libraries
  • Installez le module :
R CMD INSTALL --library=~/my_r_libraries ~/tmp/my_module.tgz

Ou ouvrez une console R et utilisez devtools :

# In an R console
> library(devtools)
> devtools::install_github(repo="nmatzke/BioGeoBEARS", INSTALL_opts="--byte-compile", dependencies=FALSE, lib="~/my_r_libraries")
  • Ensuite, pour charger le module (runtime) :
# In an R console
> .libPaths( c( .libPaths(), "~/my_r_libraries/") )
> library(my_module)

Nix-shell

Comme précisé précédemment, il s’agit d’une ancienne documentation. L’utilisation de flakes est maintenant recomandée. Référez vous à Nix flakes.

Utilisation basique

Nix-shell permet d’entrer dans un environnement d’un ou plusieurs paquets. Cette fonctionnalité n’est en général disponible que depuis les frontales des clusters mais certains hôtes peuvent avoir une configuration de re-routing permettant de l’utiliser également depuis les noeuds de calcul (C’est notamment le cas depuis le cluster Dahu).

Il n’est pas nécessaire d’installer un paquet dans un profil Nix pour utiliser nix-shell. Cela rend le processus utile pour faire tourner des applications directement depuis Nix, sans avoir besoin de l’installer.

Par exemple :

## Enter into the shell of the package 'cowsay'
$ nix-shell -p cowsay
[nix-shell:~]$ echo $buildInputs
/nix/store/cr23xzsbbvjgxaf1mchn2drhh6yvsq0q-cowsay-3.03+dfsg2

## Launch cowsay from a nix-shell, without installing the package
$ nix-shell -p cowsay --run "cowsay hello"

Améliorer son environnement en utilisant nix-shell

Nix-shell est une méthode très efficace pour la création d’un environnement reproductible. Vous pouvez créer un fichier default.nix contenant la description complète de ce qu’il faut installer dans votre environnement, avec par exemple une version épinglée de nixpkgs, des modules Python personnalisés, des bibliothèques de développement…

Voici un exemple commenté d’un fichier default.nix. Ce fichier peut être placé dans un répertoire de votre projet, et il vous suffira d’écrire nix-shell <ENTER> pour construire et entrer dans cet environnement.

# `default.nix` file for a reproducible environment containing
# python 3.8 and the opencv4 module with gtk support
#
# Pin the nixpkgs version
#
let
  hostPkgs = import <nixpkgs> {};
  pinnedPkgs = hostPkgs.fetchFromGitHub {
    owner = "NixOS";
    repo = "nixpkgs";
    rev = "22.05";
    sha256 = "1ckzhh24mgz6jd1xhfgx0i9mijk6xjqxwsshnvq789xsavrmsc36";
  };
in
# Add some customizations
let
  # Allow unfree packages
  pkgs = (import pinnedPkgs) {
  config = rec {
    allowUnfree = true;
    };
  };
  # Opencv is provided with no Gtk support by default, into nixpkgs
  # so, we create here an override to enable Gtk into our opencv environment
  opencvGtk = pkgs.python3.pkgs.opencv4.override (old : { enableGtk2 = true; });

# Create the shell
in with pkgs;
let
in mkShell rec {
  name = "python3shell";
  libPath = with pkgs ; lib.makeLibraryPath [
                          stdenv.cc.cc
                          zlib
                        ];
  # Here, we list some needed python modules, especialy our
  # overrided opencv one (opencvGtk)
  buildInputs = with python3.pkgs; [
    pip
    scipy
    matplotlib
    h5py
    opencvGtk
  ] ++ [ lsb-release ];

  # Shell hooks are here to help you customize your environment variables, alises,...
  # We even provide a way to install pip modules into the project directory
  shellHook = ''
    export LD_LIBRARY_PATH=${libPath}:$LD_LIBRARY_PATH
    alias pip="PIP_PREFIX='$(pwd)/_build/pip_packages' TMPDIR='$HOME' \pip"
    export PYTHONPATH="$(pwd)/_build/pip_packages/lib/python3.8/site-packages:$PYTHONPATH"
    export PATH="$(pwd)/_build/pip_packages/bin:$PATH"
    unset SOURCE_DATE_EPOCH
  '';
}

Vous pouvez trouver plus d’exemples customs d’environnements nix-shell ici :: https://github.com/bzizou/sysadmin/tree/master/nix_environments Pour plus d’infos sur nix-shell, vérifiez la documentation

Compilation et utilisation des programmes Openmpi (avec GCC)

Compilation

La meilleure façon de compiler un programme openmpi qui n’est pas déjà packagé est de créer un nouveau paquet. Cependant, dans certains cas, vous pouvez aussi essayer de le faire d’une façon plus directe (mais peu reproductible) en utilisant nix-shell :

$ nix-shell -p openmpi -p gcc
[nix-shell:~]$ mpicc -o hello_mpi hello_mpi.c
[nix-shell:~]$ exit

Exécution

Pour l’exécution, vous pouvez installer openmpi dans votre profil Nix :

nix-env -i -A openmpi

Notez que vous devez utiliser nix-shell pour la compilation et nix-env pour l’installation d’openmpi (runtime) dans une même session (même $NIX_PATH) afin d’éviter d’avoir une version différente d’openmpi lors de la compilation et lors de l’exécution.

Voici un échantillon d’un script OAR de soumission de job pour Dahu. Ce script fera tourner le programme résultant :

##!/bin/bash
##OAR -l /nodes=2/core=2
##OAR -t devel
##OAR --project myproject

## Ensure Nix is loaded. The following line can be into your ~/.bashrc file.
source /applis/site/nix.sh

## Run the program
mpirun --np `cat $OAR_FILE_NODES|wc -l` --machinefile $OAR_NODE_FILE --mca plm_rsh_agent "oarsh" --prefix $HOME/.nix-profile $OAR_WORKING_DIRECTORY/hello_mpi

Utilisation des compilateurs et des bibliothèques Intel

Les compilateurs et bibliothèques Intel sont des programmes propriétaires qui peuvent ne pas être distribuées normalement en tant que paquets gratuits. Nous avons donc créé un empaquetage pour CIMENT, dans le dossier GRICAD/Nur.

Utilisation rapide

Pour faciliter l’utilisation des compilateurs Intel, nous avons créé une variable d’environnement qui pointe directement vers une copie de ces compilateurs. L’utilisation de ceux-ci ne nécessite aucune connaissance spécifique de Nix. Utilisez simplement la variable $INTEL_ONEAPI comme dossier racine des compilateurs Intel. Voici un exemple pour compiler un programme mpi fortran utilisant fftw :

source /applis/site/nix.sh
source $INTEL_ONEAPI/setvars.sh
mpiifort -o main_FFTW main_FFTW.f90 -I$MKLROOT/include/fftw -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread -lm

ou pour la version 2024 :

source /applis/site/nix.sh
source $INTEL_ONEAPI_2024/setvars.sh
mpiifort -o main_FFTW main_FFTW.f90 -I$MKLROOT/include/fftw -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread -lm

Vous pouvez faire la même chose pour le runtime, ie source /appli/site/nix.sh && source $INTEL_ONEAPI/setvars.sh.

Installation

Pour un usage plus avancé, il se peut que vous deviez installer oneAPI d’Intel dans votre profil Nix.

Cela peut être fait soit en installant la version fixe:

nix-env -i $INTEL_ONEAPI_2024

soit en installant la plus récente depuis le dossier NUR de GRICAD :

NIX_PATH="nixpkgs=channel:nixos-23.11" nix-env -i nur.repos.gricad.intel-oneapi

Temps de compilation

  • Chargez les variables d’environnement sépcifiques pour les compilateurs Intel :
source ~/.nix-profile/setvars.sh

Le compilateur C icc et le compilateur Fortran ifort devraient désormais être disponibles. Le chemin d’accès aux bibliothèques est défini par la variable LIBRARY_PATH que vous devrez peut-être transmettre à vos scripts de compilation. La variable LD_LIBRARY_PATH contient également le chemin d’accès qui peut être nécessaire au moment de l’exécution.

La commande Intel mpi mpiicc devrait également être disponible.

  • Compilation
mpiicc -o hello_mpi hello_mpi.c

(notez le double ii dans mpiicc )

NOTE: vérifiez que vos binaires sont correctement liés par rapport aux bonnes bibliothèques en écrivant la commande ldd <binary_path>: la plupart des bibliothèques reportées devraient être localisées dans un chemin commençant par /nix.

NOTE: si vous avez besoin d’un chemin d’accès rapide aux bibliothèques, elles se trouvent toutes dans votre profil Nix : ~/.nix-profile. Par exemple, blacs se trouve dans ~/.nix-profile/mkl/latest/lib/intel64/.

Exécution

source ~/.nix-profile/setvars.sh
mpirun -n `cat $OAR_FILE_NODES|wc -l` -f $OAR_NODE_FILE -bootstrap-exec oarsh ./hello_mpi

Échantillon de paquet modifié pour l’utilisation du compilateur Intel : Lammps

Vous trouverez ici : https://github.com/Gricad/nur-packages/tree/master/pkgs/lammps un exemple d’un paquet nixpkgs qui a été modifié pour être compilé avec le compilateur Intel et Intel MPI.

Modification de paquet et recompilation, utilisation du dossier NUR de GRICAD

Vous pourriez avoir besoin de recompiler un paquet avec des modifications locales. Voici un exemple avec le paquet gdal que nous voulons en version 3.1.1 au lieu de la plus récente.

Il ne s’agit pas de que vous ferez si vous souhaitez contribuer au projet Nix avec une correction (il vaut mieux corriger directement le paquet sans changer son nom et soumettre vos modifications à l’équipe Nix, voir https://nixos.org/wiki/Create_and_debug_nix_packages pour plus d’informations). Mais de cette façon, vous pouvez tester les modifications apportées à votre paquet et commencer à l’utiliser directement avant de le soumettre au dépôt en amont.

Pour cette partie, vous aurez besoin d’un compte Github

  • Premièrement, récupérez une copie locale des définitions des paquets Nix (appelées expressions).
git clone https://github.com/NixOS/nixpkgs
git clone git@github.com:<your_user_name>/nur-packages.git
  • Entrez dans le dossier nur-packages et créez une nouvelle branche :
cd nur-packages
git checkout -b gdal-3.1.1

Notez que vous pouvez modifier la branche d’origine avant de la cloner, si vous ne souhaitez pas travailler avec le canal instable.

  • Créez un nouveau dossier si celui-ci n’est pas déjà présent et copiez la source du paquet gdal :
mkdir -p pkgs/gdal
cp ../nixpkgs/pkgs/development/libraries/gdal/default.nix pkgs/gdal/3.1.1.nix
  • Modifiez le fichier pkgs/gdal/3.1.1.nix et remplacez le numéro de version en haut de l’expression :
[...]
stdenv.mkDerivation rec {
  pname = "gdal";
  version = "3.1.1";

[...]
  • Nous aurons besoin du hash sha256 de cette version. Pour cela, utilisez l’outil nix-prefetch-github avec les valeurs de l’expression :
nix-shell -p nix-prefetch-github --run "nix-prefetch-github OSGeo gdal --rev v3.1.1"
## Then edit again pkgs/gdal/3.1.1.nix to replace the sha256 hash

Remplacez la ligne sha256 de pkgs/gdal/3.1.1.nix avec celle obtenue avec cette prélecture. Si vous ne le faites pas, vous continuerez de construire la version à partir du paquet, car c’est ce hash qui est utilisé pour obtenir la bonne version à partir du dépôt GitHub.

  • Modifiez le fichier default.nix qui contient la définition des paquets de ce dépôt Nur. Vous devez ajouter une entrée pour votre paquet personnalisé, par exemple gdal_311 :
  # gdal 3.1.1 version
  gdal_311 = pkgs.callPackage ./pkgs/gdal/3.1.1.nix { };
  • Construisez le paquet
## Not mandatory, but you might have to set your NIX_PATH to the unstable
## channel as we forked from the unstable channel (or switch to a stable
## channel before checking out the new git branch):

export NIX_PATH="nixpkgs=channel:nixpkgs-unstable"

## Start the build:

nix-build . -A gdal_311

Si cela échoue avec le message config.rpath' not found, ajoutez simplement la ligne preAutoreconf = "touch config.rpath"; dans l’expression et réessayez.

  • Exécution

Le paquet binaire résultant devrait être lié dans ./result:

$ ./result/bin/gdalinfo --version
GDAL 3.1.1, released 2020/06/22
  • Veuillez noter que les autres utilisateurs du même hôte pourraient installer votre paquet dans leurs profils en utilisant la destination du lien :
$ ls -l result
lrwxrwxrwx 1 bzizou users 54 Nov 16 17:43 result -> /nix/store/dz1spldnwwfwp7m4177gwwd20py4gj0z-gdal-3.1.1
$ nix-env -i /nix/store/dz1spldnwwfwp7m4177gwwd20py4gj0z-gdal-3.1.1
  • Si vous pensez que votre paquet personnalisé pourrait être utile aux autres utilisateurs de GRICAD, n’hésitez pas à commit, puis à pousser vos modifications avant de faire une requête de merge dans le dépôt nur-gricad.

Environnements de développement (usage avancé)

Il est possible de créer des environnements de développement isolés afin de :

  • ne pas interférer avec d’autres projets
  • pouvoir installer des librairies personnalisés, par exemple en Python
  • avoir une reproductibilité complète

Voici un exemple pour créer un environnement Python 3 avec le module netCDF4.

  • Créer un fichier default.nix avec le contenu :
with import <nixpkgs> {}; {
    pyEnv = stdenv.mkDerivation {
      name = "py";
      buildInputs = [ stdenv gcc zlib hdf5 python38Full netcdf python38Packages.numpy python38Packages.virtualenv ];
    };
}

Le buildInputs définit un ensemble de paquets Nix qui sont des dépendances nécessaires.

  • Maintenant, lancez une nix-shell pour entrer dans cet environnement isolé. À ce stade, les éléments peuvent être créés si les binaires ne se trouvent pas déjà dans le magasin Nix.
nix-shell

Cela nous emmène dans un shell.

  • Ensuite, vous pouvez créer un environnement virtuel Python et le charger :
python -m venv netcdf
source netcdf/bin/activate
  • Utilisez pip pour installer le module netCDF4 :
pip install netCDF4
  • Vous pouvez maintenant sortir du shell:
exit
  • Effectuez une sauvegarde de cet environement:
nix-instantiate --indirect --add-root $PWD/shell.drv
  • Cela vous permet de rentrer dans le même environnement :
nix-shell shell.drv
  • VOus pouvez l’utiliser depuis un script bash :
##!/usr/bin/env nix-shell
##!nix-shell -I shell.drv -i bash

source netcdf/bin/activate

export LD_LIBRARY_PATH="${NIX_LDFLAGS_FOR_TARGET// -L/:}"

which python
python -c "import netCDF4"