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]

Reply via email to