Skip to content

Commit ac7534c

Browse files
authored
Merge pull request #3 from parca-dev/versions
Build fixes for new version scheme
2 parents 0297094 + 377c416 commit ac7534c

File tree

4 files changed

+208
-44
lines changed

4 files changed

+208
-44
lines changed

.github/workflows/container.yml

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ on:
1313
env:
1414
REGISTRY: ghcr.io
1515
IMAGE_NAME: ${{ github.repository }}
16+
CUDA_HEADERS_REGISTRY: ghcr.io/parca-dev/cuda-headers
1617

1718
jobs:
1819
build-and-push:
@@ -45,17 +46,19 @@ jobs:
4546
# For releases: use semantic version tags
4647
type=semver,pattern={{version}}
4748
type=semver,pattern={{major}}.{{minor}}
48-
type=semver,pattern={{major}}
4949
# For main branch: use date and commit SHA
5050
type=raw,value={{date 'YYYYMMDD'}}-{{sha}},enable={{is_default_branch}}
51-
# Also tag as latest for main branch
51+
# Tag as latest for main branch
5252
type=raw,value=latest,enable={{is_default_branch}}
5353
54-
- name: Build and push multi-arch image
54+
- name: Build and push multi-arch image with both CUDA versions
5555
uses: docker/build-push-action@v5
5656
with:
5757
context: .
5858
file: ./Dockerfile
59+
build-args: |
60+
CUDA_12_HEADERS=${{ env.CUDA_HEADERS_REGISTRY }}:12
61+
CUDA_13_HEADERS=${{ env.CUDA_HEADERS_REGISTRY }}:13
5962
platforms: linux/amd64,linux/arm64
6063
target: runtime
6164
push: ${{ github.event_name != 'pull_request' }}
@@ -74,10 +77,22 @@ jobs:
7477

7578
strategy:
7679
matrix:
77-
platform:
78-
- arch: amd64
80+
include:
81+
- cuda_major: "12"
82+
cuda_full: "12.9.1"
83+
arch: amd64
7984
platform: linux/amd64
80-
- arch: arm64
85+
- cuda_major: "12"
86+
cuda_full: "12.9.1"
87+
arch: arm64
88+
platform: linux/arm64
89+
- cuda_major: "13"
90+
cuda_full: "13.0.2"
91+
arch: amd64
92+
platform: linux/amd64
93+
- cuda_major: "13"
94+
cuda_full: "13.0.2"
95+
arch: arm64
8196
platform: linux/arm64
8297

8398
steps:
@@ -87,27 +102,34 @@ jobs:
87102
- name: Set up Docker Buildx
88103
uses: docker/setup-buildx-action@v3
89104

90-
- name: Build and extract binary for ${{ matrix.platform.arch }}
105+
- name: Build and extract binary for ${{ matrix.arch }} (CUDA ${{ matrix.cuda_major }})
106+
env:
107+
LIB_NAME: libparcagpucupti.so.${{ matrix.cuda_major }}
91108
run: |
92-
mkdir -p build/${{ matrix.platform.arch }}
109+
mkdir -p build/${{ matrix.arch }}
93110
docker buildx build -f Dockerfile \
94-
--target export \
95-
--output type=local,dest=build/${{ matrix.platform.arch }} \
96-
--platform ${{ matrix.platform.platform }} \
111+
--build-arg CUDA_12_HEADERS=${{ env.CUDA_HEADERS_REGISTRY }}:12 \
112+
--build-arg CUDA_13_HEADERS=${{ env.CUDA_HEADERS_REGISTRY }}:13 \
113+
--target export-cuda${{ matrix.cuda_major }} \
114+
--output type=local,dest=build/${{ matrix.arch }} \
115+
--platform ${{ matrix.platform }} \
97116
.
98117
99-
- name: Rename binary with arch suffix
118+
- name: Rename binary with arch and CUDA version suffix
119+
env:
120+
LIB_NAME: libparcagpucupti.so.${{ matrix.cuda_major }}
121+
OUTPUT_NAME: libparcagpucupti.so.${{ matrix.cuda_major }}-${{ matrix.arch }}
100122
run: |
101-
mv build/${{ matrix.platform.arch }}/libparcagpucupti.so \
102-
build/${{ matrix.platform.arch }}/libparcagpucupti-${{ matrix.platform.arch }}.so
123+
mv build/${{ matrix.arch }}/${LIB_NAME} \
124+
build/${{ matrix.arch }}/${OUTPUT_NAME}
103125
104126
- name: Upload binary as artifact
105127
uses: actions/upload-artifact@v4
106128
with:
107-
name: libparcagpucupti-${{ matrix.platform.arch }}
108-
path: build/${{ matrix.platform.arch }}/libparcagpucupti-${{ matrix.platform.arch }}.so
129+
name: libparcagpucupti.so.${{ matrix.cuda_major }}-${{ matrix.arch }}
130+
path: build/${{ matrix.arch }}/libparcagpucupti.so.${{ matrix.cuda_major }}-${{ matrix.arch }}
109131

110132
- name: Upload to GitHub Release
111133
uses: softprops/action-gh-release@v1
112134
with:
113-
files: build/${{ matrix.platform.arch }}/libparcagpucupti-${{ matrix.platform.arch }}.so
135+
files: build/${{ matrix.arch }}/libparcagpucupti.so.${{ matrix.cuda_major }}-${{ matrix.arch }}

Dockerfile

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,83 @@
1-
# Multi-platform build for libparcagpucupti.so
2-
# Supports both AMD64 and ARM64 architectures
3-
FROM nvidia/cuda:12.4.1-devel-ubuntu22.04 AS builder
1+
# Slim multi-platform build for libparcagpucupti.so
2+
# Uses pre-built CUDA header images instead of full CUDA development images
3+
# This significantly reduces build time and disk space requirements
44

5-
# Install build tools
5+
# CUDA header images (can be overridden at build time)
6+
ARG CUDA_12_HEADERS=ghcr.io/parca-dev/cuda-headers:12
7+
ARG CUDA_13_HEADERS=ghcr.io/parca-dev/cuda-headers:13
8+
9+
# Import CUDA 12 headers
10+
FROM ${CUDA_12_HEADERS} AS cuda12-headers
11+
12+
# Import CUDA 13 headers
13+
FROM ${CUDA_13_HEADERS} AS cuda13-headers
14+
15+
# Build stage for CUDA 12
16+
FROM ubuntu:22.04 AS builder-cuda12
17+
18+
# Install only build tools (no CUDA toolkit needed)
619
RUN apt-get update && apt-get install -y \
720
cmake \
821
make \
922
gcc \
23+
g++ \
1024
systemtap-sdt-dev \
1125
&& rm -rf /var/lib/apt/lists/*
1226

27+
WORKDIR /build/cupti
28+
29+
# Copy CUDA headers and libraries from header image
30+
COPY --from=cuda12-headers /usr/local/cuda /usr/local/cuda
31+
1332
# Copy source code
33+
COPY cupti/cupti-prof.c cupti/CMakeLists.txt ./
34+
35+
# Build the library for CUDA 12
36+
ENV CUDA_ROOT=/usr/local/cuda
37+
RUN mkdir -p build && \
38+
cd build && \
39+
cmake -DCUDA_ROOT=${CUDA_ROOT} .. && \
40+
make VERBOSE=1 && \
41+
mv libparcagpucupti.so libparcagpucupti.so.12
42+
43+
# Build stage for CUDA 13
44+
FROM ubuntu:22.04 AS builder-cuda13
45+
46+
# Install only build tools (no CUDA toolkit needed)
47+
RUN apt-get update && apt-get install -y \
48+
cmake \
49+
make \
50+
gcc \
51+
g++ \
52+
systemtap-sdt-dev \
53+
&& rm -rf /var/lib/apt/lists/*
54+
1455
WORKDIR /build/cupti
15-
COPY cupti/ .
1656

17-
# Build the library
57+
# Copy CUDA headers and libraries from header image
58+
COPY --from=cuda13-headers /usr/local/cuda /usr/local/cuda
59+
60+
# Copy source code
61+
COPY cupti/cupti-prof.c cupti/CMakeLists.txt ./
62+
63+
# Build the library for CUDA 13
1864
ENV CUDA_ROOT=/usr/local/cuda
1965
RUN mkdir -p build && \
2066
cd build && \
2167
cmake -DCUDA_ROOT=${CUDA_ROOT} .. && \
22-
make VERBOSE=1
68+
make VERBOSE=1 && \
69+
mv libparcagpucupti.so libparcagpucupti.so.13
70+
71+
# Export stages for extracting single libraries (used by Makefile and release binaries)
72+
FROM scratch AS export-cuda12
73+
COPY --from=builder-cuda12 /build/cupti/build/libparcagpucupti.so.12 /
2374

24-
# Extract the built library (for local builds)
25-
FROM scratch AS export
26-
COPY --from=builder /build/cupti/build/libparcagpucupti.so /
75+
FROM scratch AS export-cuda13
76+
COPY --from=builder-cuda13 /build/cupti/build/libparcagpucupti.so.13 /
2777

28-
# Runtime image (for container registry)
78+
# Runtime image with both CUDA versions (for container registry)
2979
FROM busybox:latest AS runtime
30-
COPY --from=builder /build/cupti/build/libparcagpucupti.so /usr/local/lib/
80+
COPY --from=builder-cuda12 /build/cupti/build/libparcagpucupti.so.12 /usr/lib/
81+
COPY --from=builder-cuda13 /build/cupti/build/libparcagpucupti.so.13 /usr/lib/
82+
# Default symlink points to CUDA 12
83+
RUN ln -s /usr/lib/libparcagpucupti.so.12 /usr/lib/libparcagpucupti.so

Dockerfile.cuda-headers

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Dockerfile to create minimal CUDA header images
2+
# These are pushed to ghcr.io and used as build dependencies
3+
# Usage: docker build --build-arg CUDA_VERSION=12.9.1 -t ghcr.io/parca-dev/cuda-headers:12 .
4+
5+
ARG CUDA_VERSION=12.9.1
6+
FROM nvidia/cuda:${CUDA_VERSION}-devel-ubuntu22.04 AS extractor
7+
8+
# Extract only headers and CUPTI library (no CUDA driver library needed for build)
9+
RUN mkdir -p /cuda-sdk/include /cuda-sdk/lib64 && \
10+
cp -r /usr/local/cuda/include/* /cuda-sdk/include/ && \
11+
cp /usr/local/cuda/lib64/libcupti.so* /cuda-sdk/lib64/ && \
12+
cp /usr/local/cuda/lib64/stubs/libcuda.so /cuda-sdk/lib64/
13+
14+
# Minimal runtime image with just the SDK files
15+
FROM busybox:latest
16+
COPY --from=extractor /cuda-sdk /usr/local/cuda

Makefile

Lines changed: 88 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,106 @@
1-
.PHONY: all clean test cupti-amd64 cupti-arm64 test-infra docker-push docker-test-build docker-test-run
1+
.PHONY: all clean test cupti-amd64 cupti-arm64 cupti-all cupti-all-versions cross test-infra docker-push push-cuda-headers docker-test-build docker-test-run format
2+
3+
# CUDA version configuration
4+
CUDA_MAJOR ?= 12
5+
CUDA_FULL_VERSION ?= 12.9.1
6+
LIB_NAME = libparcagpucupti.so.$(CUDA_MAJOR)
27

38
# Default target: build everything for native architecture
49
all: cupti-all test-infra
510

611
# Build libparcagpucupti.so for AMD64 using Docker
712
cupti-amd64:
8-
@echo "=== Building libparcagpucupti.so for AMD64 with Docker ==="
13+
@echo "=== Building $(LIB_NAME) for AMD64 with Docker (CUDA $(CUDA_MAJOR)) ==="
914
@mkdir -p /tmp/parcagpu-build-amd64
1015
@docker buildx use default
1116
@docker buildx build -f Dockerfile \
12-
--target export \
17+
--build-arg CUDA_12_HEADERS=$(CUDA_12_HEADERS) \
18+
--build-arg CUDA_13_HEADERS=$(CUDA_13_HEADERS) \
19+
--target export-cuda$(CUDA_MAJOR) \
1320
--output type=local,dest=/tmp/parcagpu-build-amd64 \
14-
--platform linux/amd64 cupti
15-
@mkdir -p build/amd64
16-
@cp /tmp/parcagpu-build-amd64/libparcagpucupti.so build/amd64/
17-
@echo "AMD64 library built: build/amd64/libparcagpucupti.so"
21+
--platform linux/amd64 .
22+
@mkdir -p build/$(CUDA_MAJOR)/amd64
23+
@cp /tmp/parcagpu-build-amd64/$(LIB_NAME) build/$(CUDA_MAJOR)/amd64/
24+
@ln -sf $(LIB_NAME) build/$(CUDA_MAJOR)/amd64/libparcagpucupti.so
25+
@echo "AMD64 library built: build/$(CUDA_MAJOR)/amd64/$(LIB_NAME)"
1826

1927
# Build libparcagpucupti.so for ARM64 using Docker
2028
cupti-arm64:
21-
@echo "=== Building libparcagpucupti.so for ARM64 with Docker ==="
29+
@echo "=== Building $(LIB_NAME) for ARM64 with Docker (CUDA $(CUDA_MAJOR)) ==="
2230
@mkdir -p /tmp/parcagpu-build-arm64
2331
@docker buildx create --name parcagpu-builder --use --bootstrap 2>/dev/null || docker buildx use parcagpu-builder
2432
@docker buildx build -f Dockerfile \
25-
--target export \
33+
--build-arg CUDA_12_HEADERS=$(CUDA_12_HEADERS) \
34+
--build-arg CUDA_13_HEADERS=$(CUDA_13_HEADERS) \
35+
--target export-cuda$(CUDA_MAJOR) \
2636
--output type=local,dest=/tmp/parcagpu-build-arm64 \
27-
--platform linux/arm64 cupti
28-
@mkdir -p build/arm64
29-
@cp /tmp/parcagpu-build-arm64/libparcagpucupti.so build/arm64/
30-
@echo "ARM64 library built: build/arm64/libparcagpucupti.so"
37+
--platform linux/arm64 .
38+
@mkdir -p build/$(CUDA_MAJOR)/arm64
39+
@cp /tmp/parcagpu-build-arm64/$(LIB_NAME) build/$(CUDA_MAJOR)/arm64/
40+
@ln -sf $(LIB_NAME) build/$(CUDA_MAJOR)/arm64/libparcagpucupti.so
41+
@echo "ARM64 library built: build/$(CUDA_MAJOR)/arm64/$(LIB_NAME)"
3142

32-
# Build both architectures
43+
# Build both architectures for current CUDA version
3344
cupti-all: cupti-amd64 cupti-arm64
3445

46+
# Build runtime container with both CUDA versions for both architectures
47+
# Note: Builds but doesn't load into Docker (multi-platform images can't be loaded)
48+
# Use docker-push to push to a registry, or remove one platform to load locally
49+
cross:
50+
@echo "=== Building runtime container for AMD64 and ARM64 (includes CUDA 12 and 13) ==="
51+
@docker buildx create --name parcagpu-builder --use --bootstrap 2>/dev/null || docker buildx use parcagpu-builder
52+
@docker buildx build -f Dockerfile \
53+
--build-arg CUDA_12_HEADERS=$(CUDA_12_HEADERS) \
54+
--build-arg CUDA_13_HEADERS=$(CUDA_13_HEADERS) \
55+
--target runtime \
56+
--platform linux/amd64,linux/arm64 \
57+
.
58+
@echo "Runtime container built for both platforms (cached, not loaded into Docker)"
59+
60+
# Build all artifacts (CUDA 12 & 13 for both amd64 and arm64)
61+
cupti-all-versions:
62+
@echo "=== Building all CUDA versions (12 and 13) for both architectures ==="
63+
@$(MAKE) cupti-amd64 CUDA_MAJOR=12 CUDA_FULL_VERSION=12.9.1
64+
@$(MAKE) cupti-arm64 CUDA_MAJOR=12 CUDA_FULL_VERSION=12.9.1
65+
@$(MAKE) cupti-amd64 CUDA_MAJOR=13 CUDA_FULL_VERSION=13.0.2
66+
@$(MAKE) cupti-arm64 CUDA_MAJOR=13 CUDA_FULL_VERSION=13.0.2
67+
@echo "=== All artifacts built ==="
68+
@echo "CUDA 12: build/12/amd64/libparcagpucupti.so.12"
69+
@echo "CUDA 12: build/12/arm64/libparcagpucupti.so.12"
70+
@echo "CUDA 13: build/13/amd64/libparcagpucupti.so.13"
71+
@echo "CUDA 13: build/13/arm64/libparcagpucupti.so.13"
72+
73+
# CUDA header image configuration
74+
# Can be overridden to use local images (e.g., make cupti-all CUDA_12_HEADERS=cuda-headers:12)
75+
CUDA_HEADERS_REGISTRY ?= ghcr.io/parca-dev/cuda-headers
76+
CUDA_12_HEADERS ?= $(CUDA_HEADERS_REGISTRY):12
77+
CUDA_13_HEADERS ?= $(CUDA_HEADERS_REGISTRY):13
78+
79+
# Build and push CUDA header images to registry
80+
# These are lightweight images (~35MB each) containing only CUDA headers and libcupti
81+
# Note: Only needs to be run manually when:
82+
# - CUDA versions are updated (12.9.1 -> 12.x.x, 13.0.2 -> 13.x.x)
83+
# - New CUDA major versions are added
84+
# - CUPTI API changes require header updates
85+
push-cuda-headers:
86+
@echo "=== Building and pushing CUDA header images ==="
87+
@docker buildx create --name parcagpu-builder --use --bootstrap 2>/dev/null || docker buildx use parcagpu-builder
88+
@echo "Building CUDA 12 headers..."
89+
@docker buildx build -f Dockerfile.cuda-headers \
90+
--build-arg CUDA_VERSION=12.9.1 \
91+
--platform linux/amd64,linux/arm64 \
92+
--tag $(CUDA_HEADERS_REGISTRY):12 \
93+
--push \
94+
.
95+
@echo "Building CUDA 13 headers..."
96+
@docker buildx build -f Dockerfile.cuda-headers \
97+
--build-arg CUDA_VERSION=13.0.2 \
98+
--platform linux/amd64,linux/arm64 \
99+
--tag $(CUDA_HEADERS_REGISTRY):13 \
100+
--push \
101+
.
102+
@echo "CUDA header images pushed to $(CUDA_HEADERS_REGISTRY):12 and :13"
103+
35104
# Build test infrastructure with Zig
36105
test-infra:
37106
@echo "=== Building test infrastructure with Zig ==="
@@ -52,13 +121,17 @@ clean:
52121
# Build and push multi-arch Docker images to ghcr.io
53122
# Set IMAGE_TAG to override the default tag (e.g., make docker-push IMAGE_TAG=v1.0.0)
54123
# Set IMAGE to override the image name (e.g., make docker-push IMAGE=ghcr.io/myuser/parcagpu)
124+
# Set CUDA_12_HEADERS and CUDA_13_HEADERS to override header images (e.g., cuda-headers:12 for local)
125+
# Note: Runtime image includes both CUDA 12 and 13
55126
IMAGE ?= ghcr.io/parca-dev/parcagpu
56127
IMAGE_TAG ?= latest
57128
docker-push:
58129
@echo "=== Setting up buildx builder ==="
59130
@docker buildx create --name parcagpu-builder --use --bootstrap 2>/dev/null || docker buildx use parcagpu-builder
60-
@echo "=== Building and pushing multi-arch Docker images to $(IMAGE):$(IMAGE_TAG) ==="
131+
@echo "=== Building and pushing multi-arch Docker images to $(IMAGE):$(IMAGE_TAG) (includes CUDA 12 and 13) ==="
61132
@docker buildx build -f Dockerfile \
133+
--build-arg CUDA_12_HEADERS=$(CUDA_12_HEADERS) \
134+
--build-arg CUDA_13_HEADERS=$(CUDA_13_HEADERS) \
62135
--target runtime \
63136
--platform linux/amd64,linux/arm64 \
64137
--tag $(IMAGE):$(IMAGE_TAG) \

0 commit comments

Comments
 (0)