Mooncake/mooncake-transfer-engine
Xun Sun d36a72f0e1
[TE] add device API support (#2333)
* feat(transfer-engine): extract Device API and IBGDA transport layer

Move IBGDA files from mooncake-ep to mooncake-transfer-engine (git mv):
- 6 headers: mooncake_ibgda/ → transport/device/ibgda/
- 1 source: mlx5gda.cpp → transport/device/mlx5gda.cpp

Add new Device API layer under transport/device/:
- device_transport.h: P2pTransport + RdmaTransport interfaces
- device_ops.cuh: DeviceOps function pointer table (bottom IR)
- comm_device.cuh, p2p_device.cuh, ibgda_device.cuh: device contexts
- cuda_ops.cuh, musa_ops.cuh: platform DeviceOps implementations
- ibgda_device_transport.cpp: RdmaTransport IBGDA implementation
- p2p_device_transport.cpp: P2pTransport NVLink/MTLink implementation

Modify transfer-engine:
- transfer_engine.h/impl: add getOrCreateP2pTransport/RdmaTransport
- gpu_vendor/musa.h: add MUSA API aliases
- Build: link mlx5, add device/ subdirectory

Minimal EP changes (include paths + build system only):
- Update include paths to new transport/device/ibgda/ location
- Remove mlx5gda.cpp from EP sources
- Forward EP_USE_MUSA env var in BuildEpExt.cmake

Root CMakeLists.txt: guard CUDAToolkit with USE_CUDA

* feat(example): add device_transport_example for P2P Device API

Two-rank example demonstrating the full Device API lifecycle:
- Host side: P2pTransport for IPC handle exchange and peer mapping
- Device side: CommCtx + mc_route_put + mc_signal for GPU-initiated
  P2P data transfer and notification

Uses file-based IPC handle exchange (no external dependencies).
Requires 2 GPUs with P2P access (NVLink or PCIe).

* fix(example): handle missing TORCH_CUDA_ARCH_LIST

* fix(example): convert torch arch format to CMake CUDA format

* fix(example): construct CommCtx manually on host side

* fix(example): add using namespace mooncake::device in kernels

* fix(example): pass CommCtx by value, add barrier before cleanup

- Pass CommCtx by value to kernel (CUDA copies to param space) instead of
  dereferencing a device pointer on host (caused segfault).
- Add file-based barrier so rank 0 waits for rank 1 to finish before
  freeing its GDR buffer (IPC handle only valid while allocation exists).
- Change default metadata_server to P2PHANDSHAKE (no etcd dependency).

* fix: address review feedback — fence ordering, error checks, QP leak

- musa_ops.cuh: fix fence ordering for acquire/release semantics
  (fence after load for acquire, before store/atomic for release)
- ibgda_device_transport.cpp: check cudaMalloc return values,
  add num_qps >= num_ranks guard, destroy QP on rst2init failure
- p2p_device_transport.cpp: add device_count > 0 guard
- device_transport_example.cu: validate kDataBytes % 16 == 0
  and kDataBytes <= kSignalWordOffset

* style: apply clang-format to Device API files

* fix: guard device transport code with USE_CUDA/USE_MUSA macros

The device transport accessors (getOrCreateP2pTransport,
getOrCreateRdmaTransport) and their member variables were not guarded
by USE_CUDA/USE_MUSA preprocessor macros. When building with
USE_CUDA=OFF (the default), the device transport source files aren't
compiled but the headers and implementations still reference them,
causing linker errors in CI build-flags and build jobs.

* fix: set CMAKE_CUDA_STANDARD 20 and make ibgda PUBLIC

- common.cmake: add CMAKE_CUDA_STANDARD 20 so nvcc compiles host code
  in C++20 mode, matching CMAKE_CXX_STANDARD.  Fixes "starts_with is
  not a member of std::string" when compiling .cu files that indirectly
  include common.h.
- transport/CMakeLists.txt: change ibgda from PRIVATE to PUBLIC so
  mlx5gda_* symbols are visible to downstream consumers (Go p2p store
  via transfer_engine).  Fixes undefined reference errors for
  mlx5gda_destroy_qp, mlx5dv_devx_umem_reg, etc.

* fix: compile mlx5gda into device_transport and link mlx5 for Go consumers

The previous attempt (PUBLIC ibgda) did not work because the Go p2p-store
and mooncake-store binaries link libtransfer_engine.a via hand-written cgo
ldflags, which bypass CMake's target_link_libraries propagation entirely.

- transport/device: compile mlx5gda.cpp directly into the device_transport
  OBJECT library (like every other transport module) instead of a separate
  ibgda STATIC lib, so mlx5gda_* symbols flow into libtransfer_engine.a and
  are visible to all consumers regardless of how they link.
- transport: link libmlx5 (PUBLIC) since ibgda_device_transport.cpp /
  mlx5gda.cpp call mlx5dv_devx_* / mlx5dv_init_obj directly.
- p2p-store/build.sh, mooncake-store/go/build.sh, ci.yml: add -lmlx5 to the
  hand-written cgo ldflags so the DevX symbols resolve.
- example: set CUDA_STANDARD 20 on device_transport_example so nvcc compiles
  common.h (std::string::starts_with) in C++20 mode.

* fix: CUDA_EXTENSIONS OFF for example, add -lm for Go consumers

Follow-up to compiling mlx5gda.cpp into device_transport:

- example: nvcc has no gnu++20 dialect, so CUDA_STANDARD 20 with the default
  CUDA_EXTENSIONS=ON fails at CMake generate ("does not know the compile
  flags").  Set CUDA_EXTENSIONS OFF to request plain -std=c++20.
- p2p-store/build.sh, mooncake-store/go/build.sh: mlx5gda.cpp uses log2/ceil
  (<cmath>); now that its object lives in libtransfer_engine.a, the hand-
  written cgo ldflags need -lm to resolve log2@GLIBC_2.29.  (ci.yml already
  had -lm.)

* fix(ci): gate Device API GPU example off by default, link mlx5 for Rust

The Docker build failed at CMake generate because device_transport_example
needs the CUDA20 dialect (transfer_engine.h -> common.h uses C++20
std::string::starts_with), which the older CMake in the CI image cannot
enable. CUDA_EXTENSIONS OFF did not help since the limitation is the CMake
version, not the dialect flavor. Gate this manual, 2-GPU example behind a
new BUILD_DEVICE_TRANSPORT_EXAMPLE option (default OFF) so the default build
no longer requires CUDA20.

Also link mlx5 in the mooncake-store Rust build script: the IBGDA device
transport (mlx5 DevX) is now compiled into transfer_engine, so the Rust
test link step needs -lmlx5 to resolve mlx5dv_devx_* symbols.
2026-06-05 16:00:07 +08:00
..
benchmark [Build] Allow building tebench without USE_TENT (#2322) 2026-06-04 10:00:08 +08:00
example [TE] add device API support (#2333) 2026-06-05 16:00:07 +08:00
include [TE] add device API support (#2333) 2026-06-05 16:00:07 +08:00
nvlink-allocator [CI/Build] Switch WITH_NVIDIA_PEERMEM to env variable (#2066) 2026-05-20 10:05:21 +08:00
rust fix(transfer-engine): add missing empty checks for batch methods (#2046) 2026-05-07 16:00:54 +08:00
scripts refactor: unify fabric allocator plumbing (#2028) 2026-05-06 10:13:37 +08:00
src [TE] add device API support (#2333) 2026-06-05 16:00:07 +08:00
tent [TE] fix: improve auto gid selection and retry (#2269) 2026-06-03 20:52:24 +08:00
tests [TE] fix(efa): short-circuit same-process GPU loopback to avoid libfabric SHM segfault (#2298) 2026-06-04 11:17:17 +08:00
ubshmem-allocator refactor: unify fabric allocator plumbing (#2028) 2026-05-06 10:13:37 +08:00
CMakeLists.txt [Build] Allow building tebench without USE_TENT (#2322) 2026-06-04 10:00:08 +08:00
fabric_allocator.cmake Build tent (#2089) 2026-05-28 20:30:20 +08:00