Skip to content

[XPU] Support checkpoint-engine weight update on Intel XPU#96

Open
siju-samuel wants to merge 1 commit into
MoonshotAI:mainfrom
siju-samuel:feat/xpu-support-phase1
Open

[XPU] Support checkpoint-engine weight update on Intel XPU#96
siju-samuel wants to merge 1 commit into
MoonshotAI:mainfrom
siju-samuel:feat/xpu-support-phase1

Conversation

@siju-samuel

Copy link
Copy Markdown

Motivation

This PR adds Intel XPU as a first-class device backend behind device abstraction, and fills the IPC gap with a native SYCL ipc_memory transport, which is the XPU counterpart of CUDA IPC
The CUDA and NPU paths are unchanged, XPU-specific code is reached only when the device type is xpu.

This unblocks checkpoint-engine's fast weight-update path on Intel GPUs, which is needed for SGLang's XPU for RL rollout weight sync.

Modifications

Device abstraction

  • device_utils.py: detect xpu and map it to the xccl collective backend; add supports_device_ipc() / supports_device_p2p() capability gates so XPU enables broadcast IPC but not P2P.
  • distributed/base.py: reject custom distributed backends on XPU and fall back to the default xccl TorchBackend.

**Weight transport **

  • transport.py: add a WeightTransport seam — IpcWeightTransport (CUDA/NPU, unchanged) and XpuIpcWeightTransport (XPU) — with build_transport() selecting by device type.
  • xpu_ipc/sycl_ipc.cpp + xpu_ipc/__init__.py: native SYCL ipc_memory extension (get/open/close), JIT-compiled at runtime with -fsycl, providing the cross-process device-buffer IPC that PyTorch lacks on XPU.

Parameter server & worker

  • ps.py: route the broadcast through build_transport(), prebuild the SYCL extension at startup, and fail loudly with clear errors when device IPC/P2P is unavailable on XPU.
  • worker.py: derive the GPU-<uuid> handshake key from torch.xpu on XPU, matching the ParameterServer's _get_physical_gpu_id.

Packaging

  • pyproject.toml: ship the SYCL .cpp source as package data (JIT-compiled on XPU hosts; inert on CUDA).

Tests

  • CPU-only: test_device_manager.py, test_transport.py, test_xpu_parity.py, test_p2p_guard.py — device dispatch, transport seam, portable-handle contract, xccl selection, P2P rejection.
  • Hardware-gated: test_xpu_ipc.py — SYCL IPC roundtrip, interior-offset, full cross-process broadcast.

Accuracy Test / Verified

Device-UUID handshake verified on Intel Arc Pro B60: the worker emits the exact
GPU-<uuid> key the ParameterServer expects. 5 CPU unit tests pass.

Environment

Software Version
torch 2.13.0.dev+xpu
oneAPI (icpx) 2026.0 / 2026.1
device 8× Intel Arc Pro B60

Check list

  • Code self-tested on Intel XPU hardware
  • CPU unit tests: 38 passed (pytest tests/ -m "not gpu")
  • Hardware tests: 3 passed incl. cross-process broadcast (pytest tests/test_xpu_ipc.py)
  • CUDA/NPU paths unchanged (XPU code reached only when device type is xpu)

CC: @@kip-cxj @specture724 @weixiao-huang @ppwwyyxxc Could you please run the CI and review. TIA

Add Intel XPU as a first-class device backend alongside CUDA and NPU.

Device abstraction (device_utils.py): detect xpu, map to the xccl distributed
backend, and gate capabilities per backend -- in-place host pinning
(cudaHostRegister) and Mooncake device P2P stay CUDA/NPU-only, while
cross-process device-tensor IPC is supported on XPU via a native extension.

Weight transport (transport.py): the broadcast path shares a device buffer with
the colocated inference worker. PyTorch has no XPU tensor IPC (reduce_tensor
raises '_share_fd_: only available on CPU'), so a WeightTransport seam selects
the CUDA/NPU reduce_tensor path or a native XPU implementation.

XPU IPC (xpu_ipc/): implemented on SYCL ext::oneapi::experimental::ipc_memory,
which torch's own libsycl (oneAPI >= 2026.0, libsycl.so.9) exports. A SYCL IPC
handle is a self-contained, portable byte blob -- verified cross-process on
Arc B60 -- so it needs no out-of-band dma-buf fd transfer and no sub-allocation
offset handling: the whole handle rides the existing ZMQ channel exactly like
CUDA's reduce_tensor tuple. The -fsycl extension coexists with torch's single
SYCL runtime in-process.

Only the broadcast update method is supported on XPU; P2P is rejected with a
clear error (Mooncake has no Level Zero backend for XPU device memory).

Robustness: the exported IPC handle is released in an outer try/finally so an
early failure (export, ZMQ bind, or first send) can no longer leak it, while the
collective barrier stays in the inner finally to avoid deadlocking peers on an
asymmetric failure. The P2P store is skipped entirely on backends that do not
support device P2P (e.g. XPU) instead of being eagerly initialized and only
guarded against ImportError. icpx discovery falls back to PATH (via
shutil.which) for oneAPI layouts outside /opt or a sourced setvars.sh that does
not export CMPLR_ROOT.

Tests: CPU-only coverage for device dispatch, the transport seam, the P2P
guard, and the XPU parity paths (portable-handle contract, xccl backend
selection, in-place-pin disable, detach-on-early-failure, icpx PATH fallback);
hardware-gated tests for the SYCL IPC roundtrip, interior-pointer offset, and
the full cross-process broadcast.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant