From 6b5204048b05bf16ba3db338a1f0ab3a66b38737 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franck=20P=C3=A9rignon?=
 <franck.perignon@univ-grenoble-alpes.fr>
Date: Fri, 13 Sep 2024 16:33:17 +0200
Subject: [PATCH] [cpu-intel-user:docker-build][[gpu-nvidia-user:docker-build]
 add docker images (mamba based) with user mode (rather than root) + jobs to
 build a docker image binder-complient

---
 .gitlab-ci.yml                           | 179 +++++++++++++++--
 ci/ci-templates.yml                      |  26 +--
 ci/docker_images/ci_cpu_intel/Dockerfile |   1 +
 ci/docker_images/ci_user/Dockerfile      | 245 +++++++++++++++++++++++
 ci/docker_images/lab-mamba/Dockerfile    |  41 ++++
 ci/hysopenv.yaml                         |  76 +++++++
 ci/hysopenv_cpu_intel.yaml               |   1 +
 ci/scripts/build_and_debug.sh            |  66 +++---
 ci/scripts/config.sh                     |   2 +-
 ci/scripts/run_examples.sh               |   4 +
 src/meson.build                          |   6 +
 11 files changed, 589 insertions(+), 58 deletions(-)
 create mode 100644 ci/docker_images/ci_user/Dockerfile
 create mode 100644 ci/docker_images/lab-mamba/Dockerfile
 create mode 100644 ci/hysopenv.yaml

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index a7e3ba336..9ec87b79d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -29,37 +29,72 @@ include:
 # Jobs to build docker images and save them into the Gitlab container registry
 ubuntu:cpu-intel:docker-build:
   variables:
-    DOCKERFILE_PATH: ci_cpu_intel
     IMAGE_NAME: ci_cpu_intel
+    DOCKER_TARGET: final-stage
+    RESULT_NAME: $CI_REGISTRY_IMAGE/ci_cpu_intel
   extends: .docker-build
   tags:
     - lmap
     - cpu
   rules:
-    - if: $CI_COMMIT_MESSAGE =~ /\[docker-build-cpu-intel\]/ || $CI_COMMIT_MESSAGE =~ /\[docker-build-all\]/
-      when: always
+    - if: $CI_COMMIT_MESSAGE =~ /\[docker-build\]/
+    - if: $CI_COMMIT_TAG
+    - if: $CI_COMMIT_MESSAGE =~ /\[docker-build-cpu-intel\]/
 
 ubuntu:gpu-nvidia:docker-build:
   variables:
-    DOCKERFILE_PATH: ci_gpu_nvidia
     IMAGE_NAME: ci_gpu_nvidia
+    DOCKER_TARGET: final-stage
+    RESULT_NAME: $CI_REGISTRY_IMAGE/ci_gpu_nvidia
   extends: .docker-build
   tags:
     - lmap
     - cpu
   rules:
-    - if: $CI_COMMIT_MESSAGE =~ /\[docker-build-gpu-nvidia\]/ || $CI_COMMIT_MESSAGE =~ /\[docker-build-all\]/
-      when: always
+    - if: $CI_COMMIT_MESSAGE =~ /\[docker-build\]/
+    - if: $CI_COMMIT_TAG
+    - if: $CI_COMMIT_MESSAGE =~ /\[docker-build-gpu-nvidia\]/
 
-###############
-## CPU Intel ##
-###############
+ubuntu:cpu-intel-user:docker-build:
+  variables:
+    IMAGE_NAME: ci_user
+    DOCKER_TARGET: hysop-final-cpu
+    RESULT_NAME: $CI_REGISTRY_IMAGE/ci_cpu_intel_user
+  extends: .docker-build
+  tags:
+    - lmap
+    - cpu
+  rules:
+    - if: $CI_COMMIT_MESSAGE =~ /\[docker-build\]/
+    - if: $CI_COMMIT_TAG
+    - if: $CI_COMMIT_MESSAGE =~ /\[cpu-intel-user:docker-build:\]/
+
+ubuntu:gpu-nvidia-user:docker-build:
+  variables:
+    IMAGE_NAME: ci_user
+    DOCKER_TARGET: hysop-final-gpu
+    RESULT_NAME: $CI_REGISTRY_IMAGE/ci_gpu_nvidia_user
+  extends: .docker-build
+  tags:
+    - lmap
+    - cpu
+  rules:
+    - if: $CI_COMMIT_MESSAGE =~ /\[docker-build\]/
+    - if: $CI_COMMIT_TAG
+    - if: $CI_COMMIT_MESSAGE =~ /\[gpu-nvidia-user:docker-build\]/
+
+##############################
+## CPU Intel                ##
+##############################
 config:ci-cpu-intel:
   variables:
-    IMAGE_NAME: $HYSOP_REGISTRY/ci_cpu_intel:latest
+    IMAGE_NAME: $HYSOP_REGISTRY/ci_cpu_intel_user:latest
   extends:
     - .hysop-configure
     - .lmap-cpu
+  needs:
+     - job: ubuntu:cpu-intel:docker-build # wait for docker image if docker build is on ...
+       optional: true
 
 build:ci-cpu-intel:
   variables:
@@ -95,14 +130,128 @@ examples:ci-cpu-intel:
 
 docker:hysop:cpu-intel:
   variables:
-    DOCKERFILE_PATH: hysop_cpu_intel
-    HYSOP_DOCKER_TARGET: hysop_cpu_intel
+    DOCKER_TARGET: hysop_cpu_intel
     IMAGE_NAME: hysop_cpu_intel
   extends:
     - .hysop-docker-hysop
     - .lmap-cpu
   needs: ["build:ci-cpu-intel", "test:ci-cpu-intel"]
 
+####################################
+## CPU Intel with a non root user ##
+####################################
+config:ci-cpu-intel-user:
+  variables:
+    IMAGE_NAME: $HYSOP_REGISTRY/ci_cpu_intel:latest
+  extends:
+    - .hysop-configure
+    - .lmap-cpu
+  needs:
+     - job: ubuntu:cpu-intel-user:docker-build # wait for docker image if docker build is on ...
+       optional: true
+
+build:ci-cpu-intel-user:
+  variables:
+      IMAGE_NAME: $HYSOP_REGISTRY/ci_cpu_intel:latest
+  needs: ["config:ci-cpu-intel-user"]
+  extends:
+    - .hysop-build
+    - .lmap-cpu
+
+install:ci-cpu-intel-user:
+  variables:
+      IMAGE_NAME: $HYSOP_REGISTRY/ci_cpu_intel:latest
+  needs: ["build:ci-cpu-intel-user"]
+  extends:
+    - .hysop-install
+    - .lmap-cpu
+
+test:ci-cpu-intel-user:
+  variables:
+      IMAGE_NAME: $HYSOP_REGISTRY/ci_cpu_intel:latest
+  needs: ["install:ci-cpu-intel-user"]
+  extends:
+    - .hysop-test
+    - .lmap-cpu
+
+examples:ci-cpu-intel-user:
+  variables:
+    IMAGE_NAME: $HYSOP_REGISTRY/ci_cpu_intel:latest
+  needs: ["install:ci-cpu-intel-user"]
+  extends:
+    - .hysop-examples
+    - .lmap-cpu
+
+# Jobs to create docker images with a full hysop install, ready to use as a notebook
+# First for binder ...
+binder:mamba:cpu:
+    variables:
+      IMAGE_NAME: lab-mamba
+      RESULT_NAME: $CI_REGISTRY/particle_methods/hysop_binder/hysopbinderlab
+      SICONOS_DOCKER_TARGET: binderlab
+    extends:
+      - .hysop-docker-hysop
+    needs: ["install:ci-cpu-intel-user"]
+
+# then for any user
+jupyterlab:mamba:cpu:
+    variables:
+      IMAGE_NAME: lab-mamba
+      RESULT_NAME: $CI_REGISTRY/particle_methods/hysop/hysoplab
+      SICONOS_DOCKER_TARGET: jupylab
+    extends:
+      - .hysop-docker-hysop
+    needs: ["binder:mamba"]
+
+#####################################
+## GPU nvidia with a non root user ##
+#####################################
+config:ci-gpu-nvidia-user:
+  variables:
+    IMAGE_NAME: $HYSOP_REGISTRY/ci_cpu_intel:latest
+  extends:
+    - .hysop-configure
+    - .lmap-cpu
+  needs:
+     - job: ubuntu:gpu-nvidia-user:docker-build # wait for docker image if docker build is on ...
+       optional: true
+
+build:ci-gpu-nvidia-user:
+  variables:
+      IMAGE_NAME: $HYSOP_REGISTRY/ci_cpu_intel:latest
+  needs: ["config:ci-gpu-nvidia-user"]
+  extends:
+    - .hysop-build
+    - .lmap-cpu
+
+install:ci-gpu-nvidia-user:
+  variables:
+      IMAGE_NAME: $HYSOP_REGISTRY/ci_cpu_intel:latest
+  needs: ["build:ci-gpu-nvidia-user"]
+  extends:
+    - .hysop-install
+    - .lmap-cpu
+
+test:ci-gpu-nvidia-user:
+  variables:
+      IMAGE_NAME: $HYSOP_REGISTRY/ci_cpu_intel:latest
+  needs: ["install:ci-gpu-nvidia-user"]
+  extends:
+    - .hysop-test
+    - .lmap-cpu
+
+examples:ci-gpu-nvidia-user:
+  variables:
+    IMAGE_NAME: $HYSOP_REGISTRY/ci_cpu_intel:latest
+  needs: ["install:ci-gpu-nvidia-user"]
+  extends:
+    - .hysop-examples
+    - .lmap-cpu
+
+
+
+
+
 ##################
 ##  Nvidia GPUs ##
 ##################
@@ -112,6 +261,9 @@ config:ci-gpu-nvidia:
   extends:
     - .hysop-configure
     - .hysop-gpu
+  needs:
+     - job: ubuntu:gpu-nvidia:docker-build # wait for docker image if docker build is on ...
+       optional: true
 
 build:ci-gpu-nvidia:
   variables:
@@ -147,8 +299,7 @@ examples:ci-gpu-nvidia:
 
 docker:hysop:gpu-nvidia:
   variables:
-    DOCKERFILE_PATH: hysop_gpu_nvidia
-    HYSOP_DOCKER_TARGET: hysop_gpu_nvidia
+    DOCKER_TARGET: hysop_gpu_nvidia
     IMAGE_NAME: hysop_gpu_nvidia
   extends:
     - .hysop-docker-hysop
diff --git a/ci/ci-templates.yml b/ci/ci-templates.yml
index 7ac6558a5..755470ad4 100644
--- a/ci/ci-templates.yml
+++ b/ci/ci-templates.yml
@@ -66,7 +66,8 @@ stages:
   # To run all tests
   - test
   # To create a Dockerfile with Hysop installed
-  - docker_hysop_img
+  - hysop_img_binder 
+  - hysop_img_lab
   # jobs run on images generated in previous stage, available in the project registry:
   # https://gricad-gitlab.univ-grenoble-alpes.fr/particle_methods/hysop/container_registry
   - doc
@@ -79,10 +80,7 @@ stages:
 .docker-rules:
    rules:
     - if: $CI_COMMIT_MESSAGE =~ /\[docker-build\]/
-      when: always
     - if: $CI_COMMIT_TAG
-      when: always
-    - when: never
 
 .docker-manual-rules:
     rules:
@@ -123,11 +121,13 @@ stages:
     entrypoint: [""]
   script:
     - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_DEPLOY_USER\",\"password\":\"$CI_DEPLOY_PASSWORD\"}}}" > /kaniko/.docker/config.json
+    - export DOCKERFILE_PATH=$CI_PROJECT_DIR/ci/docker_images/$IMAGE_NAME
     - /kaniko/executor
       --context $CI_PROJECT_DIR
-      --dockerfile $CI_PROJECT_DIR/ci/docker_images/$DOCKERFILE_PATH/Dockerfile
-      --destination $CI_REGISTRY_IMAGE/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA
-      --destination $CI_REGISTRY_IMAGE/$IMAGE_NAME:latest
+      --dockerfile $DOCKERFILE_PATH/Dockerfile
+      --target=$DOCKER_TARGET
+      --destination $RESULT_NAME:$CI_COMMIT_SHORT_SHA
+      --destination $RESULT_NAME:latest
       --single-snapshot
 
 .docker-build:
@@ -250,15 +250,17 @@ workflow:
   image:
     name: gcr.io/kaniko-project/executor:debug
     entrypoint: [""]
-  stage: docker_hysop_img
+  stage: hysop_img_binder
   script:
     - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_DEPLOY_USER\",\"password\":\"$CI_DEPLOY_PASSWORD\"}}}" > /kaniko/.docker/config.json
+    - export DOCKERFILE_PATH=$CI_PROJECT_DIR/ci/docker_images/$IMAGE_NAME
     - /kaniko/executor
       --build-arg    BUILD_DIR=$BUILD_DIR
       --build-arg    CI_PROJECT_DIR=$CI_PROJECT_DIR
       --context     $CI_PROJECT_DIR
-      --dockerfile  $CI_PROJECT_DIR/ci/docker_images/$DOCKERFILE_PATH/Dockerfile
-      --target=$HYSOP_DOCKER_TARGET
-      --destination $CI_REGISTRY_IMAGE/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA
-      --destination $CI_REGISTRY_IMAGE/$IMAGE_NAME:latest
+      --dockerfile  $DOCKERFILE_PATH/Dockerfile
+      --target=$DOCKER_TARGET
+      --destination $RESULT_NAME-$CI_COMMIT_REF_SLUG:latest
+      --destination $RESULT_NAME-$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHORT_SHA
       --single-snapshot
+      --cleanup
diff --git a/ci/docker_images/ci_cpu_intel/Dockerfile b/ci/docker_images/ci_cpu_intel/Dockerfile
index 0ea9a1bf2..7e7f24988 100644
--- a/ci/docker_images/ci_cpu_intel/Dockerfile
+++ b/ci/docker_images/ci_cpu_intel/Dockerfile
@@ -43,6 +43,7 @@ RUN apt update  && apt upgrade -y && apt install -y -qq \
     apt autoremove -y                                && \
     rm -rf /var/lib/apt/lists/*                      && \
     rm -rf $HOME/.cache/pip/*
+
 #
 # Install conda/mamba packages listed in ci/hysopenv_cpu_intel.yaml file
 #
diff --git a/ci/docker_images/ci_user/Dockerfile b/ci/docker_images/ci_user/Dockerfile
new file mode 100644
index 000000000..a75a02ba0
--- /dev/null
+++ b/ci/docker_images/ci_user/Dockerfile
@@ -0,0 +1,245 @@
+##
+## Copyright (c) HySoP 2011-2024
+##
+## This file is part of HySoP software.
+## See "https://particle_methods.gricad-pages.univ-grenoble-alpes.fr/hysop-doc/"
+## for further info.
+##
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
+##
+##     http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+##
+
+# This Dockerfiles contains all the stages required to build a Docker image
+#  with all the deps and setup required to build hysop
+# - on a cpu platform : target stage 'hysop-final-cpu'
+# - on a gpu platform : target stage 'hysop-final-gpu'
+
+
+# Docker muti-stage builds or buildkit (parallel stages)
+# https://docs.docker.com/build/building/multi-stage/
+#
+FROM mambaorg/micromamba AS hysop-base
+LABEL authors="hysop_team@univ-xxx.fr"
+USER root
+ENV DEBIAN_FRONTEND=noninteractive
+ENV PYTHON_EXECUTABLE=python3.12
+
+#
+# Install somme linux tools, compilers and libs
+#
+RUN apt update  && apt upgrade -y && apt install -y -qq \
+    wget                                                \
+    git-core                                            \
+    make                                                \
+    pkg-config                                          \
+    g++                                                 \
+    gfortran                                            \
+    # libopenmpi-dev                                      \
+    libclfft-dev                                     && \
+    apt autoclean  -y                                && \
+    apt autoremove -y                                && \
+    rm -rf /var/lib/apt/lists/*                      && \
+    rm -rf $HOME/.cache/pip/*
+
+RUN micromamba config prepend channels conda-forge && \
+    micromamba self-update && \
+    micromamba clean --all --yes
+
+ARG NB_USER=hysop-user
+ARG NB_UID=1000
+ENV USER ${NB_USER}
+ENV NB_UID ${NB_UID}
+ENV HOME /home/${NB_USER}
+ 
+RUN adduser --disabled-password \
+    --gecos "Default user" \
+    --uid ${NB_UID} \
+    ${NB_USER}
+    
+
+FROM hysop-base AS hysop-base-python
+USER hysop-user
+WORKDIR /home/hysop-user
+ARG PYTHON_VERSION=3.12.4
+ARG MAMBA_DOCKERFILE_ACTIVATE=1  # (otherwise python, cmake ... will not be found)
+#
+# Install conda/mamba packages listed in ci/hysopenv_cpu_intel.yaml file
+#
+ENV OMPI_FC gfortran
+ENV OMPI_CXX g++
+ENV OMPI_CC gcc
+COPY --chown=hysop-user:hysop-user  ci/hysopenv.yaml  /home/hysopenv.yaml
+RUN micromamba config prepend channels conda-forge                     && \
+    micromamba config set channel_priority strict                      && \
+    micromamba install -n base -y -f /home/hysopenv.yaml             && \
+    micromamba clean --all --yes
+
+
+########
+# HPTT # (longest time compilation)
+########
+FROM hysop-base-python AS hptt
+
+RUN git clone https://gitlab.com/keckj/hptt.git && \
+    cd hptt                                     && \
+    sed -i "s#-mavx##g" CMakeLists.txt          && \
+    sed -i "s#-march=native##g" CMakeLists.txt  && \
+    sed -i "s#-mtune=native##g" CMakeLists.txt
+RUN cmake -S hptt -B build-hptt -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX && \
+    cmake --build build-hptt -j$(nproc)                             && \
+    cmake --install build-hptt                             
+ENV HPTT_ROOT /opt/conda
+RUN cd hptt/pythonAPI                             && \
+    pip install --no-cache-dir --upgrade .                     
+RUN rm -rf hptt build-hptt
+
+#########
+# FLINT #
+#########
+FROM hysop-base-python AS flint
+
+#
+# python flint (FLINT2 + ARB + python-flint)
+#
+# flint 3.0.1 version is the last version (16 nov 2023)
+# (now ARB has been merged into flint 3)
+#
+RUN wget -q https://github.com/flintlib/flint/archive/refs/tags/v3.0.1.tar.gz  && \
+    tar -xzf v*.tar.gz                                                         && \
+    rm -f v*.tar.gz                                                            && \
+    mv flint* flint
+RUN cmake -S flint -B build-flint -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX && \  
+    cmake --build build-flint -j$(nproc)                                       && \
+    cmake --install build-flint
+# RUN rm -rf flint* build-flint
+
+#####################
+# HDF5_mpi and H5PY #
+#####################
+# NOT USED !
+FROM hysop-base-python  AS hdf5_mpi_h5py
+
+ENV MPICC "mpicc"
+ARG pip_install_opts='--upgrade --no-binary=h5py --no-deps --no-build-isolation'
+RUN wget -q https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.14/hdf5-1.14.3/src/hdf5-1.14.3.tar.gz && \
+    tar -xzf hdf5-*.tar.gz  && \
+    rm -f hdf5-*.tar.gz     
+RUN cd hdf5-*               && \
+    CC="${MPICC}" ./configure --prefix=$CONDA_PREFIX --enable-parallel     \
+                              --enable-shared=yes --enable-static=no && \
+    make -j$(nproc)         && \
+    make install            
+RUN rm -rf hdf5-*      && \
+    CC="${MPICC}" HDF5_MPI="ON" HDF5_VERSION="1.14.3"          \
+    HDF5_DIR=$CONDA_PREFIX H5PY_SETUP_REQUIRES=0                  \
+    pip install ${pip_install_opts} h5py==3.11.0
+
+##########
+# Stage  #
+##########
+FROM hysop-base-python  AS hysop-full-python
+
+# Some python packages are not available in micromamba!
+RUN pip install --no-cache-dir --upgrade    \
+    tee colors.py primefac   \
+    argparse_color_formatter \
+    memory-tempfile
+
+# gpyFFT
+# WARNING: Old package!
+RUN git clone https://github.com/geggo/gpyfft.git                           && \
+ cd gpyfft                                                                  && \
+ sed 's#finalize(self, _destroy_plan, self.plan)##' -i gpyfft/gpyfftlib.pyx && \
+ pip install --no-cache-dir . 
+RUN rm -rf gpyfft
+
+# #
+# FFTW latest version nov 2023
+# Compilation is necessary because there is no mpi version
+# with the float precisions requested by hysop (single, double, long)
+# --> indeed there is. See yaml file
+#
+# ENV FFTW_ROOT=$CONDA_PREFIX
+# RUN wget -q http://www.fftw.org/fftw-3.3.10.tar.gz && \
+# tar -xzf fftw-*.tar.gz                         && \
+# rm -f fftw-*.tar.gz                            && \
+#  cd fftw-*                                      && \
+#  ./configure --enable-openmp --enable-threads --enable-mpi --enable-shared --with-pic --prefix="${FFTW_ROOT}" --enable-single && \
+#  make -j$(nproc) && make install && make clean  && \
+#  ./configure --enable-openmp --enable-threads --enable-mpi --enable-shared --with-pic --prefix="${FFTW_ROOT}" && \
+#  make -j$(nproc) && make install && make clean  && \
+#  ./configure --enable-openmp --enable-threads --enable-mpi --enable-shared --with-pic --prefix="${FFTW_ROOT}" --enable-long-double && \
+#  make -j$(nproc) && make install && make clean
+# RUN rm -rf /tmp/fftw-*
+
+#
+# PYFFTW git version (last test: july 2024)
+# pyfftw is linked to fftw3 compiled above
+
+#ARG pip_install_opts='--no-binary=pyfftw --no-deps --no-build-isolation'
+ARG pip_install_opts='--no-cache-dir --no-binary=pyfftw --no-deps'
+RUN git clone https://github.com/pyFFTW/pyFFTW.git                           && \
+    cd pyFFTW                                                                && \
+#    PYFFTW_INCLUDE="/include"                                                   \
+    pip install ${pip_install_opts} .   
+RUN rm -rf pyFFTW
+
+###############
+# Final-Stage #
+###############
+FROM hysop-full-python AS hysop-final
+
+# Copy only necessary files from previous stages
+COPY --from=hptt /opt/conda/lib/*hptt* /opt/conda/lib
+COPY --from=hptt /opt/conda/include /opt/conda/include
+COPY --from=flint /opt/conda/include/flint /opt/conda/include/flint
+COPY --from=flint /opt/conda/lib/*flint* /opt/conda/lib
+# Copy only necessary parts of /opt/conda
+COPY --from=hptt /opt/conda/lib/python3.12/site-packages/hptt \
+                 /opt/conda/lib/python3.12/site-packages/hptt
+
+# Important for f2py command summit in meson build system!
+ENV MPIFC mpif90
+ENV MPICC mpicc
+ENV MPICXX mpic++
+ENV FC mpif90
+
+# Required to help meson finding packages
+ENV PKG_CONFIG_PATH /opt/conda/lib/pkgconfig 
+
+ARG MPI_HOME=/opt/conda
+ENV MPIRUN_EXECUTABLE="${MPI_HOME}/bin/mpirun"
+ENV MPIEXEC_EXECUTABLE="${MPI_HOME}/bin/mpiexec"
+
+RUN rm -rf $HOME/.cache/pip/*   && \
+    rm -rf /tmp/*
+
+
+# ---- cpu image ---
+FROM hysop-final AS hysop-final-cpu
+
+RUN micromamba install -n base -y  intel-opencl-rt && micromamba clean --all --yes
+
+
+# --- GPU image ---
+FROM hysop-final AS hysop-final-gpu
+
+USER root
+# Nvidia library path.
+# The nvidia libraries are intalled/copied when docker container is created!
+RUN echo "/usr/lib/x86_64-linux-gnu/libnvidia-opencl.so.1" > \
+         /opt/conda/etc/OpenCL/vendors/nvidia.icd
+
+USER hysop-user
+ENV NVIDIA_VISIBLE_DEVICES all
+ENV NVIDIA_DRIVER_CAPABILITIES compute,utility
+ENV PYOPENCL_COMPILER_OUTPUT=1
diff --git a/ci/docker_images/lab-mamba/Dockerfile b/ci/docker_images/lab-mamba/Dockerfile
new file mode 100644
index 000000000..bea4ed450
--- /dev/null
+++ b/ci/docker_images/lab-mamba/Dockerfile
@@ -0,0 +1,41 @@
+ARG REGISTRY=gricad-registry.univ-grenoble-alpes.fr
+ARG PROJECT=particle_methods/hysop
+ARG DEFAULT_IMAGE=ci_cpu_intel_user
+ARG IMAGENAME=$REGISTRY/$PROJECT/$DEFAULT_IMAGE
+
+FROM $IMAGENAME AS binderlab
+ENV WORK=/home/hysop-user
+WORKDIR $WORK
+ENV SHELL /bin/bash
+ENV PATH /opt/conda/bin:$PATH
+ENV MPIFC mpif90
+ENV MPICC mpicc
+ENV MPICXX mpic++
+ENV FC mpif90
+ARG MPI_HOME=/opt/conda
+ENV MPIRUN_EXECUTABLE="${MPI_HOME}/bin/mpirun"
+ENV MPIEXEC_EXECUTABLE="${MPI_HOME}/bin/mpiexec"
+
+# Required to help meson finding packages
+ENV PKG_CONFIG_PATH /opt/conda/lib/pkgconfig 
+
+
+ENV NVIDIA_VISIBLE_DEVICES all
+ENV NVIDIA_DRIVER_CAPABILITIES compute,utility
+ENV PYOPENCL_COMPILER_OUTPUT=1
+
+ARG MAMBA_DOCKERFILE_ACTIVATE=1  # (otherwise python, cmake ... will not be found)
+ARG BUILD_DIR /home/hysop-user/build
+ARG CI_PROJECT_DIR /home/hysop-user/hysop
+RUN meson $BUILD_DIR $CI_PROJECT_DIR
+RUN meson compile  -C $BUILD_DIR
+RUN meson install -C $BUILD_DIR
+
+FROM binderlab AS jupylab
+ENV JUPYTER_PORT=8888
+ENV JUPYTER_ENABLE_LAB yes
+EXPOSE $JUPYTER_PORT
+ENTRYPOINT ["/usr/local/bin/_entrypoint.sh", "/opt/conda/bin/jupyter", "lab","--ip=0.0.0.0","--allow-root", "--no-browser"]
+
+
+
diff --git a/ci/hysopenv.yaml b/ci/hysopenv.yaml
new file mode 100644
index 000000000..d25247755
--- /dev/null
+++ b/ci/hysopenv.yaml
@@ -0,0 +1,76 @@
+##
+## Copyright (c) HySoP 2011-2024
+##
+## This file is part of HySoP software.
+## See "https://particle_methods.gricad-pages.univ-grenoble-alpes.fr/hysop-doc/"
+## for further info.
+##
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
+##
+##     http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+##
+
+# This is the packages list required to compile hysop software
+# Works for cpu and gpu platforms.
+# 
+# Remarks:
+# - when running on a non-gpu platformyou also need to add the package 
+#   intel-opencl-rt
+#
+# - to use system mpi implementation, replace
+#   - openmpi 
+#   with
+#   - openmpi=x.y.z=external_*, x.y.z being the local mpi version
+#   See  "Forces conda to use system openmpi already installed!"
+# (https://conda-forge.org/docs/user/tipsandtricks.html#
+#          using-external-message-passing-interface-mpi-libraries)
+
+name: base
+channels:
+  - conda-forge
+dependencies:
+  - python=3.12
+  - clinfo
+  - cmake
+  - cython
+  - editdistance
+  - gmpy2
+  - jsonpickle
+  - matplotlib
+  - meson
+  - meson-python # need for pip install --no-build-isolation --no-deps .
+  - mpi4py
+  - networkx
+  - ninja
+  - numba
+  - numcodecs
+  - numpy
+  - openmpi # no hack for mpi, use conda
+  - portalocker
+  - psutil
+  - py-cpuinfo
+  - pyopencl==2024.1
+  - pytest
+  - python-flint
+  - pyvis
+  - scipy
+  - sympy
+  - wheel
+  - zarr
+  - hdf5=*=mpi*
+  - h5py=*=mpi*
+  - fftw=*=mpi*
+  - tox
+channels:
+  - numba
+dependencies:
+  - llvmlite
+
diff --git a/ci/hysopenv_cpu_intel.yaml b/ci/hysopenv_cpu_intel.yaml
index 3cbcc932c..accb71ca7 100644
--- a/ci/hysopenv_cpu_intel.yaml
+++ b/ci/hysopenv_cpu_intel.yaml
@@ -21,6 +21,7 @@ name: base
 channels:
   - conda-forge
 dependencies:
+  - python=3.12
   - clinfo
   - cmake
   - cython
diff --git a/ci/scripts/build_and_debug.sh b/ci/scripts/build_and_debug.sh
index b5e92186d..fe5908cd9 100755
--- a/ci/scripts/build_and_debug.sh
+++ b/ci/scripts/build_and_debug.sh
@@ -20,38 +20,42 @@
 ##
 set -feu -o pipefail
 
-PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE:-"$(which python3)"}
-PYTHON_INCLUDE_DIR=$(${PYTHON_EXECUTABLE} -c "import sysconfig as sc; print(sc.get_paths()['include'])")
-PYTHON_LIBRARY=$(${PYTHON_EXECUTABLE} -c "import sysconfig as sc, os; print(os.path.normpath(os.path.sep.join(sc.get_config_vars('LIBDIR', 'INSTSONAME'))))")
+# Ensure that required variables are set.
+: ${CI_PROJECT_DIR:?"Please set environment variable CI_PROJECT_DIR equal to the path to hysop sources."}
+
+BUILD_DIR="${BUILD_DIR:=$HOME/build}"
+
+meson setup $BUILD_DIR $CI_PROJECT_DIR
+meson compile -C $BUILD_DIR
 
 # /hysop should be mounted as read only by run_tests_in_docker.sh
-if [[ ! -d '/hysop' ]]; then
-    echo "This script should not be called from host, but from within a docker image."
-    echo " => /hysop has not been mounted (see hysop/ci/utils/run_debug.sh)."
-    exit 1
-fi
-
-CC=gcc
-CXX=g++
-FC=gfortran
-
-HYSOP_DIR='/tmp/hysop'
-
-cp -r /hysop "${HYSOP_DIR}"
-find "${HYSOP_DIR}" -name '*.sh' -exec sed -i 's/\r//' '{}' \;
-rm -rf "${HYSOP_DIR}/build"
-
-cd "${HYSOP_DIR}"
-mkdir build
-cd build
-cmake -DCMAKE_BUILD_TYPE=Debug -DVERBOSE=OFF -DWITH_SCALES=ON -DFIND_FFTW_STATIC_ONLY=ON -DFIND_FFTW_VERBOSE=ON -DPython3_EXECUTABLE="${PYTHON_EXECUTABLE}" -DPython3_INCLUDE_DIR="${PYTHON_INCLUDE_DIR}" -DPython3_LIBRARY="${PYTHON_LIBRARY}" ..
-make -j8
-make install
-cd -
-rm -rf build
-
-export OMPI_ALLOW_RUN_AS_ROOT=1
-export OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1
-export OMPI_MCA_rmaps_base_oversubscribe=1
+#if [[ ! -d '/hysop' ]]; then
+#    echo "This script should not be called from host, but from within a docker image."
+#    echo " => /hysop has not been mounted (see hysop/ci/utils/run_debug.sh)."
+#    exit 1
+#fi
+
+##CC=gcc
+#CXX=g++
+#FC=gfortran
+
+#HYSOP_DIR='/tmp/hysop'
+
+#cp -r /hysop "${HYSOP_DIR}"
+#find "${HYSOP_DIR}" -name '*.sh' -exec sed -i 's/\r//' '{}' \;
+#rm -rf "${HYSOP_DIR}/build"
+
+#cd "${HYSOP_DIR}"
+#mkdir build
+#cd build
+#cmake -DCMAKE_BUILD_TYPE=Debug -DVERBOSE=OFF -DWITH_SCALES=ON -DFIND_FFTW_STATIC_ONLY=ON -DFIND_FFTW_VERBOSE=ON -DPython3_EXECUTABLE="${PYTHON_EXECUTABLE}" -DPython3_INCLUDE_DIR="${PYTHON_INCLUDE_DIR}" -DPython3_LIBRARY="${PYTHON_LIBRARY}" ..
+#make -j8
+#make install
+#cd -
+#rm -rf build
+
+#export OMPI_ALLOW_RUN_AS_ROOT=1
+#export OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1
+#export OMPI_MCA_rmaps_base_oversubscribe=1
 
 bash
diff --git a/ci/scripts/config.sh b/ci/scripts/config.sh
index e34fe884d..034997e86 100755
--- a/ci/scripts/config.sh
+++ b/ci/scripts/config.sh
@@ -22,7 +22,7 @@
 set -feu -o pipefail
 
 # Ensure that required variables are set.
-: ${CI_PROJECT_DIR:?"Please set environment variable CI_PROJECT_DIR with 'hysop' repository (absolute) path."}
+#: ${CI_PROJECT_DIR:?"Please set environment variable CI_PROJECT_DIR with 'hysop' repository (absolute) path."}
 : ${BUILD_DIR:?"Please set environment variable BUILD_DIR to the required build path."}
 #: ${INSTALL_DIR:?"Please set environment variable INSTALL_DIR to the expected install path."}
 
diff --git a/ci/scripts/run_examples.sh b/ci/scripts/run_examples.sh
index 613bf7ddb..b69abfcad 100755
--- a/ci/scripts/run_examples.sh
+++ b/ci/scripts/run_examples.sh
@@ -20,6 +20,10 @@
 ##
 set -feu -o pipefail
 
+# Ensure that required variables are set.
+: ${EXAMPLE_DIR:?"Please set environment variable EXAMPLE_DIR to the required build path."}
+
+
 PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE:-"$(which python3)"}
 
 COMMON_EXAMPLE_OPTIONS='-VNC -d16 -cp float -maxit 2 --autotuner-max-candidates 1 --save-checkpoint --checkpoint-dump-freq 0 --checkpoint-dump-period 0 --checkpoint-dump-last --checkpoint-dump-times'
diff --git a/src/meson.build b/src/meson.build
index b60d16d30..99487c0c2 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -109,6 +109,7 @@ if use_mpi == 'ON' # Have to be ON! OFF is deprecated!
   if use_fortran == 'ON'
     # - Looking for mpi lib for fortran.
     mpi_dep = dependency('mpi', language: 'fortran')
+    
     static_library_dep    += [mpi_dep]
 
     if mpi_dep.found()
@@ -154,7 +155,12 @@ if with_fftw == 'ON'
 
   # - Looking for fft3w or fft3wf or fftw3l (/usr/local/lib/pkgconfig)
   fft_dep     = dependency(         'fftw3', required:true)
+   
+  if not fft_dep.found()
+     message('raté')
+  endif 
 
+  
   if fft_dep.found()
      fft_lib_path = fft_dep.get_variable(default_value: '"libdir" in pkgconfig not available!',
                                          pkgconfig    : 'libdir')
-- 
GitLab