Skip to content

Commit d1c8b0f

Browse files
authored
Unify Common CI Code for Windows and Linux (#645)
* Test out a simple env-vars script for build * Double quotes to expand out the bash var, separator * Reuse env var code in the tests, add test runner * Simplify compute-sanitizer setup, fix bindings name
1 parent 5267a41 commit d1c8b0f

File tree

6 files changed

+227
-217
lines changed

6 files changed

+227
-217
lines changed

.github/workflows/build-wheel.yml

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -59,29 +59,12 @@ jobs:
5959
uses: ilammy/msvc-dev-cmd@v1 # TODO: ask admin to allow pinning commits
6060

6161
- name: Set environment variables
62-
run: |
63-
PYTHON_VERSION_FORMATTED=$(echo '${{ matrix.python-version }}' | tr -d '.')
64-
if [[ "${{ inputs.host-platform }}" == linux* ]]; then
65-
CIBW_BUILD="cp${PYTHON_VERSION_FORMATTED}-manylinux*"
66-
REPO_DIR=$(pwd)
67-
elif [[ "${{ inputs.host-platform }}" == win* ]]; then
68-
CIBW_BUILD="cp${PYTHON_VERSION_FORMATTED}-win_amd64"
69-
PWD=$(pwd)
70-
REPO_DIR=$(cygpath -w $PWD)
71-
fi
72-
73-
echo "CUDA_BINDINGS_PARALLEL_LEVEL=$(nproc)" >> $GITHUB_ENV
74-
CUDA_CORE_ARTIFACT_BASENAME="cuda-core-python${PYTHON_VERSION_FORMATTED}-${{ inputs.host-platform }}"
75-
echo "CUDA_CORE_ARTIFACT_BASENAME=${CUDA_CORE_ARTIFACT_BASENAME}" >> $GITHUB_ENV
76-
echo "CUDA_CORE_ARTIFACT_NAME=${CUDA_CORE_ARTIFACT_BASENAME}-${{ github.sha }}" >> $GITHUB_ENV
77-
echo "CUDA_CORE_ARTIFACTS_DIR=$(realpath "$REPO_DIR/cuda_core/dist")" >> $GITHUB_ENV
78-
echo "CUDA_CORE_CYTHON_TESTS_DIR=$(realpath "$REPO_DIR/cuda_core/tests/cython")" >> $GITHUB_ENV
79-
CUDA_BINDINGS_ARTIFACT_BASENAME="cuda-bindings-python${PYTHON_VERSION_FORMATTED}-cuda${{ inputs.cuda-version }}-${{ inputs.host-platform }}"
80-
echo "CUDA_BINDINGS_ARTIFACT_BASENAME=${CUDA_BINDINGS_ARTIFACT_BASENAME}" >> $GITHUB_ENV
81-
echo "CUDA_BINDINGS_ARTIFACT_NAME=${CUDA_BINDINGS_ARTIFACT_BASENAME}-${{ github.sha }}" >> $GITHUB_ENV
82-
echo "CUDA_BINDINGS_ARTIFACTS_DIR=$(realpath "$REPO_DIR/cuda_bindings/dist")" >> $GITHUB_ENV
83-
echo "CUDA_BINDINGS_CYTHON_TESTS_DIR=$(realpath "$REPO_DIR/cuda_bindings/tests/cython")" >> $GITHUB_ENV
84-
echo "CIBW_BUILD=${CIBW_BUILD}" >> $GITHUB_ENV
62+
env:
63+
CUDA_VER: ${{ inputs.cuda-version }}
64+
HOST_PLATFORM: ${{ inputs.host-platform }}
65+
PY_VER: ${{ matrix.python-version }}
66+
SHA: ${{ github.sha }}
67+
run: ./ci/tools/env-vars build
8568

8669
- name: Dump environment
8770
run: |

.github/workflows/test-wheel-linux.yml

Lines changed: 17 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -154,57 +154,14 @@ jobs:
154154
dependent_exes: "jq wget"
155155

156156
- name: Set environment variables
157-
run: |
158-
PYTHON_VERSION_FORMATTED=$(echo '${{ matrix.PY_VER }}' | tr -d '.')
159-
if [[ "${{ inputs.host-platform }}" == linux* ]]; then
160-
REPO_DIR=$(pwd)
161-
elif [[ "${{ inputs.host-platform }}" == win* ]]; then
162-
PWD=$(pwd)
163-
REPO_DIR=$(cygpath -w $PWD)
164-
fi
165-
166-
BUILD_CUDA_MAJOR="$(cut -d '.' -f 1 <<< ${{ inputs.build-ctk-ver }})"
167-
TEST_CUDA_MAJOR="$(cut -d '.' -f 1 <<< ${{ matrix.CUDA_VER }})"
168-
if [[ $BUILD_CUDA_MAJOR != $TEST_CUDA_MAJOR ]]; then
169-
SKIP_CUDA_BINDINGS_TEST=1
170-
SKIP_CYTHON_TEST=1
171-
else
172-
SKIP_CUDA_BINDINGS_TEST=0
173-
BUILD_CUDA_MINOR="$(cut -d '.' -f 2 <<< ${{ inputs.build-ctk-ver }})"
174-
TEST_CUDA_MINOR="$(cut -d '.' -f 2 <<< ${{ matrix.CUDA_VER }})"
175-
if [[ $BUILD_CUDA_MINOR != $TEST_CUDA_MINOR ]]; then
176-
SKIP_CYTHON_TEST=1
177-
else
178-
SKIP_CYTHON_TEST=0
179-
fi
180-
fi
181-
182-
# We don't test compute-sanitizer on CTK<12 because backporting fixes is too much effort
183-
# We only test compute-sanitizer on python 3.12 arbitrarily; we don't need to use sanitizer on the entire matrix
184-
# Only local ctk installs have compute-sanitizer; there is not wheel for it
185-
if [[ "${{ inputs.python-version }}" == "3.12" && "${{ inputs.cuda-version }}" != "11.8.0" && "${{ inputs.local-ctk }}" == 1 ]]; then
186-
SETUP_SANITIZER=1
187-
echo "LATEST_CUDA_VERSION=$(bash .github/workflows/guess_latest.sh)" >> $GITHUB_ENV
188-
else
189-
SETUP_SANITIZER=0
190-
fi
191-
echo "SETUP_SANITIZER=${SETUP_SANITIZER}" >> $GITHUB_ENV
192-
193-
# make outputs from the previous job as env vars
194-
CUDA_CORE_ARTIFACT_BASENAME="cuda-core-python${PYTHON_VERSION_FORMATTED}-${{ inputs.host-platform }}"
195-
echo "PYTHON_VERSION_FORMATTED=${PYTHON_VERSION_FORMATTED}" >> $GITHUB_ENV
196-
echo "CUDA_CORE_ARTIFACT_BASENAME=${CUDA_CORE_ARTIFACT_BASENAME}" >> $GITHUB_ENV
197-
echo "CUDA_CORE_ARTIFACT_NAME=${CUDA_CORE_ARTIFACT_BASENAME}-${{ github.sha }}" >> $GITHUB_ENV
198-
echo "CUDA_CORE_ARTIFACTS_DIR=$(realpath "$REPO_DIR/cuda_core/dist")" >> $GITHUB_ENV
199-
echo "CUDA_CORE_CYTHON_TESTS_DIR=$(realpath "$REPO_DIR/cuda_core/tests/cython")" >> $GITHUB_ENV
200-
CUDA_BINDINGS_ARTIFACT_BASENAME="cuda-bindings-python${PYTHON_VERSION_FORMATTED}-cuda${{ inputs.build-ctk-ver }}-${{ inputs.host-platform }}"
201-
echo "CUDA_BINDINGS_ARTIFACT_BASENAME=${CUDA_BINDINGS_ARTIFACT_BASENAME}" >> $GITHUB_ENV
202-
echo "CUDA_BINDINGS_ARTIFACT_NAME=${CUDA_BINDINGS_ARTIFACT_BASENAME}-${{ github.sha }}" >> $GITHUB_ENV
203-
echo "CUDA_BINDINGS_ARTIFACTS_DIR=$(realpath "$REPO_DIR/cuda_bindings/dist")" >> $GITHUB_ENV
204-
echo "CUDA_BINDINGS_CYTHON_TESTS_DIR=$(realpath "$REPO_DIR/cuda_bindings/tests/cython")" >> $GITHUB_ENV
205-
206-
echo "SKIP_CUDA_BINDINGS_TEST=${SKIP_CUDA_BINDINGS_TEST}" >> $GITHUB_ENV
207-
echo "SKIP_CYTHON_TEST=${SKIP_CYTHON_TEST}" >> $GITHUB_ENV
157+
env:
158+
BUILD_CUDA_VER: ${{ inputs.build-ctk-ver }}
159+
CUDA_VER: ${{ matrix.CUDA_VER }}
160+
HOST_PLATFORM: ${{ inputs.host-platform }}
161+
LOCAL_CTK: ${{ matrix.LOCAL_CTK }}
162+
PY_VER: ${{ matrix.PY_VER }}
163+
SHA: ${{ github.sha }}
164+
run: ./ci/tools/env-vars test
208165

209166
- name: Download cuda-python build artifacts
210167
if: ${{ env.SKIP_CUDA_BINDINGS_TEST == '0'}}
@@ -327,66 +284,20 @@ jobs:
327284
cuda-components: "cuda_sanitizer_api"
328285

329286
- name: Set up compute-sanitizer
330-
run: |
331-
if [[ "${SETUP_SANITIZER}" == 1 ]]; then
332-
COMPUTE_SANITIZER="${CUDA_HOME}/bin/compute-sanitizer"
333-
COMPUTE_SANITIZER_VERSION=$(${COMPUTE_SANITIZER} --version | grep -Eo "[0-9]{4}\.[0-9]\.[0-9]" | sed -e 's/\.//g')
334-
SANITIZER_CMD="${COMPUTE_SANITIZER} --target-processes=all --launch-timeout=0 --tool=memcheck --error-exitcode=1"
335-
if [[ "$COMPUTE_SANITIZER_VERSION" -ge 202111 ]]; then
336-
SANITIZER_CMD="${SANITIZER_CMD} --padding=32"
337-
fi
338-
echo "CUDA_PYTHON_TESTING_WITH_COMPUTE_SANITIZER=1" >> $GITHUB_ENV
339-
else
340-
SANITIZER_CMD=""
341-
fi
342-
echo "SANITIZER_CMD=${SANITIZER_CMD}" >> $GITHUB_ENV
287+
run: setup-sanitizer
343288

344289
- name: Run cuda.bindings tests
345290
if: ${{ env.SKIP_CUDA_BINDINGS_TEST == '0' }}
346-
run: |
347-
pushd "${CUDA_BINDINGS_ARTIFACTS_DIR}"
348-
if [[ "${{ matrix.LOCAL_CTK }}" == 1 ]]; then
349-
ls $CUDA_PATH
350-
pip install $(ls *.whl)[test]
351-
else
352-
pip install $(ls *.whl)[all,test]
353-
fi
354-
popd
355-
356-
pushd ./cuda_bindings
357-
${SANITIZER_CMD} pytest -rxXs -v tests/
358-
if [[ "${SKIP_CYTHON_TEST}" == 0 ]]; then
359-
${SANITIZER_CMD} pytest -rxXs -v tests/cython
360-
fi
361-
popd
291+
env:
292+
CUDA_VER: ${{ matrix.CUDA_VER }}
293+
LOCAL_CTK: ${{ matrix.LOCAL_CTK }}
294+
run: run-tests bindings
362295

363296
- name: Run cuda.core tests
364-
run: |
365-
# If build/test majors match: cuda.bindings is installed in the previous step.
366-
# If mismatch: cuda.bindings is installed from the backport branch.
367-
if [[ "${SKIP_CUDA_BINDINGS_TEST}" == 1 ]]; then
368-
pushd "${CUDA_BINDINGS_ARTIFACTS_DIR}"
369-
if [[ "${{ matrix.LOCAL_CTK }}" == 1 ]]; then
370-
pip install *.whl
371-
else
372-
pip install $(ls *.whl)[all]
373-
fi
374-
popd
375-
fi
376-
TEST_CUDA_MAJOR="$(cut -d '.' -f 1 <<< ${{ matrix.CUDA_VER }})"
377-
pushd "${CUDA_CORE_ARTIFACTS_DIR}"
378-
pip install $(ls *.whl)["cu${TEST_CUDA_MAJOR}","test-cu${TEST_CUDA_MAJOR}"]
379-
popd
380-
381-
pushd ./cuda_core
382-
${SANITIZER_CMD} pytest -rxXs -v tests/
383-
384-
# Currently our CI always installs the latest bindings (from either major version).
385-
# This is not compatible with the test requirements.
386-
if [[ "${SKIP_CYTHON_TEST}" == 0 ]]; then
387-
${SANITIZER_CMD} pytest -rxXs -v tests/cython
388-
fi
389-
popd
297+
env:
298+
CUDA_VER: ${{ matrix.CUDA_VER }}
299+
LOCAL_CTK: ${{ matrix.LOCAL_CTK }}
300+
run: run-tests core
390301

391302
- name: Ensure cuda-python installable
392303
run: |

.github/workflows/test-wheel-windows.yml

Lines changed: 32 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -96,41 +96,30 @@ jobs:
9696
- name: Ensure GPU is working
9797
run: nvidia-smi
9898

99-
- name: Set environment variables
99+
- name: Install Git for Windows
100+
# the GPU runner image does not have Git Bash pre-installed...
101+
env:
102+
# doesn't seem there's an easy way to avoid hard-coding it?
103+
GFW_EXE_URL: https://github.com/git-for-windows/git/releases/download/v2.49.0.windows.1/PortableGit-2.49.0-64-bit.7z.exe
100104
run: |
101-
$PYTHON_VERSION_FORMATTED = '${{ matrix.PY_VER }}' -replace '\.'
102-
$REPO_DIR = $PWD.Path
103-
104-
$BUILD_CUDA_MAJOR = '${{ inputs.build-ctk-ver }}' -split '\.' | Select-Object -First 1
105-
$TEST_CUDA_MAJOR = '${{ matrix.CUDA_VER }}' -split '\.' | Select-Object -First 1
106-
if ($BUILD_CUDA_MAJOR -ne $TEST_CUDA_MAJOR) {
107-
$SKIP_CUDA_BINDINGS_TEST = 1
108-
$SKIP_CYTHON_TEST = 1
109-
} else {
110-
$SKIP_CUDA_BINDINGS_TEST = 0
111-
$BUILD_CUDA_MINOR = '${{ inputs.build-ctk-ver }}' -split '\.' | Select-Object -Skip 1 -First 1
112-
$TEST_CUDA_MINOR = '${{ matrix.CUDA_VER }}' -split '\.' | Select-Object -Skip 1 -First 1
113-
if ($BUILD_CUDA_MINOR -ne $TEST_CUDA_MINOR) {
114-
$SKIP_CYTHON_TEST = 1
115-
} else {
116-
$SKIP_CYTHON_TEST = 0
117-
}
118-
}
105+
Invoke-WebRequest -Uri "$env:GFW_EXE_URL" -OutFile "PortableGit.7z.exe"
106+
# Self-extracting, see https://gitforwindows.org/zip-archives-extracting-the-released-archives.html
107+
Start-Process .\PortableGit.7z.exe -Wait -Verbose -ArgumentList '-y -gm2'
108+
ls -l PortableGit
109+
echo "$((Get-Location).Path)\\PortableGit\\bin" >> $env:GITHUB_PATH
110+
$env:Path += ";$((Get-Location).Path)\\PortableGit\\bin"
111+
bash --version
119112
120-
# Make outputs from the previous job as env vars
121-
$CUDA_CORE_ARTIFACT_BASENAME = "cuda-core-python${PYTHON_VERSION_FORMATTED}-${{ inputs.host-platform }}"
122-
"PYTHON_VERSION_FORMATTED=${PYTHON_VERSION_FORMATTED}" >> $env:GITHUB_ENV
123-
"CUDA_CORE_ARTIFACT_BASENAME=${CUDA_CORE_ARTIFACT_BASENAME}" >> $env:GITHUB_ENV
124-
"CUDA_CORE_ARTIFACT_NAME=${CUDA_CORE_ARTIFACT_BASENAME}-${{ github.sha }}" >> $env:GITHUB_ENV
125-
"CUDA_CORE_ARTIFACTS_DIR=$($ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath("$REPO_DIR\cuda_core\dist"))" >> $env:GITHUB_ENV
126-
"CUDA_CORE_CYTHON_TESTS_DIR=$($ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath("$REPO_DIR\cuda_core\tests\cython"))" >> $env:GITHUB_ENV
127-
$CUDA_BINDINGS_ARTIFACT_BASENAME = "cuda-bindings-python${PYTHON_VERSION_FORMATTED}-cuda${{ inputs.build-ctk-ver }}-${{ inputs.host-platform }}"
128-
"CUDA_BINDINGS_ARTIFACT_BASENAME=${CUDA_BINDINGS_ARTIFACT_BASENAME}" >> $env:GITHUB_ENV
129-
"CUDA_BINDINGS_ARTIFACT_NAME=${CUDA_BINDINGS_ARTIFACT_BASENAME}-${{ github.sha }}" >> $env:GITHUB_ENV
130-
"CUDA_BINDINGS_ARTIFACTS_DIR=$($ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath("$REPO_DIR\cuda_bindings\dist"))" >> $env:GITHUB_ENV
131-
"CUDA_BINDINGS_CYTHON_TESTS_DIR=$($ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath("$REPO_DIR\cuda_bindings\tests\cython"))" >> $env:GITHUB_ENV
132-
"SKIP_CUDA_BINDINGS_TEST=${SKIP_CUDA_BINDINGS_TEST}" >> $env:GITHUB_ENV
133-
"SKIP_CYTHON_TEST=${SKIP_CYTHON_TEST}" >> $env:GITHUB_ENV
113+
- name: Set environment variables
114+
env:
115+
BUILD_CUDA_VER: ${{ inputs.build-ctk-ver }}
116+
CUDA_VER: ${{ matrix.CUDA_VER }}
117+
HOST_PLATFORM: ${{ inputs.host-platform }}
118+
LOCAL_CTK: ${{ matrix.LOCAL_CTK }}
119+
PY_VER: ${{ matrix.PY_VER }}
120+
SHA: ${{ github.sha }}
121+
shell: bash --noprofile --norc -xeuo pipefail {0}
122+
run: ./ci/tools/env-vars test
134123

135124
- name: Download cuda-python build artifacts
136125
if: ${{ env.SKIP_CUDA_BINDINGS_TEST == '0'}}
@@ -161,21 +150,6 @@ jobs:
161150
}
162151
gh --version
163152
164-
- name: Install Git for Windows
165-
# the GPU runner image does not have Git Bash pre-installed...
166-
if: ${{ matrix.LOCAL_CTK == '1' }}
167-
env:
168-
# doesn't seem there's an easy way to avoid hard-coding it?
169-
GFW_EXE_URL: https://github.com/git-for-windows/git/releases/download/v2.49.0.windows.1/PortableGit-2.49.0-64-bit.7z.exe
170-
run: |
171-
Invoke-WebRequest -Uri "$env:GFW_EXE_URL" -OutFile "PortableGit.7z.exe"
172-
# Self-extracting, see https://gitforwindows.org/zip-archives-extracting-the-released-archives.html
173-
Start-Process .\PortableGit.7z.exe -Wait -Verbose -ArgumentList '-y -gm2'
174-
ls -l PortableGit
175-
echo "$((Get-Location).Path)\\PortableGit\\bin" >> $env:GITHUB_PATH
176-
$env:Path += ";$((Get-Location).Path)\\PortableGit\\bin"
177-
bash --version
178-
179153
- name: Install zstd
180154
# the GPU runner image does not have zstd pre-installed... and it's needed by actions/cache
181155
if: ${{ matrix.LOCAL_CTK == '1' }}
@@ -278,48 +252,18 @@ jobs:
278252

279253
- name: Run cuda.bindings tests
280254
if: ${{ env.SKIP_CUDA_BINDINGS_TEST == '0' }}
281-
run: |
282-
Push-Location $env:CUDA_BINDINGS_ARTIFACTS_DIR
283-
if ('${{ matrix.LOCAL_CTK }}' -eq '1') {
284-
Get-ChildItem $env:CUDA_PATH
285-
echo $PATH
286-
pip install "$((Get-ChildItem -Filter *.whl).FullName)[test]"
287-
} else {
288-
pip install "$((Get-ChildItem -Filter *.whl).FullName)[all,test]"
289-
}
290-
Pop-Location
291-
292-
Push-Location ./cuda_bindings
293-
pytest -rxXs -v tests/
294-
if ($env:SKIP_CYTHON_TEST -eq '0') {
295-
pytest -rxXs -v tests/cython
296-
}
297-
Pop-Location
255+
env:
256+
CUDA_VER: ${{ matrix.CUDA_VER }}
257+
LOCAL_CTK: ${{ matrix.LOCAL_CTK }}
258+
shell: bash --noprofile --norc -xeuo pipefail {0}
259+
run: run-tests bindings
298260

299261
- name: Run cuda.core tests
300-
run: |
301-
# If build/test majors match: cuda.bindings is installed in the previous step.
302-
# If mismatch: cuda.bindings is installed from the backport branch.
303-
if ($env:SKIP_CUDA_BINDINGS_TEST -eq '1') {
304-
Push-Location $env:CUDA_BINDINGS_ARTIFACTS_DIR
305-
if ('${{ matrix.LOCAL_CTK }}' -eq '1') {
306-
pip install (Get-ChildItem -Filter *.whl).FullName
307-
} else {
308-
pip install "$((Get-ChildItem -Filter *.whl).FullName)[all]"
309-
}
310-
Pop-Location
311-
}
312-
$TEST_CUDA_MAJOR = '${{ matrix.CUDA_VER }}' -split '\.' | Select-Object -First 1
313-
Push-Location $env:CUDA_CORE_ARTIFACTS_DIR
314-
pip install "$((Get-ChildItem -Filter *.whl).FullName)[cu${TEST_CUDA_MAJOR},test-cu${TEST_CUDA_MAJOR}]"
315-
Pop-Location
316-
317-
Push-Location ./cuda_core
318-
pytest -rxXs -v tests/
319-
if ($env:SKIP_CYTHON_TEST -eq '0') {
320-
pytest -rxXs -v tests/cython
321-
}
322-
Pop-Location
262+
env:
263+
CUDA_VER: ${{ matrix.CUDA_VER }}
264+
LOCAL_CTK: ${{ matrix.LOCAL_CTK }}
265+
shell: bash --noprofile --norc -xeuo pipefail {0}
266+
run: run-tests core
323267

324268
- name: Ensure cuda-python installable
325269
run: |

0 commit comments

Comments
 (0)