SKIP_TO_MAIN_CONTENT
machine.dev
SIGN_UP
04.0 // Documentation v1.15.1 Last updated 2026-11-11

CUDA CI on GitHub Actions

Compile and execute a CUDA kernel in GitHub Actions on a Machine GPU runner. Check device execution separately from compilation.

CUDA CI should compile your kernel and run it on a GPU. A successful build only proves the compiler accepted it. We want to know the result is right.

Complete the quickstart, then add this workflow to your repository. Start with $10 of free GPU time. No charge, no commitment.

Compile and run a kernel

The runner provides the NVIDIA driver. This workflow uses a CUDA development container for the compiler and runtime. It prints their versions, compiles a tiny kernel and checks the value copied back to the host. Every CUDA call is checked so a device error can’t look like a passing test.

name: CUDA kernel test
on: workflow_dispatch
permissions:
  contents: read
jobs:
  cuda:
    runs-on: machine/id=${{ github.run_id }}-${{ github.run_attempt }}/gpu=t4/tenancy=spot
    timeout-minutes: 10
    container:
      image: nvidia/cuda:12.8.1-devel-ubuntu24.04
      options: --gpus all
    steps:
      - name: Compile and run
        shell: bash
        run: |
          nvidia-smi
          nvcc --version
          cat > smoke.cu <<'CUDA'
          #include <cuda_runtime.h>
          #include <cstdio>
          #define CHECK(call) do { \
            cudaError_t err = (call); \
            if (err != cudaSuccess) { \
              std::fprintf(stderr, "%s\n", cudaGetErrorString(err)); \
              return 1; \
            } \
          } while (0)
          __global__ void answer(int *out) { *out = 42; }
          int main() {
            int *device = nullptr;
            int result = 0;
            CHECK(cudaMalloc(&device, sizeof(int)));
            answer<<<1, 1>>>(device);
            CHECK(cudaGetLastError());
            CHECK(cudaDeviceSynchronize());
            CHECK(cudaMemcpy(&result, device, sizeof(int), cudaMemcpyDeviceToHost));
            CHECK(cudaFree(device));
            return result == 42 ? 0 : 1;
          }
          CUDA
          nvcc smoke.cu -o smoke
          ./smoke

Run it from the Actions tab. The example stays below the free tier’s 30-minute limit (there’s also one concurrent job per unpaid team).

Test your project

Add checkout and your build commands in place of smoke.cu. Set architecture flags for the GPU you selected. Keep a development image when you need nvcc; a runtime image won’t contain the compiler.

Machine’s runner image can change. Pin your container and build dependencies when compiler reproducibility matters, and keep the version output in the logs. See NVIDIA’s CUDA programming guide for the execution and error-handling model.

Use trusted code for initial manual runs. Review fork PRs before allowing them onto runners, and keep workflow permissions at the minimum your build needs.

This is a device smoke test. It won’t catch races in your own kernel; add those checks to your project with Compute Sanitizer and representative inputs.