From cdd2b2e240fdefeef0201d1af7725c034c88ce80 Mon Sep 17 00:00:00 2001 From: Kristjan Eimre Date: Fri, 22 May 2026 21:19:34 +0200 Subject: [PATCH 01/16] mv static installs to dockerfile --- .devcontainer/Dockerfile | 15 ++++++++++++++- .devcontainer/devcontainer.json | 13 ++++++++++--- .devcontainer/scripts/post_create.sh | 9 +++++++++ .devcontainer/scripts/venv.sh | 28 ---------------------------- 4 files changed, 33 insertions(+), 32 deletions(-) create mode 100644 .devcontainer/scripts/post_create.sh delete mode 100644 .devcontainer/scripts/venv.sh diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 29363553a..bed7fc62f 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -62,7 +62,7 @@ COPY external/macis/manifest/cgmanifest.json /tmp/macis_cgmanifest.json # Delete build directory after installation ENV KEEP_BUILD_DIR=0 RUN bash /tmp/install_cpp_dependencies.sh /tmp/cpp_cgmanifest.json /tmp/macis_cgmanifest.json && \ - rm /tmp/install_cpp_dependencies.sh /tmp/cpp_cgmanifest.json /tmp/macis_cgmanifest.json + rm /tmp/install_cpp_dependencies.sh /tmp/cpp_cgmanifest.json /tmp/macis_cgmanifest.json # Create/align the non-root user and group (safe for repeated builds) RUN if getent group "$USER_GID" >/dev/null; then \ @@ -89,3 +89,16 @@ USER $USERNAME # Setup bash prompt RUN echo 'export PS1="\[\033[1;34m\]\u@qdk-dev:\w$ \[\033[0m\]"' >> ~/.bashrc + +# Create the Python virtual environment and pre-install workspace-independent +# Python dev dependencies. +ENV VIRTUAL_ENV=/home/$USERNAME/qdk_chemistry_venv \ + PATH=/home/$USERNAME/qdk_chemistry_venv/bin:$PATH +RUN python -m venv "$VIRTUAL_ENV" \ + && pip install --upgrade pip setuptools wheel \ + && pip install --no-cache-dir \ + "ipykernel>=7.2,<8" \ + "pandas>=3.0,<4" \ + "pre-commit>=4.6,<5" \ + "rdkit>=2026.3.2,<2026.4" \ + && echo "source $VIRTUAL_ENV/bin/activate" >> ~/.bashrc diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 412ed3be0..e8998b280 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -60,11 +60,18 @@ } }, "features": { - "ghcr.io/devcontainers/features/git:1": {} + "ghcr.io/devcontainers/features/git:1": {}, + "ghcr.io/devcontainers/features/node:1": { + "version": "lts" + }, + "ghcr.io/devcontainers/features/rust:1": { + "version": "stable", + "profile": "default" + } }, "remoteEnv": { "CPATH": "${containerEnv:CPATH}:/usr/include/hdf5/serial:/usr/include/eigen3" }, - "postCreateCommand": "bash .devcontainer/scripts/venv.sh", + "postCreateCommand": "bash .devcontainer/scripts/post_create.sh", "remoteUser": "vscode" -} +} \ No newline at end of file diff --git a/.devcontainer/scripts/post_create.sh b/.devcontainer/scripts/post_create.sh new file mode 100644 index 000000000..b12054458 --- /dev/null +++ b/.devcontainer/scripts/post_create.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Post-create step: install QDK Chemistry from the mounted source. +set -euo pipefail +source "$HOME/qdk_chemistry_venv/bin/activate" +export CMAKE_BUILD_PARALLEL_LEVEL=4 + +# Install python library +cd ./python +pip install -v .[all] diff --git a/.devcontainer/scripts/venv.sh b/.devcontainer/scripts/venv.sh deleted file mode 100644 index 28d16c59f..000000000 --- a/.devcontainer/scripts/venv.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -python -m venv $HOME/qdk_chemistry_venv -source $HOME/qdk_chemistry_venv/bin/activate - -pip install --upgrade pip - -# Install node -export NVM_DIR="$HOME/.nvm" -mkdir -p $NVM_DIR -wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash -source $NVM_DIR/nvm.sh && nvm install node && nvm use node - -# Install Rust -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y -source $HOME/.cargo/env -which rustc - -# Install ipykernel -pip install ipykernel pandas pre-commit rdkit - -# Install QDK Chemistry package -cd ./python -export CMAKE_BUILD_PARALLEL_LEVEL=2 -QDK_UARCH=native pip install -v .[all] - -# Add venv to bash -echo "source $HOME/qdk_chemistry_venv/bin/activate" >> $HOME/.bashrc From 716761694e6242d1a4ae6c879d2a4fa561493515 Mon Sep 17 00:00:00 2001 From: Kristjan Eimre Date: Fri, 22 May 2026 21:30:17 +0200 Subject: [PATCH 02/16] dev-container: install c++ and python separately --- .devcontainer/scripts/post_create.sh | 5 +++++ INSTALL.md | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/.devcontainer/scripts/post_create.sh b/.devcontainer/scripts/post_create.sh index b12054458..6ef26055e 100644 --- a/.devcontainer/scripts/post_create.sh +++ b/.devcontainer/scripts/post_create.sh @@ -4,6 +4,11 @@ set -euo pipefail source "$HOME/qdk_chemistry_venv/bin/activate" export CMAKE_BUILD_PARALLEL_LEVEL=4 +# Build C++ and install to /usr/local +cmake -S cpp -B cpp/build -G Ninja +cmake --build cpp/build +sudo cmake --install cpp/build + # Install python library cd ./python pip install -v .[all] diff --git a/INSTALL.md b/INSTALL.md index bdfdc7d5d..a8d54f639 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -125,6 +125,10 @@ Alternatively, click the green button in the bottom-left corner of VS Code and s After the initial build, restart VS Code and reopen in the container to ensure the Python virtual environment is properly loaded. +### Step 4: Develop! + +The dev container builds the C++ library and links it the python package in separate steps, as shown in `.devcontainer/scripts/post_create.sh`. After changing the source code, you need to rebuild and install accordingly. + **NOTE:** - The first build can take up to two hours on slower systems. From 34941beb3dd304b70ce960edddbf88f41b19b306 Mon Sep 17 00:00:00 2001 From: Kristjan Eimre Date: Fri, 22 May 2026 21:30:52 +0200 Subject: [PATCH 03/16] add devcontainer-lock.json --- .devcontainer/devcontainer-lock.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .devcontainer/devcontainer-lock.json diff --git a/.devcontainer/devcontainer-lock.json b/.devcontainer/devcontainer-lock.json new file mode 100644 index 000000000..9dbb8ff3a --- /dev/null +++ b/.devcontainer/devcontainer-lock.json @@ -0,0 +1,19 @@ +{ + "features": { + "ghcr.io/devcontainers/features/git:1": { + "version": "1.3.5", + "resolved": "ghcr.io/devcontainers/features/git@sha256:27905dc196c01f77d6ba8709cb82eeaf330b3b108772e2f02d1cd0d826de1251", + "integrity": "sha256:27905dc196c01f77d6ba8709cb82eeaf330b3b108772e2f02d1cd0d826de1251" + }, + "ghcr.io/devcontainers/features/node:1": { + "version": "1.7.1", + "resolved": "ghcr.io/devcontainers/features/node@sha256:8c0de46939b61958041700ee89e3493f3b2e4131a06dc46b4d9423427d06e5f6", + "integrity": "sha256:8c0de46939b61958041700ee89e3493f3b2e4131a06dc46b4d9423427d06e5f6" + }, + "ghcr.io/devcontainers/features/rust:1": { + "version": "1.5.0", + "resolved": "ghcr.io/devcontainers/features/rust@sha256:0c55e65f2e3df736e478f26ee4d5ed41bae6b54dac1318c443e31444c8ed283c", + "integrity": "sha256:0c55e65f2e3df736e478f26ee4d5ed41bae6b54dac1318c443e31444c8ed283c" + } + } +} From 8d4054185e99a37e5ff4b2d0d19cdde608126ced Mon Sep 17 00:00:00 2001 From: Kristjan Eimre Date: Fri, 22 May 2026 21:43:58 +0200 Subject: [PATCH 04/16] fix devcontainer.json schema change --- .devcontainer/devcontainer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e8998b280..f11db8b2e 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -24,8 +24,8 @@ "python.formatting.provider": "none", "editor.formatOnSave": true, "editor.codeActionsOnSave": { - "source.fixAll.ruff": true, - "source.organizeImports.ruff": true + "source.fixAll.ruff": "explicit", + "source.organizeImports.ruff": "explicit" }, "python.linting.enabled": true, "python.linting.lintOnSave": true, @@ -74,4 +74,4 @@ }, "postCreateCommand": "bash .devcontainer/scripts/post_create.sh", "remoteUser": "vscode" -} \ No newline at end of file +} From 970cfa50c64651c5be36a96dc8e9d8e478941177 Mon Sep 17 00:00:00 2001 From: Kristjan Eimre Date: Fri, 22 May 2026 21:44:10 +0200 Subject: [PATCH 05/16] fix pre-commit --- INSTALL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/INSTALL.md b/INSTALL.md index a8d54f639..cbaaf57fa 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -125,7 +125,7 @@ Alternatively, click the green button in the bottom-left corner of VS Code and s After the initial build, restart VS Code and reopen in the container to ensure the Python virtual environment is properly loaded. -### Step 4: Develop! +### Step 4: Develop The dev container builds the C++ library and links it the python package in separate steps, as shown in `.devcontainer/scripts/post_create.sh`. After changing the source code, you need to rebuild and install accordingly. From 853a948f7962ca686cd3b10ab4e3b68cd640a0f1 Mon Sep 17 00:00:00 2001 From: Kristjan Eimre Date: Fri, 22 May 2026 22:46:06 +0300 Subject: [PATCH 06/16] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- INSTALL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/INSTALL.md b/INSTALL.md index cbaaf57fa..342a71854 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -127,7 +127,7 @@ After the initial build, restart VS Code and reopen in the container to ensure t ### Step 4: Develop -The dev container builds the C++ library and links it the python package in separate steps, as shown in `.devcontainer/scripts/post_create.sh`. After changing the source code, you need to rebuild and install accordingly. +The dev container builds the C++ library and links it to the Python package in separate steps, as shown in `.devcontainer/scripts/post_create.sh`. After changing the source code, you need to rebuild and install accordingly. **NOTE:** From 054dafc235f2dfb078ccd1fe18e5ecd12ea04738 Mon Sep 17 00:00:00 2001 From: Kristjan Eimre Date: Fri, 22 May 2026 22:46:23 +0300 Subject: [PATCH 07/16] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .devcontainer/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index bed7fc62f..950d5710b 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -97,8 +97,8 @@ ENV VIRTUAL_ENV=/home/$USERNAME/qdk_chemistry_venv \ RUN python -m venv "$VIRTUAL_ENV" \ && pip install --upgrade pip setuptools wheel \ && pip install --no-cache-dir \ - "ipykernel>=7.2,<8" \ - "pandas>=3.0,<4" \ + "ipykernel>=6.0" \ + "pandas>=2.0.0" \ "pre-commit>=4.6,<5" \ - "rdkit>=2026.3.2,<2026.4" \ + "rdkit" \ && echo "source $VIRTUAL_ENV/bin/activate" >> ~/.bashrc From c7cba9b46309beda6d8175ec0c511bd45effec91 Mon Sep 17 00:00:00 2001 From: Kristjan Eimre Date: Fri, 22 May 2026 21:58:58 +0200 Subject: [PATCH 08/16] fix python.defaultInterpreterPath --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f11db8b2e..084a4bba3 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -20,7 +20,7 @@ "ms-toolsai.jupyter" ], "settings": { - "python.defaultInterpreterPath": "/usr/local/bin/python", + "python.defaultInterpreterPath": "${containerEnv:VIRTUAL_ENV}/bin/python", "python.formatting.provider": "none", "editor.formatOnSave": true, "editor.codeActionsOnSave": { From 8920308b6835b2918e80c98284c3dc33455de618 Mon Sep 17 00:00:00 2001 From: Kristjan Eimre Date: Fri, 22 May 2026 22:01:37 +0200 Subject: [PATCH 09/16] dockerfile: add --no-cache-dir --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 950d5710b..5995dbb38 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -95,7 +95,7 @@ RUN echo 'export PS1="\[\033[1;34m\]\u@qdk-dev:\w$ \[\033[0m\]"' >> ~/.bashrc ENV VIRTUAL_ENV=/home/$USERNAME/qdk_chemistry_venv \ PATH=/home/$USERNAME/qdk_chemistry_venv/bin:$PATH RUN python -m venv "$VIRTUAL_ENV" \ - && pip install --upgrade pip setuptools wheel \ + && pip install --no-cache-dir --upgrade pip setuptools wheel \ && pip install --no-cache-dir \ "ipykernel>=6.0" \ "pandas>=2.0.0" \ From 731cfad264c598834ea60cbed93303e7148ab519 Mon Sep 17 00:00:00 2001 From: Kristjan Eimre Date: Fri, 29 May 2026 00:12:25 +0200 Subject: [PATCH 10/16] switch to non-sudo cpp install --- .devcontainer/Dockerfile | 8 ++++++++ .devcontainer/scripts/post_create.sh | 11 +++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 5995dbb38..6503ec3e0 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -15,6 +15,9 @@ ENV LANG=en_US.UTF-8 \ LD_LIBRARY_PATH=/usr/local/lib:${LD_LIBRARY_PATH} \ PATH=/usr/local/bin:${PATH} +# Cap cmake build parallelism to prevent OOM (e.g., in dev-loop rebuilds) +ENV CMAKE_BUILD_PARALLEL_LEVEL=4 + # Create a non-root user with sudo privileges ARG USERNAME=vscode ARG USER_UID=1000 @@ -31,6 +34,7 @@ RUN apt-get update && \ gnupg \ build-essential \ cmake \ + ccache \ clang \ pkg-config \ python3 \ @@ -94,6 +98,7 @@ RUN echo 'export PS1="\[\033[1;34m\]\u@qdk-dev:\w$ \[\033[0m\]"' >> ~/.bashrc # Python dev dependencies. ENV VIRTUAL_ENV=/home/$USERNAME/qdk_chemistry_venv \ PATH=/home/$USERNAME/qdk_chemistry_venv/bin:$PATH + RUN python -m venv "$VIRTUAL_ENV" \ && pip install --no-cache-dir --upgrade pip setuptools wheel \ && pip install --no-cache-dir \ @@ -102,3 +107,6 @@ RUN python -m venv "$VIRTUAL_ENV" \ "pre-commit>=4.6,<5" \ "rdkit" \ && echo "source $VIRTUAL_ENV/bin/activate" >> ~/.bashrc + +# Make user-local C++ installations discoverable +ENV CMAKE_PREFIX_PATH=/home/$USERNAME/.local${CMAKE_PREFIX_PATH:+:${CMAKE_PREFIX_PATH}} diff --git a/.devcontainer/scripts/post_create.sh b/.devcontainer/scripts/post_create.sh index 6ef26055e..d92fb671a 100644 --- a/.devcontainer/scripts/post_create.sh +++ b/.devcontainer/scripts/post_create.sh @@ -2,12 +2,15 @@ # Post-create step: install QDK Chemistry from the mounted source. set -euo pipefail source "$HOME/qdk_chemistry_venv/bin/activate" -export CMAKE_BUILD_PARALLEL_LEVEL=4 -# Build C++ and install to /usr/local -cmake -S cpp -B cpp/build -G Ninja +# Build C++ and install to a user-local prefix. +# Use the in-tree macis (external/macis) per INSTALL.md; prevents a +# full rebuild on reconfigure. +cmake -S cpp -B cpp/build -G Ninja \ + -DCMAKE_INSTALL_PREFIX="$HOME/.local" \ + -DCMAKE_DISABLE_FIND_PACKAGE_macis=ON cmake --build cpp/build -sudo cmake --install cpp/build +cmake --install cpp/build # Install python library cd ./python From c32136fedc1f36ce23975e8bd5b238217b68e064 Mon Sep 17 00:00:00 2001 From: Kristjan Eimre Date: Fri, 29 May 2026 00:25:50 +0200 Subject: [PATCH 11/16] simplify setting CMAKE_PREFIX_PATH --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 6503ec3e0..81d255e97 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -109,4 +109,4 @@ RUN python -m venv "$VIRTUAL_ENV" \ && echo "source $VIRTUAL_ENV/bin/activate" >> ~/.bashrc # Make user-local C++ installations discoverable -ENV CMAKE_PREFIX_PATH=/home/$USERNAME/.local${CMAKE_PREFIX_PATH:+:${CMAKE_PREFIX_PATH}} +ENV CMAKE_PREFIX_PATH=/home/$USERNAME/.local From aa56017847dde2ea2cf300f804e90227f850da15 Mon Sep 17 00:00:00 2001 From: Kristjan Eimre Date: Fri, 29 May 2026 12:58:29 +0000 Subject: [PATCH 12/16] set default CMAKE build as debug --- .devcontainer/devcontainer.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 084a4bba3..66c3c7124 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -55,7 +55,9 @@ "C_Cpp.codeAnalysis.clangTidy.runAutomatically": true, "C_Cpp.formatting": "clangFormat", "C_Cpp.clang_format_style": "file", - "C_Cpp.clang_format_fallbackStyle": "Google" + "C_Cpp.clang_format_fallbackStyle": "Google", + "C_Cpp.default.cppStandard": "c++20", + "cmake.buildType": "Debug" } } }, @@ -70,7 +72,8 @@ } }, "remoteEnv": { - "CPATH": "${containerEnv:CPATH}:/usr/include/hdf5/serial:/usr/include/eigen3" + "CPATH": "${containerEnv:CPATH}:/usr/include/hdf5/serial:/usr/include/eigen3", + "CMAKE_BUILD_TYPE": "Debug" }, "postCreateCommand": "bash .devcontainer/scripts/post_create.sh", "remoteUser": "vscode" From cce315b3d17095885c7bb87083d679a8b2200f01 Mon Sep 17 00:00:00 2001 From: Kristjan Eimre Date: Tue, 23 Jun 2026 15:42:06 +0200 Subject: [PATCH 13/16] add parallelism helper --- .devcontainer/Dockerfile | 11 +++-- .../scripts/install_cpp_dependencies.sh | 25 +++++++++-- .devcontainer/scripts/parallelism.sh | 45 +++++++++++++++++++ .devcontainer/scripts/post_create.sh | 4 ++ 4 files changed, 78 insertions(+), 7 deletions(-) create mode 100644 .devcontainer/scripts/parallelism.sh diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 81d255e97..812bcc083 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -15,9 +15,6 @@ ENV LANG=en_US.UTF-8 \ LD_LIBRARY_PATH=/usr/local/lib:${LD_LIBRARY_PATH} \ PATH=/usr/local/bin:${PATH} -# Cap cmake build parallelism to prevent OOM (e.g., in dev-loop rebuilds) -ENV CMAKE_BUILD_PARALLEL_LEVEL=4 - # Create a non-root user with sudo privileges ARG USERNAME=vscode ARG USER_UID=1000 @@ -58,6 +55,11 @@ RUN apt-get update && \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* +# Install the memory-/core-aware build parallelism helper. It is used during +# dependency installation and may also be sourced by development scripts and +# interactive shells. +COPY .devcontainer/scripts/parallelism.sh /usr/local/share/qdk/parallelism.sh + # Install C++ dependencies COPY .devcontainer/scripts/install_cpp_dependencies.sh /tmp/install_cpp_dependencies.sh COPY cpp/manifest/qdk-chemistry/cgmanifest.json /tmp/cpp_cgmanifest.json @@ -108,5 +110,8 @@ RUN python -m venv "$VIRTUAL_ENV" \ "rdkit" \ && echo "source $VIRTUAL_ENV/bin/activate" >> ~/.bashrc +# Set the safe CMAKE_BUILD_PARALLEL_LEVEL for interactive shells +RUN echo "source /usr/local/share/qdk/parallelism.sh" >> ~/.bashrc + # Make user-local C++ installations discoverable ENV CMAKE_PREFIX_PATH=/home/$USERNAME/.local diff --git a/.devcontainer/scripts/install_cpp_dependencies.sh b/.devcontainer/scripts/install_cpp_dependencies.sh index d7e32aca8..73d2b9de4 100644 --- a/.devcontainer/scripts/install_cpp_dependencies.sh +++ b/.devcontainer/scripts/install_cpp_dependencies.sh @@ -37,13 +37,30 @@ BUILD_DIR="${BUILD_DIR:-/tmp/qdk_deps_build}" INSTALL_PREFIX="${INSTALL_PREFIX:-/usr/local}" BUILD_TYPE="${BUILD_TYPE:-Release}" BUILD_SHARED_LIBS="${BUILD_SHARED_LIBS:-OFF}" # Default to static -LIBINT_JOBS=${LIBINT_JOBS:-4} # Limit libint build jobs to 4 due to high memory usage + KEEP_BUILD_DIR="${KEEP_BUILD_DIR:-0}" -if command -v nproc >/dev/null 2>&1; then - JOBS=$(nproc) # Linux + +PARALLELISM_HELPER="/usr/local/share/qdk/parallelism.sh" +if [ -f "$PARALLELISM_HELPER" ]; then + # shellcheck source=/dev/null + source "$PARALLELISM_HELPER" +fi + +if command -v parallel_jobs_for_memory >/dev/null 2>&1; then + # Use the parallelism helper to determine job counts based on memory + JOBS="${JOBS:-$(parallel_jobs_for_memory 1)}" + LIBINT_JOBS="${LIBINT_JOBS:-$(parallel_jobs_for_memory 4)}" else - JOBS=$(sysctl -n hw.logicalcpu) # macOS + # Fallback when helper is unavailable + if command -v nproc >/dev/null 2>&1; then + DEFAULT_JOBS=$(nproc) # Linux + else + DEFAULT_JOBS=$(sysctl -n hw.logicalcpu) # macOS + fi + JOBS="${JOBS:-$DEFAULT_JOBS}" + LIBINT_JOBS="${LIBINT_JOBS:-4}" fi + MAC_BUILD="OFF" if [[ "$OSTYPE" == "darwin"* ]]; then MAC_BUILD="ON" diff --git a/.devcontainer/scripts/parallelism.sh b/.devcontainer/scripts/parallelism.sh new file mode 100644 index 000000000..3d7ab45f9 --- /dev/null +++ b/.devcontainer/scripts/parallelism.sh @@ -0,0 +1,45 @@ +# shellcheck shell=bash +# +# This file is intended to be sourced. +# +# It provides: +# - parallel_jobs_for_memory() +# - a default CMAKE_BUILD_PARALLEL_LEVEL (unless already set) +# +# parallel_jobs_for_memory +# +# Compute a safe parallel job count based on available RAM and CPU cores. +# +# Result: +# min(cpu_cores, floor(total_ram_gb / memory_per_job_gb)) +# +# with a minimum value of 1. +# +parallel_jobs_for_memory() { + local memory_per_job_gb="$1" + local cores mem_bytes jobs + + if command -v nproc >/dev/null 2>&1; then + # Linux + cores=$(nproc) + mem_bytes=$(awk '/MemTotal/ {print $2 * 1024}' /proc/meminfo) + else + # macOS + cores=$(sysctl -n hw.logicalcpu) + mem_bytes=$(sysctl -n hw.memsize) + fi + + # tiny overhead to get common cases correct (e.g., 15.9GB RAM, 8GB per job -> 2 jobs) + mem_bytes=$(( mem_bytes * 103 / 100 )) + + jobs=$(( mem_bytes / (memory_per_job_gb * 1024 * 1024 * 1024) )) + + (( jobs < 1 )) && jobs=1 + (( jobs > cores )) && jobs=$cores + + echo "$jobs" +} + +if [ -z "${CMAKE_BUILD_PARALLEL_LEVEL:-}" ]; then + export CMAKE_BUILD_PARALLEL_LEVEL="$(parallel_jobs_for_memory 8)" +fi diff --git a/.devcontainer/scripts/post_create.sh b/.devcontainer/scripts/post_create.sh index d92fb671a..c45c37155 100644 --- a/.devcontainer/scripts/post_create.sh +++ b/.devcontainer/scripts/post_create.sh @@ -3,6 +3,10 @@ set -euo pipefail source "$HOME/qdk_chemistry_venv/bin/activate" +# Set a memory-/core-aware CMAKE_BUILD_PARALLEL_LEVEL (unless already set) so the +# initial build below does not oversubscribe CPU or OOM on constrained machines. +source /usr/local/share/qdk/parallelism.sh + # Build C++ and install to a user-local prefix. # Use the in-tree macis (external/macis) per INSTALL.md; prevents a # full rebuild on reconfigure. From af039c7bd8e391ea105a875c2974f6a6fe752c4c Mon Sep 17 00:00:00 2001 From: Kristjan Eimre Date: Tue, 23 Jun 2026 16:32:31 +0200 Subject: [PATCH 14/16] rm redundant comment --- .devcontainer/scripts/install_cpp_dependencies.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/.devcontainer/scripts/install_cpp_dependencies.sh b/.devcontainer/scripts/install_cpp_dependencies.sh index 73d2b9de4..07d88660b 100644 --- a/.devcontainer/scripts/install_cpp_dependencies.sh +++ b/.devcontainer/scripts/install_cpp_dependencies.sh @@ -241,7 +241,6 @@ cmake .. -DCMAKE_BUILD_TYPE="$BUILD_TYPE" \ -DCMAKE_INSTALL_PREFIX="$INSTALL_PREFIX" \ -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ -DBUILD_SHARED_LIBS="$BUILD_SHARED_LIBS" -# libint's compilation is memory intensive so parallel jobs are limited to 4 to prevent OOM errors make -j"$LIBINT_JOBS" make install cd "$BUILD_DIR" From 5eed992775433cdc9ece0596d6fa91a963b4c409 Mon Sep 17 00:00:00 2001 From: Kristjan Eimre Date: Tue, 23 Jun 2026 16:44:39 +0200 Subject: [PATCH 15/16] respect cgroup limit --- .devcontainer/scripts/parallelism.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.devcontainer/scripts/parallelism.sh b/.devcontainer/scripts/parallelism.sh index 3d7ab45f9..7d251b13a 100644 --- a/.devcontainer/scripts/parallelism.sh +++ b/.devcontainer/scripts/parallelism.sh @@ -29,6 +29,17 @@ parallel_jobs_for_memory() { mem_bytes=$(sysctl -n hw.memsize) fi + # If running inside a cgroup with a memory limit, respect it. + local cgroup_limit_bytes="" + if [ -r /sys/fs/cgroup/memory.max ]; then + cgroup_limit_bytes="$(cat /sys/fs/cgroup/memory.max)" # cgroup v2 + elif [ -r /sys/fs/cgroup/memory/memory.limit_in_bytes ]; then + cgroup_limit_bytes="$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes)" # cgroup v1 + fi + if [[ "$cgroup_limit_bytes" =~ ^[0-9]+$ ]] && (( cgroup_limit_bytes > 0 )) && (( cgroup_limit_bytes < mem_bytes )); then + mem_bytes="$cgroup_limit_bytes" + fi + # tiny overhead to get common cases correct (e.g., 15.9GB RAM, 8GB per job -> 2 jobs) mem_bytes=$(( mem_bytes * 103 / 100 )) From 4fdf0478bcc2b13705d314e635e2624a43038410 Mon Sep 17 00:00:00 2001 From: Kristjan Eimre Date: Tue, 23 Jun 2026 17:52:28 +0300 Subject: [PATCH 16/16] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .devcontainer/scripts/parallelism.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/scripts/parallelism.sh b/.devcontainer/scripts/parallelism.sh index 7d251b13a..7d883b065 100644 --- a/.devcontainer/scripts/parallelism.sh +++ b/.devcontainer/scripts/parallelism.sh @@ -19,12 +19,12 @@ parallel_jobs_for_memory() { local memory_per_job_gb="$1" local cores mem_bytes jobs - if command -v nproc >/dev/null 2>&1; then + if [ -r /proc/meminfo ] && command -v nproc >/dev/null 2>&1; then # Linux cores=$(nproc) mem_bytes=$(awk '/MemTotal/ {print $2 * 1024}' /proc/meminfo) else - # macOS + # macOS (or other non-/proc environments) cores=$(sysctl -n hw.logicalcpu) mem_bytes=$(sysctl -n hw.memsize) fi