From abed843704e7279313f155fe2776396103ddc751 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Fri, 17 Jan 2025 18:42:43 +0000 Subject: [PATCH 01/43] Update build wheels job to test the wheels Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 113 +++++++++++++++++++++++++++- scripts/ci/test_wheels.sh | 22 +++--- 2 files changed, 123 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index 687ec38..336751a 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -11,7 +11,10 @@ on: options: - 'Release' - 'Debug' - + artifacts_from_run: + type: string + description: Optional argument to take artifacts from a prior run of this workflow; facilitates rerunning a failed workflow without re-building the artifacts. + required: false concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -51,6 +54,7 @@ jobs: uses: ./.github/actions/get-cudaq-version - name: Get CUDAQ code + if: ${{ !inputs.artifacts_from_run }} uses: actions/checkout@v4 with: repository: ${{ steps.get-cudaq-version.outputs.repo }} @@ -59,17 +63,124 @@ jobs: set-safe-directory: true - name: Build CUDAQ toolchain + if: ${{ !inputs.artifacts_from_run }} run: | .github/workflows/scripts/build_cudaq.sh - name: Build wheels + if: ${{ !inputs.artifacts_from_run }} run: | .github/workflows/scripts/build_wheels.sh \ --cudaq-prefix $HOME/.cudaq \ --build-type ${{ inputs.build_type }} - name: Upload artifact + if: ${{ !inputs.artifacts_from_run }} uses: actions/upload-artifact@v4 with: name: wheels-py${{ matrix.python }}-${{ matrix.platform }} path: /wheels/** + + test-cudaqx-wheels: + name: Test CUDA-QX wheels (CPU) + needs: linux-build + runs-on: linux-${{ matrix.platform }}-cpu4 + container: ubuntu:22.04 + permissions: + actions: write + contents: read + strategy: + fail-fast: false + matrix: + python: ['3.10', '3.11', '3.12'] + platform: ['amd64', 'arm64'] + + steps: + - name: Get code + uses: actions/checkout@v4 + with: + set-safe-directory: true + + - name: Install Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + - name: Install requirements + run: | + bash .github/workflows/scripts/install_git_cli.sh + apt install -y --no-install-recommends libgfortran5 unzip + + - name: Download CUDAQX wheels + uses: actions/download-artifact@v4 + with: + name: wheels-py${{ matrix.python }}-${{ matrix.platform }} + path: /wheels + run-id: ${{ inputs.artifacts_from_run || github.run_id }} + + - name: Test wheels + run: | + ls /wheels + bash scripts/ci/test_wheels.sh ${{ matrix.python }} + + test-wheels-gpu: + name: Test CUDA-QX wheels (GPU) + needs: linux-build + runs-on: linux-${{ matrix.runner.arch }}-gpu-${{ matrix.runner.gpu }}-latest-1 + container: + image: nvidia/cuda:12.0.0-base-ubuntu22.04 + # Enable this if you want to collect core files. (You may might to enable + # Debug builds if you're doing this.) + #options: --privileged --ulimit core=-1 --security-opt seccomp=unconfined + env: + NVIDIA_VISIBLE_DEVICES: ${{ env.NVIDIA_VISIBLE_DEVICES }} + permissions: + actions: write + contents: read + strategy: + fail-fast: false + matrix: + runner: [ + { arch: arm64, gpu: a100 }, + { arch: amd64, gpu: v100 }, + ] + python: ['3.10', '3.11', '3.12'] + + steps: + - name: Get code + uses: actions/checkout@v4 + with: + set-safe-directory: true + + - name: Install Python ${{ matrix.python }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + - name: Install requirements + run: | + bash .github/workflows/scripts/install_git_cli.sh + apt install -y --no-install-recommends libgfortran5 unzip + #echo 'core.%p' | tee /proc/sys/kernel/core_pattern + #echo "Running cat /proc/sys/kernel/core_pattern" + #cat /proc/sys/kernel/core_pattern + + - name: Download CUDAQX wheels + uses: actions/download-artifact@v4 + with: + name: wheels-py${{ matrix.python }}-${{ matrix.runner.arch }} + path: /wheels + run-id: ${{ inputs.artifacts_from_run || github.run_id }} + + - name: Test wheels + continue-on-error: true + run: | + ls /wheels + bash scripts/ci/test_wheels.sh ${{ matrix.python }} + + # - name: Upload any core files + # if: success() || failure() + # uses: actions/upload-artifact@v4 + # with: + # name: core-files-${{ matrix.python }}-arm64 + # path: core.* diff --git a/scripts/ci/test_wheels.sh b/scripts/ci/test_wheels.sh index 6983b41..2da2e10 100644 --- a/scripts/ci/test_wheels.sh +++ b/scripts/ci/test_wheels.sh @@ -11,28 +11,28 @@ # Exit immediately if any command returns a non-zero status set -e +# Uncomment these lines to enable core files +#set +e +#ulimit -c unlimited + # Installing dependencies -python_version=3.10 +python_version=$1 +python_version_no_dot=$(echo $python_version | tr -d '.') # 3.10 --> 310 python=python${python_version} -apt-get update && apt-get install -y --no-install-recommends \ - libgfortran5 python${python_version} python$(echo ${python_version} | cut -d . -f 1)-pip - -${python} -m pip install --no-cache-dir pytest nvidia-cublas-cu11 +#apt-get update && apt-get install -y --no-install-recommends \ +# libgfortran5 python${python_version} python$(echo ${python_version} | cut -d . -f 1)-pip -cd /cuda-qx - -${python} -m pip install wheels/cuda_quantum_cu12-0.0.0-cp310-cp310-manylinux_2_28_x86_64.whl +${python} -m pip install --no-cache-dir pytest # QEC library # ====================================== -${python} -m pip install wheels/cudaq_qec-0.0.1-cp310-cp310-*.whl +${python} -m pip install wheels/cudaq_qec-0.0.1-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl ${python} -m pytest libs/qec/python/tests/ # Solvers library # ====================================== -${python} -m pip install wheels/cudaq_solvers-0.0.1-cp310-cp310-*.whl +${python} -m pip install wheels/cudaq_solvers-0.0.1-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl ${python} -m pytest libs/solvers/python/tests/ - From d6a35cda2b807d3b78811f49b532618f13b5a165 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Fri, 17 Jan 2025 18:54:11 +0000 Subject: [PATCH 02/43] Skip more steps if prior run was provided Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index 336751a..76e4614 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -28,7 +28,7 @@ jobs: # easier to rely on their's devdeps images to do the building. # FIXME: there is no guarantee that this CUDA-Q image aligns with the CUDA-Q # commit that we are trying to align with. - container: ghcr.io/nvidia/cuda-quantum-devdeps:manylinux-${{ matrix.platform }}-${{ matrix.toolchain.id }}-main + container: ${{ inputs.artifacts_from_run && 'ubuntu-latest' || format('ghcr.io/nvidia/cuda-quantum-devdeps:manylinux-{0}-{1}-main', matrix.platform, matrix.toolchain.id) }} permissions: actions: write contents: read @@ -45,11 +45,13 @@ jobs: steps: - name: Get code + if: ${{ !inputs.artifacts_from_run }} uses: actions/checkout@v4 with: set-safe-directory: true - name: Get required CUDAQ version + if: ${{ !inputs.artifacts_from_run }} id: get-cudaq-version uses: ./.github/actions/get-cudaq-version From 7eb2907b95fdac48c3afade76fe98281c6f86ce8 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Fri, 17 Jan 2025 20:17:17 +0000 Subject: [PATCH 03/43] Update wheel name used by test script Signed-off-by: Ben Howe --- scripts/ci/test_wheels.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/ci/test_wheels.sh b/scripts/ci/test_wheels.sh index 2da2e10..0e550a2 100644 --- a/scripts/ci/test_wheels.sh +++ b/scripts/ci/test_wheels.sh @@ -28,11 +28,11 @@ ${python} -m pip install --no-cache-dir pytest # QEC library # ====================================== -${python} -m pip install wheels/cudaq_qec-0.0.1-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl +${python} -m pip install wheels/cudaq_qec-*-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl ${python} -m pytest libs/qec/python/tests/ # Solvers library # ====================================== -${python} -m pip install wheels/cudaq_solvers-0.0.1-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl +${python} -m pip install wheels/cudaq_solvers-*-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl ${python} -m pytest libs/solvers/python/tests/ From 9bdbde764e579d84396b86439f4a244c3f20d858 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Fri, 17 Jan 2025 20:45:31 +0000 Subject: [PATCH 04/43] Fix path Signed-off-by: Ben Howe --- scripts/ci/test_wheels.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/ci/test_wheels.sh b/scripts/ci/test_wheels.sh index 0e550a2..f3c1db3 100644 --- a/scripts/ci/test_wheels.sh +++ b/scripts/ci/test_wheels.sh @@ -28,11 +28,11 @@ ${python} -m pip install --no-cache-dir pytest # QEC library # ====================================== -${python} -m pip install wheels/cudaq_qec-*-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl +${python} -m pip install /wheels/cudaq_qec-*-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl ${python} -m pytest libs/qec/python/tests/ # Solvers library # ====================================== -${python} -m pip install wheels/cudaq_solvers-*-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl +${python} -m pip install /wheels/cudaq_solvers-*-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl ${python} -m pytest libs/solvers/python/tests/ From 63e8b93d5d2baf71b32cc237e363b533b2ed66f3 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Fri, 17 Jan 2025 21:20:59 +0000 Subject: [PATCH 05/43] Build wheels for appropriate Python version Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 10 ++++++++-- .github/workflows/scripts/build_cudaq.sh | 3 ++- .github/workflows/scripts/build_wheels.sh | 16 ++++++++++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index 76e4614..83a7cd0 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -50,6 +50,11 @@ jobs: with: set-safe-directory: true + - name: Install Python ${{ matrix.python }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + - name: Get required CUDAQ version if: ${{ !inputs.artifacts_from_run }} id: get-cudaq-version @@ -67,14 +72,15 @@ jobs: - name: Build CUDAQ toolchain if: ${{ !inputs.artifacts_from_run }} run: | - .github/workflows/scripts/build_cudaq.sh + .github/workflows/scripts/build_cudaq.sh ${{ matrix.python }} - name: Build wheels if: ${{ !inputs.artifacts_from_run }} run: | .github/workflows/scripts/build_wheels.sh \ --cudaq-prefix $HOME/.cudaq \ - --build-type ${{ inputs.build_type }} + --build-type ${{ inputs.build_type }} \ + --python-version ${{ matrix.python }} - name: Upload artifact if: ${{ !inputs.artifacts_from_run }} diff --git a/.github/workflows/scripts/build_cudaq.sh b/.github/workflows/scripts/build_cudaq.sh index 2f207c1..6fc49a2 100755 --- a/.github/workflows/scripts/build_cudaq.sh +++ b/.github/workflows/scripts/build_cudaq.sh @@ -16,7 +16,8 @@ source /opt/rh/gcc-toolset-11/enable export CC=gcc export CXX=g++ -python_version=3.10 +python_version=$1 +python_version=${python_version:-3.10} python=python${python_version} ${python} -m pip install --no-cache-dir numpy auditwheel diff --git a/.github/workflows/scripts/build_wheels.sh b/.github/workflows/scripts/build_wheels.sh index 6bbe097..1d8ec59 100755 --- a/.github/workflows/scripts/build_wheels.sh +++ b/.github/workflows/scripts/build_wheels.sh @@ -19,6 +19,7 @@ show_help() { echo " --build-type Build type (e.g., Release)" echo " --cudaq-prefix Path to CUDA-Q's install prefix" echo " (default: \$HOME/.cudaq)" + echo " --python-version Python version to build wheel for (e.g. 3.10)" } parse_options() { @@ -42,6 +43,15 @@ parse_options() { exit 1 fi ;; + --python-version) + if [[ -n "$2" && "$2" != -* ]]; then + python_version=("$2") + shift 2 + else + echo "Error: Argument for $1 is missing" >&2 + exit 1 + fi + ;; -*) echo "Error: Unknown option $1" >&2 show_help @@ -56,18 +66,20 @@ parse_options() { done } -# Initialize an empty array to store libs names +# Defaults cudaq_prefix=$HOME/.cudaq build_type=Release +python_version=3.10 # Parse options parse_options "$@" +echo "Building in $build_type mode for Python $python_version" + # ============================================================================== # Helpers # ============================================================================== -python_version=3.10 python=python${python_version} ARCH=$(uname -m) From 58ec167859a0cae89f7ed3b5413d15bb334ef6ef Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Fri, 17 Jan 2025 21:40:02 +0000 Subject: [PATCH 06/43] Remove Python installation into manylinux Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index 83a7cd0..c77a83d 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -50,11 +50,6 @@ jobs: with: set-safe-directory: true - - name: Install Python ${{ matrix.python }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python }} - - name: Get required CUDAQ version if: ${{ !inputs.artifacts_from_run }} id: get-cudaq-version From 3bfe9a1ab4dbd18f3339f7d16da71fba1abf0d4d Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Fri, 17 Jan 2025 22:10:27 +0000 Subject: [PATCH 07/43] Remove continue-on-error Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index c77a83d..4ddd69a 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -176,7 +176,6 @@ jobs: run-id: ${{ inputs.artifacts_from_run || github.run_id }} - name: Test wheels - continue-on-error: true run: | ls /wheels bash scripts/ci/test_wheels.sh ${{ matrix.python }} From c2c2c9a9da059377cefb834153ff145da1ae94e2 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Fri, 17 Jan 2025 22:34:54 +0000 Subject: [PATCH 08/43] Add qec-lib-plugins Signed-off-by: Ben Howe --- libs/qec/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/qec/pyproject.toml b/libs/qec/pyproject.toml index 1c37ac5..2371daf 100644 --- a/libs/qec/pyproject.toml +++ b/libs/qec/pyproject.toml @@ -37,7 +37,7 @@ build-dir = "_skbuild" build.verbose = true cmake.version = ">=3.28" cmake.build-type = "Release" -install.components = ["qec-python", "qec-lib"] +install.components = ["qec-python", "qec-lib", "qec-lib-plugins"] wheel.packages = [] logging.level = "DEBUG" ninja.version = ">=1.10" From 84e696c3689dead296755182887acaab0c06800c Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Fri, 17 Jan 2025 23:15:43 +0000 Subject: [PATCH 09/43] Use getCUDAQLibraryPath instead of DECODER_PLUGIN_DIR Signed-off-by: Ben Howe --- libs/qec/lib/CMakeLists.txt | 1 - libs/qec/lib/decoder.cpp | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/qec/lib/CMakeLists.txt b/libs/qec/lib/CMakeLists.txt index 55b5433..bdbe043 100644 --- a/libs/qec/lib/CMakeLists.txt +++ b/libs/qec/lib/CMakeLists.txt @@ -9,7 +9,6 @@ set(LIBRARY_NAME cudaq-qec) add_compile_options(-Wno-attributes) -add_compile_definitions(DECODER_PLUGIN_DIR="${CMAKE_INSTALL_PREFIX}/lib/decoder-plugins") # FIXME?: This must be a shared library. Trying to build a static one will fail. add_library(${LIBRARY_NAME} SHARED diff --git a/libs/qec/lib/decoder.cpp b/libs/qec/lib/decoder.cpp index 9f4cc56..bfb76fc 100644 --- a/libs/qec/lib/decoder.cpp +++ b/libs/qec/lib/decoder.cpp @@ -8,6 +8,7 @@ #include "cudaq/qec/decoder.h" #include "cudaq/qec/plugin_loader.h" +#include "cudaq/utils/cudaq_utils.h" #include #include #include @@ -78,7 +79,8 @@ std::unique_ptr get_decoder(const std::string &name, // Constructor function for auto-loading plugins __attribute__((constructor)) void load_decoder_plugins() { // Load plugins from the decoder-specific plugin directory - load_plugins(DECODER_PLUGIN_DIR, PluginType::DECODER); + load_plugins(cudaq::getCUDAQLibraryPath() + "/decoder-plugins", + PluginType::DECODER); } // Destructor function to clean up only decoder plugins From 58b6f99083f887cfe692ef4d5d875de3c1d96a9e Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Fri, 17 Jan 2025 23:48:15 +0000 Subject: [PATCH 10/43] Try again Signed-off-by: Ben Howe --- libs/qec/lib/decoder.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/qec/lib/decoder.cpp b/libs/qec/lib/decoder.cpp index bfb76fc..6339bd0 100644 --- a/libs/qec/lib/decoder.cpp +++ b/libs/qec/lib/decoder.cpp @@ -79,8 +79,9 @@ std::unique_ptr get_decoder(const std::string &name, // Constructor function for auto-loading plugins __attribute__((constructor)) void load_decoder_plugins() { // Load plugins from the decoder-specific plugin directory - load_plugins(cudaq::getCUDAQLibraryPath() + "/decoder-plugins", - PluginType::DECODER); + std::filesystem::path cudaqLibPath{cudaq::getCUDAQLibraryPath()}; + auto pluginPath = cudaqLibPath.parent_path() / "decoder-plugins"; + load_plugins(pluginPath.string(), PluginType::DECODER); } // Destructor function to clean up only decoder plugins From 9f6790d57cad446d572480a2c005a808a76972e4 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 00:32:01 +0000 Subject: [PATCH 11/43] Update and use getCUDAQXLibraryPath Signed-off-by: Ben Howe --- .../include/cuda-qx/core}/library_utils.h | 23 +++++++++++++++---- libs/qec/lib/decoder.cpp | 5 +++- .../molecule/drivers/pyscf_driver.cpp | 5 ++-- 3 files changed, 25 insertions(+), 8 deletions(-) rename libs/{solvers/lib/operators/molecule/drivers => core/include/cuda-qx/core}/library_utils.h (79%) diff --git a/libs/solvers/lib/operators/molecule/drivers/library_utils.h b/libs/core/include/cuda-qx/core/library_utils.h similarity index 79% rename from libs/solvers/lib/operators/molecule/drivers/library_utils.h rename to libs/core/include/cuda-qx/core/library_utils.h index 54da7bb..39c75b7 100644 --- a/libs/solvers/lib/operators/molecule/drivers/library_utils.h +++ b/libs/core/include/cuda-qx/core/library_utils.h @@ -20,9 +20,12 @@ namespace cudaqx::__internal__ { +enum class CudaQXLibType { Solvers, QEC }; + /// @brief Structure to hold CUDAQX library data. struct CUDAQXLibraryData { std::string path; ///< The path to the CUDAQX library. + std::string libName; // The name to search for }; #if defined(__APPLE__) && defined(__MACH__) @@ -31,11 +34,11 @@ struct CUDAQXLibraryData { /// path. inline static void getCUDAQXLibraryPath(CUDAQXLibraryData *data) { auto nLibs = _dyld_image_count(); + auto casted = static_cast(data); for (uint32_t i = 0; i < nLibs; i++) { auto ptr = _dyld_get_image_name(i); std::string libName(ptr); - if (libName.find("cudaq-core") != std::string::npos) { - auto casted = static_cast(data); + if (libName.find(casted->libName) != std::string::npos) { casted->path = std::string(ptr); } } @@ -51,8 +54,8 @@ inline static void getCUDAQXLibraryPath(CUDAQXLibraryData *data) { inline static int getCUDAQXLibraryPath(struct dl_phdr_info *info, size_t size, void *data) { std::string libraryName(info->dlpi_name); - if (libraryName.find("cudaq-solvers") != std::string::npos) { - auto casted = static_cast(data); + auto casted = static_cast(data); + if (libraryName.find(casted->libName) != std::string::npos) { casted->path = std::string(info->dlpi_name); } return 0; @@ -61,8 +64,18 @@ inline static int getCUDAQXLibraryPath(struct dl_phdr_info *info, size_t size, /// @brief Retrieves the path of the CUDAQX library. /// @return A string containing the path to the CUDAQX library. -inline static std::string getCUDAQXLibraryPath() { +inline static std::string getCUDAQXLibraryPath(const CudaQXLibType lib) { __internal__::CUDAQXLibraryData data; + data.libName = [&]() -> std::string { + switch (lib) { + case CudaQXLibType::QEC: + return "cudaq-qec"; + case CudaQXLibType::Solvers: + return "cudaq-solvers"; + } + return "UNKNOWN"; + }(); + #if defined(__APPLE__) && defined(__MACH__) getCUDAQXLibraryPath(&data); #else diff --git a/libs/qec/lib/decoder.cpp b/libs/qec/lib/decoder.cpp index 6339bd0..b3b5f0e 100644 --- a/libs/qec/lib/decoder.cpp +++ b/libs/qec/lib/decoder.cpp @@ -14,6 +14,8 @@ #include #include +#include "cuda-qx/core/library_utils.h" + INSTANTIATE_REGISTRY(cudaq::qec::decoder, const cudaqx::tensor &) INSTANTIATE_REGISTRY(cudaq::qec::decoder, const cudaqx::tensor &, const cudaqx::heterogeneous_map &) @@ -79,7 +81,8 @@ std::unique_ptr get_decoder(const std::string &name, // Constructor function for auto-loading plugins __attribute__((constructor)) void load_decoder_plugins() { // Load plugins from the decoder-specific plugin directory - std::filesystem::path cudaqLibPath{cudaq::getCUDAQLibraryPath()}; + std::filesystem::path cudaqLibPath{cudaqx::__internal__::getCUDAQXLibraryPath( + cudaqx::__internal__::CudaQXLibType::QEC)}; auto pluginPath = cudaqLibPath.parent_path() / "decoder-plugins"; load_plugins(pluginPath.string(), PluginType::DECODER); } diff --git a/libs/solvers/lib/operators/molecule/drivers/pyscf_driver.cpp b/libs/solvers/lib/operators/molecule/drivers/pyscf_driver.cpp index a5bb696..4568819 100644 --- a/libs/solvers/lib/operators/molecule/drivers/pyscf_driver.cpp +++ b/libs/solvers/lib/operators/molecule/drivers/pyscf_driver.cpp @@ -8,8 +8,8 @@ #include "nlohmann/json.hpp" +#include "cuda-qx/core/library_utils.h" #include "cuda-qx/core/tensor.h" -#include "library_utils.h" #include "process.h" #include "cudaq/solvers/operators/molecule/fermion_compiler.h" #include "cudaq/solvers/operators/molecule/molecule_package_driver.h" @@ -62,7 +62,8 @@ class RESTPySCFDriver : public MoleculePackageDriver { std::unique_ptr make_available() const override { // Start up the web service, if failed, return nullptr - std::filesystem::path libPath{cudaqx::__internal__::getCUDAQXLibraryPath()}; + std::filesystem::path libPath{cudaqx::__internal__::getCUDAQXLibraryPath( + cudaqx::__internal__::CudaQXLibType::Solvers)}; auto cudaqLibPath = libPath.parent_path(); auto cudaqPySCFTool = cudaqLibPath.parent_path() / "bin" / "cudaq-pyscf"; auto argString = cudaqPySCFTool.string() + " --server-mode"; From 35c14df3106952e1aebe3920cbe51027589255f7 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 00:34:05 +0000 Subject: [PATCH 12/43] Rename variable Signed-off-by: Ben Howe --- libs/qec/lib/decoder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/qec/lib/decoder.cpp b/libs/qec/lib/decoder.cpp index b3b5f0e..95c1b7a 100644 --- a/libs/qec/lib/decoder.cpp +++ b/libs/qec/lib/decoder.cpp @@ -81,9 +81,9 @@ std::unique_ptr get_decoder(const std::string &name, // Constructor function for auto-loading plugins __attribute__((constructor)) void load_decoder_plugins() { // Load plugins from the decoder-specific plugin directory - std::filesystem::path cudaqLibPath{cudaqx::__internal__::getCUDAQXLibraryPath( + std::filesystem::path libPath{cudaqx::__internal__::getCUDAQXLibraryPath( cudaqx::__internal__::CudaQXLibType::QEC)}; - auto pluginPath = cudaqLibPath.parent_path() / "decoder-plugins"; + auto pluginPath = libPath.parent_path() / "decoder-plugins"; load_plugins(pluginPath.string(), PluginType::DECODER); } From 3545bdb79e6d6b79687fd111e49509802085798e Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 02:15:40 +0000 Subject: [PATCH 13/43] Be more precise with lib names Signed-off-by: Ben Howe --- .gitignore | 1 + libs/core/include/cuda-qx/core/library_utils.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 506d28e..ccec909 100644 --- a/.gitignore +++ b/.gitignore @@ -82,6 +82,7 @@ __pycache__/ docs/sphinx/_doxygen docs/sphinx/_mdgen **/_build/* +**/_skbuild/* _version.py # third party integrations diff --git a/libs/core/include/cuda-qx/core/library_utils.h b/libs/core/include/cuda-qx/core/library_utils.h index 39c75b7..8dfa01b 100644 --- a/libs/core/include/cuda-qx/core/library_utils.h +++ b/libs/core/include/cuda-qx/core/library_utils.h @@ -69,9 +69,9 @@ inline static std::string getCUDAQXLibraryPath(const CudaQXLibType lib) { data.libName = [&]() -> std::string { switch (lib) { case CudaQXLibType::QEC: - return "cudaq-qec"; + return "/libcudaq-qec."; case CudaQXLibType::Solvers: - return "cudaq-solvers"; + return "/libcudaq-solvers."; } return "UNKNOWN"; }(); From f5317dfa5c1551707739aa94cdd305e0b007389d Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 02:18:06 +0000 Subject: [PATCH 14/43] Formatting Signed-off-by: Ben Howe --- libs/core/include/cuda-qx/core/library_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/core/include/cuda-qx/core/library_utils.h b/libs/core/include/cuda-qx/core/library_utils.h index 8dfa01b..d8e97f5 100644 --- a/libs/core/include/cuda-qx/core/library_utils.h +++ b/libs/core/include/cuda-qx/core/library_utils.h @@ -24,7 +24,7 @@ enum class CudaQXLibType { Solvers, QEC }; /// @brief Structure to hold CUDAQX library data. struct CUDAQXLibraryData { - std::string path; ///< The path to the CUDAQX library. + std::string path; ///< The path to the CUDAQX library. std::string libName; // The name to search for }; From 0e3e87a09ddedc6e962a0a03e8407479f9778c5b Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 02:56:30 +0000 Subject: [PATCH 15/43] Add Debug Signed-off-by: Ben Howe --- libs/core/include/cuda-qx/core/library_utils.h | 2 ++ libs/qec/lib/plugin_loader.cpp | 1 + scripts/ci/test_wheels.sh | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libs/core/include/cuda-qx/core/library_utils.h b/libs/core/include/cuda-qx/core/library_utils.h index d8e97f5..4a864ff 100644 --- a/libs/core/include/cuda-qx/core/library_utils.h +++ b/libs/core/include/cuda-qx/core/library_utils.h @@ -54,8 +54,10 @@ inline static void getCUDAQXLibraryPath(CUDAQXLibraryData *data) { inline static int getCUDAQXLibraryPath(struct dl_phdr_info *info, size_t size, void *data) { std::string libraryName(info->dlpi_name); + printf("BMH libraryName is %s\n", libraryName.c_str()); auto casted = static_cast(data); if (libraryName.find(casted->libName) != std::string::npos) { + printf("BMH Setting it.\n"); casted->path = std::string(info->dlpi_name); } return 0; diff --git a/libs/qec/lib/plugin_loader.cpp b/libs/qec/lib/plugin_loader.cpp index 35a69f5..018c577 100644 --- a/libs/qec/lib/plugin_loader.cpp +++ b/libs/qec/lib/plugin_loader.cpp @@ -19,6 +19,7 @@ static std::map &get_plugin_handles() { // Function to load plugins from a directory based on their type void load_plugins(const std::string &plugin_dir, PluginType type) { + printf("BMH Loading plugins from %s\n", plugin_dir.c_str()); if (!fs::exists(plugin_dir)) { std::cerr << "WARNING: Plugin directory does not exist: " << plugin_dir << std::endl; diff --git a/scripts/ci/test_wheels.sh b/scripts/ci/test_wheels.sh index f3c1db3..321572e 100644 --- a/scripts/ci/test_wheels.sh +++ b/scripts/ci/test_wheels.sh @@ -29,7 +29,7 @@ ${python} -m pip install --no-cache-dir pytest # ====================================== ${python} -m pip install /wheels/cudaq_qec-*-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl -${python} -m pytest libs/qec/python/tests/ +${python} -m pytest -s libs/qec/python/tests/test_decoder.py::test_decoder_plugin_initialization # libs/qec/python/tests/ # Solvers library # ====================================== From b7c9ad6b297e2074a36bdbf675c3088c0ed37bd5 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 03:27:43 +0000 Subject: [PATCH 16/43] More debug Signed-off-by: Ben Howe --- libs/qec/lib/plugin_loader.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/qec/lib/plugin_loader.cpp b/libs/qec/lib/plugin_loader.cpp index 018c577..149cd2e 100644 --- a/libs/qec/lib/plugin_loader.cpp +++ b/libs/qec/lib/plugin_loader.cpp @@ -27,6 +27,7 @@ void load_plugins(const std::string &plugin_dir, PluginType type) { } for (const auto &entry : fs::directory_iterator(plugin_dir)) { if (entry.path().extension() == ".so") { + printf("BMH Opening %s\n", entry.path().c_str()); void *raw_handle = dlopen(entry.path().c_str(), RTLD_NOW); if (raw_handle) { // Custom deleter ensures dlclose is called @@ -42,6 +43,8 @@ void load_plugins(const std::string &plugin_dir, PluginType type) { std::cerr << "ERROR: Failed to load plugin: " << entry.path() << " Error: " << dlerror() << std::endl; } + } else { + printf("BMH Skipping %s\n", entry.path().c_str()); } } } From 707099076980736822fcac9ad9b7f6f89079ae2d Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 05:31:56 +0000 Subject: [PATCH 17/43] Fix RPATH problem that was causing bad auditwheel grafting If the RPATH for the plugin did not point to the correct cudaq-qec.so file, then the auditwheel script was grafting a brand new cuda-qec-1234abcd.so file, which was causing duplicate extension_point registries. This was very bad. Setting the correct RPATH seems to make auditwheel behave much better. Signed-off-by: Ben Howe --- libs/qec/lib/decoders/plugins/example/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/qec/lib/decoders/plugins/example/CMakeLists.txt b/libs/qec/lib/decoders/plugins/example/CMakeLists.txt index 2cb1ea3..9399faf 100644 --- a/libs/qec/lib/decoders/plugins/example/CMakeLists.txt +++ b/libs/qec/lib/decoders/plugins/example/CMakeLists.txt @@ -47,18 +47,18 @@ set_target_properties(${MODULE_NAME} PROPERTIES # ============================================================================== if (NOT SKBUILD) - set_target_properties(${LIBRARY_NAME} PROPERTIES + set_target_properties(${MODULE_NAME} PROPERTIES BUILD_RPATH "$ORIGIN" INSTALL_RPATH "$ORIGIN:$ORIGIN/.." ) # Let CMake automatically add paths of linked libraries to the RPATH: - set_target_properties(${LIBRARY_NAME} PROPERTIES + set_target_properties(${MODULE_NAME} PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) else() # CUDA-Q install its libraries in site-packages/lib (or dist-packages/lib) # Thus, we need the $ORIGIN/../lib - set_target_properties(${LIBRARY_NAME} PROPERTIES + set_target_properties(${MODULE_NAME} PROPERTIES INSTALL_RPATH "$ORIGIN/../../lib" ) endif() From bb7b874003cfc80fbed1eb3fde4a267074bde309 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 05:38:03 +0000 Subject: [PATCH 18/43] Cleanup Signed-off-by: Ben Howe --- libs/qec/lib/decoder.cpp | 4 +--- libs/qec/lib/plugin_loader.cpp | 4 ---- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/libs/qec/lib/decoder.cpp b/libs/qec/lib/decoder.cpp index 95c1b7a..656a345 100644 --- a/libs/qec/lib/decoder.cpp +++ b/libs/qec/lib/decoder.cpp @@ -7,15 +7,13 @@ ******************************************************************************/ #include "cudaq/qec/decoder.h" +#include "cuda-qx/core/library_utils.h" #include "cudaq/qec/plugin_loader.h" -#include "cudaq/utils/cudaq_utils.h" #include #include #include #include -#include "cuda-qx/core/library_utils.h" - INSTANTIATE_REGISTRY(cudaq::qec::decoder, const cudaqx::tensor &) INSTANTIATE_REGISTRY(cudaq::qec::decoder, const cudaqx::tensor &, const cudaqx::heterogeneous_map &) diff --git a/libs/qec/lib/plugin_loader.cpp b/libs/qec/lib/plugin_loader.cpp index 149cd2e..35a69f5 100644 --- a/libs/qec/lib/plugin_loader.cpp +++ b/libs/qec/lib/plugin_loader.cpp @@ -19,7 +19,6 @@ static std::map &get_plugin_handles() { // Function to load plugins from a directory based on their type void load_plugins(const std::string &plugin_dir, PluginType type) { - printf("BMH Loading plugins from %s\n", plugin_dir.c_str()); if (!fs::exists(plugin_dir)) { std::cerr << "WARNING: Plugin directory does not exist: " << plugin_dir << std::endl; @@ -27,7 +26,6 @@ void load_plugins(const std::string &plugin_dir, PluginType type) { } for (const auto &entry : fs::directory_iterator(plugin_dir)) { if (entry.path().extension() == ".so") { - printf("BMH Opening %s\n", entry.path().c_str()); void *raw_handle = dlopen(entry.path().c_str(), RTLD_NOW); if (raw_handle) { // Custom deleter ensures dlclose is called @@ -43,8 +41,6 @@ void load_plugins(const std::string &plugin_dir, PluginType type) { std::cerr << "ERROR: Failed to load plugin: " << entry.path() << " Error: " << dlerror() << std::endl; } - } else { - printf("BMH Skipping %s\n", entry.path().c_str()); } } } From 5bbd9fc65a5a0f66bad2fb8188f72953418d94ec Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 05:53:46 +0000 Subject: [PATCH 19/43] Use unique_ptr and use more namespaces Signed-off-by: Ben Howe --- libs/qec/include/cudaq/qec/plugin_loader.h | 23 ++++++++++++++++------ libs/qec/lib/decoder.cpp | 4 ++-- libs/qec/lib/plugin_loader.cpp | 14 ++++++------- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/libs/qec/include/cudaq/qec/plugin_loader.h b/libs/qec/include/cudaq/qec/plugin_loader.h index 280b1f1..a416824 100644 --- a/libs/qec/include/cudaq/qec/plugin_loader.h +++ b/libs/qec/include/cudaq/qec/plugin_loader.h @@ -6,14 +6,15 @@ * the terms of the Apache License 2.0 which accompanies this distribution. * ******************************************************************************/ -#ifndef PLUGIN_LOADER_H -#define PLUGIN_LOADER_H +#pragma once #include #include #include #include +namespace cudaq::qec { + /// @brief Enum to define different types of plugins enum class PluginType { DECODER, // Decoder plugins @@ -21,11 +22,21 @@ enum class PluginType { // Add other plugin types here as needed }; +struct PluginDeleter // deleter +{ + void operator()(void *h) const { + if (h) + dlclose(h); + }; +}; + /// @brief A struct to store plugin handle with its type struct PluginHandle { - std::shared_ptr handle; // Pointer to the shared library handle. This is - // the result of dlopen() function. - PluginType type; // Type of the plugin (e.g., decoder, code, etc) + // Pointer to the shared library handle. This is the result of dlopen() + // function. + std::unique_ptr handle; + // Type of the plugin (e.g., decoder, code, etc) + PluginType type; }; /// @brief Function to load plugins from a directory based on type @@ -39,4 +50,4 @@ void load_plugins(const std::string &plugin_dir, PluginType type); /// be cleaned up. void cleanup_plugins(PluginType type); -#endif // PLUGIN_LOADER_H +} // namespace cudaq::qec \ No newline at end of file diff --git a/libs/qec/lib/decoder.cpp b/libs/qec/lib/decoder.cpp index 656a345..35e3dc9 100644 --- a/libs/qec/lib/decoder.cpp +++ b/libs/qec/lib/decoder.cpp @@ -74,7 +74,6 @@ std::unique_ptr get_decoder(const std::string &name, const cudaqx::heterogeneous_map options) { return decoder::get(name, H, options); } -} // namespace cudaq::qec // Constructor function for auto-loading plugins __attribute__((constructor)) void load_decoder_plugins() { @@ -89,4 +88,5 @@ __attribute__((constructor)) void load_decoder_plugins() { __attribute__((destructor)) void cleanup_decoder_plugins() { // Clean up decoder-specific plugins cleanup_plugins(PluginType::DECODER); -} \ No newline at end of file +} +} // namespace cudaq::qec \ No newline at end of file diff --git a/libs/qec/lib/plugin_loader.cpp b/libs/qec/lib/plugin_loader.cpp index 35a69f5..d5d7c37 100644 --- a/libs/qec/lib/plugin_loader.cpp +++ b/libs/qec/lib/plugin_loader.cpp @@ -12,6 +12,8 @@ namespace fs = std::filesystem; +namespace cudaq::qec { + static std::map &get_plugin_handles() { static std::map plugin_handles; return plugin_handles; @@ -28,15 +30,11 @@ void load_plugins(const std::string &plugin_dir, PluginType type) { if (entry.path().extension() == ".so") { void *raw_handle = dlopen(entry.path().c_str(), RTLD_NOW); if (raw_handle) { - // Custom deleter ensures dlclose is called - auto deleter = [](void *h) { - if (h) - dlclose(h); - }; - get_plugin_handles().emplace( entry.path().filename().string(), - PluginHandle{std::shared_ptr(raw_handle, deleter), type}); + PluginHandle{std::unique_ptr(raw_handle, + PluginDeleter()), + type}); } else { std::cerr << "ERROR: Failed to load plugin: " << entry.path() << " Error: " << dlerror() << std::endl; @@ -57,3 +55,5 @@ void cleanup_plugins(PluginType type) { } } } + +} // namespace cudaq::qec \ No newline at end of file From 1eac4aefd7b28113a329ad9ed949251279f64810 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 06:05:12 +0000 Subject: [PATCH 20/43] More cleanup Signed-off-by: Ben Howe --- libs/core/include/cuda-qx/core/library_utils.h | 2 -- libs/qec/python/bindings/py_decoder.cpp | 9 --------- 2 files changed, 11 deletions(-) diff --git a/libs/core/include/cuda-qx/core/library_utils.h b/libs/core/include/cuda-qx/core/library_utils.h index 4a864ff..d8e97f5 100644 --- a/libs/core/include/cuda-qx/core/library_utils.h +++ b/libs/core/include/cuda-qx/core/library_utils.h @@ -54,10 +54,8 @@ inline static void getCUDAQXLibraryPath(CUDAQXLibraryData *data) { inline static int getCUDAQXLibraryPath(struct dl_phdr_info *info, size_t size, void *data) { std::string libraryName(info->dlpi_name); - printf("BMH libraryName is %s\n", libraryName.c_str()); auto casted = static_cast(data); if (libraryName.find(casted->libName) != std::string::npos) { - printf("BMH Setting it.\n"); casted->path = std::string(info->dlpi_name); } return 0; diff --git a/libs/qec/python/bindings/py_decoder.cpp b/libs/qec/python/bindings/py_decoder.cpp index 11b6789..2b16bc3 100644 --- a/libs/qec/python/bindings/py_decoder.cpp +++ b/libs/qec/python/bindings/py_decoder.cpp @@ -14,7 +14,6 @@ #include "common/Logger.h" #include "cudaq/qec/decoder.h" -#include "cudaq/qec/plugin_loader.h" #include "type_casters.h" #include "utils.h" @@ -71,14 +70,6 @@ std::unordered_map() : mod.def_submodule("qecrt"); From a39f31c32252de57ee5406830a38b7c93b7441ff Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 17:28:51 +0000 Subject: [PATCH 21/43] Restore Python cleanup Signed-off-by: Ben Howe --- libs/qec/python/bindings/py_decoder.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libs/qec/python/bindings/py_decoder.cpp b/libs/qec/python/bindings/py_decoder.cpp index 2b16bc3..11b6789 100644 --- a/libs/qec/python/bindings/py_decoder.cpp +++ b/libs/qec/python/bindings/py_decoder.cpp @@ -14,6 +14,7 @@ #include "common/Logger.h" #include "cudaq/qec/decoder.h" +#include "cudaq/qec/plugin_loader.h" #include "type_casters.h" #include "utils.h" @@ -70,6 +71,14 @@ std::unordered_map() : mod.def_submodule("qecrt"); From 7d43a3b837f44fdb1a112a3f5f4b61b5ec12853b Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 18:19:25 +0000 Subject: [PATCH 22/43] Build CUDA-Q wheels from source (needed to test CUDA-QX wheels) Signed-off-by: Ben Howe --- .github/actions/get-cudaq-version/action.yaml | 12 +- .github/actions/get-cudaq-wheels/action.yaml | 163 ++++++++++++++++++ .github/workflows/build_wheels.yaml | 68 +++++++- 3 files changed, 231 insertions(+), 12 deletions(-) create mode 100644 .github/actions/get-cudaq-wheels/action.yaml diff --git a/.github/actions/get-cudaq-version/action.yaml b/.github/actions/get-cudaq-version/action.yaml index 907f122..dea4ef0 100644 --- a/.github/actions/get-cudaq-version/action.yaml +++ b/.github/actions/get-cudaq-version/action.yaml @@ -14,11 +14,13 @@ runs: - name: Install jq run: | - if [ -x "$(command -v apt-get)" ]; then - apt-get update - apt-get install -y --no-install-recommends jq - elif [ -x "$(command -v dnf)" ]; then - dnf install -y --nobest --setopt=install_weak_deps=False jq + if [ ! -x "$(command -v jq)" ]; then + if [ -x "$(command -v apt-get)" ]; then + apt-get update + apt-get install -y --no-install-recommends jq + elif [ -x "$(command -v dnf)" ]; then + dnf install -y --nobest --setopt=install_weak_deps=False jq + fi fi shell: bash diff --git a/.github/actions/get-cudaq-wheels/action.yaml b/.github/actions/get-cudaq-wheels/action.yaml new file mode 100644 index 0000000..ce2faf0 --- /dev/null +++ b/.github/actions/get-cudaq-wheels/action.yaml @@ -0,0 +1,163 @@ +name: Get CUDAQ wheels +description: 'Either restore CUDAQ wheels from cache or build them' + +inputs: + repo: + description: 'CUDAQ repository.' + required: true + ref: + description: 'The branch, tag or SHA to checkout.' + required: true + token: + description: 'CUDAQ repository access token.' + default: '' + required: false + pr-number: + description: 'Unique pull request identifier.' + default: '' + required: false + save-build: + description: 'Indicates whether to save the build' + default: 'false' + required: false + lookup-only: + description: 'Check if a cache entry exists without downloading the cache' + default: 'false' + required: false + platform: + description: 'Platform (amd64 or arm64)' + default: '' + required: true +outputs: + found-cache: + description: 'A boolean value to indicate that a cache entry was found.' + value: ${{ steps.check-cache.outputs.valid }} + +runs: + using: "composite" + steps: + # ========================================================================== + # Try to restore from cache + # ========================================================================== + + - name: Create CUDAQ wheel cache key + id: cudaq-wheels-key + env: + # This are a list of files that when changed should require a new cudaq build + to_hash: | + .github/actions/get-cudaq-wheels/** + .cudaq_version + run: | + hash=${{ hashFiles(format('{0}', env.to_hash)) }} + echo "main=cudaq-wheels-${{ inputs.platform }}-${{ inputs.ref }}-$hash" >> $GITHUB_OUTPUT + if [[ -n "${{ inputs.pr-number }}" ]]; then + echo "pr=-pr${{ inputs.pr-number }}" >> $GITHUB_OUTPUT + fi + sudo mkdir /cudaq-wheels && sudo chmod 777 /cudaq-wheels + shell: bash --noprofile --norc -euo pipefail {0} + + - name: Try to restoring CUDAQ wheels from cache + id: restore-cudaq-wheels + uses: actions/cache/restore@v4 + with: + fail-on-cache-miss: false + path: /cudaq-wheels + key: ${{ steps.cudaq-wheels-key.outputs.main }}${{ steps.cudaq-wheels-key.outputs.pr }} + restore-keys: ${{ steps.cudaq-wheels-key.outputs.main }} + lookup-only: ${{ inputs.lookup-only }} + + # The restore action could find a partial match using the `restore-keys`. In such cases + # it would still report `cache-hit` as false, but would load the cache from the partial + # one. Thus, we need to check whether the cache is valid by other means. + - name: Check if cache is valid + id: check-cache + run: | + if [[ "${{ steps.restore-cudaq-wheels.outputs.cache-matched-key }}" == "" ]]; then + echo "valid=false" >> $GITHUB_OUTPUT + else + echo "valid=true" >> $GITHUB_OUTPUT + fi + shell: bash --noprofile --norc -euo pipefail {0} + + # ========================================================================== + # Build CUDAQ wheels + # ========================================================================== + + - name: Login to GitHub CR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ github.token }} + + - name: Get CUDAQ code + if: steps.check-cache.outputs.valid == 'false' && inputs.lookup-only == 'false' + uses: actions/checkout@v4 + with: + repository: ${{ inputs.repo }} + ref: ${{ inputs.ref }} + path: cudaq + set-safe-directory: true + + - name: Set up context for buildx + run: | + docker context create builder_context + shell: bash --noprofile --norc -euo pipefail {0} + + - name: Set up buildx runner + uses: docker/setup-buildx-action@v3 + with: + endpoint: builder_context + driver-opts: network=host + + - name: Build 3.10 wheel + uses: docker/build-push-action@v5 + with: + context: cudaq + file: ./cudaq/docker/release/cudaq.wheel.Dockerfile + build-args: | + base_image=ghcr.io/nvidia/cuda-quantum-devdeps:manylinux-${{ inputs.platform }}-cu12.0-gcc11-main + release_version=0.99.99 + python_version=3.10 + outputs: /cudaq-wheels + + - name: Build 3.11 wheel + uses: docker/build-push-action@v5 + with: + context: cudaq + file: ./cudaq/docker/release/cudaq.wheel.Dockerfile + build-args: | + base_image=ghcr.io/nvidia/cuda-quantum-devdeps:manylinux-${{ inputs.platform }}-cu12.0-gcc11-main + release_version=0.99.99 + python_version=3.11 + outputs: /cudaq-wheels + + - name: Build 3.12 wheel + uses: docker/build-push-action@v5 + with: + context: cudaq + file: ./cudaq/docker/release/cudaq.wheel.Dockerfile + build-args: | + base_image=ghcr.io/nvidia/cuda-quantum-devdeps:manylinux-${{ inputs.platform }}-cu12.0-gcc11-main + release_version=0.99.99 + python_version=3.12 + outputs: /cudaq-wheels + + - name: Upload wheel + uses: actions/upload-artifact@v4 + with: + name: cudaq-wheels-${{ inputs.platform }} + path: /cudaq-wheels + retention-days: 10 + if-no-files-found: error + + # ========================================================================== + # Store CUDAQ wheels cache + # ========================================================================== + + - name: Store CUDAQ wheels in the cache + if: steps.check-cache.outputs.valid == 'false' && inputs.save-build == 'true' && inputs.lookup-only == 'false' + uses: actions/cache/save@v4 + with: + path: /cudaq-wheels + key: ${{ steps.cudaq-wheels-key.outputs.main }}${{ steps.cudaq-wheels-key.outputs.pr }} diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index 4ddd69a..73c4322 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -21,8 +21,8 @@ concurrency: cancel-in-progress: true jobs: - linux-build: - name: Linux build + build-cudaqx-wheels: + name: Build CUDA-QX wheels runs-on: linux-${{ matrix.platform }}-cpu8 # CUDAQ requires a highly specialized environment to build. Thus, it is much # easier to rely on their's devdeps images to do the building. @@ -67,7 +67,7 @@ jobs: - name: Build CUDAQ toolchain if: ${{ !inputs.artifacts_from_run }} run: | - .github/workflows/scripts/build_cudaq.sh ${{ matrix.python }} + .github/workflows/scripts/build_cudaq.sh ${{ matrix.python }} - name: Build wheels if: ${{ !inputs.artifacts_from_run }} @@ -84,9 +84,49 @@ jobs: name: wheels-py${{ matrix.python }}-${{ matrix.platform }} path: /wheels/** + # Building the CUDA-Q wheels must be done outside of a container context, so + # this is a separate job. + build-cudaq-wheels: + name: Build CUDA-Q wheels + strategy: + fail-fast: false + matrix: + platform: ['amd64', 'arm64'] + runs-on: ${{ startsWith(github.repository, 'NVIDIA/cudaqx') && format('linux-{0}-cpu32', matrix.platform) || 'ubuntu-latest' }} + permissions: + actions: write + contents: read + pull-requests: read + steps: + - name: Get code + uses: actions/checkout@v4 + with: + set-safe-directory: true + + - name: Get required CUDAQ version + id: get-cudaq-version + uses: ./.github/actions/get-cudaq-version + + - name: Get CUDAQ wheels + uses: ./.github/actions/get-cudaq-wheels + with: + repo: ${{ steps.get-cudaq-version.outputs.repo }} + ref: ${{ steps.get-cudaq-version.outputs.ref }} + token: ${{ secrets.CUDAQ_ACCESS_TOKEN }} + save-build: true + platform: ${{ matrix.platform }} + + - name: Upload CUDAQ wheels + uses: actions/upload-artifact@v4 + with: + name: cudaq-wheels-${{ matrix.platform }} + path: /cudaq-wheels + retention-days: 10 + if-no-files-found: error + test-cudaqx-wheels: name: Test CUDA-QX wheels (CPU) - needs: linux-build + needs: [build-cudaqx-wheels, build-cudaq-wheels] runs-on: linux-${{ matrix.platform }}-cpu4 container: ubuntu:22.04 permissions: @@ -114,7 +154,14 @@ jobs: bash .github/workflows/scripts/install_git_cli.sh apt install -y --no-install-recommends libgfortran5 unzip - - name: Download CUDAQX wheels + - name: Download CUDA-Q wheels + uses: actions/download-artifact@v4 + with: + name: cudaq-wheels-${{ matrix.platform }} + path: /cudaq-wheels + run-id: ${{ inputs.artifacts_from_run || github.run_id }} + + - name: Download CUDA-QX wheels uses: actions/download-artifact@v4 with: name: wheels-py${{ matrix.python }}-${{ matrix.platform }} @@ -128,7 +175,7 @@ jobs: test-wheels-gpu: name: Test CUDA-QX wheels (GPU) - needs: linux-build + needs: [build-cudaqx-wheels, build-cudaq-wheels] runs-on: linux-${{ matrix.runner.arch }}-gpu-${{ matrix.runner.gpu }}-latest-1 container: image: nvidia/cuda:12.0.0-base-ubuntu22.04 @@ -168,7 +215,14 @@ jobs: #echo "Running cat /proc/sys/kernel/core_pattern" #cat /proc/sys/kernel/core_pattern - - name: Download CUDAQX wheels + - name: Download CUDA-Q wheels + uses: actions/download-artifact@v4 + with: + name: cudaq-wheels-${{ matrix.platform }} + path: /cudaq-wheels + run-id: ${{ inputs.artifacts_from_run || github.run_id }} + + - name: Download CUDA-QX wheels uses: actions/download-artifact@v4 with: name: wheels-py${{ matrix.python }}-${{ matrix.runner.arch }} From 4b50c6cb59d87ae86234ff4bb4309e6bc77ce85f Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 18:59:24 +0000 Subject: [PATCH 23/43] Fix duplicate artifact upload error Signed-off-by: Ben Howe --- .github/actions/get-cudaq-wheels/action.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/actions/get-cudaq-wheels/action.yaml b/.github/actions/get-cudaq-wheels/action.yaml index ce2faf0..475499a 100644 --- a/.github/actions/get-cudaq-wheels/action.yaml +++ b/.github/actions/get-cudaq-wheels/action.yaml @@ -143,14 +143,6 @@ runs: python_version=3.12 outputs: /cudaq-wheels - - name: Upload wheel - uses: actions/upload-artifact@v4 - with: - name: cudaq-wheels-${{ inputs.platform }} - path: /cudaq-wheels - retention-days: 10 - if-no-files-found: error - # ========================================================================== # Store CUDAQ wheels cache # ========================================================================== From 2f52cb84fe86e319de082bc7882e79706c107af3 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 19:08:12 +0000 Subject: [PATCH 24/43] Update test script to use custom-built CUDA-Q wheels Signed-off-by: Ben Howe --- scripts/ci/test_wheels.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/ci/test_wheels.sh b/scripts/ci/test_wheels.sh index 321572e..b2ac877 100644 --- a/scripts/ci/test_wheels.sh +++ b/scripts/ci/test_wheels.sh @@ -25,6 +25,13 @@ python=python${python_version} ${python} -m pip install --no-cache-dir pytest +# If special CUDA-Q wheels have been built for this test, install them here. This will +if [ -d /cudaq-wheels ]; then + echo "Custom CUDA-Q wheels directory found; installing ..." + ls -1 /cudaq-wheels/cuda_quantum-*-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl + ${python} -m pip install /cudaq-wheels/cuda_quantum-*-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl +fi + # QEC library # ====================================== From ea3423996992bd7a90782122165029ab94c76b22 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 19:37:26 +0000 Subject: [PATCH 25/43] artifacts_from_run updates Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index 73c4322..52cf5c8 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -99,15 +99,18 @@ jobs: pull-requests: read steps: - name: Get code + if: ${{ !inputs.artifacts_from_run }} uses: actions/checkout@v4 with: set-safe-directory: true - name: Get required CUDAQ version + if: ${{ !inputs.artifacts_from_run }} id: get-cudaq-version uses: ./.github/actions/get-cudaq-version - name: Get CUDAQ wheels + if: ${{ !inputs.artifacts_from_run }} uses: ./.github/actions/get-cudaq-wheels with: repo: ${{ steps.get-cudaq-version.outputs.repo }} @@ -117,6 +120,7 @@ jobs: platform: ${{ matrix.platform }} - name: Upload CUDAQ wheels + if: ${{ !inputs.artifacts_from_run }} uses: actions/upload-artifact@v4 with: name: cudaq-wheels-${{ matrix.platform }} From 629920bbee17d95ec743b67d6d02ab58581f976d Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 19:39:32 +0000 Subject: [PATCH 26/43] artifacts_from_run updates Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index 52cf5c8..8b53b32 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -28,7 +28,7 @@ jobs: # easier to rely on their's devdeps images to do the building. # FIXME: there is no guarantee that this CUDA-Q image aligns with the CUDA-Q # commit that we are trying to align with. - container: ${{ inputs.artifacts_from_run && 'ubuntu-latest' || format('ghcr.io/nvidia/cuda-quantum-devdeps:manylinux-{0}-{1}-main', matrix.platform, matrix.toolchain.id) }} + container: ${{ inputs.artifacts_from_run && 'ubuntu:22.04' || format('ghcr.io/nvidia/cuda-quantum-devdeps:manylinux-{0}-{1}-main', matrix.platform, matrix.toolchain.id) }} permissions: actions: write contents: read From 7ae5056bb8d50b799c27dcf100ffd47353a280fb Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 19:52:37 +0000 Subject: [PATCH 27/43] artifacts_from_run: provide token Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index 8b53b32..f6c60af 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -225,6 +225,7 @@ jobs: name: cudaq-wheels-${{ matrix.platform }} path: /cudaq-wheels run-id: ${{ inputs.artifacts_from_run || github.run_id }} + github-token: ${{ github.token }} - name: Download CUDA-QX wheels uses: actions/download-artifact@v4 @@ -232,6 +233,7 @@ jobs: name: wheels-py${{ matrix.python }}-${{ matrix.runner.arch }} path: /wheels run-id: ${{ inputs.artifacts_from_run || github.run_id }} + github-token: ${{ github.token }} - name: Test wheels run: | From 00a8297dde18fc66326db9c774b226e75220beff Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 20:00:42 +0000 Subject: [PATCH 28/43] More tokens Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index f6c60af..c8c4895 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -164,6 +164,7 @@ jobs: name: cudaq-wheels-${{ matrix.platform }} path: /cudaq-wheels run-id: ${{ inputs.artifacts_from_run || github.run_id }} + github-token: ${{ github.token }} - name: Download CUDA-QX wheels uses: actions/download-artifact@v4 @@ -171,6 +172,7 @@ jobs: name: wheels-py${{ matrix.python }}-${{ matrix.platform }} path: /wheels run-id: ${{ inputs.artifacts_from_run || github.run_id }} + github-token: ${{ github.token }} - name: Test wheels run: | From a36a515ec166742eaa649d999bd07bece6725aa6 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 20:06:27 +0000 Subject: [PATCH 29/43] Token debug Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index c8c4895..6499511 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -164,7 +164,7 @@ jobs: name: cudaq-wheels-${{ matrix.platform }} path: /cudaq-wheels run-id: ${{ inputs.artifacts_from_run || github.run_id }} - github-token: ${{ github.token }} + github-token: ${{ secrets.WORKFLOW_TOKEN }} - name: Download CUDA-QX wheels uses: actions/download-artifact@v4 @@ -172,7 +172,7 @@ jobs: name: wheels-py${{ matrix.python }}-${{ matrix.platform }} path: /wheels run-id: ${{ inputs.artifacts_from_run || github.run_id }} - github-token: ${{ github.token }} + github-token: ${{ secrets.WORKFLOW_TOKEN }} - name: Test wheels run: | @@ -227,7 +227,7 @@ jobs: name: cudaq-wheels-${{ matrix.platform }} path: /cudaq-wheels run-id: ${{ inputs.artifacts_from_run || github.run_id }} - github-token: ${{ github.token }} + github-token: ${{ secrets.WORKFLOW_TOKEN }} - name: Download CUDA-QX wheels uses: actions/download-artifact@v4 @@ -235,7 +235,7 @@ jobs: name: wheels-py${{ matrix.python }}-${{ matrix.runner.arch }} path: /wheels run-id: ${{ inputs.artifacts_from_run || github.run_id }} - github-token: ${{ github.token }} + github-token: ${{ secrets.WORKFLOW_TOKEN }} - name: Test wheels run: | From 1200ad34839d3a0a1c88a62e7a587dbba1978e3c Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 20:13:03 +0000 Subject: [PATCH 30/43] test_wheels debug Signed-off-by: Ben Howe --- scripts/ci/test_wheels.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/ci/test_wheels.sh b/scripts/ci/test_wheels.sh index b2ac877..db64f15 100644 --- a/scripts/ci/test_wheels.sh +++ b/scripts/ci/test_wheels.sh @@ -28,6 +28,9 @@ ${python} -m pip install --no-cache-dir pytest # If special CUDA-Q wheels have been built for this test, install them here. This will if [ -d /cudaq-wheels ]; then echo "Custom CUDA-Q wheels directory found; installing ..." + echo "First ls /cudaq-wheels" + ls /cudaq-wheels + echo "Now show what will be pip installed" ls -1 /cudaq-wheels/cuda_quantum-*-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl ${python} -m pip install /cudaq-wheels/cuda_quantum-*-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl fi From e56c0c0325afdefa8ffe2327ce64dcd0adbb022f Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 20:15:29 +0000 Subject: [PATCH 31/43] Fix test_wheels wheel name Signed-off-by: Ben Howe --- scripts/ci/test_wheels.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/ci/test_wheels.sh b/scripts/ci/test_wheels.sh index db64f15..d0004f9 100644 --- a/scripts/ci/test_wheels.sh +++ b/scripts/ci/test_wheels.sh @@ -31,8 +31,8 @@ if [ -d /cudaq-wheels ]; then echo "First ls /cudaq-wheels" ls /cudaq-wheels echo "Now show what will be pip installed" - ls -1 /cudaq-wheels/cuda_quantum-*-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl - ${python} -m pip install /cudaq-wheels/cuda_quantum-*-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl + ls -1 /cudaq-wheels/cuda_quantum_*-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl + ${python} -m pip install /cudaq-wheels/cuda_quantum_*-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl fi # QEC library From 2143901b1ced5ef199570ba15a9842fab00d89aa Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 20:35:40 +0000 Subject: [PATCH 32/43] Update dependency on cuda-quantum for wheel Signed-off-by: Ben Howe --- libs/qec/pyproject.toml | 2 +- libs/solvers/pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/qec/pyproject.toml b/libs/qec/pyproject.toml index 2371daf..ea809cd 100644 --- a/libs/qec/pyproject.toml +++ b/libs/qec/pyproject.toml @@ -11,7 +11,7 @@ maintainers = [{name = "NVIDIA Corporation & Affiliates"}] requires-python = ">=3.10" readme = "README.md" dependencies = [ - 'cuda-quantum-cu12 ~= 0.9.0', + 'cuda-quantum-cu12 >= 0.9', ] classifiers = [ 'Intended Audience :: Science/Research', diff --git a/libs/solvers/pyproject.toml b/libs/solvers/pyproject.toml index ebe26a3..dd75f0b 100644 --- a/libs/solvers/pyproject.toml +++ b/libs/solvers/pyproject.toml @@ -11,7 +11,7 @@ maintainers = [{name = "NVIDIA Corporation & Affiliates"}] requires-python = ">=3.10" readme = "README.md" dependencies = [ - 'cuda-quantum-cu12 ~= 0.9.0', + 'cuda-quantum-cu12 >= 0.9', 'fastapi', 'networkx', 'pyscf', From 2aefae0ea13e8642f7f0c14ca0160f83e7c3611a Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 21:11:39 +0000 Subject: [PATCH 33/43] Fix download Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index 6499511..61ec4cb 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -224,7 +224,7 @@ jobs: - name: Download CUDA-Q wheels uses: actions/download-artifact@v4 with: - name: cudaq-wheels-${{ matrix.platform }} + name: cudaq-wheels-${{ matrix.runner.arch }} path: /cudaq-wheels run-id: ${{ inputs.artifacts_from_run || github.run_id }} github-token: ${{ secrets.WORKFLOW_TOKEN }} From 53098595600908ad8fbf4c236b8e11cdafda4cc4 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 21:57:33 +0000 Subject: [PATCH 34/43] Update conditional logic Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index 61ec4cb..e949aad 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -23,6 +23,7 @@ concurrency: jobs: build-cudaqx-wheels: name: Build CUDA-QX wheels + if: ${{ !inputs.artifacts_from_run }} runs-on: linux-${{ matrix.platform }}-cpu8 # CUDAQ requires a highly specialized environment to build. Thus, it is much # easier to rely on their's devdeps images to do the building. @@ -45,18 +46,15 @@ jobs: steps: - name: Get code - if: ${{ !inputs.artifacts_from_run }} uses: actions/checkout@v4 with: set-safe-directory: true - name: Get required CUDAQ version - if: ${{ !inputs.artifacts_from_run }} id: get-cudaq-version uses: ./.github/actions/get-cudaq-version - name: Get CUDAQ code - if: ${{ !inputs.artifacts_from_run }} uses: actions/checkout@v4 with: repository: ${{ steps.get-cudaq-version.outputs.repo }} @@ -65,12 +63,10 @@ jobs: set-safe-directory: true - name: Build CUDAQ toolchain - if: ${{ !inputs.artifacts_from_run }} run: | .github/workflows/scripts/build_cudaq.sh ${{ matrix.python }} - name: Build wheels - if: ${{ !inputs.artifacts_from_run }} run: | .github/workflows/scripts/build_wheels.sh \ --cudaq-prefix $HOME/.cudaq \ @@ -78,7 +74,6 @@ jobs: --python-version ${{ matrix.python }} - name: Upload artifact - if: ${{ !inputs.artifacts_from_run }} uses: actions/upload-artifact@v4 with: name: wheels-py${{ matrix.python }}-${{ matrix.platform }} @@ -88,6 +83,7 @@ jobs: # this is a separate job. build-cudaq-wheels: name: Build CUDA-Q wheels + if: ${{ !inputs.artifacts_from_run }} strategy: fail-fast: false matrix: @@ -99,18 +95,15 @@ jobs: pull-requests: read steps: - name: Get code - if: ${{ !inputs.artifacts_from_run }} uses: actions/checkout@v4 with: set-safe-directory: true - name: Get required CUDAQ version - if: ${{ !inputs.artifacts_from_run }} id: get-cudaq-version uses: ./.github/actions/get-cudaq-version - name: Get CUDAQ wheels - if: ${{ !inputs.artifacts_from_run }} uses: ./.github/actions/get-cudaq-wheels with: repo: ${{ steps.get-cudaq-version.outputs.repo }} @@ -120,7 +113,6 @@ jobs: platform: ${{ matrix.platform }} - name: Upload CUDAQ wheels - if: ${{ !inputs.artifacts_from_run }} uses: actions/upload-artifact@v4 with: name: cudaq-wheels-${{ matrix.platform }} @@ -131,6 +123,7 @@ jobs: test-cudaqx-wheels: name: Test CUDA-QX wheels (CPU) needs: [build-cudaqx-wheels, build-cudaq-wheels] + if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }} runs-on: linux-${{ matrix.platform }}-cpu4 container: ubuntu:22.04 permissions: @@ -182,6 +175,7 @@ jobs: test-wheels-gpu: name: Test CUDA-QX wheels (GPU) needs: [build-cudaqx-wheels, build-cudaq-wheels] + if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }} runs-on: linux-${{ matrix.runner.arch }}-gpu-${{ matrix.runner.gpu }}-latest-1 container: image: nvidia/cuda:12.0.0-base-ubuntu22.04 From 323ac49c32c046ccfcdb6b8da320f5e091e497c9 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 22:02:16 +0000 Subject: [PATCH 35/43] Update conditional logic - 2 Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index e949aad..754d728 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -123,7 +123,7 @@ jobs: test-cudaqx-wheels: name: Test CUDA-QX wheels (CPU) needs: [build-cudaqx-wheels, build-cudaq-wheels] - if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }} + if: ${{ !failure() && !cancelled() }} runs-on: linux-${{ matrix.platform }}-cpu4 container: ubuntu:22.04 permissions: @@ -175,7 +175,7 @@ jobs: test-wheels-gpu: name: Test CUDA-QX wheels (GPU) needs: [build-cudaqx-wheels, build-cudaq-wheels] - if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }} + if: ${{ !failure() && !cancelled() }} runs-on: linux-${{ matrix.runner.arch }}-gpu-${{ matrix.runner.gpu }}-latest-1 container: image: nvidia/cuda:12.0.0-base-ubuntu22.04 From 9841a11d008c1d2913408a79a64f1323fb150495 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sat, 18 Jan 2025 22:13:19 +0000 Subject: [PATCH 36/43] Update conditional logic - 3 Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index 754d728..c8f1f2e 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -29,7 +29,7 @@ jobs: # easier to rely on their's devdeps images to do the building. # FIXME: there is no guarantee that this CUDA-Q image aligns with the CUDA-Q # commit that we are trying to align with. - container: ${{ inputs.artifacts_from_run && 'ubuntu:22.04' || format('ghcr.io/nvidia/cuda-quantum-devdeps:manylinux-{0}-{1}-main', matrix.platform, matrix.toolchain.id) }} + container: ${{ format('ghcr.io/nvidia/cuda-quantum-devdeps:manylinux-{0}-{1}-main', matrix.platform, matrix.toolchain.id) }} permissions: actions: write contents: read @@ -157,7 +157,7 @@ jobs: name: cudaq-wheels-${{ matrix.platform }} path: /cudaq-wheels run-id: ${{ inputs.artifacts_from_run || github.run_id }} - github-token: ${{ secrets.WORKFLOW_TOKEN }} + github-token: ${{ inputs.artifacts_from_run && secrets.WORKFLOW_TOKEN || github.token }} - name: Download CUDA-QX wheels uses: actions/download-artifact@v4 @@ -165,7 +165,7 @@ jobs: name: wheels-py${{ matrix.python }}-${{ matrix.platform }} path: /wheels run-id: ${{ inputs.artifacts_from_run || github.run_id }} - github-token: ${{ secrets.WORKFLOW_TOKEN }} + github-token: ${{ inputs.artifacts_from_run && secrets.WORKFLOW_TOKEN || github.token }} - name: Test wheels run: | @@ -221,7 +221,7 @@ jobs: name: cudaq-wheels-${{ matrix.runner.arch }} path: /cudaq-wheels run-id: ${{ inputs.artifacts_from_run || github.run_id }} - github-token: ${{ secrets.WORKFLOW_TOKEN }} + github-token: ${{ inputs.artifacts_from_run && secrets.WORKFLOW_TOKEN || github.token }} - name: Download CUDA-QX wheels uses: actions/download-artifact@v4 @@ -229,7 +229,7 @@ jobs: name: wheels-py${{ matrix.python }}-${{ matrix.runner.arch }} path: /wheels run-id: ${{ inputs.artifacts_from_run || github.run_id }} - github-token: ${{ secrets.WORKFLOW_TOKEN }} + github-token: ${{ inputs.artifacts_from_run && secrets.WORKFLOW_TOKEN || github.token }} - name: Test wheels run: | From 537dcc8b1a738587d00ea34f0b3c6c42b247515f Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sun, 19 Jan 2025 17:13:16 +0000 Subject: [PATCH 37/43] Add retention-days Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 3 ++- .github/workflows/pr_sanity_checks.yaml | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index c8f1f2e..662a40f 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -78,6 +78,7 @@ jobs: with: name: wheels-py${{ matrix.python }}-${{ matrix.platform }} path: /wheels/** + retention-days: 14 # Building the CUDA-Q wheels must be done outside of a container context, so # this is a separate job. @@ -117,7 +118,7 @@ jobs: with: name: cudaq-wheels-${{ matrix.platform }} path: /cudaq-wheels - retention-days: 10 + retention-days: 14 if-no-files-found: error test-cudaqx-wheels: diff --git a/.github/workflows/pr_sanity_checks.yaml b/.github/workflows/pr_sanity_checks.yaml index dd1ff29..7761d84 100644 --- a/.github/workflows/pr_sanity_checks.yaml +++ b/.github/workflows/pr_sanity_checks.yaml @@ -107,6 +107,7 @@ jobs: with: name: clang-format-patch path: clang-*.patch + retention-days: 14 check-python: name: Check Python code formatting @@ -165,6 +166,7 @@ jobs: with: name: yapf-format-patch path: yapf-*.patch + retention-days: 14 # This job is used for branch protection checks. verify: From 0346badd4265f29f56ec8a7a04a548de51a59ce1 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sun, 19 Jan 2025 17:18:26 +0000 Subject: [PATCH 38/43] Use smaller runners to be more resource friendly Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index 662a40f..c4ac34b 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -89,7 +89,7 @@ jobs: fail-fast: false matrix: platform: ['amd64', 'arm64'] - runs-on: ${{ startsWith(github.repository, 'NVIDIA/cudaqx') && format('linux-{0}-cpu32', matrix.platform) || 'ubuntu-latest' }} + runs-on: ${{ startsWith(github.repository, 'NVIDIA/cudaqx') && format('linux-{0}-cpu8', matrix.platform) || 'ubuntu-latest' }} permissions: actions: write contents: read From 8a83f43f52c72f4e0cf97a93a2ea77bcc3e51f00 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sun, 19 Jan 2025 17:26:01 +0000 Subject: [PATCH 39/43] Cleanup Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 2 +- libs/qec/include/cudaq/qec/plugin_loader.h | 2 +- libs/qec/lib/decoder.cpp | 2 +- libs/qec/lib/plugin_loader.cpp | 2 +- scripts/ci/test_wheels.sh | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index c4ac34b..96339fe 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -29,7 +29,7 @@ jobs: # easier to rely on their's devdeps images to do the building. # FIXME: there is no guarantee that this CUDA-Q image aligns with the CUDA-Q # commit that we are trying to align with. - container: ${{ format('ghcr.io/nvidia/cuda-quantum-devdeps:manylinux-{0}-{1}-main', matrix.platform, matrix.toolchain.id) }} + container: ghcr.io/nvidia/cuda-quantum-devdeps:manylinux-${{ matrix.platform }}-${{ matrix.toolchain.id }}-main permissions: actions: write contents: read diff --git a/libs/qec/include/cudaq/qec/plugin_loader.h b/libs/qec/include/cudaq/qec/plugin_loader.h index a416824..4a7cdd4 100644 --- a/libs/qec/include/cudaq/qec/plugin_loader.h +++ b/libs/qec/include/cudaq/qec/plugin_loader.h @@ -50,4 +50,4 @@ void load_plugins(const std::string &plugin_dir, PluginType type); /// be cleaned up. void cleanup_plugins(PluginType type); -} // namespace cudaq::qec \ No newline at end of file +} // namespace cudaq::qec diff --git a/libs/qec/lib/decoder.cpp b/libs/qec/lib/decoder.cpp index 35e3dc9..1a31b32 100644 --- a/libs/qec/lib/decoder.cpp +++ b/libs/qec/lib/decoder.cpp @@ -89,4 +89,4 @@ __attribute__((destructor)) void cleanup_decoder_plugins() { // Clean up decoder-specific plugins cleanup_plugins(PluginType::DECODER); } -} // namespace cudaq::qec \ No newline at end of file +} // namespace cudaq::qec diff --git a/libs/qec/lib/plugin_loader.cpp b/libs/qec/lib/plugin_loader.cpp index d5d7c37..c84dd69 100644 --- a/libs/qec/lib/plugin_loader.cpp +++ b/libs/qec/lib/plugin_loader.cpp @@ -56,4 +56,4 @@ void cleanup_plugins(PluginType type) { } } -} // namespace cudaq::qec \ No newline at end of file +} // namespace cudaq::qec diff --git a/scripts/ci/test_wheels.sh b/scripts/ci/test_wheels.sh index d0004f9..711f68b 100644 --- a/scripts/ci/test_wheels.sh +++ b/scripts/ci/test_wheels.sh @@ -39,7 +39,7 @@ fi # ====================================== ${python} -m pip install /wheels/cudaq_qec-*-cp${python_version_no_dot}-cp${python_version_no_dot}-*.whl -${python} -m pytest -s libs/qec/python/tests/test_decoder.py::test_decoder_plugin_initialization # libs/qec/python/tests/ +${python} -m pytest -s libs/qec/python/tests/ # Solvers library # ====================================== From 366c0216d6c5eb4fe96f36d676097ddc2409b051 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sun, 19 Jan 2025 17:48:44 +0000 Subject: [PATCH 40/43] Remove commented out / unneeded code Signed-off-by: Ben Howe --- scripts/ci/test_wheels.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/ci/test_wheels.sh b/scripts/ci/test_wheels.sh index 711f68b..9f91a0b 100644 --- a/scripts/ci/test_wheels.sh +++ b/scripts/ci/test_wheels.sh @@ -20,9 +20,6 @@ python_version=$1 python_version_no_dot=$(echo $python_version | tr -d '.') # 3.10 --> 310 python=python${python_version} -#apt-get update && apt-get install -y --no-install-recommends \ -# libgfortran5 python${python_version} python$(echo ${python_version} | cut -d . -f 1)-pip - ${python} -m pip install --no-cache-dir pytest # If special CUDA-Q wheels have been built for this test, install them here. This will From 9bb4b6c4eca76712d973f333e8d74cd7ba9a1dfd Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sun, 19 Jan 2025 17:57:38 +0000 Subject: [PATCH 41/43] Add option to use released CUDA-Q wheels instead of building Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index 96339fe..6dcec15 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -6,11 +6,19 @@ on: build_type: type: choice required: true - description: 'Build Type' + description: 'Build Type (ignored if using artifacts from prior run)' default: 'Release' options: - 'Release' - 'Debug' + cudaq_wheels: + type: choice + required: true + description: 'CUDA-Q wheel source (released version from PyPI or Custom built using .cudaq_version in repo)' + default: 'Custom' + options: + - 'Custom' + - 'PyPI' artifacts_from_run: type: string description: Optional argument to take artifacts from a prior run of this workflow; facilitates rerunning a failed workflow without re-building the artifacts. @@ -84,7 +92,7 @@ jobs: # this is a separate job. build-cudaq-wheels: name: Build CUDA-Q wheels - if: ${{ !inputs.artifacts_from_run }} + if: ${{ !inputs.artifacts_from_run && inputs.cudaq_wheels == 'Custom'}} strategy: fail-fast: false matrix: @@ -153,6 +161,7 @@ jobs: apt install -y --no-install-recommends libgfortran5 unzip - name: Download CUDA-Q wheels + if: ${{ inputs.cudaq_wheels == 'Custom' }} uses: actions/download-artifact@v4 with: name: cudaq-wheels-${{ matrix.platform }} @@ -217,6 +226,7 @@ jobs: #cat /proc/sys/kernel/core_pattern - name: Download CUDA-Q wheels + if: ${{ inputs.cudaq_wheels == 'Custom' }} uses: actions/download-artifact@v4 with: name: cudaq-wheels-${{ matrix.runner.arch }} From 6f245033cee622fc14a7d758593d9707065f8791 Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Sun, 19 Jan 2025 18:02:15 +0000 Subject: [PATCH 42/43] Update runs-on Signed-off-by: Ben Howe --- .github/workflows/build_wheels.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml index 6dcec15..190cf11 100644 --- a/.github/workflows/build_wheels.yaml +++ b/.github/workflows/build_wheels.yaml @@ -74,7 +74,7 @@ jobs: run: | .github/workflows/scripts/build_cudaq.sh ${{ matrix.python }} - - name: Build wheels + - name: Build CUDA-QX wheels run: | .github/workflows/scripts/build_wheels.sh \ --cudaq-prefix $HOME/.cudaq \ @@ -97,7 +97,9 @@ jobs: fail-fast: false matrix: platform: ['amd64', 'arm64'] - runs-on: ${{ startsWith(github.repository, 'NVIDIA/cudaqx') && format('linux-{0}-cpu8', matrix.platform) || 'ubuntu-latest' }} + # Use 32 CPUs rather than 8 (above) because we are only spawning one job per + # platform rather than one job per Python version per platform. + runs-on: ${{ startsWith(github.repository, 'NVIDIA/cudaqx') && format('linux-{0}-cpu32', matrix.platform) || 'ubuntu-latest' }} permissions: actions: write contents: read From 74837ea20e281adeaa9ed14d9728f0ffdb44d9db Mon Sep 17 00:00:00 2001 From: Ben Howe Date: Tue, 21 Jan 2025 22:41:02 +0000 Subject: [PATCH 43/43] Address PR comments Signed-off-by: Ben Howe --- libs/core/include/cuda-qx/core/library_utils.h | 10 +++++----- libs/qec/lib/decoder.cpp | 2 +- .../lib/operators/molecule/drivers/pyscf_driver.cpp | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libs/core/include/cuda-qx/core/library_utils.h b/libs/core/include/cuda-qx/core/library_utils.h index d8e97f5..b0404d3 100644 --- a/libs/core/include/cuda-qx/core/library_utils.h +++ b/libs/core/include/cuda-qx/core/library_utils.h @@ -20,11 +20,11 @@ namespace cudaqx::__internal__ { -enum class CudaQXLibType { Solvers, QEC }; +enum class CUDAQXLibraryType { Solvers, QEC }; /// @brief Structure to hold CUDAQX library data. struct CUDAQXLibraryData { - std::string path; ///< The path to the CUDAQX library. + std::string path; // The path to the CUDAQX library std::string libName; // The name to search for }; @@ -64,13 +64,13 @@ inline static int getCUDAQXLibraryPath(struct dl_phdr_info *info, size_t size, /// @brief Retrieves the path of the CUDAQX library. /// @return A string containing the path to the CUDAQX library. -inline static std::string getCUDAQXLibraryPath(const CudaQXLibType lib) { +inline static std::string getCUDAQXLibraryPath(const CUDAQXLibraryType lib) { __internal__::CUDAQXLibraryData data; data.libName = [&]() -> std::string { switch (lib) { - case CudaQXLibType::QEC: + case CUDAQXLibraryType::QEC: return "/libcudaq-qec."; - case CudaQXLibType::Solvers: + case CUDAQXLibraryType::Solvers: return "/libcudaq-solvers."; } return "UNKNOWN"; diff --git a/libs/qec/lib/decoder.cpp b/libs/qec/lib/decoder.cpp index 1a31b32..f7833d5 100644 --- a/libs/qec/lib/decoder.cpp +++ b/libs/qec/lib/decoder.cpp @@ -79,7 +79,7 @@ std::unique_ptr get_decoder(const std::string &name, __attribute__((constructor)) void load_decoder_plugins() { // Load plugins from the decoder-specific plugin directory std::filesystem::path libPath{cudaqx::__internal__::getCUDAQXLibraryPath( - cudaqx::__internal__::CudaQXLibType::QEC)}; + cudaqx::__internal__::CUDAQXLibraryType::QEC)}; auto pluginPath = libPath.parent_path() / "decoder-plugins"; load_plugins(pluginPath.string(), PluginType::DECODER); } diff --git a/libs/solvers/lib/operators/molecule/drivers/pyscf_driver.cpp b/libs/solvers/lib/operators/molecule/drivers/pyscf_driver.cpp index 4568819..205c07b 100644 --- a/libs/solvers/lib/operators/molecule/drivers/pyscf_driver.cpp +++ b/libs/solvers/lib/operators/molecule/drivers/pyscf_driver.cpp @@ -63,7 +63,7 @@ class RESTPySCFDriver : public MoleculePackageDriver { // Start up the web service, if failed, return nullptr std::filesystem::path libPath{cudaqx::__internal__::getCUDAQXLibraryPath( - cudaqx::__internal__::CudaQXLibType::Solvers)}; + cudaqx::__internal__::CUDAQXLibraryType::Solvers)}; auto cudaqLibPath = libPath.parent_path(); auto cudaqPySCFTool = cudaqLibPath.parent_path() / "bin" / "cudaq-pyscf"; auto argString = cudaqPySCFTool.string() + " --server-mode";