Skip to content

[Interop] Prototype Vulkan opaque-FD import for CUDA and AMDGPU - #904

Draft
rglebovamd wants to merge 1 commit into
Genesis-Embodied-AI:mainfrom
rglebovamd:rglebov/vkimport-prototype
Draft

[Interop] Prototype Vulkan opaque-FD import for CUDA and AMDGPU#904
rglebovamd wants to merge 1 commit into
Genesis-Embodied-AI:mainfrom
rglebovamd:rglebov/vkimport-prototype

Conversation

@rglebovamd

@rglebovamd rglebovamd commented Sep 3, 2026

Copy link
Copy Markdown

Context

The Nyx AMD/ROCm integration needs an API-neutral way to import Vulkan external-memory allocations into the active Quadrants CUDA or AMDGPU backend. Nyx exports an opaque FD plus the full allocation size, logical payload size, and byte offset. The Genesis plugin should not select or call CUDA/HIP directly.

This is the quick prototype requested for API/design review. It is intentionally a draft, Linux-only, and not presented as the final production implementation.

Prototype approach

  • Adds quadrants.interop.VkImport.
  • Imports VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD through CUDA Driver or HIP based on the active Quadrants backend.
  • Maps only the requested logical range while importing the complete Vulkan allocation.
  • Implements DLPack producer methods for PyTorch views.
  • Provides release_to_vulkan() and acquire_from_vulkan() ownership-boundary methods.
  • Uses transactional FD ownership: imports a duplicate and consumes the caller FD only after import and mapping both succeed.
  • Rejects invalid ranges, shapes, dtypes, unsupported backends, and mismatched GPUs with actionable errors.
  • Frees mapped memory and the imported external-memory object on close().

Validation performed

Using the Nyx integration on AMD and NVIDIA:

  • CUDA and HIP opaque-FD import/read/write passed.
  • 16-byte allocation / 12-byte logical payload passed.
  • Nonzero byte offset mapping passed.
  • DLPack tensor shape, dtype, and device passed.
  • Failed-construction FD ownership passed.
  • AMD-Vulkan-to-CUDA and NVIDIA-Vulkan-to-HIP mismatch rejection passed.
  • Full Genesis -> Quadrants VkImport -> Nyx rendering passed on both backends.
  • Unit metadata/ownership validation in this PR: 8 tests passed.

Important prototype limitations / review questions

  1. Synchronization: the prototype uses device-wide synchronization. What should the production stream/queue API be? Do we want imported/exported binary or timeline semaphores for Vulkan visibility?
  2. Implementation layer: should the final external-memory import live in Quadrants C++ bindings rather than Python ctypes?
  3. DLPack lifetime: the prototype requires the VkImport object to outlive every tensor view and uses a no-op DLPack deleter. What ownership model should the final API expose?
  4. Device selection: CUDA currently uses device zero in the active process. The final version should use the exact initialized Quadrants device and ideally verify PCI/device identity against Vulkan.
  5. Platform scope: this implements Linux opaque FDs only. Win32 external-memory handles need a separate ownership contract.
  6. API shape: please review the constructor fields and the release_to_vulkan() / acquire_from_vulkan() names before the Nyx plugin pins them.

Test

pytest tests/python/test_vk_import.py -q

The Nyx plugin PRs remain drafts until this API is finalized, released/pinned, and the real CUDA/AMD conformance matrix passes.

Semaphore capability note

Both tested Vulkan devices report timeline-semaphore support and CUDA exposes the required external-semaphore functions. However, the ROCm 7.2 HIP headers explicitly document hipImportExternalSemaphore, hipSignalExternalSemaphoresAsync, and hipWaitExternalSemaphoresAsync as unsupported on Linux. The public API should therefore keep semaphores optional and retain a device/queue synchronization fallback for the initial AMD Linux path unless runtime probing shows the HIP documentation is stale.

Comment thread docs/source/user_guide/interop.md Outdated
The `copy` parameter is supported on `to_numpy()` and `to_torch()` for `ScalarField`, `MatrixField` (and `VectorField`), `StructField`, `qd.Tensor`, and all `Ndarray` types. See [Zero-copy interop via DLPack](#zero-copy-interop-via-dlpack) for the support matrix and lifetime rules.


## Prototype Vulkan external-memory import

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

please remove the word 'prototype' from the doc

Comment thread docs/source/user_guide/interop.md Outdated
## Prototype Vulkan external-memory import

`quadrants.interop.VkImport` is a Linux-only prototype for importing a Vulkan
`VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD` allocation into the active CUDA or

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

.md docs should not be line-wrapped

Comment thread docs/source/user_guide/interop.md Outdated
in both directions and may require imported/exported binary or timeline
semaphores rather than device-wide host synchronization.

### Current limitations

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

remove 'current'

Comment thread docs/source/user_guide/interop.md Outdated
uses device-wide synchronization and assumes the Vulkan queue is flushed by the
producer/consumer call sequence.

A production implementation must define specification-valid memory visibility

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

replace 'A production implementation' with 'FIXME:'

Comment thread docs/source/user_guide/interop.md Outdated

`release_to_vulkan()` completes compute-device work before Vulkan consumes the
allocation. `acquire_from_vulkan()` completes the current prototype's ownership
boundary before compute reads Vulkan-written memory. The prototype currently

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

remove 'currently'

Comment thread python/quadrants/interop/_vk_import.py Outdated
@@ -0,0 +1,382 @@
"""Prototype Linux Vulkan opaque-FD import for API review and validation.

The implementation intentionally uses ctypes and device-wide synchronization.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

comments should be 120c wrapped, not 80c

Add a Linux-only review prototype for importing Vulkan opaque-FD allocations
into the active CUDA or AMDGPU backend and exposing the mapped logical range
through DLPack.

The constructor uses transactional FD ownership and validates allocation,
offset, logical size, shape, and dtype before consuming the caller handle.
The prototype uses device-wide synchronization; production synchronization may
require external semaphores or stream integration.
@rglebovamd
rglebovamd force-pushed the rglebov/vkimport-prototype branch from ebad6e3 to 7f3b81f Compare September 3, 2026 18:27
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.

2 participants