Skip to content

Commit d257d4c

Browse files
committed
Merge remote-tracking branch 'origin/main' into use-prereq-lockfile-src
2 parents ac3f222 + 39ca4ab commit d257d4c

File tree

83 files changed

+2374
-685
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+2374
-685
lines changed

.github/pre-commit/spelling_allowlist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ QPP
108108
QPU
109109
QPUs
110110
QPU’s
111+
QRMI
111112
QTX
112113
QX
113114
QaaS

.github/workflows/build_package_sources.yml

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,6 @@
2424
on:
2525
workflow_dispatch:
2626
inputs:
27-
push_to_NGC:
28-
required: false
29-
type: boolean
30-
default: false
31-
description: 'Push the built source image to NGC, otherwise push to GHCR.'
32-
environment:
33-
required: false
34-
type: string
3527
artifact_url:
3628
required: false
3729
type: string
@@ -455,39 +447,52 @@ jobs:
455447
push: false
456448

457449
- name: Log in to GitHub CR
458-
if: github.event.inputs.push_to_NGC != 'true'
459450
uses: docker/login-action@v3
460451
with:
461452
registry: ghcr.io
462453
username: ${{ github.actor }}
463454
password: ${{ github.token }}
464455

465-
- name: Log in to NGC
466-
if: github.event.inputs.push_to_NGC == 'true'
467-
uses: docker/login-action@v3
468-
with:
469-
registry: nvcr.io
470-
username: '$oauthtoken'
471-
password: ${{ secrets.NGC_CREDENTIALS }}
472-
473-
- name: Tag and push to GHCR or NGC
456+
- name: Tag and push amd64 image
474457
id: push
475458
run: |
476459
docker load --input /tmp/package-sources.tar
477460
cuda_major=$(echo "${{ matrix.cuda }}" | cut -d. -f1)
478461
target_image="nvcr.io/nvidia/nightly/cuda-quantum:cu${cuda_major}-latest"
479462
tag_suffix="${target_image##*:}"
480-
if [ "${{ github.event.inputs.push_to_NGC }}" = "true" ]; then
481-
# Derive push destination from target_image: .../cuda-quantum:tag -> .../cuda-quantum-src:tag
482-
repo_part="${target_image%:*}"
483-
tag="${repo_part}-src:${tag_suffix}"
484-
else
485-
owner_lower=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
486-
tag="ghcr.io/${owner_lower}/cuda-quantum-src:${tag_suffix}"
487-
fi
488-
docker tag package-sources:latest "$tag"
489-
docker push "$tag"
463+
owner_lower=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
464+
tag="ghcr.io/${owner_lower}/cuda-quantum-src:${tag_suffix}"
465+
tag_amd64="${tag}-amd64"
466+
tag_arm64="${tag}-arm64"
467+
docker tag package-sources:latest "$tag_amd64"
468+
docker push "$tag_amd64"
490469
echo "image_tag=$tag" | tee -a $GITHUB_OUTPUT
470+
echo "tag_amd64=$tag_amd64" | tee -a $GITHUB_OUTPUT
471+
echo "tag_arm64=$tag_arm64" | tee -a $GITHUB_OUTPUT
472+
473+
- name: Create arm64 image (copy /sources from amd64)
474+
run: |
475+
tag_amd64="${{ steps.push.outputs.tag_amd64 }}"
476+
tag_arm64="${{ steps.push.outputs.tag_arm64 }}"
477+
base_image="${{ steps.base-image.outputs.base_image }}"
478+
# Extract /sources from amd64 image
479+
cid=$(docker create "$tag_amd64")
480+
docker cp "$cid:/sources" ./sources-from-amd64
481+
docker rm "$cid"
482+
# Build arm64 image: same base, add /sources
483+
cat > Dockerfile.arm64 << EOF
484+
FROM ${base_image}
485+
COPY sources-from-amd64 /sources
486+
EOF
487+
docker buildx build --platform linux/arm64 -f Dockerfile.arm64 -t "$tag_arm64" --load .
488+
docker push "$tag_arm64"
489+
490+
- name: Create and push multi-arch manifest
491+
run: |
492+
tag="${{ steps.push.outputs.image_tag }}"
493+
tag_amd64="${{ steps.push.outputs.tag_amd64 }}"
494+
tag_arm64="${{ steps.push.outputs.tag_arm64 }}"
495+
docker buildx imagetools create --tag "$tag" "$tag_amd64" "$tag_arm64"
491496
492497
- name: Summary
493498
run: |

.github/workflows/ci_macos.yml

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
11
on:
2+
workflow_call:
3+
inputs:
4+
cache_base:
5+
required: false
6+
type: string
7+
default: main
8+
cudaq_version:
9+
required: false
10+
type: string
11+
description: 'Override version for wheel/installer (e.g. when called from deployments for a release).'
12+
default: ''
213
# Daily rebuild on main to ensure devdeps rebuilt as needed
314
schedule:
415
- cron: '0 4 * * *' # aim to be ready by 9am CET/CEST
@@ -59,11 +70,16 @@ jobs:
5970

6071
- id: version
6172
run: |
62-
is_versioned=${{ github.ref_type == 'tag' || startsWith(github.ref_name, 'releases/') || startsWith(github.ref_name, 'staging/') }}
63-
if ${is_versioned}; then
64-
cudaq_version=$(echo ${{ github.ref_name }} | egrep -o "([0-9]{1,}\.)+[0-9]{1,}")
73+
if [ -n "${{ inputs.cudaq_version }}" ]; then
74+
cudaq_version=$(echo "${{ inputs.cudaq_version }}" | egrep -o "([0-9]{1,}\.)+[0-9]{1,}([A-Za-z0-9_\-\.]*)" || true)
75+
cudaq_version=${cudaq_version:-0.0.0}
6576
else
66-
cudaq_version=0.0.0
77+
is_versioned=${{ github.ref_type == 'tag' || startsWith(github.ref_name, 'releases/') || startsWith(github.ref_name, 'staging/') }}
78+
if ${is_versioned}; then
79+
cudaq_version=$(echo ${{ github.ref_name }} | egrep -o "([0-9]{1,}\.)+[0-9]{1,}")
80+
else
81+
cudaq_version=0.0.0
82+
fi
6783
fi
6884
echo "cudaq_version=$cudaq_version" >> $GITHUB_OUTPUT
6985
@@ -88,8 +104,9 @@ jobs:
88104
name: Build & Test (arm64)
89105
needs: devdeps
90106
runs-on: macos-26
91-
timeout-minutes: 180
92107
env:
108+
CC: clang
109+
CXX: clang++
93110
MACOSX_DEPLOYMENT_TARGET: '13.0'
94111

95112
steps:
@@ -127,8 +144,6 @@ jobs:
127144
- name: Build MLIR Python bindings
128145
run: |
129146
source scripts/set_env_defaults.sh
130-
131-
# Incremental rebuild: add python-bindings to cached LLVM build
132147
Python3_EXECUTABLE="$(which python3)" \
133148
LLVM_PROJECTS='clang;lld;mlir;openmp;python-bindings' \
134149
LLVM_SOURCE="$HOME/.llvm-project" \
@@ -152,8 +167,9 @@ jobs:
152167
python_version: ['3.11', '3.12', '3.13']
153168
fail-fast: false
154169
runs-on: macos-26
155-
timeout-minutes: 90
156170
env:
171+
CC: clang
172+
CXX: clang++
157173
MACOSX_DEPLOYMENT_TARGET: '13.0'
158174
outputs:
159175
cudaq_version: ${{ needs.metadata.outputs.cudaq_version }}
@@ -189,8 +205,6 @@ jobs:
189205
- name: Build MLIR Python bindings
190206
run: |
191207
source scripts/set_env_defaults.sh
192-
193-
# Incremental rebuild: add python-bindings to cached LLVM build
194208
Python3_EXECUTABLE="$(which python3)" \
195209
LLVM_PROJECTS='clang;lld;mlir;openmp;python-bindings' \
196210
LLVM_SOURCE="$HOME/.llvm-project" \
@@ -216,7 +230,7 @@ jobs:
216230
# Consistent with Linux: pycudaq-<python_version_dashed>-<platform_info>
217231
name: pycudaq-${{ matrix.python_version }}-darwin-arm64
218232
path: dist/cuda_quantum*.whl
219-
retention-days: 1
233+
retention-days: 3
220234
if-no-files-found: error
221235

222236
# ============================================================================
@@ -230,7 +244,6 @@ jobs:
230244
python_version: ['3.11', '3.12', '3.13']
231245
fail-fast: false
232246
runs-on: macos-26
233-
timeout-minutes: 30
234247

235248
steps:
236249
- name: Checkout repository
@@ -268,8 +281,9 @@ jobs:
268281
name: Installer (arm64)
269282
needs: [devdeps, metadata]
270283
runs-on: macos-26
271-
timeout-minutes: 120
272284
env:
285+
CC: clang
286+
CXX: clang++
273287
MACOSX_DEPLOYMENT_TARGET: '13.0'
274288
outputs:
275289
cudaq_version: ${{ needs.metadata.outputs.cudaq_version }}
@@ -307,8 +321,6 @@ jobs:
307321
- name: Build MLIR Python bindings
308322
run: |
309323
source scripts/set_env_defaults.sh
310-
311-
# Incremental rebuild: add python-bindings to cached LLVM build
312324
Python3_EXECUTABLE="$(which python3)" \
313325
LLVM_PROJECTS='clang;lld;mlir;openmp;python-bindings' \
314326
LLVM_SOURCE="$HOME/.llvm-project" \
@@ -332,7 +344,7 @@ jobs:
332344
# Consistent with Linux: cudaq-<platform>-<config>-installer-<run_id>
333345
name: cudaq-arm64-darwin-installer-${{ github.run_id }}
334346
path: out/install_cuda_quantum*
335-
retention-days: 1
347+
retention-days: 3
336348
if-no-files-found: error
337349

338350
# ============================================================================
@@ -343,7 +355,6 @@ jobs:
343355
name: Validate Installation (arm64)
344356
needs: [installer, wheel]
345357
runs-on: macos-26
346-
timeout-minutes: 30
347358

348359
steps:
349360
- name: Checkout repository
@@ -366,16 +377,34 @@ jobs:
366377
name: pycudaq-3.12-darwin-arm64
367378
path: wheel/
368379

369-
- name: Install CUDA-Q (C++ via installer)
380+
- name: Create test user
381+
run: |
382+
sudo sysadminctl -addUser cudaqtest -password 'cudaqtest123' -admin
383+
sudo mkdir -p /Users/cudaqtest
384+
sudo chown cudaqtest /Users/cudaqtest
385+
386+
- name: Install CUDA-Q (C++ via installer to neutral path)
370387
run: |
388+
install_path=/opt/cudaq-test
389+
sudo mkdir -p "$install_path"
390+
sudo chown cudaqtest "$install_path"
371391
chmod +x installer/install_cuda_quantum*
372-
bash installer/install_cuda_quantum* --accept -- --installpath $HOME/.cudaq
392+
sudo -u cudaqtest bash installer/install_cuda_quantum* --accept -- --installpath "$install_path"
373393
374394
- name: Install CUDA-Q (Python via wheel)
375395
run: |
376-
pip install wheel/*.whl
396+
sudo -u cudaqtest -H python3 -m venv /Users/cudaqtest/venv
397+
sudo -u cudaqtest -H /Users/cudaqtest/venv/bin/pip install wheel/*.whl
377398
378399
- name: Validate installation
379400
run: |
380-
source $HOME/.zshrc
381-
bash scripts/validate_installation.sh
401+
install_path=/opt/cudaq-test
402+
workdir=$(sudo -u cudaqtest mktemp -d)
403+
sudo cp -R scripts docs "$workdir/"
404+
sudo chown -R cudaqtest "$workdir"
405+
sudo -u cudaqtest bash -lc "
406+
source /Users/cudaqtest/venv/bin/activate
407+
source ${install_path}/set_env.sh
408+
cd ${workdir}
409+
bash scripts/validate_installation.sh
410+
"

.github/workflows/deployments.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ on:
3030
description: Create a GitHub release with the given version number (e.g. 0.3.0). A GitHub release with that version must not exist already.
3131
required: false
3232
default: ''
33+
include_macos:
34+
type: boolean
35+
description: Build and include macOS wheels and installer.
36+
required: false
37+
default: true
3338
workflow_run:
3439
workflows:
3540
- PR merged
@@ -295,7 +300,7 @@ jobs:
295300

296301
dispatch:
297302
name: Dispatch deployments
298-
needs: [metadata, devdeps, wheeldeps, openmpi]
303+
needs: [metadata, devdeps, wheeldeps, source_build, openmpi]
299304
if: github.event_name != 'workflow_dispatch'
300305
runs-on: ubuntu-latest
301306

@@ -809,3 +814,14 @@ jobs:
809814
cuda_version: ${{ matrix.cuda_version }}
810815
build_cache: ${{ fromJson(needs.config.outputs.json).build_cache[format('{0}-cu{1}-installer', matrix.platform, matrix.cuda_version)] }}
811816
environment: ghcr-deployment
817+
818+
macos_ci:
819+
name: macOS CI
820+
needs: metadata
821+
if: >-
822+
needs.metadata.outputs.create_packages == 'true'
823+
&& (github.event_name != 'workflow_dispatch' || inputs.include_macos != false)
824+
uses: ./.github/workflows/ci_macos.yml
825+
with:
826+
cache_base: ${{ needs.metadata.outputs.cache_base }}
827+
cudaq_version: ${{ inputs.create_release }}

.github/workflows/dev_environment_macos.yml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,12 @@ jobs:
8989
# Unlike Linux CI which uses Docker layer caching (automatically invalidates
9090
# when the copied files change), macOS uses ORAS artifact caching with no
9191
# content-based invalidation. This hash ensures cache is rebuilt when
92-
# build scripts change. Update this list if new files affect the build.
92+
# build scripts or the devdeps workflow itself change (e.g. LLVM_PROJECTS).
9393
scripts_hash=$(cat \
9494
scripts/install_prerequisites.sh \
9595
scripts/build_llvm.sh \
9696
scripts/set_env_defaults.sh \
97+
.github/workflows/dev_environment_macos.yml \
9798
| sha256sum | cut -c1-8)
9899
echo "scripts_hash=$scripts_hash" >> $GITHUB_OUTPUT
99100
@@ -116,6 +117,9 @@ jobs:
116117
contents: read
117118
packages: write
118119
id-token: write
120+
env:
121+
CC: clang
122+
CXX: clang++
119123

120124
outputs:
121125
image_hash: ${{ steps.image_hash.outputs.image_hash }}
@@ -170,10 +174,15 @@ jobs:
170174
brew unlink gcc 2>/dev/null || true
171175
brew link gcc --overwrite 2>/dev/null || true
172176
173-
# Build prerequisites without Python bindings
174-
# Python bindings are rebuilt per-Python-version in wheel jobs
177+
# NumPy is required by MLIR's find_package(Python3 ... NumPy)
178+
pip3 install numpy --break-system-packages
179+
180+
# Build prerequisites with Python bindings enabled so the cmake
181+
# cache already has MLIR_ENABLE_BINDINGS_PYTHON=ON. Downstream
182+
# wheel jobs only change Python3_EXECUTABLE, which keeps ninja's
183+
# incremental rebuild scoped to the binding targets.
175184
source scripts/set_env_defaults.sh
176-
export LLVM_PROJECTS='clang;lld;mlir;openmp'
185+
export LLVM_PROJECTS='clang;lld;mlir;openmp;python-bindings'
177186
178187
echo "Building prerequisites..."
179188
echo "LLVM_INSTALL_PREFIX=$LLVM_INSTALL_PREFIX"

.github/workflows/integration_tests.yml

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -423,9 +423,9 @@ jobs:
423423
;;
424424
tii)
425425
echo "### Setting up TII account" >> $GITHUB_STEP_SUMMARY
426-
echo "::add-mask::${{ secrets.TII_AUTH_TOKEN }}"
426+
echo "::add-mask::${{ secrets.TII_API_TOKEN }}"
427427
echo "::add-mask::${{ secrets.TII_PROJECT }}"
428-
echo "TII_AUTH_TOKEN=${{ secrets.TII_AUTH_TOKEN }}" >> $GITHUB_ENV
428+
echo "TII_API_TOKEN=${{ secrets.TII_API_TOKEN }}" >> $GITHUB_ENV
429429
echo "TII_PROJECT=${{ secrets.TII_PROJECT }}" >> $GITHUB_ENV
430430
;;
431431
esac
@@ -643,11 +643,27 @@ jobs:
643643
python3 $filename 1> /dev/null
644644
test_status=$?
645645
if [ $test_status -eq 0 ]; then
646-
echo ":white_check_mark: Successfully ran test: $filename" >> $GITHUB_STEP_SUMMARY
646+
echo ":white_check_mark: Successfully ran test: $filename (direct execution)" >> $GITHUB_STEP_SUMMARY
647647
else
648-
echo ":x: Test failed (failed to execute): $filename" >> $GITHUB_STEP_SUMMARY
648+
echo ":x: Test failed (failed to execute): $filename (direct execution)" >> $GITHUB_STEP_SUMMARY
649649
test_err_sum=$((test_err_sum+1))
650650
fi
651+
if [ "$(uname)" = "Linux" ] && [ "$(uname -m)" = "x86_64" ] && \
652+
[ -f "${QRMI_INSTALL_PREFIX:-/usr/local/qrmi}/lib64/libqrmi.so" ]; then
653+
PASQAL_MACHINE_TARGET=qrmi \
654+
SLURM_JOB_QPU_RESOURCES=EMU_FREE \
655+
EMU_FREE_QRMI_PASQAL_CLOUD_PROJECT_ID=$PASQAL_PROJECT_ID \
656+
python3 "$filename" 1> /dev/null
657+
test_status=$?
658+
if [ $test_status -eq 0 ]; then
659+
echo ":white_check_mark: Successfully ran test: $filename (qrmi execution)" >> $GITHUB_STEP_SUMMARY
660+
else
661+
echo ":x: Test failed (failed to execute): $filename (qrmi execution)" >> $GITHUB_STEP_SUMMARY
662+
test_err_sum=$((test_err_sum+1))
663+
fi
664+
else
665+
echo ":information_source: Skipped QRMI test for $filename (QRMI not available in this build)" >> $GITHUB_STEP_SUMMARY
666+
fi
651667
else
652668
echo "::warning::Unsupported file type: $filename"
653669
echo ":warning: Test skipped (unsupported file type): $filename" >> $GITHUB_STEP_SUMMARY
@@ -776,6 +792,7 @@ jobs:
776792
echo "::warning::Unsupported file type: $filename"
777793
echo ":warning: Test skipped (unsupported file type): $filename" >> $GITHUB_STEP_SUMMARY
778794
test_skip_sum=$((test_skip_sum+1))
795+
fi
779796
;;
780797
esac
781798
done

0 commit comments

Comments
 (0)