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
78 changes: 78 additions & 0 deletions libs/qec/lib/realtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -246,3 +246,81 @@ endif()

add_subdirectory(quantinuum)
add_subdirectory(simulation)

set(_cudaq_device_call_prefixes "")
if(CUDAQ_REALTIME_ROOT)
list(APPEND _cudaq_device_call_prefixes "${CUDAQ_REALTIME_ROOT}")
list(APPEND _cudaq_device_call_prefixes "${CUDAQ_REALTIME_ROOT}/build")
endif()
if(CUDAQ_INSTALL_PREFIX)
list(APPEND _cudaq_device_call_prefixes "${CUDAQ_INSTALL_PREFIX}")
endif()
if(CUDAQ_INSTALL_DIR)
list(APPEND _cudaq_device_call_prefixes "${CUDAQ_INSTALL_DIR}")
endif()

if(CUDAQ_REALTIME_INCLUDE_DIR AND NOT CUDAQ_DEVICE_CALL_INCLUDE_DIR)
find_path(CUDAQ_DEVICE_CALL_INCLUDE_DIR
NAMES cudaq_internal/device_call/DeviceCallService.h
HINTS ${_cudaq_device_call_prefixes}
PATH_SUFFIXES include runtime/internal/device_call/include
)
if(CUDAQ_DEVICE_CALL_INCLUDE_DIR)
message(STATUS "Found cuda-quantum device_call headers at ${CUDAQ_DEVICE_CALL_INCLUDE_DIR}")
endif()
endif()

if(CUDAQ_REALTIME_INCLUDE_DIR AND NOT CUDAQ_DEVICE_CALL_INCLUDE_DIR)
foreach(_device_call_headers_target IN ITEMS
cudaq::cudaq-device-call-runtime-headers
cudaq-device-call-runtime-headers
cudaq::cudaq-device-call-runtime
cudaq-device-call-runtime)
if(TARGET ${_device_call_headers_target})
get_target_property(_device_call_include_dirs
${_device_call_headers_target} INTERFACE_INCLUDE_DIRECTORIES)
foreach(_device_call_include_dir IN LISTS _device_call_include_dirs)
if(_device_call_include_dir MATCHES "^\\$<BUILD_INTERFACE:(.*)>$")
set(_device_call_include_dir "${CMAKE_MATCH_1}")
elseif(_device_call_include_dir MATCHES "^\\$<INSTALL_INTERFACE:(.*)>$"
AND CUDAQ_INSTALL_DIR)
set(_device_call_include_dir
"${CUDAQ_INSTALL_DIR}/${CMAKE_MATCH_1}")
endif()
if(EXISTS "${_device_call_include_dir}/cudaq_internal/device_call/DeviceCallService.h")
set(CUDAQ_DEVICE_CALL_INCLUDE_DIR "${_device_call_include_dir}")
message(STATUS "Found cuda-quantum device_call headers from target ${_device_call_headers_target} at ${CUDAQ_DEVICE_CALL_INCLUDE_DIR}")
break()
endif()
endforeach()
endif()
if(CUDAQ_DEVICE_CALL_INCLUDE_DIR)
break()
endif()
endforeach()
endif()

set(CUDAQ_DEVICE_CALL_RUNTIME_LINK "")
if(TARGET cudaq::cudaq-device-call-runtime)
set(CUDAQ_DEVICE_CALL_RUNTIME_LINK cudaq::cudaq-device-call-runtime)
message(STATUS "Found cuda-quantum device_call runtime target cudaq::cudaq-device-call-runtime")
elseif(TARGET cudaq-device-call-runtime)
set(CUDAQ_DEVICE_CALL_RUNTIME_LINK cudaq-device-call-runtime)
message(STATUS "Found cuda-quantum device_call runtime target cudaq-device-call-runtime")
else()
if(CUDAQ_REALTIME_INCLUDE_DIR AND NOT CUDAQ_DEVICE_CALL_RUNTIME_LIBRARY)
find_library(CUDAQ_DEVICE_CALL_RUNTIME_LIBRARY
NAMES cudaq-device-call-runtime
PATHS ${_cudaq_device_call_prefixes}
PATH_SUFFIXES lib
)
if(CUDAQ_DEVICE_CALL_RUNTIME_LIBRARY)
message(STATUS "Found cuda-quantum device_call runtime library at ${CUDAQ_DEVICE_CALL_RUNTIME_LIBRARY}")
endif()
endif()
if(CUDAQ_DEVICE_CALL_RUNTIME_LIBRARY)
set(CUDAQ_DEVICE_CALL_RUNTIME_LINK ${CUDAQ_DEVICE_CALL_RUNTIME_LIBRARY})
endif()
endif()

add_subdirectory(host_dispatch)
68 changes: 68 additions & 0 deletions libs/qec/lib/realtime/host_dispatch/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# ============================================================================ #
# Copyright (c) 2026 NVIDIA Corporation & Affiliates. #
# All rights reserved. #
# #
# This source code and the accompanying materials are made available under #
# the terms of the Apache License 2.0 which accompanies this distribution. #
# ============================================================================ #

if(NOT CUDAQ_REALTIME_INCLUDE_DIR OR NOT CUDAQ_DEVICE_CALL_INCLUDE_DIR
OR NOT CUDAQ_DEVICE_CALL_RUNTIME_LINK)
message(WARNING "cuda-quantum realtime/device_call headers or runtime not found. "
"Skipping cudaq-qec-realtime-decoding-host-dispatch.")
return()
endif()

add_library(cudaq-qec-realtime-decoding-host-dispatch SHARED
host_dispatch_service.cpp
)

target_compile_options(cudaq-qec-realtime-decoding-host-dispatch
PRIVATE -fvisibility=hidden -fvisibility-inlines-hidden)

cudaqx_add_device_code(cudaq-qec-realtime-decoding-host-dispatch
SOURCES
host_dispatch_device.cpp
COMPILER_FLAGS
-frealtime-lowering)

target_include_directories(cudaq-qec-realtime-decoding-host-dispatch
PUBLIC
$<BUILD_INTERFACE:${CUDAQX_QEC_INCLUDE_DIR}>
$<INSTALL_INTERFACE:${CUDAQ_INCLUDE_DIR}>
$<INSTALL_INTERFACE:include>
PRIVATE
${CUDAQ_REALTIME_INCLUDE_DIR}
${CUDAQ_DEVICE_CALL_INCLUDE_DIR}
)

target_link_options(cudaq-qec-realtime-decoding-host-dispatch PUBLIC
$<$<CXX_COMPILER_ID:GNU>:-Wl,--exclude-libs,ALL>
)

target_link_libraries(cudaq-qec-realtime-decoding-host-dispatch
PUBLIC
cudaqx-core
cudaq-qec
cudaq-qec-realtime-decoding
PRIVATE
cudaq::cudaq-common
${CUDAQ_DEVICE_CALL_RUNTIME_LINK}
$<$<BOOL:${CUDAQ_REALTIME_LIBRARY}>:${CUDAQ_REALTIME_LIBRARY}>
$<$<BOOL:${CUDAQ_REALTIME_HOST_DISPATCH_LIBRARY}>:${CUDAQ_REALTIME_HOST_DISPATCH_LIBRARY}>
)

set_target_properties(cudaq-qec-realtime-decoding-host-dispatch PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

if(_CUDAQ_REALTIME_LIB_DIR)
set_target_properties(cudaq-qec-realtime-decoding-host-dispatch PROPERTIES
BUILD_RPATH "${_CUDAQ_REALTIME_LIB_DIR};${CMAKE_BINARY_DIR}/lib"
INSTALL_RPATH "${_CUDAQ_REALTIME_LIB_DIR};${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}"
)
endif()

install(TARGETS cudaq-qec-realtime-decoding-host-dispatch
COMPONENT qec-lib
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
65 changes: 65 additions & 0 deletions libs/qec/lib/realtime/host_dispatch/host_dispatch_device.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/****************************************************************-*- C++ -*-****
* Copyright (c) 2026 NVIDIA Corporation & Affiliates. *
* All rights reserved. *
* *
* This source code and the accompanying materials are made available under *
* the terms of the Apache License 2.0 which accompanies this distribution. *
******************************************************************************/

#include "cudaq.h"
#include "cudaq/qec/realtime/decoding.h"

#include <cstddef>
#include <cstdint>
#include <vector>

extern "C" std::uint64_t qec_enqueue_syndromes_ui64(std::uint64_t decoder_id,
std::uint64_t syndrome_size,
std::uint64_t syndrome,
std::uint64_t tag);
extern "C" std::uint64_t qec_get_corrections_ui64(std::uint64_t decoder_id,
std::uint64_t return_size,
std::uint64_t reset);
extern "C" std::uint64_t qec_reset_decoder_ui64(std::uint64_t decoder_id);

namespace cudaq::qec::decoding {

__qpu__ void
enqueue_syndromes(std::uint64_t decoder_id,
const std::vector<cudaq::measure_result> &syndromes,
std::uint64_t tag) {
const std::uint64_t syndrome_size = syndromes.size();
const std::uint64_t syndrome = cudaq::to_integer(cudaq::to_bools(syndromes));
// The ignored ack keeps host-dispatch from treating this as fire-and-forget.
(void)cudaq::device_call(0, qec_enqueue_syndromes_ui64, decoder_id,
syndrome_size, syndrome, tag);
}

__qpu__ void enqueue_syndromes_test(std::uint64_t decoder_id,
const std::vector<bool> &syndromes,
std::uint64_t tag) {
const std::uint64_t syndrome_size = syndromes.size();
const std::uint64_t syndrome = cudaq::to_integer(syndromes);
// The ignored ack keeps host-dispatch from treating this as fire-and-forget.
(void)cudaq::device_call(0, qec_enqueue_syndromes_ui64, decoder_id,
syndrome_size, syndrome, tag);
}

__qpu__ std::vector<bool> get_corrections(std::uint64_t decoder_id,
std::uint64_t return_size,
bool reset) {
std::vector<bool> result(return_size);
const auto packed =
cudaq::device_call(0, qec_get_corrections_ui64, decoder_id, return_size,
static_cast<std::uint64_t>(reset));
for (std::size_t i = 0; i < return_size; ++i)
result[i] = (packed >> i) & 1;
return result;
}

__qpu__ void reset_decoder(std::uint64_t decoder_id) {
// The ignored ack keeps host-dispatch from treating this as fire-and-forget.
(void)cudaq::device_call(0, qec_reset_decoder_ui64, decoder_id);
}

} // namespace cudaq::qec::decoding
Loading
Loading