This is an automated email from the ASF dual-hosted git repository.
sleeepyjack pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datasketches-cuda.git
The following commit(s) were added to refs/heads/main by this push:
new fc03d6e Enable GPU CI (#17)
fc03d6e is described below
commit fc03d6eb21d94e60d73358c407f5e5ff085c7c7d
Author: Daniel Jünger <[email protected]>
AuthorDate: Thu Oct 22 17:57:31 2026 +0200
Enable GPU CI (#17)
---
.devcontainer/README.md | 11 ++
.../{ => cuda12.0-gcc11}/devcontainer.json | 18 +--
.../{ => cuda13.4-gcc14}/devcontainer.json | 18 +--
.devcontainer/devcontainer.json | 18 +--
.devcontainer/generate.py | 98 ++++++++++++
.github/dependabot.yml | 17 +++
.github/workflows/ci.yml | 165 +++++++++------------
.github/workflows/pre-commit.yml | 3 +
ci/matrix.json | 25 ++++
9 files changed, 251 insertions(+), 122 deletions(-)
diff --git a/.devcontainer/README.md b/.devcontainer/README.md
index 18325c1..2250f08 100644
--- a/.devcontainer/README.md
+++ b/.devcontainer/README.md
@@ -1,5 +1,16 @@
# Datasketches CUDA Dev Container
+The default container uses the newest GPU test toolchain. The CPU build
+configurations are also available under `.devcontainer/cuda12.0-gcc11/` and
+`.devcontainer/cuda13.4-gcc14/`. Their RAPIDS release, image and compiler
+selections come from `ci/matrix.json`. After updating the matrix or shared
+devcontainer settings, regenerate and check the files with:
+
+```bash
+python3 .devcontainer/generate.py
+python3 .devcontainer/generate.py --check
+```
+
## VS Code
Open the repository and use **Dev Containers: Reopen in Container**. GPU access
diff --git a/.devcontainer/devcontainer.json
b/.devcontainer/cuda12.0-gcc11/devcontainer.json
similarity index 82%
copy from .devcontainer/devcontainer.json
copy to .devcontainer/cuda12.0-gcc11/devcontainer.json
index e2e747f..a36662c 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/cuda12.0-gcc11/devcontainer.json
@@ -1,7 +1,7 @@
{
- "name": "datasketches-cuda-cuda13.3-gcc15",
+ "name": "datasketches-cuda-cuda12.0-gcc11",
"shutdownAction": "stopContainer",
- "image": "rapidsai/devcontainers:26.08-cpp-gcc15-cuda13.3",
+ "image": "rapidsai/devcontainers:26.12-cpp-gcc11-cuda12.0-ubuntu22.04",
"workspaceFolder": "/home/coder/datasketches-cuda",
"workspaceMount":
"source=${localWorkspaceFolder},target=/home/coder/datasketches-cuda,type=bind",
"hostRequirements": {
@@ -10,21 +10,21 @@
"runArgs": [
"--init",
"--name",
-
"${localEnv:USER:anon}-${localWorkspaceFolderBasename}-datasketches-cuda13.3-gcc15",
+
"${localEnv:USER:anon}-${localWorkspaceFolderBasename}-datasketches-cuda12.0-gcc11",
"--ulimit",
"nofile=500000"
],
"containerEnv": {
- "CC": "gcc-15",
- "CXX": "g++-15",
- "CUDAHOSTCXX": "g++-15",
+ "CC": "gcc-11",
+ "CXX": "g++-11",
+ "CUDAHOSTCXX": "g++-11",
"CMAKE_GENERATOR": "Ninja",
"CPM_SOURCE_CACHE": "${containerWorkspaceFolder}/build/cpm-cache",
"NVCC_APPEND_FLAGS": "-t=100",
- "DEVCONTAINER_NAME": "cuda13.3-gcc15",
- "CCCL_CUDA_VERSION": "13.3",
+ "DEVCONTAINER_NAME": "cuda12.0-gcc11",
+ "CCCL_CUDA_VERSION": "12.0",
"CCCL_HOST_COMPILER": "gcc",
- "CCCL_HOST_COMPILER_VERSION": "15",
+ "CCCL_HOST_COMPILER_VERSION": "11",
"CCCL_CUDA_EXTENDED": "false"
},
"postCreateCommand": "git config --global --add safe.directory
${containerWorkspaceFolder} || true",
diff --git a/.devcontainer/devcontainer.json
b/.devcontainer/cuda13.4-gcc14/devcontainer.json
similarity index 82%
copy from .devcontainer/devcontainer.json
copy to .devcontainer/cuda13.4-gcc14/devcontainer.json
index e2e747f..7600de0 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/cuda13.4-gcc14/devcontainer.json
@@ -1,7 +1,7 @@
{
- "name": "datasketches-cuda-cuda13.3-gcc15",
+ "name": "datasketches-cuda-cuda13.4-gcc14",
"shutdownAction": "stopContainer",
- "image": "rapidsai/devcontainers:26.08-cpp-gcc15-cuda13.3",
+ "image": "rapidsai/devcontainers:26.12-cpp-gcc14-cuda13.4-ubuntu24.04",
"workspaceFolder": "/home/coder/datasketches-cuda",
"workspaceMount":
"source=${localWorkspaceFolder},target=/home/coder/datasketches-cuda,type=bind",
"hostRequirements": {
@@ -10,21 +10,21 @@
"runArgs": [
"--init",
"--name",
-
"${localEnv:USER:anon}-${localWorkspaceFolderBasename}-datasketches-cuda13.3-gcc15",
+
"${localEnv:USER:anon}-${localWorkspaceFolderBasename}-datasketches-cuda13.4-gcc14",
"--ulimit",
"nofile=500000"
],
"containerEnv": {
- "CC": "gcc-15",
- "CXX": "g++-15",
- "CUDAHOSTCXX": "g++-15",
+ "CC": "gcc-14",
+ "CXX": "g++-14",
+ "CUDAHOSTCXX": "g++-14",
"CMAKE_GENERATOR": "Ninja",
"CPM_SOURCE_CACHE": "${containerWorkspaceFolder}/build/cpm-cache",
"NVCC_APPEND_FLAGS": "-t=100",
- "DEVCONTAINER_NAME": "cuda13.3-gcc15",
- "CCCL_CUDA_VERSION": "13.3",
+ "DEVCONTAINER_NAME": "cuda13.4-gcc14",
+ "CCCL_CUDA_VERSION": "13.4",
"CCCL_HOST_COMPILER": "gcc",
- "CCCL_HOST_COMPILER_VERSION": "15",
+ "CCCL_HOST_COMPILER_VERSION": "14",
"CCCL_CUDA_EXTENDED": "false"
},
"postCreateCommand": "git config --global --add safe.directory
${containerWorkspaceFolder} || true",
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index e2e747f..7600de0 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -1,7 +1,7 @@
{
- "name": "datasketches-cuda-cuda13.3-gcc15",
+ "name": "datasketches-cuda-cuda13.4-gcc14",
"shutdownAction": "stopContainer",
- "image": "rapidsai/devcontainers:26.08-cpp-gcc15-cuda13.3",
+ "image": "rapidsai/devcontainers:26.12-cpp-gcc14-cuda13.4-ubuntu24.04",
"workspaceFolder": "/home/coder/datasketches-cuda",
"workspaceMount":
"source=${localWorkspaceFolder},target=/home/coder/datasketches-cuda,type=bind",
"hostRequirements": {
@@ -10,21 +10,21 @@
"runArgs": [
"--init",
"--name",
-
"${localEnv:USER:anon}-${localWorkspaceFolderBasename}-datasketches-cuda13.3-gcc15",
+
"${localEnv:USER:anon}-${localWorkspaceFolderBasename}-datasketches-cuda13.4-gcc14",
"--ulimit",
"nofile=500000"
],
"containerEnv": {
- "CC": "gcc-15",
- "CXX": "g++-15",
- "CUDAHOSTCXX": "g++-15",
+ "CC": "gcc-14",
+ "CXX": "g++-14",
+ "CUDAHOSTCXX": "g++-14",
"CMAKE_GENERATOR": "Ninja",
"CPM_SOURCE_CACHE": "${containerWorkspaceFolder}/build/cpm-cache",
"NVCC_APPEND_FLAGS": "-t=100",
- "DEVCONTAINER_NAME": "cuda13.3-gcc15",
- "CCCL_CUDA_VERSION": "13.3",
+ "DEVCONTAINER_NAME": "cuda13.4-gcc14",
+ "CCCL_CUDA_VERSION": "13.4",
"CCCL_HOST_COMPILER": "gcc",
- "CCCL_HOST_COMPILER_VERSION": "15",
+ "CCCL_HOST_COMPILER_VERSION": "14",
"CCCL_CUDA_EXTENDED": "false"
},
"postCreateCommand": "git config --global --add safe.directory
${containerWorkspaceFolder} || true",
diff --git a/.devcontainer/generate.py b/.devcontainer/generate.py
new file mode 100644
index 0000000..b739cd5
--- /dev/null
+++ b/.devcontainer/generate.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python3
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import copy
+import json
+import sys
+from pathlib import Path
+
+
+ROOT = Path(__file__).resolve().parent
+MATRIX = ROOT.parent / "ci" / "matrix.json"
+
+
+def with_image(version, config):
+ result = dict(config)
+ result["image"] = (
+ f"rapidsai/devcontainers:{version}-cpp-gcc{config['gcc']}"
+ f"-cuda{config['cuda']}-{config['os']}"
+ )
+ return result
+
+
+def render(template, config):
+ result = copy.deepcopy(template)
+ suffix = f"cuda{config['cuda']}-gcc{config['gcc']}"
+ result["name"] = f"datasketches-cuda-{suffix}"
+ result["image"] = config["image"]
+ result["runArgs"][result["runArgs"].index("--name") + 1] = (
+
f"${{localEnv:USER:anon}}-${{localWorkspaceFolderBasename}}-datasketches-{suffix}"
+ )
+ result["containerEnv"].update(
+ {
+ "CC": f"gcc-{config['gcc']}",
+ "CXX": f"g++-{config['gcc']}",
+ "CUDAHOSTCXX": f"g++-{config['gcc']}",
+ "DEVCONTAINER_NAME": suffix,
+ "CCCL_CUDA_VERSION": config["cuda"],
+ "CCCL_HOST_COMPILER_VERSION": config["gcc"],
+ }
+ )
+ return json.dumps(result, indent=2) + "\n"
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--check", action="store_true", help="Verify generated
files are current")
+ parser.add_argument("--github-output", type=Path, help="Write resolved CI
matrix outputs")
+ args = parser.parse_args()
+
+ matrix = json.loads(MATRIX.read_text())
+ builds = [with_image(matrix["rapids_version"], config) for config in
matrix["build"]]
+ test_build = next(config for config in builds if config["id"] ==
matrix["test"]["build"])
+ test = {**test_build, "arch": matrix["test"]["arch"]}
+ if test["arch"] not in test_build["arch"].split(";"):
+ raise ValueError("GPU test architecture must be included in its build
configuration")
+ template = json.loads((ROOT / "devcontainer.json").read_text())
+ expected = {ROOT / "devcontainer.json": render(template, test)}
+ for config in builds:
+ name = f"cuda{config['cuda']}-gcc{config['gcc']}"
+ expected[ROOT / name / "devcontainer.json"] = render(template, config)
+
+ stale = set(ROOT.glob("cuda*-gcc*/devcontainer.json")) - set(expected)
+ for path in sorted(stale):
+ print(f"Stale generated devcontainer: {path}", file=sys.stderr)
+
+ outdated = bool(stale)
+ for path, content in expected.items():
+ if args.check:
+ if not path.exists() or path.read_text() != content:
+ print(f"Outdated generated devcontainer: {path}",
file=sys.stderr)
+ outdated = True
+ else:
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.write_text(content)
+ if args.github_output and not outdated:
+ with args.github_output.open("a") as output:
+ output.write(f"builds={json.dumps(builds, separators=(',',
':'))}\n")
+ output.write(f"test_image={test['image']}\n")
+ return int(outdated)
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..4cac097
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,17 @@
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ cooldown:
+ default-days: 4
+ groups:
+ actions-dependencies:
+ applies-to: version-updates
+ patterns:
+ - "*"
+ actions-security:
+ applies-to: security-updates
+ patterns:
+ - "*"
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c684abf..da1f731 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -5,52 +5,42 @@ on:
branches: [main, master]
pull_request:
-# Ubuntu's apt cmake (3.22 on 22.04, 3.28 on 24.04) is below our
-# cmake_minimum_required (3.30). All jobs install this version from
-# Kitware's GitHub release tarball instead.
-env:
- CMAKE_VERSION: 3.30.5
+permissions:
+ contents: read
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number ||
github.run_id }}
+ cancel-in-progress: true
jobs:
+ matrix:
+ name: matrix
+ runs-on: ubuntu-latest
+ outputs:
+ builds: ${{ steps.config.outputs.builds }}
+ test_image: ${{ steps.config.outputs.test_image }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ persist-credentials: false
+
+ - name: Verify devcontainers and read matrix
+ id: config
+ run: python3 .devcontainer/generate.py --check --github-output
"$GITHUB_OUTPUT"
+
build:
- # The matrix is sparse on purpose: each row varies all axes (CTK, host
- # compiler, CUDA arch) rather than enumerating a Cartesian product. Add
- # rows as new combinations become interesting.
- name: ${{ matrix.cfg.name }}
+ name: build (${{ matrix.cfg.name }})
+ needs: matrix
runs-on: ubuntu-latest
container:
image: ${{ matrix.cfg.image }}
strategy:
fail-fast: false
matrix:
- cfg:
- # Oldest supported CTK: CUDA 12.0, GCC 11, sm_70 (Volta),
ubuntu22.04.
- - { name: 'CTK 12.0 / GCC 11 / sm_70',
- image: 'nvidia/cuda:12.0.1-devel-ubuntu22.04',
- gcc: '11', arch: '70' }
- # Newest CTK: CUDA 13.1, GCC 14, sm_100 (Blackwell), ubuntu24.04.
- # CUDA 13 dropped older base OSes; 22.04 and 24.04 are supported.
- - { name: 'CTK 13.1 / GCC 14 / sm_100',
- image: 'nvidia/cuda:13.1.0-devel-ubuntu24.04',
- gcc: '14', arch: '100' }
+ cfg: ${{ fromJSON(needs.matrix.outputs.builds) }}
steps:
- - name: Install build prerequisites
- # The nvidia/cuda devel image ships nvcc, libcudart, and a host
- # toolchain, but not cmake/ninja or arbitrary GCC versions. Install
- # only what we need; --no-install-recommends keeps the layer small.
- # cmake comes from Kitware's release tarball because the apt cmake
- # on both 22.04 and 24.04 is below our minimum.
- run: |
- apt-get update
- apt-get install -y --no-install-recommends \
- ca-certificates curl git ninja-build \
- gcc-${{ matrix.cfg.gcc }} g++-${{ matrix.cfg.gcc }}
- curl -fsSL
"https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-linux-x86_64.tar.gz"
\
- | tar -xz -C /opt
- ln -sf /opt/cmake-${CMAKE_VERSION}-linux-x86_64/bin/cmake
/usr/local/bin/cmake
- ln -sf /opt/cmake-${CMAKE_VERSION}-linux-x86_64/bin/ctest
/usr/local/bin/ctest
-
- name: Checkout
uses: actions/checkout@v4
with:
@@ -69,69 +59,54 @@ jobs:
CC: gcc-${{ matrix.cfg.gcc }}
CXX: g++-${{ matrix.cfg.gcc }}
CUDAHOSTCXX: g++-${{ matrix.cfg.gcc }}
+ CUDACXX: /usr/local/cuda/bin/nvcc
CPM_SOURCE_CACHE: /root/.cache/CPM
run: |
cmake -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
- -DCMAKE_CUDA_ARCHITECTURES=${{ matrix.cfg.arch }}
+ -DCMAKE_CUDA_ARCHITECTURES="${{ matrix.cfg.arch }}"
- name: Build
- # Builds all targets including the GPU test binaries, which catches
- # compile/link regressions on a CPU runner. Tests live in a separate
- # job that runs on GPU hardware (see commented-out `test:` job below).
- run: cmake --build build --parallel
-
- # ---------------------------------------------------------------------------
- # GPU-runner test job. Uncomment when a self-hosted runner labeled `gpu`
- # (or a GitHub-hosted GPU runner) becomes available.
- #
- # Runs its own build because: (a) the build artifacts from the matrix above
- # are MB-sized and slow to ship via `actions/upload-artifact`; (b) a self-
- # hosted GPU runner usually has the toolchain installed already and can
- # rebuild quickly. The CPU `build` matrix above remains the cross-version
- # compile gate; this job is the runtime gate on a single canonical config.
- # Pin `image` and `gcc` to whichever combo is the project's reference
- # supported version.
- # ---------------------------------------------------------------------------
- # test:
- # name: Test (GPU)
- # needs: build
- # runs-on: [self-hosted, gpu]
- # container:
- # image: nvidia/cuda:13.1.0-devel-ubuntu24.04
- # options: --gpus all
- # steps:
- # - name: Install build prerequisites
- # run: |
- # apt-get update
- # apt-get install -y --no-install-recommends \
- # ca-certificates curl git ninja-build gcc-14 g++-14
- # curl -fsSL
"https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-linux-x86_64.tar.gz"
\
- # | tar -xz -C /opt
- # ln -sf /opt/cmake-${CMAKE_VERSION}-linux-x86_64/bin/cmake
/usr/local/bin/cmake
- # ln -sf /opt/cmake-${CMAKE_VERSION}-linux-x86_64/bin/ctest
/usr/local/bin/ctest
- # - name: Checkout
- # uses: actions/checkout@v4
- # with:
- # persist-credentials: false
- # - name: Cache CPM dependencies
- # uses: actions/cache@v4
- # with:
- # path: /root/.cache/CPM
- # key: cpm-${{ hashFiles('cmake/thirdparty/*.cmake',
'cmake/CPM.cmake', 'test/hll/CMakeLists.txt') }}
- # restore-keys: |
- # cpm-
- # - name: Configure
- # env:
- # CC: gcc-14
- # CXX: g++-14
- # CUDAHOSTCXX: g++-14
- # CPM_SOURCE_CACHE: /root/.cache/CPM
- # run: |
- # cmake -B build -G Ninja \
- # -DCMAKE_BUILD_TYPE=Release \
- # -DCMAKE_CUDA_ARCHITECTURES=native
- # - name: Build
- # run: cmake --build build --parallel
- # - name: Run tests
- # run: ctest --test-dir build --parallel 4 --output-on-failure
+ run: cmake --build build --parallel 2
+
+ - name: Package GPU tests
+ if: matrix.cfg.id == 'latest'
+ run: tar -cf gpu-tests.tar build
+
+ - name: Upload GPU tests
+ if: matrix.cfg.id == 'latest'
+ uses: actions/upload-artifact@v4
+ with:
+ name: gpu-tests
+ path: gpu-tests.tar
+ retention-days: 1
+
+ test:
+ name: test
+ needs: [matrix, build]
+ runs-on: "runs-on=${{ github.run_id
}}/family=g4dn.xlarge/image=ubuntu24-gpu-x64"
+ timeout-minutes: 120
+ container:
+ image: ${{ needs.matrix.outputs.test_image }}
+ options: --gpus all
+ steps:
+ - name: Check GPU
+ run: nvidia-smi
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ persist-credentials: false
+
+ - name: Download GPU tests
+ uses: actions/download-artifact@v4
+ with:
+ name: gpu-tests
+
+ - name: Unpack GPU tests
+ run: tar -xf gpu-tests.tar
+
+ - name: Run tests
+ run: |
+ ctest --test-dir build --show-only=json-v1 \
+ | python3 -c 'import json, sys; assert
json.load(sys.stdin)["tests"], "No CTest tests discovered"'
+ ctest --test-dir build --output-on-failure
diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml
index d4843d6..6c26b91 100644
--- a/.github/workflows/pre-commit.yml
+++ b/.github/workflows/pre-commit.yml
@@ -5,6 +5,9 @@ on:
branches: [main, master]
pull_request:
+permissions:
+ contents: read
+
jobs:
pre-commit:
runs-on: ubuntu-latest
diff --git a/ci/matrix.json b/ci/matrix.json
new file mode 100644
index 0000000..e2b1ca9
--- /dev/null
+++ b/ci/matrix.json
@@ -0,0 +1,25 @@
+{
+ "rapids_version": "26.12",
+ "build": [
+ {
+ "id": "oldest",
+ "name": "CTK 12.0 / GCC 11 / sm_70",
+ "cuda": "12.0",
+ "gcc": "11",
+ "arch": "70",
+ "os": "ubuntu22.04"
+ },
+ {
+ "id": "latest",
+ "name": "CTK 13.4 / GCC 14 / sm_107+75",
+ "cuda": "13.4",
+ "gcc": "14",
+ "arch": "107;75",
+ "os": "ubuntu24.04"
+ }
+ ],
+ "test": {
+ "build": "latest",
+ "arch": "75"
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]