Skip to content

Expose torch.cuda.current_solver_handle for cuSOLVER handle sharing - #176705

Closed
IvanYashchuk wants to merge 8 commits into
pytorch:mainfrom
IvanYashchuk:cuda-current-solver-handle
Closed

Expose torch.cuda.current_solver_handle for cuSOLVER handle sharing#176705
IvanYashchuk wants to merge 8 commits into
pytorch:mainfrom
IvanYashchuk:cuda-current-solver-handle

Conversation

@IvanYashchuk

@IvanYashchuk IvanYashchuk commented Mar 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR adds torch.cuda.current_solver_handle() and the backing C binding torch._C._cuda_getCurrentSolverHandle so Python users can access PyTorch’s current cuSOLVER handle in the same style as torch.cuda.current_blas_handle(). During validation, importing torch exposed a missing link dependency for this symbol, so the PR also links torch_python with torch_cuda_linalg in CUDA builds to ensure the handle symbol resolves correctly at runtime.

Motivation

nvmath-python cuSOLVER bindings operate on intptr_t handles and expose stream management APIs such as get_stream and set_stream. Without a way to retrieve PyTorch’s existing cuSOLVER handle, users and library authors must create and manage separate handles, which adds lifecycle and stream coordination complexity. Exposing PyTorch’s current cuSOLVER handle enables direct interoperability with nvmath-python while keeping handle ownership and configuration in PyTorch.

nvmath-python interop example
import torch
import nvmath.bindings.cusolverDn as cusolverDn

assert torch.cuda.is_available()

handle = torch.cuda.current_solver_handle()

# Save current stream associated with the PyTorch-managed cuSOLVER handle.
orig_stream = cusolverDn.get_stream(handle)

# Move the handle to a non-default CUDA stream.
alt_stream_obj = torch.cuda.Stream()
alt_stream = alt_stream_obj.cuda_stream
cusolverDn.set_stream(handle, alt_stream)
assert cusolverDn.get_stream(handle) == alt_stream

# Run a CUDA linalg op to confirm the handle remains usable.
_ = torch.linalg.cholesky(torch.eye(4, device="cuda"))

# Restore original stream.
cusolverDn.set_stream(handle, orig_stream)
assert cusolverDn.get_stream(handle) == orig_stream

cc @ptrblck @msaroufim @eqy @jerryzh168 @tinglvv @nWEIdia @jianyuh @nikitaved @mruberry @walterddr @xwang233 @lezcano @voznesenskym @penguinwu @EikanWang @jgong5 @Guobing-Chen @XiaobingSuper @zhuhaozhe @blzheng @wenzhe-nrv @jiayisunx @kadeng @chauhang @amjames @Lucaskabela @jataylo @azahed98

Copilot AI review requested due to automatic review settings March 6, 2026 10:12
@pytorch-bot

pytorch-bot Bot commented Mar 6, 2026

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/176705

Note: Links to docs will display an error until the docs builds have been completed.

❗ 1 Active SEVs

There are 1 currently active SEVs. If your PR is affected, please view them below:

✅ No Failures

As of commit 922ab32 with merge base da74fec (image):
💚 Looks good so far! There are no failures yet. 💚

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@IvanYashchuk IvanYashchuk added module: cuda Related to torch.cuda, and CUDA support in general module: linear algebra Issues related to specialized linear algebra operations in PyTorch; includes matrix multiply matmul release notes: cuda release notes category and removed module: dynamo ciflow/inductor labels Mar 6, 2026

This comment was marked as resolved.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Comment thread torch/CMakeLists.txt Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Comment thread torch/csrc/cuda/Module.cpp Outdated
Comment thread aten/src/ATen/native/cuda/LinearAlgebraStubs.cpp Outdated
@pytorch-bot pytorch-bot Bot added the ciflow/torchtitan Run TorchTitan integration tests label Mar 10, 2026
Comment thread aten/src/ATen/native/cuda/linalg/CusolverDnHandlePool.cpp Outdated
Comment thread aten/src/ATen/native/cuda/LinearAlgebraStubs.cpp
Comment thread test/test_cuda.py
Comment thread aten/src/ATen/native/cuda/linalg/BatchLinearAlgebraLib.h Outdated
@nikitaved nikitaved added ciflow/rocm-mi300 Trigger "default" config CI on ROCm MI300 ciflow/trunk Trigger trunk jobs on your pull request labels Mar 11, 2026
@jerryzh168 jerryzh168 added the triaged This issue has been looked at a team member, and triaged and prioritized into an appropriate module label Mar 19, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

torch/csrc/cuda/Module.cpp:1636

  • The PR description mentions adding a build-system link dependency (linking torch_python with torch_cuda_linalg) to resolve a missing symbol at import time, but no corresponding build/CMake changes are included in this diff. If that link dependency is still required for some configurations (e.g., split/lazy CUDA linalg builds), please add the build change; otherwise, update the PR description to reflect the actual fix path so reviewers/packagers aren’t misled.
#endif
  END_HANDLE_TH_ERRORS
}

PyObject* THCPModule_cuda_tunableop_enable(PyObject* _unused, PyObject* arg) {
  HANDLE_TH_ERRORS

@nikitaved nikitaved left a comment

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.

Thank you, @IvanYashchuk ! Looks like the failures are unrelated -- but could you please rebase?

@malfet, could you, please, have a look?

@nikitaved
nikitaved requested a review from malfet April 21, 2026 08:04
@IvanYashchuk
IvanYashchuk force-pushed the cuda-current-solver-handle branch from 36cded7 to 37bc32b Compare April 21, 2026 08:33
@pytorch pytorch deleted a comment from pytorch-bot Bot Apr 21, 2026
@IvanYashchuk

Copy link
Copy Markdown
Collaborator Author

@malfet, could you please review the changes or find someone else who could help merge this work?

@ezyang ezyang removed the ciflow/rocm label May 6, 2026
Add a CUDA binding for the current cuSOLVER handle and expose it as torch.cuda.current_solver_handle(), including Dynamo allowlist entries for both the C binding and Python API.
Document torch.cuda.current_solver_handle in CUDA API docs and add a CUDA unit test that checks the returned solver handle is a valid integer pointer.
Link torch_python against torch_cuda_linalg so the current_solver_handle binding can resolve getCurrentCUDASolverDnHandle at import time.
Route current_solver_handle through a lazy linalg bridge and export a symbol from torch_cuda_linalg, so torch import no longer requires a direct torch_python dependency on torch_cuda_linalg.
Drop the heavy linalg include from torch/csrc/cuda/Module.cpp in favor of a forward declaration and make lazy symbol resolution errors more actionable when libtorch_cuda_linalg symbols are missing.
Keep the BatchLinearAlgebra header guarded by BUILD_LAZY_CUDA_LINALG, drop the extra solver-handle declaration from that header, and apply the CusolverDnHandlePool pointer-cast nit. Update the CUDA test to skip when solver symbols are unavailable so ROCm and reduced solver builds do not fail spuriously.
Skip the test when neither cuSOLVER nor hipSOLVER is available and treat expected missing-symbol/library errors from CUDA and HIP lazy linalg paths as skip conditions so ROCm translation differences do not fail CI.
torch_python references at::native::getCurrentCUDASolverDnHandleLazy at import time, so this symbol must be exported from LinearAlgebraStubs to avoid undefined-symbol import failures in CUDA and ROCm test shards.
@IvanYashchuk
IvanYashchuk force-pushed the cuda-current-solver-handle branch from 37bc32b to 922ab32 Compare May 18, 2026 15:32
@IvanYashchuk

Copy link
Copy Markdown
Collaborator Author

@pytorchbot merge

@pytorchmergebot

Copy link
Copy Markdown
Collaborator

Merge started

Your change will be merged once all checks pass (ETA 0-4 Hours).

Learn more about merging in the wiki.

Questions? Feedback? Please reach out to the PyTorch DevX Team

Advanced Debugging
Check the merge workflow status
here

gplutop7 pushed a commit to gplutop7/pytorch that referenced this pull request Jul 15, 2026
…ytorch#176705)

## Summary
This PR adds `torch.cuda.current_solver_handle()` and the backing C binding `torch._C._cuda_getCurrentSolverHandle` so Python users can access PyTorch’s current cuSOLVER handle in the same style as `torch.cuda.current_blas_handle()`. During validation, importing `torch` exposed a missing link dependency for this symbol, so the PR also links `torch_python` with `torch_cuda_linalg` in CUDA builds to ensure the handle symbol resolves correctly at runtime.

## Motivation
`nvmath-python` cuSOLVER bindings operate on `intptr_t` handles and expose stream management APIs such as `get_stream` and `set_stream`. Without a way to retrieve PyTorch’s existing cuSOLVER handle, users and library authors must create and manage separate handles, which adds lifecycle and stream coordination complexity. Exposing PyTorch’s current cuSOLVER handle enables direct interoperability with `nvmath-python` while keeping handle ownership and configuration in PyTorch.

<details>
<summary>nvmath-python interop example</summary>

```python
import torch
import nvmath.bindings.cusolverDn as cusolverDn

assert torch.cuda.is_available()

handle = torch.cuda.current_solver_handle()

# Save current stream associated with the PyTorch-managed cuSOLVER handle.
orig_stream = cusolverDn.get_stream(handle)

# Move the handle to a non-default CUDA stream.
alt_stream_obj = torch.cuda.Stream()
alt_stream = alt_stream_obj.cuda_stream
cusolverDn.set_stream(handle, alt_stream)
assert cusolverDn.get_stream(handle) == alt_stream

# Run a CUDA linalg op to confirm the handle remains usable.
_ = torch.linalg.cholesky(torch.eye(4, device="cuda"))

# Restore original stream.
cusolverDn.set_stream(handle, orig_stream)
assert cusolverDn.get_stream(handle) == orig_stream
```

</details>

Pull Request resolved: pytorch#176705
Approved by: https://github.com/nikitaved, https://github.com/eqy
aws-kingrj pushed a commit to amazon-contributing/upstream-to-pytorch that referenced this pull request Jul 29, 2026
…ytorch#176705)

## Summary
This PR adds `torch.cuda.current_solver_handle()` and the backing C binding `torch._C._cuda_getCurrentSolverHandle` so Python users can access PyTorch’s current cuSOLVER handle in the same style as `torch.cuda.current_blas_handle()`. During validation, importing `torch` exposed a missing link dependency for this symbol, so the PR also links `torch_python` with `torch_cuda_linalg` in CUDA builds to ensure the handle symbol resolves correctly at runtime.

## Motivation
`nvmath-python` cuSOLVER bindings operate on `intptr_t` handles and expose stream management APIs such as `get_stream` and `set_stream`. Without a way to retrieve PyTorch’s existing cuSOLVER handle, users and library authors must create and manage separate handles, which adds lifecycle and stream coordination complexity. Exposing PyTorch’s current cuSOLVER handle enables direct interoperability with `nvmath-python` while keeping handle ownership and configuration in PyTorch.

<details>
<summary>nvmath-python interop example</summary>

```python
import torch
import nvmath.bindings.cusolverDn as cusolverDn

assert torch.cuda.is_available()

handle = torch.cuda.current_solver_handle()

# Save current stream associated with the PyTorch-managed cuSOLVER handle.
orig_stream = cusolverDn.get_stream(handle)

# Move the handle to a non-default CUDA stream.
alt_stream_obj = torch.cuda.Stream()
alt_stream = alt_stream_obj.cuda_stream
cusolverDn.set_stream(handle, alt_stream)
assert cusolverDn.get_stream(handle) == alt_stream

# Run a CUDA linalg op to confirm the handle remains usable.
_ = torch.linalg.cholesky(torch.eye(4, device="cuda"))

# Restore original stream.
cusolverDn.set_stream(handle, orig_stream)
assert cusolverDn.get_stream(handle) == orig_stream
```

</details>

Pull Request resolved: pytorch#176705
Approved by: https://github.com/nikitaved, https://github.com/eqy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ciflow/inductor ciflow/rocm-mi300 Trigger "default" config CI on ROCm MI300 ciflow/torchtitan Run TorchTitan integration tests ciflow/trunk Trigger trunk jobs on your pull request Merged module: cuda Related to torch.cuda, and CUDA support in general module: dynamo module: linear algebra Issues related to specialized linear algebra operations in PyTorch; includes matrix multiply matmul open source release notes: cuda release notes category triaged This issue has been looked at a team member, and triaged and prioritized into an appropriate module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants