[TENT] Add Intel XPU platform to the Transfer Engine - #4030
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Critical XPU routing, staging, and location-handling issues remain unresolved.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds Intel XPU support to TENT through a direct-link SYCL backend, build integration, runtime support, tests, and Docker tooling.
Changes:
- Adds XPU allocation, copying, pointer classification, and topology support.
- Adds
USE_XPU/DPC++ build wiring and runtime integration. - Adds acceptance tests and an Intel XPU build image.
File summaries
| File | Change |
|---|---|
mooncake-transfer-engine/tent/tests/xpu/xpu_platform_test.cpp |
Tests XPU allocation, transfers, and pointer classification. |
mooncake-transfer-engine/tent/tests/CMakeLists.txt |
Registers the XPU test target. |
mooncake-transfer-engine/tent/src/runtime/platform.cpp |
Integrates XPU platform loading. |
mooncake-transfer-engine/tent/src/platform/xpu/xpu_sycl_backend.h |
Implements SYCL device, USM, and transfer handling. |
mooncake-transfer-engine/tent/src/platform/xpu/xpu_platform.cpp |
Implements XPU platform operations. |
mooncake-transfer-engine/tent/src/platform/xpu/CMakeLists.txt |
Configures SYCL compilation and linking. |
mooncake-transfer-engine/tent/src/platform/CMakeLists.txt |
Registers the XPU platform target. |
mooncake-transfer-engine/tent/include/tent/runtime/platform.h |
Adds XPU memory-type support. |
mooncake-transfer-engine/tent/include/tent/platform/xpu.h |
Declares the XPU platform interface. |
mooncake-common/common.cmake |
Adds XPU options and compiler validation. |
docker/xpu.Dockerfile |
Provides an Intel XPU build/runtime environment. |
Review details
Suppressed comments (4)
mooncake-transfer-engine/tent/src/platform/xpu/xpu_platform.cpp:120
getMemoryTyperecognizes only allocations recorded byXpuSyclBackend. A normal TENTregisterLocalMemorycall for framework-owned Intel USM (for example, a oneAPI/PyTorch XPU buffer) is therefore reported as CPU, andcopyfalls through to hostmemcpyinstead of performing H2D/D2H. Add an external-USM classification/registration path that also tracks interior ranges, or explicitly reject/document unsupported external buffers.
if (backend().isDevicePtr(addr)) return MTYPE_XPU;
mooncake-transfer-engine/tent/src/platform/xpu/xpu_platform.cpp:74
LocationParseralso uses index-1for malformed values such asxpu:foo; this conditional then treats that error exactly like an omitted ordinal and silently allocates on device 0. Distinguish the exact barexpucase from an invalidxpu:<ordinal>and returnInvalidArgumentfor the latter.
int device_index = location.index() >= 0 ? location.index() : 0;
mooncake-transfer-engine/tent/src/platform/xpu/xpu_sycl_backend.h:171
- The singleton mutex is held across the blocking
queue.memcpy(...).wait(), so all H2D/D2H copies serialize globally, including copies targeting different XPU devices. This prevents concurrent TENT staging workers from overlapping device transfers and can become a major throughput bottleneck; narrow the critical section or use per-device synchronization while preserving allocation lifetime safety.
int copy(void *dst, const void *src, size_t len, bool to_host) {
std::lock_guard<std::mutex> lock(mu_);
const void *dev = to_host ? src : dst;
const Alloc *a = findLocked(dev);
if (!a) return 1; // device side must be a known (interior) allocation
const uintptr_t start = reinterpret_cast<uintptr_t>(dev);
if (start + len > a->base + a->size) return 1; // would run past end
try {
queues_[a->device].memcpy(dst, src, len).wait();
mooncake-transfer-engine/tent/src/platform/xpu/xpu_sycl_backend.h:65
- The fallback enumerates every SYCL device, but
sycl::malloc_deviceis only supported when the device hassycl::aspect::usm_device_allocations. A visible host/plugin device without that aspect will makeprobe()report an XPU and then fail every allocation (the test will not skip), despite the documented any-device fallback. Filter candidates by the required USM aspect, or mark unsupported devices unavailable before exposing them throughdeviceCount().
for (const auto &d : sycl::device::get_devices()) {
- Files reviewed: 11/11 changed files
- Comments generated: 6
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| initialized_ = true; | ||
| return 0; | ||
| } catch (const sycl::exception &) { | ||
| return 1; |
There was a problem hiding this comment.
Fixed. The catch block now calls queues_.clear() before returning failure, so a throw partway through enumeration never leaves a partially-populated queue vector. In the same area, device selection (both the GPU loop and the fallback) now requires sycl::aspect::usm_device_allocations, so we never pick a device that cannot service the USM allocations this backend depends on. Fixed in 1d61971.
staryxchen
left a comment
There was a problem hiding this comment.
LGTM overall. please address the AI's comments.
|
It seems that end-to-end verification cannot be proceed with this PR only. The runtime needs to add support of proposed transport. |
Add an XpuPlatform to the TENT runtime so Mooncake can stage transfers through Intel XPU (GPU) device memory. XpuPlatform extends CpuPlatform: host DRAM allocation, NUMA probing, and host<->host copies are inherited unchanged, and only the XPU-device-aware operations are overridden. Implementation is a native, direct-link SYCL build: the platform sources include <sycl/sycl.hpp> and link libsycl directly via a private XpuSyclBackend (device enumeration with GPU-preferred/any-device fallback, sycl::malloc_device USM allocation, an interior-pointer registry so chunked staging addresses classify correctly, and VRAM<->host memcpy). Because SYCL requires the Intel DPC++ compiler, USE_XPU=ON now requires USE_TENT=ON and fails fast unless the build is configured with icpx (CXX=icpx); -fsycl is applied to platform_xpu and propagated to everything that links it. - runtime: MTYPE_XPU memory type + USE_XPU loader branch - platform: XpuPlatform (probe/allocate/free/copy/getMemoryType/ getLocation) backed by XpuSyclBackend - build: USE_XPU option/gate in common.cmake; platform_xpu with -fsycl - test: tent_xpu_platform_test drives the real backend (alloc -> H2D -> D2H -> byte-equality -> free, host/interior pointer classification), skipping when no SYCL device is present; runs against the OpenCL CPU device on GPU-less hosts - docker/xpu.Dockerfile: build image based on intel/pytorch:xpu with the oneAPI DPC++ compiler added, so it both builds and runs the platform Test on Intel B60 platform.
1093c00 to
1d61971
Compare
All addressed, thanks. |
Yes, you are right, XpuTransport will be added in the following PR as in this RFC. |
|
Please resolve the format issues: https://github.com/kvcache-ai/Mooncake/actions/runs/34581790883/job/103206817476?pr=4030 Thanks! |
Description
Add an XpuPlatform to the TENT runtime so Mooncake can stage transfers through Intel XPU (GPU) device memory. XpuPlatform extends CpuPlatform: host DRAM allocation, NUMA probing, and host<->host copies are inherited unchanged, and only the XPU-device-aware operations are overridden.
Implementation is a native, direct-link SYCL build: the platform sources include <sycl/sycl.hpp> and link libsycl directly via a private XpuSyclBackend (device enumeration with GPU-preferred/any-device fallback, sycl::malloc_device USM allocation, an interior-pointer registry so chunked staging addresses classify correctly, and VRAM<->host memcpy). Because SYCL requires the Intel DPC++ compiler, USE_XPU=ON now requires USE_TENT=ON and fails fast unless the build is configured with icpx (CXX=icpx); -fsycl is applied to platform_xpu and propagated to everything that links it.
D2H -> byte-equality -> free, host/interior pointer classification), skipping when no SYCL device is present; runs against the OpenCL CPU device on GPU-less hosts
Test on Intel B60 platform.
Module
mooncake-transfer-engine)mooncake-store)mooncake-reshard)mooncake-ep)mooncake-pg)mooncake-integration)mooncake-p2p-store)mooncake-wheel)mooncake-common)mooncake-rl)Type of Change
How Has This Been Tested?
Built with the Intel DPC++ compiler and ran the XPU acceptance test on an Intel
B60 platform. The test performs a full alloc -> H2D -> D2H -> byte-equality ->
free cycle against the real oneAPI SYCL backend and validates host/interior
pointer classification; it skips gracefully when no SYCL device is visible and
runs against the OpenCL CPU device on GPU-less hosts.
Test commands:
Test results:
pointer classification verified on Intel B60)
Hardware validation on Intel Arc Pro B60 (Level-Zero)
CI runners have no Intel GPU, so
tent_xpu_platform_testthere skips the device path (or falls back to the OpenCL CPU device). I validated the real GPU path on an Intel Arc Pro B60 node.Environment
Intel(R) Arc(TM) Pro B60 Graphics, oneAPI DPC++ compilericpx 2026.1.1.intel/pytorch:xpu+ oneAPI compiler (as indocker/xpu.Dockerfile).sycl-lson the node:Build
Test — full suite (default selector): 5/5 PASSED
Test — pinned to the discrete GPU so the CPU device cannot be chosen, proving real VRAM
sycl::malloc_device+ H2D/D2H + byte-equality round-trip and interior-pointer classification run on the B60:ONEAPI_DEVICE_SELECTOR=level_zero:gpu \ ./build-xpu/.../tent_xpu_platform_test \ --gtest_filter=XpuPlatformTest.DeviceAllocCopyFreeRoundTrip:XpuPlatformTest.InteriorPointerClassifiesAsXpu # [ PASSED ] 2 tests.Notes for reviewers
tent_xpu_platform_testis a no-op/skip on GPU-less CI runners (itGTEST_SKIPs when no SYCL device is visible, or runs against the OpenCL CPU device). Real GPU coverage is the B60 run above — a green CI run does not by itself imply GPU-path coverage.-fsyclpropagates fromplatform_xputo everything that linkstransfer_engine,USE_XPU=ONrequires the entire build to be configured withCXX=icpx. This is already enforced by the gate incommon.cmake; don't mix g++ for the rest of the tree.Checklist
./scripts/code_format.shAI Assistance Disclosure
GitHub Copilot was used to assist with scaffolding the
XpuPlatform/XpuSyclBackendsources, CMake wiring, and the acceptance test. The humansubmitter has reviewed every changed line and can defend the change end-to-end.