Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 109 additions & 9 deletions .github/actions/build-lib/build_qec.sh
Original file line number Diff line number Diff line change
@@ -1,24 +1,121 @@
#!/bin/sh
set -e

# Download realtime artifacts from GitHub release (if CUDAQ_REALTIME_ROOT not set)
# REVERT-WITH-CUDAQ-REALTIME-BUILD
# Build cuda-quantum realtime library + hololink tools (if CUDAQ_REALTIME_ROOT not set)
if [ -z "$CUDAQ_REALTIME_ROOT" ]; then
CUDAQ_REALTIME_ROOT=/tmp/cudaq-realtime
CUDAQ_REALTIME_REPO=https://github.com/NVIDIA/cuda-quantum.git
CUDAQ_REALTIME_REF=9ce3d2e886
_build_cwd=$(pwd)

cd /tmp
git clone --filter=blob:none --no-checkout https://github.com/NVIDIA/cuda-quantum
cd cuda-quantum
rm -rf cudaq-realtime-src $CUDAQ_REALTIME_ROOT
git clone --filter=blob:none --no-checkout $CUDAQ_REALTIME_REPO cudaq-realtime-src
cd cudaq-realtime-src
git sparse-checkout init --cone
git sparse-checkout set realtime
git checkout 9ce3d2e886c92800ff02665a6f077cffabc86b66 # main
cd realtime
mkdir build && cd build
cmake -G Ninja -DCMAKE_INSTALL_PREFIX="$CUDAQ_REALTIME_ROOT" ..
git checkout $CUDAQ_REALTIME_REF

# Install build tools and DOCA/Holoscan SDK for HSB.
# The cudaqx CI container has Mellanox OFED pre-installed, so we cannot use
# install_dev_prerequisites.sh (it installs doca-all which conflicts with
# the container's OFED packages). Instead, install only the DOCA dev headers
# and Holoscan SDK that we actually need.
CUDA_MAJOR_VERSION=$(nvcc --version | sed -n 's/^.*release \([0-9]\+\).*$/\1/p')
apt-get update && apt-get install -y --no-install-recommends \
ninja-build curl pkg-config
# HSB -> find_package(holoscan) -> rapids_logger requires cmake >= 3.30.4;
# the CI container ships cmake 3.28.
pip install cmake
export PATH="$(python3 -c 'import cmake,os;print(os.path.join(os.path.dirname(cmake.__file__),"data","bin"))'):$PATH"

# Add DOCA repo and install only the GPUNetIO dev package (not doca-all)
DOCA_ARCH=$(uname -m)
case "$DOCA_ARCH" in aarch64|arm64) DOCA_ARCH="arm64-sbsa" ;; esac
DOCA_REPO="https://linux.mellanox.com/public/repo/doca/3.3.0/ubuntu24.04/$DOCA_ARCH"
curl -fsSL "$DOCA_REPO/GPG-KEY-Mellanox.pub" -o /usr/share/keyrings/GPG-KEY-Mellanox.pub
echo "deb [signed-by=/usr/share/keyrings/GPG-KEY-Mellanox.pub] $DOCA_REPO /" \
> /etc/apt/sources.list.d/doca.list
apt-get update
apt-get -y install --no-install-recommends libdoca-sdk-gpunetio-dev

# hololink_core links CUDA::nvrtc -- must match the exact toolkit version
CUDA_FULL_VERSION=$(nvcc --version | sed -n 's/^.*release \([0-9]\+\.[0-9]\+\).*$/\1/p')
CUDA_VER_DASH=$(echo $CUDA_FULL_VERSION | sed 's/\./-/')
apt-get install -y cuda-nvrtc-dev-$CUDA_VER_DASH 2>/dev/null || true

# Holoscan SDK (force-install if normal install fails due to missing deps)
apt-get install -y --no-install-recommends holoscan-cuda-$CUDA_MAJOR_VERSION || {
_hsdk_tmp=$(mktemp -d)
(cd "$_hsdk_tmp" && apt-get download holoscan holoscan-cuda-$CUDA_MAJOR_VERSION \
&& dpkg --force-depends -i holoscan*.deb)
rm -rf "$_hsdk_tmp"
}

# Build holoscan-sensor-bridge (hololink) FIRST, so cuda-quantum realtime
# can build the bridge-hololink wrapper library that links against it.
HSB_REPO=https://github.com/nvidia-holoscan/holoscan-sensor-bridge.git
HSB_REF=release-2.6.0-EA
HSB_PATCHES="/tmp/cudaq-realtime-src/realtime/scripts/hololink-patches"
HSB_ROOT=/tmp/holoscan-sensor-bridge
HSB_BUILD=${HSB_ROOT}/build

if [ ! -d /opt/mellanox/doca/include ]; then
echo "ERROR: DOCA SDK installation failed" >&2
exit 1
fi
if [ ! -d /opt/nvidia/holoscan ]; then
echo "ERROR: Holoscan SDK installation failed" >&2
exit 1
fi

cd /tmp
rm -rf holoscan-sensor-bridge
git clone --depth 1 --branch $HSB_REF $HSB_REPO holoscan-sensor-bridge
cd holoscan-sensor-bridge
for p in "$HSB_PATCHES"/*.patch; do
echo "Applying patch: $(basename $p)"
git apply "$p"
done
# Strip operators we don't need to avoid configure failures from missing deps
sed -i '/add_subdirectory(audio_packetizer)/d; /add_subdirectory(compute_crc)/d;
/add_subdirectory(csi_to_bayer)/d; /add_subdirectory(image_processor)/d;
/add_subdirectory(iq_dec)/d; /add_subdirectory(iq_enc)/d;
/add_subdirectory(linux_coe_receiver)/d; /add_subdirectory(linux_receiver)/d;
/add_subdirectory(packed_format_converter)/d; /add_subdirectory(sub_frame_combiner)/d;
/add_subdirectory(udp_transmitter)/d; /add_subdirectory(emulator)/d;
/add_subdirectory(sig_gen)/d; /add_subdirectory(sig_viewer)/d' \
src/hololink/operators/CMakeLists.txt
export CUDA_NATIVE_ARCH=80
cmake -G Ninja -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DHOLOLINK_BUILD_ONLY_NATIVE=OFF \
-DHOLOLINK_BUILD_PYTHON=OFF \
-DHOLOLINK_BUILD_TESTS=OFF \
-DHOLOLINK_BUILD_TOOLS=OFF \
-DHOLOLINK_BUILD_EXAMPLES=OFF \
-DHOLOLINK_BUILD_EMULATOR=OFF
cmake --build build --target gpu_roce_transceiver hololink_core
echo "holoscan-sensor-bridge built at $HSB_BUILD"

# Build cuda-quantum realtime with hololink tools enabled,
# which produces libcudaq-realtime-bridge-hololink.so needed by the bridge.
cd /tmp/cudaq-realtime-src/realtime
mkdir -p build && cd build
cmake -G Ninja -DCMAKE_INSTALL_PREFIX="$CUDAQ_REALTIME_ROOT" \
-DCUDAQ_REALTIME_ENABLE_HOLOLINK_TOOLS=ON \
-DHOLOSCAN_SENSOR_BRIDGE_SOURCE_DIR=$HSB_ROOT \
-DHOLOSCAN_SENSOR_BRIDGE_BUILD_DIR=$HSB_BUILD \
..
ninja
ninja install

cd "$_build_cwd"
fi

HSB_ROOT=/tmp/holoscan-sensor-bridge
HSB_BUILD=${HSB_ROOT}/build

cmake -S libs/qec -B "$1" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=gcc-11 \
Expand All @@ -29,6 +126,9 @@ cmake -S libs/qec -B "$1" \
-DCUDAQX_INCLUDE_TESTS=ON \
-DCUDAQX_BINDINGS_PYTHON=ON \
-DCMAKE_INSTALL_PREFIX="$2" \
-DCUDAQ_REALTIME_ROOT=$CUDAQ_REALTIME_ROOT
-DCUDAQ_REALTIME_ROOT=$CUDAQ_REALTIME_ROOT \
-DCUDAQX_QEC_ENABLE_HOLOLINK_TOOLS=ON \
-DHOLOSCAN_SENSOR_BRIDGE_SOURCE_DIR=$HSB_ROOT \
-DHOLOSCAN_SENSOR_BRIDGE_BUILD_DIR=$HSB_BUILD

cmake --build "$1" --target install
76 changes: 75 additions & 1 deletion libs/qec/unittests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ target_link_libraries(test_qec PRIVATE GTest::gtest_main cudaq-qec cudaq::cudaq-
add_dependencies(CUDAQXQECUnitTests test_qec)
gtest_discover_tests(test_qec)


# TensorRT decoder test is only built for x86 architectures
if(CUDAQ_QEC_BUILD_TRT_DECODER AND CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64|amd64)|(^i.86$)")
add_executable(test_trt_decoder ./decoders/trt_decoder/test_trt_decoder.cpp)
Expand Down Expand Up @@ -145,10 +144,23 @@ if(CUDAQ_REALTIME_ROOT AND CMAKE_CUDA_COMPILER)
PATH_SUFFIXES lib
)

# libcudaq-realtime.so has a DT_NEEDED for libcudaq-realtime-host-dispatch.so.
# With DT_RUNPATH (CMake default), the executable's RUNPATH is not inherited
# by transitive dependencies. Link it directly so the executable's own RUNPATH
# resolves it at runtime.
find_library(CUDAQ_REALTIME_HOST_DISPATCH_LIBRARY
NAMES cudaq-realtime-host-dispatch
PATHS ${_cudaq_realtime_prefixes}
PATH_SUFFIXES lib
)

if(CUDAQ_REALTIME_INCLUDE_DIR AND CUDAQ_REALTIME_LIBRARY AND CUDAQ_REALTIME_DISPATCH_LIBRARY)
message(STATUS "Found cuda-quantum realtime headers at ${CUDAQ_REALTIME_INCLUDE_DIR}")
message(STATUS "Found cuda-quantum realtime library at ${CUDAQ_REALTIME_LIBRARY}")
message(STATUS "Found cuda-quantum realtime dispatch library at ${CUDAQ_REALTIME_DISPATCH_LIBRARY}")
if(CUDAQ_REALTIME_HOST_DISPATCH_LIBRARY)
message(STATUS "Found cuda-quantum realtime host dispatch library at ${CUDAQ_REALTIME_HOST_DISPATCH_LIBRARY}")
endif()

add_executable(test_realtime_decoding
${CMAKE_CURRENT_SOURCE_DIR}/decoders/realtime/test_realtime_decoding.cu
Expand Down Expand Up @@ -180,6 +192,7 @@ if(CUDAQ_REALTIME_ROOT AND CMAKE_CUDA_COMPILER)
cudaq-qec-realtime-cudevice
${CUDAQ_REALTIME_LIBRARY}
${CUDAQ_REALTIME_DISPATCH_LIBRARY}
$<$<BOOL:${CUDAQ_REALTIME_HOST_DISPATCH_LIBRARY}>:${CUDAQ_REALTIME_HOST_DISPATCH_LIBRARY}>
)

# Ensure runtime can locate libcudaq-realtime.so
Expand All @@ -193,6 +206,61 @@ if(CUDAQ_REALTIME_ROOT AND CMAKE_CUDA_COMPILER)
gtest_discover_tests(test_realtime_decoding
TEST_PREFIX "test_realtime_decoding."
)
# ------------------------------------------------------------------
# Realtime QLDPC graph decode CI test (CPU-launched CUDA graph + relay BP)
# ------------------------------------------------------------------

# cudaq-qec-realtime-decoding transitively pulls in cudaq-qec, which
# references CUDA-Q quantum runtime symbols. Satisfy them here.
find_library(_CUDAQ_LIBRARY NAMES cudaq
PATHS ${CUDAQ_INSTALL_PREFIX} $ENV{CUDAQ_INSTALL_PREFIX}
${CUDAQ_DIR}/.. $ENV{CUDAQ_DIR}/..
PATH_SUFFIXES lib)
find_library(_NVQIR_LIBRARY NAMES nvqir
PATHS ${CUDAQ_INSTALL_PREFIX} $ENV{CUDAQ_INSTALL_PREFIX}
${CUDAQ_DIR}/.. $ENV{CUDAQ_DIR}/..
PATH_SUFFIXES lib)

add_executable(test_realtime_qldpc_graph_decoding
${CMAKE_CURRENT_SOURCE_DIR}/realtime/qec_graph_decode_test/test_realtime_qldpc_graph_decoding.cpp
)

target_include_directories(test_realtime_qldpc_graph_decoding PRIVATE
${CUDAToolkit_INCLUDE_DIRS}
${CUDAQ_REALTIME_INCLUDE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../include
${CMAKE_SOURCE_DIR}/libs/core/include
)

target_compile_definitions(test_realtime_qldpc_graph_decoding PRIVATE
TEST_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/realtime/qec_roce_decode_test/data"
)

target_link_libraries(test_realtime_qldpc_graph_decoding PRIVATE
GTest::gtest_main
CUDA::cudart
${CUDAQ_REALTIME_LIBRARY}
$<$<BOOL:${CUDAQ_REALTIME_HOST_DISPATCH_LIBRARY}>:${CUDAQ_REALTIME_HOST_DISPATCH_LIBRARY}>
cudaq-qec-realtime-decoding
$<$<BOOL:${_CUDAQ_LIBRARY}>:${_CUDAQ_LIBRARY}>
$<$<BOOL:${_NVQIR_LIBRARY}>:${_NVQIR_LIBRARY}>
)

target_link_options(test_realtime_qldpc_graph_decoding PRIVATE
"LINKER:--allow-shlib-undefined"
)

set_target_properties(test_realtime_qldpc_graph_decoding PROPERTIES
BUILD_RPATH "${CUDAQ_REALTIME_LIB_DIR};${CMAKE_BINARY_DIR}/lib/decoder-plugins"
INSTALL_RPATH "${CUDAQ_REALTIME_LIB_DIR};${CMAKE_BINARY_DIR}/lib/decoder-plugins"
)

add_dependencies(CUDAQXQECUnitTests test_realtime_qldpc_graph_decoding)
# Not registered as a ctest: the test dynamically loads the nv-qldpc-decoder
# plugin and requires CUDA-Q quantum runtime symbols (libnvqir) at runtime,
# neither of which are available in CI. Building the target is sufficient to
# verify compilation.

else()
message(WARNING "cuda-quantum realtime dependency not found. "
"Set CUDAQ_REALTIME_ROOT or CUDAQ_INSTALL_PREFIX to enable "
Expand All @@ -206,3 +274,9 @@ add_subdirectory(backend-specific)
add_subdirectory(realtime)
add_subdirectory(decoders/pymatching)

# Hololink bridge tools (FPGA playback + graph-launched QLDPC bridge)
if(CUDAQX_QEC_ENABLE_HOLOLINK_TOOLS)
add_subdirectory(utils)
endif()


Loading
Loading