mirror of
https://github.com/luxfi/node.git
synced 2026-07-29 00:26:40 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b8b3c8004 |
@@ -0,0 +1,127 @@
|
||||
name: Docker (GPU variant)
|
||||
|
||||
# Per-arch NATIVE build of the GPU-accelerated node image (DEXVM_GPU=1).
|
||||
#
|
||||
# The standard image (docker.yml) is pure-Go (CGO_ENABLED=0) and cross-compiles
|
||||
# arm64 on an amd64 runner — correct, because nothing native is linked. The GPU
|
||||
# variant is different: its D-Chain dexvm plugin links the per-arch native
|
||||
# liblux_gpu (lux_gpu_dex_match_order), and a native GPU lib CANNOT be
|
||||
# cross-linked. So each arch is built on the arcd pool that owns the matching
|
||||
# silicon and the matching liblux_gpu artifact from lux-private/gpu-kernels:
|
||||
#
|
||||
# arm64 → spark (GB10, CUDA) → lux-gpu-linux-arm64.tar.gz
|
||||
# amd64 → evo (ROCm, native-linux personality) → lux-gpu-linux-amd64.tar.gz
|
||||
#
|
||||
# Each job emits ghcr.io/luxfi/node:<tag>-gpu-<arch>; the manifest job fuses
|
||||
# them into ghcr.io/luxfi/node:<tag>-gpu. The plain (CPU) manifest is untouched.
|
||||
#
|
||||
# This is opt-in and separate from docker.yml on purpose: an operator that wants
|
||||
# GPU matching pulls :<tag>-gpu; everyone else pulls the portable CPU image.
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: 'version tag to build as the GPU variant, e.g. v1.33.1'
|
||||
required: true
|
||||
lux_gpu_version:
|
||||
description: 'lux-private/gpu-kernels release providing the per-arch liblux_gpu'
|
||||
required: false
|
||||
default: 'v0.1.0'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: arm64
|
||||
runner: spark-lux-linux # GB10 — CUDA host, native arm64
|
||||
platform: linux/arm64
|
||||
- arch: amd64
|
||||
runner: evo-lux-linux # Strix Halo — ROCm host, native amd64
|
||||
platform: linux/amd64
|
||||
name: node:gpu-${{ matrix.arch }} (native)
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.tag }}
|
||||
|
||||
# NATIVE only — no QEMU, no cross. The GPU lib is per-arch; assert the
|
||||
# runner arch matches the target before building.
|
||||
- name: Assert native arch
|
||||
run: |
|
||||
set -euo pipefail
|
||||
host="$(uname -m)"
|
||||
case "${{ matrix.arch }}" in
|
||||
arm64) [ "$host" = "aarch64" ] || [ "$host" = "arm64" ] || { echo "::error::arm64 target on $host"; exit 1; } ;;
|
||||
amd64) [ "$host" = "x86_64" ] || { echo "::error::amd64 target on $host"; exit 1; } ;;
|
||||
esac
|
||||
echo "OK native ${{ matrix.arch }} on $host"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
driver: docker-container
|
||||
driver-opts: network=host
|
||||
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Resolve cross-repo PAT for private luxfi/* deps
|
||||
id: pat
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
UNIVERSE_PAT: ${{ secrets.UNIVERSE_PAT }}
|
||||
run: |
|
||||
tok="$GH_TOKEN"; [ -z "$tok" ] && tok="$UNIVERSE_PAT"
|
||||
[ -n "$tok" ] || { echo "::error::no GH_TOKEN/UNIVERSE_PAT for private luxfi deps"; exit 1; }
|
||||
echo "::add-mask::$tok"
|
||||
{ echo "token<<EOF"; echo "$tok"; echo "EOF"; } >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Single-arch, native build. DEXVM_GPU=1 + CGO_ENABLED=1 make the dexvm
|
||||
# plugin link the per-arch liblux_gpu fetched inside the Dockerfile from
|
||||
# the lux-gpu release. BUILDPLATFORM == TARGETPLATFORM (native) so the
|
||||
# Dockerfile's cross-compile branch is never taken.
|
||||
- name: Build & push GPU variant (native ${{ matrix.arch }})
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile
|
||||
platforms: ${{ matrix.platform }}
|
||||
push: true
|
||||
build-args: |
|
||||
CGO_ENABLED=1
|
||||
DEXVM_GPU=1
|
||||
LUX_GPU_VERSION=${{ github.event.inputs.lux_gpu_version }}
|
||||
secrets: |
|
||||
ghtok=${{ steps.pat.outputs.token }}
|
||||
tags: ghcr.io/luxfi/node:${{ github.event.inputs.tag }}-gpu-${{ matrix.arch }}
|
||||
|
||||
manifest:
|
||||
needs: build
|
||||
runs-on: [self-hosted, linux, amd64]
|
||||
steps:
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Fuse per-arch GPU images into one manifest
|
||||
run: |
|
||||
set -euo pipefail
|
||||
T="ghcr.io/luxfi/node:${{ github.event.inputs.tag }}-gpu"
|
||||
docker manifest create "$T" "$T-amd64" "$T-arm64"
|
||||
docker manifest push "$T"
|
||||
echo "published $T (amd64 + arm64)"
|
||||
+51
-6
@@ -363,9 +363,16 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
# REPLACES the former chains/dexvm proxy (which relayed clob_* over ZAP to a
|
||||
# standalone dchain-venue): there is no DexZapEndpoint and no standalone venue in
|
||||
# the trading path. cmd/dchain wraps the VM in the SAME rpc.Serve plugin harness
|
||||
# luxfi/evm boots through, and is pure-Go (CGO=0) — the optional GPU AMM
|
||||
# accelerator in pkg/lx is a separate concern gated by its own cuda/metal tags and
|
||||
# is NOT linked here. v1.5.10 is the first tag whose cmd/dchain builds CGO=0
|
||||
# luxfi/evm boots through. The STANDARD node builds this plugin pure-Go (CGO=0),
|
||||
# so its matcher is lx.MatchOrderCPU — the pure-Go oracle that works on every
|
||||
# arch with no native deps. GPU acceleration is OPT-IN via DEXVM_GPU=1 (below):
|
||||
# pkg/lx's single orderbook_gpu.go links the unified lux-gpu (liblux_gpu) and
|
||||
# runtime-selects CUDA/HIP/Metal, falling back to MatchOrderCPU when no device is
|
||||
# present — so the two paths are byte-equal by contract (orderbook_gpu_test.go).
|
||||
# Because lux-gpu is a per-arch native lib, the DEXVM_GPU variant CANNOT be
|
||||
# cross-compiled: it must be built on the matching arcd GPU pool (see the
|
||||
# per-arch GPU-variant build in .github/workflows/docker-gpu.yml). v1.5.10 is
|
||||
# the first tag whose cmd/dchain builds CGO=0
|
||||
# (drops the phantom dchain+cgo gate); v1.5.11 wires CLOB order ingestion over the
|
||||
# node HTTP router (VM.CreateHandlers -> /ext/bc/D/dex/<method>, pkg/dchain/ingest.go)
|
||||
# so an order POSTed to the node flows submitTx -> mempool -> consensus -> Verify
|
||||
@@ -386,13 +393,47 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
# fills are trade: rows). Bump with every dex release that changes the VM, like
|
||||
# CHAINS_REF for the other 10 VMs.
|
||||
ARG DEX_REF=v1.5.15
|
||||
|
||||
# GPU-accelerated D-Chain matcher (opt-in). DEXVM_GPU=1 fetches the per-arch
|
||||
# unified lux-gpu (built natively on the arcd GPU pools by
|
||||
# lux-private/gpu-kernels' liblux-gpu.yml — CUDA/arm64 on spark, HIP/amd64 on
|
||||
# evo, Metal on the mac) and builds the dexvm plugin with CGO_ENABLED=1 so
|
||||
# pkg/lx/orderbook_gpu.go links liblux_gpu (lux_gpu_dex_match_order +
|
||||
# lux_gpu_backend_name). Default 0 = the portable pure-Go CPU matcher, unchanged.
|
||||
# The fetch is per-arch and best-effort in the same spirit as lux-accel above,
|
||||
# but for DEXVM_GPU=1 a MISSING lib is FATAL: an operator asking for the GPU
|
||||
# variant must get a GPU-linked plugin, not a silent CPU one. Do NOT set
|
||||
# DEXVM_GPU=1 in a cross-arch (BUILDPLATFORM != TARGETPLATFORM) build — a native
|
||||
# GPU lib cannot be cross-linked; build the GPU variant on the matching pool.
|
||||
ARG DEXVM_GPU=0
|
||||
ARG LUX_GPU_VERSION=v0.1.0
|
||||
RUN --mount=type=secret,id=ghtok,required=false \
|
||||
if [ "${DEXVM_GPU}" = "1" ]; then \
|
||||
ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) && \
|
||||
AUTH=""; [ -s /run/secrets/ghtok ] && AUTH="--header=Authorization: Bearer $(cat /run/secrets/ghtok)"; \
|
||||
wget -q ${AUTH:+"$AUTH"} \
|
||||
"https://github.com/lux-private/gpu-kernels/releases/download/${LUX_GPU_VERSION}/lux-gpu-linux-${ARCH}.tar.gz" \
|
||||
-O /tmp/lux-gpu.tar.gz \
|
||||
&& tar -xzf /tmp/lux-gpu.tar.gz -C /usr/local \
|
||||
&& rm /tmp/lux-gpu.tar.gz \
|
||||
&& ldconfig 2>/dev/null || true; \
|
||||
test -f /usr/local/lib/pkgconfig/lux-gpu.pc \
|
||||
|| { echo "FATAL: DEXVM_GPU=1 but lux-gpu ${LUX_GPU_VERSION} (${ARCH}) unavailable — cannot build the GPU dexvm variant"; exit 1; }; \
|
||||
else \
|
||||
echo "DEXVM_GPU=0: dexvm builds pure-Go CPU matcher (no lux-gpu link)"; \
|
||||
fi
|
||||
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
git clone --depth 1 --branch ${DEX_REF} https://github.com/luxfi/dex.git /tmp/dex && \
|
||||
find /tmp/dex -name go.sum -exec sed -i -E '/^github.com\/(luxfi|hanzoai)\//d' {} + && \
|
||||
cd /tmp/dex && \
|
||||
. /build/build_env.sh && \
|
||||
# DEXVM_GPU=1 → CGO on, orderbook_gpu.go links lux-gpu (pkg-config finds the
|
||||
# per-arch lib fetched above). Default → CGO off, portable pure-Go matcher.
|
||||
if [ "${DEXVM_GPU}" = "1" ]; then DEX_CGO=1; else DEX_CGO=0; fi && \
|
||||
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:${PKG_CONFIG_PATH:-}" && \
|
||||
GOARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \
|
||||
CGO_ENABLED=0 GOFLAGS=-mod=mod \
|
||||
CGO_ENABLED=${DEX_CGO} GOFLAGS=-mod=mod \
|
||||
go build -ldflags="-s -w" \
|
||||
-o /luxd/build/plugins/mDVT5EWMumBp3LCqvKwuyZQeY1VXr1jvjGNAt8nL4UFiXvqXr ./cmd/dchain && \
|
||||
chmod +x /luxd/build/plugins/mDVT5EWMumBp3LCqvKwuyZQeY1VXr1jvjGNAt8nL4UFiXvqXr && \
|
||||
@@ -423,8 +464,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
curl ca-certificates git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# GPU crypto library (optional -- only present when built with CGO_ENABLED=1 + luxcpp).
|
||||
# Pure Go fallbacks are used when the library is absent.
|
||||
# Native GPU libraries (optional). /usr/local/lib exists (empty) on the builder
|
||||
# for the standard CGO_ENABLED=0 / DEXVM_GPU=0 image, so this COPY is a no-op
|
||||
# there. For the DEXVM_GPU=1 variant it carries the per-arch liblux_gpu.so that
|
||||
# the D-Chain dexvm plugin dynamically links; ldconfig then makes it resolvable.
|
||||
# Pure-Go fallbacks are used whenever the library is absent.
|
||||
COPY --from=builder /usr/local/lib/ /usr/local/lib/
|
||||
RUN ldconfig 2>/dev/null || true
|
||||
|
||||
# Maintain compatibility with previous images.
|
||||
|
||||
Reference in New Issue
Block a user