Skip to content

build: cache C++ and CUDA compilation in container builds - #97

Open
DuncanBetts wants to merge 2 commits into
Neroued:masterfrom
DuncanBetts:build/cache-cxx-cuda
Open

build: cache C++ and CUDA compilation in container builds#97
DuncanBetts wants to merge 2 commits into
Neroued:masterfrom
DuncanBetts:build/cache-cxx-cuda

Conversation

@DuncanBetts

@DuncanBetts DuncanBetts commented Aug 26, 2026

Copy link
Copy Markdown

Container image rebuilds currently discard all previous compiler work whenever
COPY . . changes. In the reproduction below, adding one harmless line to one
.cpp file and one .cu file causes all 278 Ninja steps to run again, even
though 261 of the 263 compiler inputs are unchanged.

Cause. The Dockerfile invokes the C, C++, and CUDA compilers directly and keeps
the build tree inside the invalidated image layer. There is therefore no
compiler-output cache available after a source change. The repository also has
no persistent containerized development-build path.

Fix. Three files:

file change
Dockerfile install ccache; split out a reusable build-env stage; configure CMake's C, C++, and CUDA compiler launchers; retain compiler outputs in a 20 GiB cache mount; print cumulative statistics
compose.yaml add a build service with the source mounted read-only and named volumes for the Ninja build tree and ccache
README.md document the iterative podman compose run --rm build workflow

The image build and Compose paths serve slightly different cases:

  • Dockerfile builds start with a fresh Ninja tree after source-layer
    invalidation, but ccache restores unchanged compiler outputs.
  • Compose builds retain both /build and /ccache, allowing Ninja to skip
    unchanged targets before ccache is consulted.

Verification. The before and after recordings run the same 100×30 terminal
script against the same checkout:

  1. perform a cold image build;
  2. add the same harmless static_assert to one C++ and one CUDA file;
  3. rebuild the image;
  4. restore the exact source tree.
result after the two-file edit before after
Ninja steps 278 278
cacheable compiler calls on the rebuild unavailable 263
compiler-cache hits 0 261
compiler-cache misses 263 2

The after recording prints cumulative totals for both builds:
526 cacheable calls, 261 hits, and 265 misses. The 265 misses comprise
the initial cold build's 263 misses plus the two genuinely changed
translation units.

Reproduction script (ninfer-cache-demo.sh):

#!/bin/sh
set -eux

demo_label=$1
cd /home/duncan/git/prefix-cache-research/repos/ninfer

printf '\n=== 1. Build image ===\n'
podman build --no-cache --tag "localhost/ninfer-cache-demo:${demo_label}" .

printf '\n=== 2. Apply one C++ and one CUDA source edit ===\n'
git apply --verbose /tmp/ninfer-cache-probe.patch
git diff --stat

printf '\n=== 3. Rebuild image after the same two-file edit ===\n'
podman build --tag "localhost/ninfer-cache-demo:${demo_label}" .

printf '\n=== Restore the exact source tree ===\n'
git apply --reverse --verbose /tmp/ninfer-cache-probe.patch
git diff --exit-code -- src/artifact/typed_binding.cpp src/ops/launcher/residual_add.cu

Recording — before:

NInfer rebuild before ccache

Recording — after:

NInfer rebuild with ccache

Marker timestamps are relative to the start of each recording:

chapter before after duration (before / after)
cold image build 00:00.002 00:00.003 02:26.133 / 02:31.940
edit C++ + CUDA 02:26.135 02:31.943 00:00.004 / 00:00.002
rebuild after edit 02:26.139 02:31.945 02:07.750 / 00:21.837
restore source 04:33.889 02:53.782 00:00.005 / 00:00.003

Relevant documentation:

Scope. Build ergonomics only. The runtime stage, installed runtime packages,
CMake targets, generated executables, and inference behavior are unchanged.
Python and ccache are present only in the build environment.

Changes made using AI, with careful steering and review by myself. Thanks for creating Ninfer Neroued, I hope you find these build time savings useful in future work, you can take it as a token of my appreciation :).

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e64041e07a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread compose.yaml Outdated
Comment thread compose.yaml Outdated
@DuncanBetts DuncanBetts changed the title build: cache C++ and CUDA compilation in container builds build: cache C++ and CUDA compilation in container builds Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant