Skip to content

XPU: register pinned host memory via Level Zero ext_memmap - #8887

Open
delock wants to merge 4 commits into
deepspeedai:masterfrom
delock:gma/xpu-pin-memory-l0
Open

delock wants to merge 4 commits into
deepspeedai:masterfrom
delock:gma/xpu-pin-memory-l0

Conversation

@delock

@delock delock commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

DeepSpeed's native pin-memory path (DS_PIN_MEMORY_BACKEND=native) currently has no device registration on XPU — register_host_memory() returns False, so pinned host buffers are mlock-only and device access to them does not go through device page-table mappings. This PR implements the L0 equivalent of cudaHostRegister on the XPU accelerator.

Implementation

  • XPU_Accelerator.register_host_memory(): map existing host memory into the device's page tables via Level Zero's external host-memory mapping (zeMemAllocHost with the ZE_extension_external_memmap_sysmem descriptor chain), created in our own L0 context — device page tables are shared across the driver's contexts, so buffers registered here are accessible from torch's runtime as well.
  • unregister_host_memory() releases the mapping.
  • Graceful degradation: returns False when the L0 loader or the extension is unavailable.

Tests

Three monkeypatched unit tests in tests/unit/v1/pin_memory/test_pin_memory.py (same pattern as the existing CUDA/CPU/NPU tests — no XPU hardware needed in CI):

  • registration calls Level Zero with the correct descriptor chain (host desc -> pNext -> external memmap desc), address and size passthrough
  • a mapping that comes back at a different address is treated as a failed registration
  • failure paths return False rather than raising

Operational notes

  • On multi-NUMA hosts, binding the process to the GPU's NUMA node (numactl --cpunodebind=N --membind=N) is recommended when registering large ranges.
  • ulimit -l unlimited (or an equivalent memlock limit) is required for large registrations; the DeepSpeed pin-memory path already checks and reports this.

Implement register_host_memory on the XPU accelerator using Level Zero's
zeMemAllocHost + external memory mapping (the L0 equivalent of
cudaHostRegister), with posix_memalign + mlock for the native pin path.
An earlier attempt that registered through the SYCL runtime did not work
and is replaced by this direct L0 route. Also adds a ZeRO-3 offload e2e
benchmark (registered vs unregistered) and XPU coverage in the pin-memory
unit tests.

Signed-off-by: Ma, Guokai <guokai.ma@intel.com>
@delock
delock force-pushed the gma/xpu-pin-memory-l0 branch from be9da92 to d3fbb9a Compare October 23, 2026 06:09
@delock
delock marked this pull request as ready for review October 23, 2026 06:11
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-23T06:17:05.222344Z d3fbb9a Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@PKUWZP
PKUWZP self-requested a review October 23, 2026 06:12
@delock

delock commented Oct 23, 2026

Copy link
Copy Markdown
Collaborator Author

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d3fbb9afc0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread accelerator/xpu_accelerator.py Outdated
if handles is None:
return None
ze, context = handles
ze.zeMemFree(context, address)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Propagate Level Zero unmap failures

When Level Zero returns a non-success status from this call, unregister_host_memory still appears to succeed because the result is discarded. In that scenario NativePinnedMemory._unregister_device discards the tracked registration and unpin frees the CPU allocation (deepspeed/utils/pin_memory.py:109-118), leaving any mapping that the driver retained pointing at host pages that can be recycled; check the result and raise so the caller keeps the allocation alive.

Useful? React with 👍 / 👎.

Comment thread accelerator/xpu_accelerator.py Outdated
"Level Zero returned a non-identity mapping for host registration "
"(%#x != %#x); falling back to mlock-only pinned memory.", mapped.value, address)
return False
return rc == _ZE_RESULT_SUCCESS

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Warn when Level Zero rejects host registration

When loader and extension discovery succeeds but zeMemAllocHost rejects a range or runs out of resources, this return silently degrades DS_PIN_MEMORY_REGISTER_DEVICE=1 to mlock-only. The false return does not enter the exception warning in NativePinnedMemory._new_locked (deepspeed/utils/pin_memory.py:73-77), unlike the missing-extension and nonidentity branches here, so users can unknowingly benchmark or train without device registration; emit a warning_once with the Level Zero result before returning false.

Useful? React with 👍 / 👎.


class _FakeLoader:

def zeMemAllocHost(self, context, host_desc, size, alignment, out):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Validate registration with a real XPU transfer

For actual XPU execution, this fake loader only writes the requested pointer back, so it cannot establish the key production assumption that a mapping created in this private Level Zero context is recognized by torch's XPU context or actually enables an asynchronous H2D/D2H copy. I checked .github/workflows/xpu-max1100.yml:67-84; that hardware workflow does not run tests/unit/v1/pin_memory, while the commit reports only monkeypatched tests, so add and execute an end-to-end native-pinned transfer or offload test on real XPU hardware before relying on this path.

AGENTS.md reference: AGENTS.md:L81-L82

Useful? React with 👍 / 👎.

@delock delock Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this PR is validated on a real XPU machine. So this fake loader is only a mock. From test point of view, this v1 test better be run on each of the accelerators, rather than contain tests for different accelerators. This may require a separate sweep on our current test structure for multi-accelerator and solve together. I think this comments should not be blocking

- unregister_host_memory raises on zeMemFree failure (matching the CUDA
  path's check_error) so NativePinnedMemory.unpin keeps the CPU allocation
  alive instead of freeing pages the driver may still have mapped
- register_host_memory warns (warning_once) with the Level Zero result code
  when zeMemAllocHost rejects a range, instead of silently degrading to
  mlock-only
- tests: add alloc-failure degradation and unregister-failure raise cases

Signed-off-by: Ma, Guokai <guokai.ma@intel.com>
@delock
delock force-pushed the gma/xpu-pin-memory-l0 branch from 45623d1 to c2e29e5 Compare October 23, 2026 06:42
@jinyouzhi

This comment has been minimized.

@PKUWZP

PKUWZP commented Oct 23, 2026

Copy link
Copy Markdown
Collaborator

@delock Do we want to label this PR with the roadmap items?

@delock delock added the roadmap Roadmap direction for DeepSpeed label Oct 26, 2026
Level Zero maps an ext_memmap_sysmem range only for the first device of
the context that creates it; device-initiated copies from any other
device fail with ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY (reproduced on
Arc Pro B60/B70 with a raw Level Zero program, independent of torch).
DeepSpeed ranks each pick local_rank, so every rank but the first of a
node crashed on the first registered copy.

- register in a context restricted to the target device
  (zeContextCreateEx), cached per torch device index
- match the L0 device by UUID instead of assuming zeDeviceGet order
- track registrations (address -> loader+context) so unregister frees in
  the context that created the mapping

Signed-off-by: Ma, Guokai <guokai.ma@intel.com>
@delock

delock commented Oct 26, 2026

Copy link
Copy Markdown
Collaborator Author

Hi @jinyouzhi , let me know if the latest commit works for you, thanks!

@jinyouzhi

Copy link
Copy Markdown
Contributor

Hi @jinyouzhi , let me know if the latest commit works for you, thanks!

c643a9b I tested this commit and it works for me. LGTM, Thanks! @delock

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

roadmap Roadmap direction for DeepSpeed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants