[FEAT] Add Ascend stream support to the Torch C-DLPack addon - #690
[FEAT] Add Ascend stream support to the Torch C-DLPack addon#690voidLitchi wants to merge 1 commit into
Conversation
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
Thanks @voidLitchi . We are increasingly moving towards upstream to bring up the convention which is more robust in terms of ABI version and use the optional plugin mainly for backward compact cases. Ideally the best places the DLPack exchange API location definition should be contributed to the upstream package(in this case torch_npu package as part of its dlpack module). the overall mechanism is torch_npu get autoloaded as a torch backend. It can bundle this variant of the C DLPack Exchange API in then override |
| #include <c10/hip/HIPStream.h> | ||
| #include <ATen/hip/impl/HIPStreamMasqueradingAsCUDA.h> | ||
| #endif | ||
| #ifdef BUILD_WITH_ASCEND |
There was a problem hiding this comment.
Thank you for reviewing! I have already renamed all ascend to torch_npu as you suggested in 1403e7f.
| # add both include and lib paths so the linker can find libtorch_npu. | ||
| # Note: c10_npu symbols are compiled into libtorch_npu itself; there is | ||
| # no separate libc10_npu to link against. | ||
| if args.build_with_ascend: |
There was a problem hiding this comment.
Updated to build_with_torch_npu in the same commit.
## Motivation PyTorch exposes Ascend tensors through torch_npu's PrivateUse1 backend and exports them as kDLExtDev through DLPack. The existing Torch C-DLPack addon can convert these tensors, but its current_work_stream callback only handles CUDA and ROCm. TVM-FFI therefore receives a null stream for torch_npu and may launch a kernel on the default NPU stream instead of the caller's current torch.npu stream. ## Changes - Detect torch_npu after CUDA and ROCm on Linux, and use a torch_npu-specific addon even when PyTorch already exposes a DLPack C exchange API. - Preserve the upstream PyTorch API preference for CUDA and ROCm. - Add a mutually exclusive --build-with-torch-npu option and reject it on Windows and macOS. - Discover torch_npu headers and libraries from the installed package, define BUILD_WITH_TORCH_NPU, and link libtorch_npu. - Return c10_npu::getCurrentNPUStream(device_id).stream() for kDLExtDev from the addon's current_work_stream callback. - Reuse the upstream ABI-aware addon cache key and Torch-version-based C++ standard selection. ## Testing - Add unit coverage for backend selection, platform fallback, existing API preference, and mutually exclusive build options. - Add a torch_npu runtime test that compares current_work_stream against a non-default torch.npu stream. - Verify the modified files with the CI-pinned Ruff and ty versions, ASF header and file-type checks, version consistency, Python compilation, and standalone selection and argument-parsing checks on Windows. The torch_npu runtime test requires a Linux host with torch_npu and Ascend hardware.
|
thanks @voidLitchi just want to follow up on my comment in implementation goes to torch_npu, if that is possible it would be more ideal and likely we won't need these extra changes here |
Thanks for the suggestion. We discussed this with the Ascend community, and we agree that torch_npu is the more appropriate home for this capability. |
Motivation
TVM-FFI uses the DLPack C exchange API’s
current_work_streamcallback to propagate the framework’s current execution stream into an FFI call. This allows a kernel launched through TVM-FFI to follow the caller’s stream ordering without requiring an explicit synchronization.On Ascend,
torch_npuregisters the NPU backend through PyTorch’sPrivateUse1mechanism. These tensors are currently represented askDLExtDevwhen exchanged through DLPack. The optional Torch C-DLPack addon can already convert such tensors, but itscurrent_work_streamimplementation previously handled only CUDA and ROCm. An Ascend request therefore returned a null stream and caused the caller to fall back to the default NPU stream instead of using the activetorch.npustream.This PR extends the optional addon so that Ascend kernels launched through TVM-FFI receive the correct current NPU stream.
Changes
Backend selection and addon loading
ascendresult.torch_npunor the Ascend runtime supports those platforms.torch.Tensoralready provides__dlpack_c_exchange_api__. The upstream PyTorch API can convert the tensor, but it does not provide the required Ascendcurrent_work_streambehavior.Ascend addon build support
--build-with-ascendbuild option alongside the existing CUDA and ROCm options.torch_npupackage and add its header and library directories to the build.BUILD_WITH_ASCENDonly for the Ascend addon.libtorch_npu, which exports thec10_npustream symbols used by the addon.Current NPU stream propagation
When built with Ascend support, the addon now handles
kDLExtDevin itscurrent_work_streamcallback and returns:This keeps TVM-FFI kernel launches on the active
torch.npustream, including non-default streams selected throughtorch.npu.stream(...).Why Ascend detection has a separate
torch.npubranchROCm follows PyTorch’s AMD compatibility model and intentionally reuses the
torch.cudaPython API. CUDA and ROCm can therefore share the same initial availability check and be distinguished usingtorch.version.cudaandtorch.version.hip, as documented in the [PyTorch ROCm semantics](https://docs.pytorch.org/docs/stable/notes/hip.html).torch_npufollows a different integration model. It is an out-of-tree extension that registers Ascend throughPrivateUse1and exposes its runtime API astorch.npu, rather than reusingtorch.cuda. This model is also described in PyTorch’s [device-extension autoload RFC](pytorch/pytorch#122468).As a result, Ascend cannot be folded into the CUDA/ROCm branch without changing the supported PyTorch/extension compatibility model. A generic
torch.accelerator-based implementation was considered, but adopting it here would broaden the change across existing backends and supported PyTorch versions. The guarded:check is therefore kept as an Ascend-specific compatibility path. CUDA and ROCm retain priority when their shared
torch.cudainterface is active.DLPack device type follow-up
This PR intentionally continues to use
kDLExtDevfor Ascend.A dedicated
kDLAscenddevice type will be proposed to the DLPack project so that Ascend memory is no longer represented by the generic extension-device value. That migration is not included here because it requires coordinated changes across DLPack, TVM-FFI, PyTorch/torch_npu, and downstream consumers.At the time of writing:
84d107b.mainis three commits ahead at[77aafa4](https://github.com/dmlc/dlpack/commit/77aafa4d3b0f80feffce9ad4c718dd26751ee0e4)and has already allocated values 19 and 20 tokDLTPUandkDLTPUHost.kDLAscendshould be standardized in DLPack first instead of being provisionally assigned by TVM-FFI.After such an enum is accepted, TVM-FFI would need to update more than the vendored header. The required work includes:
DLDeviceTypeenum, name mappings, type stubs, and device tests.PrivateUse1↔ DLPack conversion logic.kDLExtDevandkDLAscendare accepted, because existingtorch_npuversions will continue to producekDLExtDev.Switching this PR directly to a new enum would therefore break compatibility with existing producers without completing the corresponding ecosystem migration. Keeping
kDLExtDevhere makes the stream fix usable immediately while leaving the enum standardization to a separate follow-up.Testing
The PR adds coverage for:
current_work_stream(kDLExtDev, device_id)against a non-defaulttorch.npu.Streamhandle.