diff --git a/.gitignore b/.gitignore
index 9fbfccca6dfda997d8a0dbfc4b373590feeecad8..f3571f3fefd133675c1989b50247a12d107bc685 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
+# common
+.cache
+
 # C++ Build
 build*/
 install*/
@@ -10,6 +13,9 @@ install*/
 __pycache__
 *.pyc
 *.egg-info
+dist*/
+wheelhouse/*
+_version.py
 
 # Mermaid
 *.mmd
@@ -18,4 +24,4 @@ __pycache__
 xml*/
 
 # ONNX
-*.onnx
\ No newline at end of file
+*.onnx
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 271581e4d845ea93d5fd3a09f471edec69913277..1c2606707d16cd401e575354a1cbb99a11451ff8 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,39 +1,64 @@
-################################################################################
-# Pre-configured CI/CD for your Aidge module.
-#
-# Three stages are already pre-configured to run on Eclipse Aidge CI:
-# - build: ubuntu_cpp, ubuntu_python and windows_cpp;
-# - test: ubuntu_cpp, ubuntu_python and windows_cpp;
-# - coverage: ubuntu_cpp and ubuntu_python.
-#
-# If your project is pure C++ or pure Python, you can remove the "_python" or 
-# "_cpp" jobs respectively.
-# "ubuntu" jobs require an Ubuntu runner with a docker executor with tag 
-# "docker".
-# "windows" jobs require a Windows runner with a docker-windows executor with 
-# tag "windows".
-#
-# You can change the docker images in the YML scripts directly. The default 
-# images are:
-# - nvidia/cuda:12.2.0-devel-ubuntu22.04 for Ubuntu jobs;
-# - buildtools for Windows jobs, built on top of 
-#   mcr.microsoft.com/windows/servercore:ltsc2022 with Microsoft Visual Studio 
-#   2022 BuildTools installed.
-#
-# See Aidge project wiki for more details on how to setup your own docker images
-# and Gitlab runners.
-################################################################################
+###############################################################################
+#                Aidge Continuous Integration and Deployment                  #
+#                                                                             #
+###############################################################################
 
 stages:
-  # Build
+  - static_analysis
   - build
-  # Unit test stage
   - test
-  # Code coverage
   - coverage
+  - release
+  - deploy
 
 include:
-  - local: '/.gitlab/ci/_global.gitlab-ci.yml'
-  - local: '/.gitlab/ci/build.gitlab-ci.yml'
-  - local: '/.gitlab/ci/test.gitlab-ci.yml'
-  - local: '/.gitlab/ci/coverage.gitlab-ci.yml'
+  - project: 'eclipse/aidge/gitlab_shared_files' 
+    ref: 'main'
+    file: 
+      # choose which jobs to run by including the corresponding files.
+      - '.gitlab/ci/ubuntu_cpp.gitlab-ci.yml'
+
+      - '.gitlab/ci/ubuntu_python.gitlab-ci.yml'
+      - '.gitlab/ci/release/cibuildwheel_ubuntu.gitlab-ci.yml'   
+
+      # - '.gitlab/ci/windows_cpp.gitlab-ci.yml'
+
+      # - '.gitlab/ci/windows_python.gitlab-ci.yml'   
+      # - '.gitlab/ci/release/cibuildwheel_windows.gitlab-ci.yml'   
+
+
+release:pip:ubuntu:
+  tags: 
+    - release:cuda
+  variables:
+    DOCKER_HOST: unix:///var/run/docker.sock
+    CIBW_ENVIRONMENT: >-
+      BUILD_WITH_CUDA=1
+      AIDGE_DEPENDENCIES='aidge_core aidge_backend_cpu'
+      AIDGE_INSTALL='/AIDGE_INSTALL_CIBUILDWHEEL'
+      CUDA_TOOLKIT_VERSION='11-8'
+      DOCKER_HOST='unix:///var/run/docker.sock'
+      ARCH='x86_64'
+      CUDNN_VERSION='9'
+      CUDA_MAJOR_VERSION='11'
+      CUDA_MINOR_VERSION='8'
+      SEARCH_PATH='/home/ubuntu/builds/$CI_RUNNER_SHORT_TOKEN/$CI_CONCURRENT_ID'
+
+  parallel:
+    matrix:
+      - CIBW_BUILD: "cp38-manylinux_x86_64"
+      - CIBW_BUILD: "cp39-manylinux_x86_64"
+      - CIBW_BUILD: "cp310-manylinux_x86_64"
+
+  before_script:
+    # retrieve aidge dependencies
+    - DEPENDENCY_JOB="build:ubuntu_python"
+    - !reference [.ubuntu:download:repositories, before_script] # located in common.gitlab-ci.yml
+
+  script:
+    - /home/ubuntu/.local/bin/cibuildwheel --output-dir wheelhouse
+
+  after_script:
+    # Ensure all files are owned by the correct user at the end of the job
+    - sudo chown -R $(whoami):$(whoami) .
+
diff --git a/.gitlab/ci/_global.gitlab-ci.yml b/.gitlab/ci/_global.gitlab-ci.yml
deleted file mode 100644
index ccc83c5d24623f1f00eaa78bc596f0cb1ff429dc..0000000000000000000000000000000000000000
--- a/.gitlab/ci/_global.gitlab-ci.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-################################################################################
-# Centralized definitions of common job parameter values.                      #
-# Parameters with many optional configurations may be in separate files.       #
-#                                                                              #
-################################################################################
-variables:
-  GIT_SUBMODULE_STRATEGY: recursive
-  OMP_NUM_THREADS: 4
-  GIT_SSL_NO_VERIFY: 1
-  DEBIAN_FRONTEND: noninteractive
-
-# See https://docs.gitlab.com/ee/ci/yaml/workflow.html#switch-between-branch-pipelines-and-merge-request-pipelines
-workflow:
-  rules:
-    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
-    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
-      when: never
-    - if: $CI_COMMIT_BRANCH
-
-default:
-  image: nvidia/cuda:12.2.0-devel-ubuntu22.04
-  before_script:
-    - apt update
-    - apt install -y cmake cppcheck python-is-python3 pip git gcovr unzip curl
-    - apt install -y libcudnn8-dev
diff --git a/.gitlab/ci/build.gitlab-ci.yml b/.gitlab/ci/build.gitlab-ci.yml
deleted file mode 100644
index e1b464af5c188a05f8951d5c834c8fde0a2dbcf9..0000000000000000000000000000000000000000
--- a/.gitlab/ci/build.gitlab-ci.yml
+++ /dev/null
@@ -1,244 +0,0 @@
-include:
-  - project: 'eclipse/aidge/gitlab_shared_files'
-    ref: 'main'
-    file: 
-      - '.gitlab/ci/shared_script.gitlab-ci.yml'
-
-build:ubuntu_cpp:
-  stage: build
-  needs: []
-  tags:
-    - docker
-
-  script:
-    # Download dependencies
-    - DEPENDENCY_JOB="$CI_JOB_NAME"
-    # aidge_core
-    - DEPENDENCY_NAME="aidge_core"
-    - !reference [.download_dependency, script]
-    # aidge_backend_cpu
-    - DEPENDENCY_NAME="aidge_backend_cpu"
-    - !reference [.download_dependency, script]
-
-    # Build current module
-    - export CMAKE_PREFIX_PATH=../install_cpp
-    - mkdir -p build_cpp
-    - cd build_cpp
-    - cmake -DCMAKE_INSTALL_PREFIX:PATH=../install_cpp -DCMAKE_BUILD_TYPE=Debug -DWERROR=ON -DCOVERAGE=ON ..
-    - make -j4 all install
-
-  artifacts:
-    expire_in: 1 week
-    paths:
-      - build_cpp/
-      - install_cpp/
-
-build:ubuntu_cpp_g++10:
-  stage: build
-  needs: []
-  tags:
-    - docker
-
-  script:
-    # Download dependencies
-    - DEPENDENCY_JOB="build:ubuntu_cpp_g++:\ [10]"
-    # aidge_core
-    - DEPENDENCY_NAME="aidge_core"
-    - !reference [.download_dependency, script]
-    # aidge_backend_cpu
-    - DEPENDENCY_NAME="aidge_backend_cpu"
-    - !reference [.download_dependency, script]
-
-    # Build current module
-    - export CMAKE_PREFIX_PATH=../install_cpp
-    - apt install -y g++-10
-    - mkdir -p build_cpp
-    - mkdir -p install_cpp
-    - cd build_cpp
-    - export CXX=/usr/bin/g++-10
-    - cmake -DCMAKE_INSTALL_PREFIX:PATH=../install_cpp -DCMAKE_BUILD_TYPE=Debug -DWERROR=ON -DCOVERAGE=OFF ..
-    - make -j4 all install
-
-build:ubuntu_cpp_g++12:
-  stage: build
-  needs: []
-  tags:
-    - docker
-
-  script:
-    # Download dependencies
-    - DEPENDENCY_JOB="build:ubuntu_cpp:g++:\ [12]"
-    # aidge_core
-    - DEPENDENCY_NAME="aidge_core"
-    - !reference [.download_dependency, script]
-    # aidge_backend_cpu
-    - DEPENDENCY_NAME="aidge_backend_cpu"
-    - !reference [.download_dependency, script]
-
-
-    # Build current module
-    - export CMAKE_PREFIX_PATH=../install_cpp
-    - apt install -y g++-12
-    - mkdir -p build_cpp
-    - mkdir -p install_cpp
-    - cd build_cpp
-    - export CXX=/usr/bin/g++-12
-    - cmake -DCMAKE_INSTALL_PREFIX:PATH=../install_cpp -DCMAKE_BUILD_TYPE=Debug -DWERROR=ON -DCOVERAGE=OFF -DPYBIND=0 -DCMAKE_EXPORT_COMPILE_COMMANDS=1 ..
-    - make -j4 all install
-
-build:ubuntu_cpp_clang12:
-  stage: build
-  needs: []
-  tags:
-    - docker
-
-  script:
-    # Download dependencies
-    - DEPENDENCY_JOB="build:ubuntu_cpp:clang:\ [12]"
-    # aidge_core
-    - DEPENDENCY_NAME="aidge_core"
-    - !reference [.download_dependency, script]
-    # aidge_backend_cpu
-    - DEPENDENCY_NAME="aidge_backend_cpu"
-    - !reference [.download_dependency, script]
-
-
-    # Build current module
-    - export CMAKE_PREFIX_PATH=../install_cpp
-    - apt install -y clang-12
-    - mkdir -p build_cpp
-    - mkdir -p install_cpp
-    - cd build_cpp
-    - export CXX=/usr/bin/clang++-12
-    - cmake -DCMAKE_INSTALL_PREFIX:PATH=../install_cpp -DCMAKE_BUILD_TYPE=Debug -DWERROR=ON -DCOVERAGE=OFF ..
-    - make -j4 all install
-
-build:ubuntu_cpp_clang15:
-  stage: build
-  needs: []
-  tags:
-    - docker
-
-  script:
-    # Download dependencies
-    - DEPENDENCY_JOB="build:ubuntu_cpp:clang:\ [15]"
-    # aidge_core
-    - DEPENDENCY_NAME="aidge_core"
-    - !reference [.download_dependency, script]
-    # aidge_backend_cpu
-    - DEPENDENCY_NAME="aidge_backend_cpu"
-    - !reference [.download_dependency, script]
-
-    # Build current module
-    - export CMAKE_PREFIX_PATH=../install_cpp
-    - apt install -y clang-15
-    - mkdir -p build_cpp
-    - mkdir -p install_cpp
-    - cd build_cpp
-    - export CXX=/usr/bin/clang++-15
-    - cmake -DCMAKE_INSTALL_PREFIX:PATH=../install_cpp -DCMAKE_BUILD_TYPE=Debug -DWERROR=ON -DCOVERAGE=OFF ..
-    - make -j4 all install
-
-build:ubuntu_python:
-  stage: build
-  needs: []
-  tags:
-    - docker
-
-  script:
-    # Download dependencies
-    - DEPENDENCY_JOB="build:ubuntu_python"
-    # aidge_core (python)
-    - DEPENDENCY_NAME="aidge_core"
-    - !reference [.download_dependency, script]
-    # aidge_backend_cpu (python)
-    - DEPENDENCY_NAME="aidge_backend_cpu"
-    - !reference [.download_dependency, script]
-
-    - python3 -m pip install virtualenv
-    - virtualenv venv
-    - source venv/bin/activate
-    - python3 -m pip install -r requirements.txt
-    - python3 -m pip install .
-
-  artifacts:
-    expire_in: 1 week
-    paths:
-      - venv/
-
-# build:windows_cpp:
-#   stage: build
-#   needs: []
-#   tags:
-#     - windows
-
-#   image: buildtools
-#   before_script:
-#     # Install Chocolatey
-#     - Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
-#     # Install dependencies
-#     - choco install cmake.install --installargs '"ADD_CMAKE_TO_PATH=System"' -Y
-#     - choco install git -Y
-#     - choco install python -Y
-#     - choco install cuda -Y
-#     # Update PATH
-#     - $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
-#   script:
-#     # Download dependencies
-#     # aidge_core
-#     - 'curl "https://gitlab.eclipse.org/api/v4/projects/5139/jobs/artifacts/main/download?job=build:windows_cpp" -o build_artifacts.zip'
-#     - Expand-Archive -Path .\build_artifacts.zip -DestinationPath . -Force
-#     - Remove-Item .\build_cpp\ -Recurse
-#     # aidge_backend_cpu
-#     - 'curl "https://gitlab.eclipse.org/api/v4/projects/5140/jobs/artifacts/main/download?job=build:windows_cpp" -o build_artifacts.zip'
-#     - Expand-Archive -Path .\build_artifacts.zip -DestinationPath . -Force
-#     - Remove-Item .\build_cpp\ -Recurse
-
-#     - $env:CMAKE_PREFIX_PATH = '../install_cpp'
-#     - mkdir -p build_cpp
-#     - cd build_cpp
-#     - cmake -DCMAKE_INSTALL_PREFIX:PATH=../install_cpp -DCMAKE_BUILD_TYPE=Debug ..
-#     - cmake --build . -j2
-#     - cmake --install . --config Debug
-
-#   artifacts:
-#     expire_in: 1 week
-#     paths:
-#       - build_cpp/
-#       - install_cpp/
-
-# build:windows_python:
-#   stage: build
-#   needs: []
-#   tags:
-#     - windows
-
-#   image: buildtools
-#   before_script:
-#     # Install Chocolatey
-#     - Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
-#     # Install dependencies
-#     - choco install cmake.install --installargs '"ADD_CMAKE_TO_PATH=System"' -Y
-#     - choco install git -Y
-#     - choco install python -Y
-#     - choco install cuda -Y
-#     # Update PATH
-#     - $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
-#   script:
-#     # Download dependencies
-#     # aidge_core (Python)
-#     - 'curl "https://gitlab.eclipse.org/api/v4/projects/5139/jobs/artifacts/main/download?job=build:windows_python" -o build_artifacts.zip'
-#     - Expand-Archive -Path .\build_artifacts.zip -DestinationPath . -Force
-#     # aidge_backend_cpu (Python)
-#     - 'curl "https://gitlab.eclipse.org/api/v4/projects/5140/jobs/artifacts/main/download?job=build:windows_python" -o build_artifacts.zip'
-#     - Expand-Archive -Path .\build_artifacts.zip -DestinationPath . -Force
-
-#     - python -m pip install virtualenv
-#     - virtualenv venv
-#     - venv\Scripts\Activate.ps1
-#     - python -m pip install -r requirements.txt
-#     - python -m pip install .
-#   artifacts:
-#     expire_in: 1 week
-#     paths:
-#       - venv/
diff --git a/.gitlab/ci/cibuildwheel_build_deps_before_build_wheel.ps1 b/.gitlab/ci/cibuildwheel_build_deps_before_build_wheel.ps1
new file mode 100644
index 0000000000000000000000000000000000000000..c2715ea5550432838d3cc8692e97204b278d2c85
--- /dev/null
+++ b/.gitlab/ci/cibuildwheel_build_deps_before_build_wheel.ps1
@@ -0,0 +1,23 @@
+$ErrorActionPreference = "Stop"
+
+# Retrieve and clean the dependencies string from the environment variable
+$AIDGE_DEPENDENCIES = $env:AIDGE_DEPENDENCIES -split ' '
+Write-Host "Aidge dependencies : $AIDGE_DEPENDENCIES"
+if ( $($AIDGE_DEPENDENCIES.Length) -eq 0) {
+        Write-Host "- No dependencies provided for current repsitory"
+        New-Item -ItemType Directory -Force -Path ".\build" | Out-Null
+        Remove-Item -Path ".\build\*" -Recurse -Force
+    } else {
+        Write-Host "Retrieving given dependencies to build current package : $AIDGE_DEPENDENCIES"
+    foreach ($dep in $($AIDGE_DEPENDENCIES -split " ")) {
+        Write-Host "Retrieving : $dep"
+        $curr_loc=$(Get-Location)
+        Set-Location ../$dep
+        Get-Location 
+        Get-ChildItem .
+        New-Item -Path ".\build" -ItemType Directory -Force | Out-Null
+        Get-ChildItem -Path ".\build" -File | Remove-Item -Force
+        python -m pip install . -v
+        Set-Location $curr_loc
+    }
+}
diff --git a/.gitlab/ci/cibuildwheel_build_deps_before_build_wheel.sh b/.gitlab/ci/cibuildwheel_build_deps_before_build_wheel.sh
new file mode 100755
index 0000000000000000000000000000000000000000..4f74488ae41714a4ce03ba7514bf93842768c5ae
--- /dev/null
+++ b/.gitlab/ci/cibuildwheel_build_deps_before_build_wheel.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+set -e
+if [[ "$1" == "" ]]; then 
+  echo "build aidge deps in cibuildwheel container before building wheel."
+  echo "search path defines where the dependencies will be searched."
+  echo "Hint : In wheel containers, files are mounted on /host by default."
+  echo "\nusage : ./cibuildwheel_build_deps_before_build_wheel.sh $search_path"
+fi
+set -x
+if [[ $AIDGE_DEPENDENCIES ==  "" ]]; then # case for aidge_ core
+  mkdir -p build # creating build if its not already there to hold the build of cpp files
+  rm -rf build/* # build from scratch
+else 
+  for repo in $AIDGE_DEPENDENCIES ; do # case for other projects
+    search_path=$1
+    REPO_PATH=$(find $search_path ! -writable -prune -o  -type d     \
+                                    -name "$repo"                    \
+                                    -not -path "*/install/*"         \
+                                    -not -path "*/.git/*"            \
+                                    -not -path "*/miniconda/*"       \
+                                    -not -path "*/conda/*"           \
+                                    -not -path "*/.local/*"          \
+                                    -not -path "*/lib/*"             \
+                                    -not -path "*/$repo/$repo/*"     \
+                                    -not -path "*/proc/*"            \
+                                    -print -quit)
+    if [[ -z "$REPO_PATH" ]]; then 
+      echo "ERROR : dependency $repo not found in search_path \"$search_path\". ABORTING."
+      exit -1
+    fi
+
+    cd $REPO_PATH
+    mkdir -p build # creating build if its not already there to hold the build of cpp files
+    rm -rf build/* # build from scratch
+    pip install . -v
+    cd -
+  done
+fi
+set +x
+set +e
diff --git a/.gitlab/ci/coverage.gitlab-ci.yml b/.gitlab/ci/coverage.gitlab-ci.yml
deleted file mode 100644
index 33547fc3f52771c456fba3d34a6e8d96eebafd8a..0000000000000000000000000000000000000000
--- a/.gitlab/ci/coverage.gitlab-ci.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-coverage:ubuntu_cpp:
-  stage: coverage
-  needs: ["build:ubuntu_cpp"]
-  tags:
-    - docker
-  script:
-    - cd build_cpp
-    - ctest --output-on-failure
-    # HTML report for visualization
-    - gcovr --html-details --exclude-unreachable-branches -o coverage.html --root ${CI_PROJECT_DIR} --filter '\.\./include/' --filter '\.\./src/'
-    # Coberta XML report for Gitlab integration
-    - gcovr --xml-pretty --exclude-unreachable-branches --print-summary -o coverage.xml --root ${CI_PROJECT_DIR} --filter '\.\./include/' --filter '\.\./src/'
-  coverage: /^\s*lines:\s*\d+.\d+\%/
-  artifacts:
-    name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
-    expire_in: 2 days
-    reports:
-      coverage_report:
-        coverage_format: cobertura
-        path: build_cpp/coverage.xml
-
-coverage:ubuntu_python:
-  stage: coverage
-  needs: ["build:ubuntu_python"]
-  tags:
-    - docker
-  script:
-    - source venv/bin/activate
-    - python3 -m pip install numpy coverage
-    - cd ${CI_PROJECT_NAME}
-    # Retrieve the installation path of the module, since it is installed with pip.
-    - export MODULE_LOCATION=`python -c "import ${CI_PROJECT_NAME} as _; print(_.__path__[0])"`
-    - python3 -m coverage run --source=$MODULE_LOCATION -m unittest discover -s unit_tests/ -v -b
-    - python3 -m coverage report
-    - python3 -m coverage xml
-  coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
-  artifacts:
-    reports:
-      coverage_report:
-        coverage_format: cobertura
-        path: ${CI_PROJECT_NAME}/coverage.xml
diff --git a/.gitlab/ci/test.gitlab-ci.yml b/.gitlab/ci/test.gitlab-ci.yml
deleted file mode 100644
index 92b932f86193d1525b9bba8cad0b92271f3c966f..0000000000000000000000000000000000000000
--- a/.gitlab/ci/test.gitlab-ci.yml
+++ /dev/null
@@ -1,48 +0,0 @@
-test:ubuntu_cpp:
-  stage: test
-  needs: ["build:ubuntu_cpp"]
-  tags:
-    - docker
-  script:
-    - cd build_cpp
-    - ctest --output-junit ctest-results.xml --output-on-failure
-  artifacts:
-    reports:
-      junit: build_cpp/ctest-results.xml
-
-test:ubuntu_python:
-  stage: test
-  needs: ["build:ubuntu_python"]
-  tags:
-    - docker
-  script:
-    - source venv/bin/activate
-    - cd ${CI_PROJECT_NAME}
-    - python3 -m pip install numpy unittest-xml-reporting
-    - python3 -m pip list
-    # Run on discovery all tests located in core/unit_tests/python
-    - python3 -m xmlrunner discover -s unit_tests/ -v -b --output-file xmlrunner-results.xml
-  artifacts:
-    reports:
-      junit: ${CI_PROJECT_NAME}/xmlrunner-results.xml
-
-# test:windows_cpp:
-#   stage: test
-#   needs: ["build:windows_cpp"]
-#   tags:
-#     - windows
-#   image: buildtools
-#   before_script:
-#     # Install Chocolatey
-#     - Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
-#     # Install dependencies
-#     - choco install cmake.install --installargs '"ADD_CMAKE_TO_PATH=System"' -Y
-#     - choco install python -Y
-#     # Update PATH
-#     - $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
-#   script:
-#     - cd build_cpp
-#     - ctest --output-junit ctest-results.xml --output-on-failure
-#   artifacts:
-#     reports:
-#       junit: build_cpp/ctest-results.xml
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8dfd9982c7562a92e82212a6b2c9536b6fa5f451..bea1b398ced94f3ec4da97b5db6237fd9882d87d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,11 +1,15 @@
 # CMake >= 3.18 is required for good support of FindCUDAToolkit
 cmake_minimum_required(VERSION 3.18)
+set(CXX_STANDARD 14)
+
+file(STRINGS "${CMAKE_SOURCE_DIR}/version.txt" version)
 
-file(READ "${CMAKE_SOURCE_DIR}/version.txt" version)
-add_definitions(-DPROJECT_VERSION="${version}")
-file(READ "${CMAKE_SOURCE_DIR}/project_name.txt" project)
+project(aidge_backend_cuda
+        VERSION ${version}
+        DESCRIPTION "CUDA implementations of the operators of aidge framework."
+        LANGUAGES CXX)
 
-message(STATUS "Project name: ${project}")
+message(STATUS "Project name: ${CMAKE_PROJECT_NAME}")
 message(STATUS "Project version: ${version}")
 
 execute_process(
@@ -13,23 +17,18 @@ execute_process(
     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
     OUTPUT_VARIABLE GIT_COMMIT_HASH
     OUTPUT_STRIP_TRAILING_WHITESPACE
+    ERROR_QUIET
 )
 message(STATUS "Latest git commit: ${GIT_COMMIT_HASH}")
-
 # Define a preprocessor macro with the Git commit version
 add_definitions(-DGIT_COMMIT_HASH="${GIT_COMMIT_HASH}")
 
-
-# Note : project name is {project} and python module name is also {project}
-set(module_name _${project}) # target name
-
-
-project(${project})
-set(CXX_STANDARD 14)
+# Note : project name is ${CMAKE_PROJECT_NAME} and python module name is also ${CMAKE_PROJECT_NAME}
+set(module_name _${CMAKE_PROJECT_NAME}) # target name
 
 ##############################################
 # Define options
-option(PYBIND "python binding" ON)
+option(PYBIND "python binding" OFF)
 option(WERROR "Warning as error" OFF)
 option(TEST "Enable tests" ON)
 option(COVERAGE "Enable coverage" OFF)
@@ -38,34 +37,76 @@ option(ENABLE_ASAN "Enable ASan (AddressSanitizer) for runtime analysis of memor
 ##############################################
 # Import utils CMakeLists
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
-include(PybindModuleCreation)
 
 if(CMAKE_COMPILER_IS_GNUCXX AND COVERAGE)
     Include(CodeCoverage)
 endif()
 
-enable_language(CUDA)
+##############################################
+# Find system dependencies
+##############################################
+# FIND AIDGE Dependencies
+if(NOT $ENV{AIDGE_INSTALL} STREQUAL "")
+    set(CMAKE_INSTALL_PREFIX $ENV{AIDGE_INSTALL})
+    list(APPEND CMAKE_PREFIX_PATH $ENV{AIDGE_INSTALL})
+    message(WARNING "Env var AIDGE_INSTALL detected : $ENV{AIDGE_INSTALL}. Set CMAKE_INSTALL_PREFIX to AIDGE_INSTALL & added to CMAKE_PREFIX_PATH"
+                    "\n\tCMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}"
+                    "\n\tCMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}")
+endif()
+find_package(aidge_core REQUIRED)
+if(TEST)
+    find_package(aidge_backend_cpu REQUIRED)
+endif()
+
+##########
+# CUDA
+if(NOT $ENV{AIDGE_INSTALL} STREQUAL "")
+    message(WARNING "Env var CIBUILDWHEEL detected : currently building for a release job."
+                    "\nSetting manually CUDACXX, PATH & LD_LIBRARY_PATH Variables")
+    list(APPEND ENV{LD_LIBRARY_PATH} /usr/local/cuda/lib64)
+    list(APPEND ENV{PATH} /usr/local/cuda/bin)
+    set(ENV{CUDACXX} /usr/local/cuda/bin/nvcc)
+endif()
+find_package(CUDAToolkit REQUIRED)
+if(NOT DEFINED CMAKE_CUDA_STANDARD)
+    set(CMAKE_CUDA_STANDARD 14)
+    set(CMAKE_CUDA_STANDARD_REQUIRED ON)
+endif()
+if(NOT DEFINED CMAKE_CUDA_ARCHITECURE)
+    set(CMAKE_CUDA_ARCHITECTURE native)
+endif()
 
 message(STATUS "Cuda compiler version = ${CMAKE_CUDA_COMPILER_VERSION}")
 # Define a preprocessor macro with the Cuda compiler version
 add_definitions(-DCUDA_COMPILER_VERSION="${CMAKE_CUDA_COMPILER_VERSION}")
 
+message(STATUS "CUDA STANDARD : ${CMAKE_CUDA_STANDARD}")
+message(STATUS "CUDA ARCHITECTURE : ${CMAKE_CUDA_ARCHITECTURES}")
 
-##############################################
-# Find system dependencies
-find_package(CUDAToolkit REQUIRED)
+enable_language(CUDA)
 
-find_package(aidge_core REQUIRED)
-if(TEST)
-    find_package(aidge_backend_cpu REQUIRED)
-endif()
 ##############################################
 # Create target and set properties
-
 file(GLOB_RECURSE src_files "src/*.cpp" "src/*.cu")
 file(GLOB_RECURSE inc_files "include/*.hpp")
 
 add_library(${module_name} ${src_files} ${inc_files})
+
+# PYTHON BINDING
+if (PYBIND)
+    # Handles Python + pybind11 headers dependencies
+    include(PybindModuleCreation)
+    # creates a target of the same name as CMAKE_PROJECT_NAME
+        generate_python_binding(${CMAKE_PROJECT_NAME} ${module_name}) # the python bindings module has the same name as the project.
+
+    target_link_libraries(${module_name}
+        PUBLIC
+            pybind11::pybind11
+        PRIVATE
+            Python::Module
+        )
+endif()
+
 target_link_libraries(${module_name}
     PUBLIC
         _aidge_core # _ is added because we link the target not the project
@@ -103,27 +144,9 @@ target_include_directories(${module_name}
         ${CMAKE_CURRENT_SOURCE_DIR}/src
 )
 
-if(NOT DEFINED CMAKE_CUDA_STANDARD)
-    set(CMAKE_CUDA_STANDARD 14)
-    set(CMAKE_CUDA_STANDARD_REQUIRED ON)
-endif()
-
 set_property(TARGET ${module_name} PROPERTY POSITION_INDEPENDENT_CODE ON)
 set_target_properties(${module_name} PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
 
-# PYTHON BINDING
-if (PYBIND)
-    generate_python_binding(${project} ${module_name})
-
-    # Handles Python + pybind11 headers dependencies
-    target_link_libraries(${module_name}
-        PUBLIC
-            pybind11::pybind11
-        PRIVATE
-            Python::Python
-        )
-endif()
-
 target_compile_features(${module_name} PRIVATE cxx_std_14)
 
 target_compile_options(${module_name} PRIVATE
@@ -142,11 +165,10 @@ endif()
 
 ##############################################
 # Installation instructions
-
 include(GNUInstallDirs)
-set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${project})
+set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME})
 
-install(TARGETS ${module_name} EXPORT ${project}-targets
+install(TARGETS ${module_name} EXPORT ${CMAKE_PROJECT_NAME}-targets
   LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
   ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
   RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
@@ -157,8 +179,8 @@ install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
 
 #Export the targets to a script
 
-install(EXPORT ${project}-targets
- FILE "${project}-targets.cmake"
+install(EXPORT ${CMAKE_PROJECT_NAME}-targets
+ FILE "${CMAKE_PROJECT_NAME}-targets.cmake"
  DESTINATION ${INSTALL_CONFIGDIR}
 #  COMPONENT ${module_name}
 )
@@ -167,32 +189,34 @@ install(EXPORT ${project}-targets
 include(CMakePackageConfigHelpers)
 
 write_basic_package_version_file(
-    "${CMAKE_CURRENT_BINARY_DIR}/${project}-config-version.cmake"
+    "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-config-version.cmake"
     VERSION ${version}
     COMPATIBILITY AnyNewerVersion
 )
 
-configure_package_config_file("${project}-config.cmake.in"
-    "${CMAKE_CURRENT_BINARY_DIR}/${project}-config.cmake"
+configure_package_config_file("${CMAKE_PROJECT_NAME}-config.cmake.in"
+    "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-config.cmake"
     INSTALL_DESTINATION ${INSTALL_CONFIGDIR}
 )
 
 #Install the config, configversion and custom find modules
 install(FILES
-    "${CMAKE_CURRENT_BINARY_DIR}/${project}-config.cmake"
-    "${CMAKE_CURRENT_BINARY_DIR}/${project}-config-version.cmake"
+    "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-config.cmake"
+    "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-config-version.cmake"
     DESTINATION ${INSTALL_CONFIGDIR}
 )
 
 ##############################################
 ## Exporting from the build tree
-export(EXPORT ${project}-targets
-    FILE "${CMAKE_CURRENT_BINARY_DIR}/${project}-targets.cmake")
-
+export(EXPORT ${CMAKE_PROJECT_NAME}-targets
+    FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-targets.cmake")
 
 ##############################################
 ## Add test
 if(TEST)
+    if(PYBIND)
+        message(FATAL_ERROR "PYBIND and TEST are both enabled. But cannot compile with catch_2.\nChoose between pybind and Catch2 for compilation.")
+    endif()
     enable_testing()
     add_subdirectory(unit_tests)
 endif()
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000000000000000000000000000000000000..7cbc972fca5c7af1ffb6df6c08480ebad982884c
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,8 @@
+include README.md LICENCE
+recursive-include aidge_backend_cuda *.py 
+recursive-exclude aidge_backend_cuda/unit_tests *.py
+
+recursive-include include *.hpp
+recursive-include src *.cpp
+recursive-include python_binding *.cpp
+include CMakeLists.txt
diff --git a/README.md b/README.md
index 30b34248e75429d321b3b1bfa1861496ed50878f..09e16ed4f48371ff11093aa69a17c576c2b8d173 100644
--- a/README.md
+++ b/README.md
@@ -3,15 +3,28 @@
 # Aidge CUDA library
 
 You can find in this folder the library that implements the CUDA operators.
+[TOC]
 
-## Pip installation
+## Installation
 
-You will need to install first the aidge_core library before installing aidge_backend_cuda.
-Also, make sure that the install path was set before installing aidge_core library.
-Then run in your python environnement : 
+### Dependencies
+- `GCC`
+- `Make`/`Ninja`
+- `CMake`
+- `Python` (optional, if you have no intend to use this library in python with pybind)
+
+#### Aidge dependencies
+ - `aidge_core`
+ - `aidge_backend_cpu`
+
+### Pip installation
 ``` bash
 pip install . -v
 ```
+> **TIPS:** Use environment variables to change compilation options:
+> - `AIDGE_INSTALL`: to set the installation folder. Defaults to /usr/local/lib. :warning: This path must be identical to aidge_core install path.
+> - `AIDGE_PYTHON_BUILD_TYPE`: to set the compilation mode to **Debug** or **Release** 
+> - `AIDGE_BUILD_GEN`: to set the build backend with 
 
 ## Standard C++ Compilation
 
diff --git a/aidge_backend_cuda/__init__.py b/aidge_backend_cuda/__init__.py
index a2c06b0ec8a29b7100b0cf7c461092c491197331..c59afd66efc6197d93268e9e205f35048a26d60e 100644
--- a/aidge_backend_cuda/__init__.py
+++ b/aidge_backend_cuda/__init__.py
@@ -1 +1,2 @@
-from aidge_backend_cuda.aidge_backend_cuda import * # import so generated by PyBind
+from aidge_backend_cuda.aidge_backend_cuda import *  # import so generated by PyBind
+from ._version import *
diff --git a/aidge_backend_cuda/unit_tests/test_tensor.py b/aidge_backend_cuda/unit_tests/test_tensor.py
index 6c4717442803badd3d0ac2ea96fb3be44baeaaff..035e0f96d9dee1e948c2aa621181c3f215a457c3 100644
--- a/aidge_backend_cuda/unit_tests/test_tensor.py
+++ b/aidge_backend_cuda/unit_tests/test_tensor.py
@@ -6,15 +6,17 @@ import numpy as np
 
 
 class test_tensor(unittest.TestCase):
-    """Test tensor binding
-    """
+    """Test tensor binding"""
+
     def setUp(self):
         pass
+
     def tearDown(self):
         pass
 
     def test_getavailable_backends(self):
         self.assertTrue("cuda" in aidge_core.Tensor.get_available_backends())
 
-if __name__ == '__main__':
+
+if __name__ == "__main__":
     unittest.main()
diff --git a/cmake/PybindModuleCreation.cmake b/cmake/PybindModuleCreation.cmake
index 8030c1a8639e4b7ae0c5fb865e928a4260c6ae7d..8f386bef59ed86dfa366eca5d4fccae24b28d24e 100644
--- a/cmake/PybindModuleCreation.cmake
+++ b/cmake/PybindModuleCreation.cmake
@@ -1,21 +1,25 @@
-function(generate_python_binding name target_to_bind)
+function(generate_python_binding pybind_module_name target_to_bind) 
     add_definitions(-DPYBIND)
     Include(FetchContent)
 
+    set(PYBIND_VERSION v2.10.4)
+    set(PYBIND11_FINDPYTHON ON)
+    message(STATUS "Retrieving pybind ${PYBIND_VERSION} from git")
+
     FetchContent_Declare(
-    PyBind11
-    GIT_REPOSITORY https://github.com/pybind/pybind11.git
-    GIT_TAG        v2.10.4 # or a later release
+        PyBind11
+        GIT_REPOSITORY https://github.com/pybind/pybind11.git
+        GIT_TAG        ${PYBIND_VERSION} # or a later release
     )
 
     # Use the New FindPython mode, recommanded. Requires CMake 3.15+
-    find_package(Python COMPONENTS Interpreter Development)
+    find_package(Python COMPONENTS Interpreter Development.Module)
     FetchContent_MakeAvailable(PyBind11)
 
-    message(STATUS "Creating binding for module ${name}")
+    message(STATUS "Creating binding for module ${pybind_module_name}")
     file(GLOB_RECURSE pybind_src_files "python_binding/*.cpp")
 
-    pybind11_add_module(${name} MODULE ${pybind_src_files} "NO_EXTRAS") # NO EXTRA recquired for pip install
-    target_include_directories(${name} PUBLIC "python_binding")
-    target_link_libraries(${name} PUBLIC ${target_to_bind})
+    pybind11_add_module(${pybind_module_name} MODULE ${pybind_src_files} "NO_EXTRAS") # NO EXTRA recquired for pip install
+    target_include_directories(${pybind_module_name} PUBLIC "python_binding")
+    target_link_libraries(${pybind_module_name} PUBLIC ${target_to_bind})
 endfunction()
diff --git a/project_name.txt b/project_name.txt
deleted file mode 100644
index d029f485dbbd8bc3386a50eee3a4d8aa201aeb74..0000000000000000000000000000000000000000
--- a/project_name.txt
+++ /dev/null
@@ -1 +0,0 @@
-aidge_backend_cuda
\ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000000000000000000000000000000000000..911af058463e100bc35453315919ec8bda3f2845
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,114 @@
+[project]
+name = "aidge_backend_cuda"
+description="CUDA implementations of the operators of aidge framework"
+dependencies = [
+    "numpy",
+]
+requires-python = ">= 3.7"
+readme = "README.md"
+license = { file = "LICENSE" }
+classifiers = [
+    "Development Status :: 2 - Pre-Alpha",
+    "Programming Language :: Python :: 3"
+]
+dynamic = ["version"]
+
+#####################################################
+# SETUPTOOLS
+[tool.setuptools]
+[tool.setuptools.packages.find]
+where = ["."]  # list of folders that contain the packages (["."] by default)
+include = ["aidge_backend_cuda*"]  # package names should match these glob patterns (["*"] by default)
+exclude = ["aidge_backend_cuda.unit_tests*"]  # exclude packages matching these glob patterns (empty by default)
+namespaces = false  # to disable scanning PEP 420 namespaces (true by default)
+# SETUPTOOLS_SCM
+[tool.setuptools_scm]
+write_to = "aidge_backend_cuda/_version.py"
+
+[build-system]
+requires = [
+    "setuptools>=68",
+    "setuptools-scm",
+    "cmake>=3.18.0",
+    "toml"
+]
+build-backend = "setuptools.build_meta"
+
+#####################################################
+# CIBUILDWHEEL
+[tool.cibuildwheel]
+build-frontend = "build"
+test-requires = "pytest"
+test-command = "pytest {project}/aidge_backend_cuda/unit_tests"
+# uncomment to run cibuildwheel locally on selected distros
+# build=[
+#     "cp38-manylinux_x86_64",
+#     "cp39-manylinux_x86_64",
+#     "cp310-manylinux_x86_64"
+# ]
+
+[tool.cibuildwheel.container-engine]
+# pass command line options to 'docker run'
+name = "docker"
+create-args = [
+    "--runtime=nvidia",
+    "--gpus", "all",
+    "--privileged",
+    "-v","/cache",
+    "-v","/var/run/docker.sock:/var/run/docker.sock",
+]
+
+### AIDGE DEPENDENCIES DECLARATION
+[tool.cibuildwheel.environment]
+# These variables are here for debug purpose but their values when called from CI are set in .gitlab-ci.yml
+BUILD_WITH_CUDA=1
+AIDGE_DEPENDENCIES = "aidge_core aidge_backend_cpu" # format => "dep_1 dep_2 ... dep_n"
+AIDGE_INSTALL="/AIDGE_INSTALL_CIBUILDWHEEL"
+ARCH="x86_64"
+CUDNN_VERSION="9"
+CUDA_MAJOR_VERSION="11"
+CUDA_MINOR_VERSION="8"
+DOCKER_HOST="unix:///var/run/docker.sock"
+SEARCH_PATH="/home/ubuntu/aidge/aidge" # debug path
+# these two following variables are set within CMakeLists.txt when calling cibuildwheel from CI
+LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"
+PATH="/usr/local/cuda/bin:$PATH"
+[tool.cibuildwheel.linux]
+before-build = [
+    "export CUDA_TOOLKIT_VERSION=$CUDA_MAJOR_VERSION-$CUDA_MINOR_VERSION",
+    "echo '\n\n\n\n yum -y install cuda-toolkit-$CUDA_TOOLKIT_VERSION.$ARCH'",
+    "yum-config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel7/$ARCH/cuda-rhel7.repo",
+    "yum clean all",
+    "yum -y install cuda-toolkit-$CUDA_TOOLKIT_VERSION.$ARCH",
+    "yum list available | grep cudnn",
+    "yum -y install libcudnn$CUDNN_VERSION-cuda-$CUDA_MAJOR_VERSION.$ARCH",
+    "yum -y install libcudnn$CUDNN_VERSION-devel-cuda-$CUDA_MAJOR_VERSION.$ARCH",
+    "export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH",
+    "export PATH=/usr/local/cuda/bin:$PATH",
+    "which nvcc",
+    "nvcc --version",
+    "echo '\n\n\n\nInstalling required dependencies for aidge_backend_cuda.\n\n'",
+    "bash .gitlab/ci/cibuildwheel_build_deps_before_build_wheel.sh /host/$SEARCH_PATH"
+]
+before-test= [
+    "export CUDA_TOOLKIT_VERSION=$CUDA_MAJOR_VERSION-$CUDA_MINOR_VERSION",
+    "echo '\n\n\n\n yum -y install cuda-toolkit-$CUDA_TOOLKIT_VERSION.$ARCH'",
+    "yum-config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel7/$ARCH/cuda-rhel7.repo",
+    "yum clean all",
+    "yum -y install cuda-toolkit-$CUDA_TOOLKIT_VERSION.$ARCH",
+    "yum list available | grep cudnn",
+    "yum -y install libcudnn$CUDNN_VERSION-cuda-$CUDA_MAJOR_VERSION.$ARCH",
+    "yum -y install libcudnn$CUDNN_VERSION-devel-cuda-$CUDA_MAJOR_VERSION.$ARCH",
+    "export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH",
+    "export PATH=/usr/local/cuda/bin:$PATH",
+    "nvcc --version",
+    "echo '\n\n\n\nInstalling required dependencies for aidge_backend_cuda.\n\n'",
+    "bash .gitlab/ci/cibuildwheel_build_deps_before_build_wheel.sh /host/$SEARCH_PATH"
+]
+[tool.cibuildwheel.windows]
+before-build = [
+    "powershell -File .\\.gitlab\\ci\\cibuildwheel_build_deps_before_build_wheel.ps1"
+]
+before-test = [
+    "powershell -File .\\.gitlab\\ci\\cibuildwheel_build_deps_before_build_wheel.ps1"
+]
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/setup.py b/setup.py
index 80500f3165dd87eb7b6dd73c78b89806cc8a874a..706fc53ca08319ee487ef789ebc85f0d513ab25b 100644
--- a/setup.py
+++ b/setup.py
@@ -1,37 +1,25 @@
 #!/usr/bin/env python3
-""" Aidge
-
-#TODO To change
-POC of the next framework named Aidge
-"""
-
-DOCLINES = (__doc__ or '').split("\n")
-
 import sys
 import os
 
-# Python supported version checks
-if sys.version_info[:2] < (3, 7):
-    raise RuntimeError("Python version >= 3.7 required.")
-
-
-CLASSIFIERS = """\
-Development Status :: 2 - Pre-Alpha
-"""
-
 import shutil
 import pathlib
-import subprocess
 import multiprocessing
 
 from math import ceil
 
+import toml
+
 from setuptools import setup, Extension
 from setuptools import find_packages
 from setuptools.command.build_ext import build_ext
 
+
 def get_project_name() -> str:
-    return open(pathlib.Path().absolute() / "project_name.txt", "r").read()
+    with open(pathlib.Path().absolute() / "pyproject.toml", "r") as file:
+        project_toml = toml.load(file)
+        return project_toml["project"]["name"]
+
 
 def get_project_version() -> str:
     aidge_root = pathlib.Path().absolute()
@@ -43,8 +31,8 @@ class CMakeExtension(Extension):
     def __init__(self, name):
         super().__init__(name, sources=[])
 
-class CMakeBuild(build_ext):
 
+class CMakeBuild(build_ext):
     def run(self):
         # This lists the number of processors available on the machine
         # The compilation will use half of them
@@ -62,17 +50,45 @@ class CMakeBuild(build_ext):
 
         os.chdir(str(build_temp))
 
-        # Impose to use the executable of the python
-        # used to launch setup.py to setup PythonInterp
-        param_py = "-DPYTHON_EXECUTABLE=" + sys.executable
+        compile_type = (
+            "Release"
+            if "AIDGE_PYTHON_BUILD_TYPE" not in os.environ
+            else os.environ["AIDGE_PYTHON_BUILD_TYPE"]
+        )
+
+        install_path = (
+            os.path.join(sys.prefix, "lib", "libAidge")
+            if "AIDGE_INSTALL" not in os.environ
+            else os.environ["AIDGE_INSTALL"]
+        )
+
+        # using ninja as default build system to build faster and with the same compiler as on windows
+        build_gen = (
+            ["-G", os.environ["AIDGE_BUILD_GEN"]]
+            if "AIDGE_BUILD_GEN" in os.environ
+            else []
+        )
+        
+        self.spawn(
+            [
+                "cmake",
+                *build_gen,
+                str(cwd),
+                "-DTEST=OFF",
+                f"-DCMAKE_INSTALL_PREFIX:PATH={install_path}",
+                f"-DCMAKE_BUILD_TYPE={compile_type}",
+                "-DPYBIND=ON",
+                "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
+                "-DCOVERAGE=OFF",
+                "-DCMAKE_CUDA_ARCHITECTURES=native",
+            ]
+        )
 
-        compile_type = 'Debug'
-        install_path = os.path.join(sys.prefix, "lib", "libAidge")  if "AIDGE_INSTALL" not in os.environ else os.environ["AIDGE_INSTALL"]
-
-        self.spawn(['cmake', str(cwd), param_py, '-DTEST=OFF', f'-DCMAKE_INSTALL_PREFIX:PATH={install_path}', f'-DCMAKE_BUILD_TYPE={compile_type}'])
         if not self.dry_run:
-            self.spawn(['cmake', '--build', '.', '--config', compile_type, '-j', max_jobs])
-            self.spawn(['cmake', '--install', '.', '--config', compile_type])
+            self.spawn(
+                ["cmake", "--build", ".", "--config", compile_type, "-j", max_jobs]
+            )
+            self.spawn(["cmake", "--install", ".", "--config", compile_type])
         os.chdir(str(cwd))
 
         aidge_package = build_lib / (get_project_name())
@@ -83,8 +99,10 @@ class CMakeBuild(build_ext):
         # Copy all shared object files from build_temp/lib to aidge_package
         for root, _, files in os.walk(build_temp.absolute()):
             for file in files:
-                if (file.endswith('.so') or file.endswith('.pyd')) and (root != str(aidge_package.absolute())):
-                    currentFile=os.path.join(root, file)
+                if (file.endswith(".so") or file.endswith(".pyd")) and (
+                    root != str(aidge_package.absolute())
+                ):
+                    currentFile = os.path.join(root, file)
                     shutil.copy(currentFile, str(aidge_package.absolute()))
 
         # Copy version.txt in aidge_package
@@ -92,23 +110,12 @@ class CMakeBuild(build_ext):
         shutil.copy("version.txt", str(aidge_package.absolute()))
 
 
-if __name__ == '__main__':
-
+if __name__ == "__main__":
     setup(
-        name=get_project_name(),
-        version=get_project_version(),
-        python_requires='>=3.7',
-        description=DOCLINES[0],
-        long_description_content_type="text/markdown",
-        long_description="\n".join(DOCLINES[2:]),
-        classifiers=[c for c in CLASSIFIERS.split('\n') if c],
-        packages=find_packages(where="."),
         include_package_data=True,
         ext_modules=[CMakeExtension(get_project_name())],
         cmdclass={
-            'build_ext': CMakeBuild,
+            "build_ext": CMakeBuild,
         },
-        install_requires=['aidge_core'],
         zip_safe=False,
-
     )
diff --git a/src/data/TensorImpl.cu b/src/data/TensorImpl.cu
index 898475b5db325afcaedff44756cc2157cf9e2eec..c70b024fbab1a031ea69d5d9b169dc115b7320db 100644
--- a/src/data/TensorImpl.cu
+++ b/src/data/TensorImpl.cu
@@ -98,3 +98,34 @@ bool Aidge::TensorImpl_cuda<T>::operator==(const TensorImpl &otherImpl) const {
     thrust::device_ptr<T> thrustOtherData(otherImplCuda.mData.data());
     return thrust::equal(thrustData, thrustData + mNbElts, thrustOtherData);
 }
+
+template void Aidge::thrust_copy<double, double>(double const*, double*, unsigned long);
+template void Aidge::thrust_copy<double, float>(double const*, float*, unsigned long);
+template void Aidge::thrust_copy<double, int>(double const*, int*, unsigned long);
+template void Aidge::thrust_copy<float, double>(float const*, double*, unsigned long);
+template void Aidge::thrust_copy<float, float>(float const*, float*, unsigned long);
+template void Aidge::thrust_copy<float, int>(float const*, int*, unsigned long);
+template void Aidge::thrust_copy<int, double>(int const*, double*, unsigned long);
+template void Aidge::thrust_copy<int, float>(int const*, float*, unsigned long);
+template void Aidge::thrust_copy<int, int>(int const*, int*, unsigned long);
+template void Aidge::thrust_copy<long, double>(long const*, double*, unsigned long);
+template void Aidge::thrust_copy<long, float>(long const*, float*, unsigned long);
+template void Aidge::thrust_copy<long, int>(long const*, int*, unsigned long);
+template void Aidge::thrust_copy<short, double>(short const*, double*, unsigned long);
+template void Aidge::thrust_copy<short, float>(short const*, float*, unsigned long);
+template void Aidge::thrust_copy<short, int>(short const*, int*, unsigned long);
+template void Aidge::thrust_copy<signed char, double>(signed char const*, double*, unsigned long);
+template void Aidge::thrust_copy<signed char, float>(signed char const*, float*, unsigned long);
+template void Aidge::thrust_copy<signed char, int>(signed char const*, int*, unsigned long);
+template void Aidge::thrust_copy<unsigned char, double>(unsigned char const*, double*, unsigned long);
+template void Aidge::thrust_copy<unsigned char, float>(unsigned char const*, float*, unsigned long);
+template void Aidge::thrust_copy<unsigned char, int>(unsigned char const*, int*, unsigned long);
+template void Aidge::thrust_copy<unsigned int, double>(unsigned int const*, double*, unsigned long);
+template void Aidge::thrust_copy<unsigned int, float>(unsigned int const*, float*, unsigned long);
+template void Aidge::thrust_copy<unsigned int, int>(unsigned int const*, int*, unsigned long);
+template void Aidge::thrust_copy<unsigned long, double>(unsigned long const*, double*, unsigned long);
+template void Aidge::thrust_copy<unsigned long, float>(unsigned long const*, float*, unsigned long);
+template void Aidge::thrust_copy<unsigned long, int>(unsigned long const*, int*, unsigned long);
+template void Aidge::thrust_copy<unsigned short, double>(unsigned short const*, double*, unsigned long);
+template void Aidge::thrust_copy<unsigned short, float>(unsigned short const*, float*, unsigned long);
+template void Aidge::thrust_copy<unsigned short, int>(unsigned short const*, int*, unsigned long);
diff --git a/src/operator/DivImpl_CUDA_kernels.cu b/src/operator/DivImpl_CUDA_kernels.cu
index 703147430a95899f6068a2989025672189dabd56..7ff5a2865a32cb38bf92571bdea6bf90ca8516eb 100644
--- a/src/operator/DivImpl_CUDA_kernels.cu
+++ b/src/operator/DivImpl_CUDA_kernels.cu
@@ -20,7 +20,7 @@ __device__ T div(T a, T b) {
 template <>
 __device__ half div<half>(half a, half b) {
 #if __CUDA_ARCH__ >= 530 && defined(CUDART_VERSION) && CUDART_VERSION >= 8000
-    return __hdiv(a, b)
+    return __hdiv(a, b);
 #else
     return __float2half(__half2float(a) / __half2float(b));
 #endif
@@ -97,4 +97,4 @@ template void Aidge::divForward<float>(const float* input1, float* output, const
 template void Aidge::divForward<half>(const half* input1, half* output, const half* input2,
                                 const std::vector<int>& input1Dims,const std::vector<int>& input2Dims, const std::vector<int>& outputDims,
                                 const std::vector<int>& input1Strides, const std::vector<int>& input2Strides,const std::vector<int>& outputStrides,
-                                int outSize);
\ No newline at end of file
+                                int outSize);
diff --git a/src/operator/ReduceMeanImpl.cpp b/src/operator/ReduceMeanImpl.cpp
index 11891065a3947796cac7aaabcc6354cdd0fca916..ff83ea5153a95e109ce7ef83c42ed4d672561ad1 100644
--- a/src/operator/ReduceMeanImpl.cpp
+++ b/src/operator/ReduceMeanImpl.cpp
@@ -79,7 +79,7 @@ void Aidge::ReduceMeanImpl_cuda::forward_(const Tensor& input, const std::vector
                             outputDesc,
                             &workspaceSize));
 
-        float *d_workspace;
+        void *d_workspace;
         CHECK_CUDA_STATUS(cudaMalloc(&d_workspace, workspaceSize));
 
         CHECK_CUDNN_STATUS(cudnnReduceTensor(CudaContext::cudnnHandle(),
@@ -132,7 +132,7 @@ void Aidge::ReduceMeanImpl_cuda::forward_(const Tensor& input, const std::vector
                             outputDesc,
                             &workspaceSize));
 
-        float *d_workspace;
+        void *d_workspace;
         CHECK_CUDA_STATUS(cudaMalloc(&d_workspace, workspaceSize));
 
         CHECK_CUDNN_STATUS(cudnnReduceTensor(CudaContext::cudnnHandle(),
@@ -197,4 +197,4 @@ void Aidge::ReduceMeanImpl_cuda::backward_(const Tensor& outGrad, const std::vec
                             axes,
                             factors,
                             static_cast<int>(op.getInput(0)->grad()->size()));
-}
\ No newline at end of file
+}
diff --git a/src/operator/ReduceSumImpl.cpp b/src/operator/ReduceSumImpl.cpp
index 08cd382db426027ae2a29f77a33f3159a51c0cdd..895584d87dab88f3f71a424a02a3b32954c4dc43 100644
--- a/src/operator/ReduceSumImpl.cpp
+++ b/src/operator/ReduceSumImpl.cpp
@@ -79,7 +79,7 @@ void Aidge::ReduceSumImpl_cuda::forward_(const Tensor& input, const std::vector<
                             outputDesc,
                             &workspaceSize));
 
-        float *d_workspace;
+        void *d_workspace;
         CHECK_CUDA_STATUS(cudaMalloc(&d_workspace, workspaceSize));
 
         CHECK_CUDNN_STATUS(cudnnReduceTensor(CudaContext::cudnnHandle(),
@@ -132,7 +132,7 @@ void Aidge::ReduceSumImpl_cuda::forward_(const Tensor& input, const std::vector<
                             outputDesc,
                             &workspaceSize));
 
-        float *d_workspace;
+        void *d_workspace;
         CHECK_CUDA_STATUS(cudaMalloc(&d_workspace, workspaceSize));
 
         CHECK_CUDNN_STATUS(cudnnReduceTensor(CudaContext::cudnnHandle(),
@@ -196,4 +196,4 @@ void Aidge::ReduceSumImpl_cuda::backward_(const Tensor& outGrad, const std::vect
                         axes,
                         factors,
                         static_cast<int>(op.getInput(0)->grad()->size()));
-}
\ No newline at end of file
+}
diff --git a/unit_tests/CMakeLists.txt b/unit_tests/CMakeLists.txt
index ab65c924e4ac9abecc132e5d7cbc4dc91e172821..807adc55e8c85f31f5e94013e174bf8cbc5a2320 100644
--- a/unit_tests/CMakeLists.txt
+++ b/unit_tests/CMakeLists.txt
@@ -1,9 +1,11 @@
 Include(FetchContent)
 
+set(CATCH2_VERSION v3.0.1)
+message(STATUS "Retrieving Catch2 ${CATCH2_VERSION} from git")
 FetchContent_Declare(
   Catch2
   GIT_REPOSITORY https://github.com/catchorg/Catch2.git
-  GIT_TAG        v3.0.1 # or a later release
+  GIT_TAG   ${CATCH2_VERSION}       # or a later release
 )
 
 FetchContent_MakeAvailable(Catch2)