Thanks to visit codestin.com
Credit goes to Github.com

Skip to content

Comments

Enable handle from cublasCreate to be used in cublasLt calls#587

Merged
vosen merged 16 commits intovosen:masterfrom
zluda-violet:interchangeable-handle
Feb 18, 2026
Merged

Enable handle from cublasCreate to be used in cublasLt calls#587
vosen merged 16 commits intovosen:masterfrom
zluda-violet:interchangeable-handle

Conversation

@zluda-violet
Copy link
Collaborator

A cublasHandle_t may be passed to cublasLt calls in place of a cublasLtHandle_t. This PR adds support for this functionality.

This is implemented by moving the ZLUDA blas and blaslt handles to zluda_common, as BlasHandle and BlasLtHandle. These are both newtype wrappers around the BlasHandles struct, using #[repr(transparent)] to ensure that they have the same in-memory representation as BlasHandles. ZludaObject is then implemented for both types, with the same COOKIE, so that LiveCheck values of both types will be interchangeable.

BlasHandles contains OnceLock fields for a rocblas_handle and a hipblasLtHandle_t. These are initialized in their respective Create functions. All cublasLt functions that take a handle then also allow lazy initialization of a hipblasLtHandle_t.

The other option would be to always initialize a hipblasLtHandle_t in zluda_blas::impl::create. This is probably low overhead, but I was trying to avoid introducing a dependency on hipblasLt into zluda_blas.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enables cublasHandle_t to be used interchangeably with cublasLtHandle_t in cublasLt function calls, implementing support for CUDA's specification that allows a regular cuBLAS handle to be passed to cuBLASLt functions.

Key changes:

  • Moves BLAS handle types from zluda_blas and zluda_blaslt to zluda_common as BlasHandle and BlasLtHandle
  • Uses #[repr(transparent)] newtype wrappers around a shared BlasHandles struct that contains OnceLock fields for both rocblas_handle and hipblasLtHandle_t
  • Implements lazy initialization of hipblasLtHandle_t when a cublasHandle_t is used in cublasLt functions

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
zluda_common/src/lib.rs Adds handle module and updates from_cuda_object! macro to use $crate:: for better portability
zluda_common/src/handle.rs New file defining BlasHandles struct with OnceLock fields and newtype wrappers BlasHandle/BlasLtHandle sharing the same COOKIE for interchangeability
zluda_blaslt/src/impl.rs Replaces local Handle with BlasLtHandle, adds lazy initialization function hipblas_lt_init, and updates all functions to use the new handle type
zluda_blas/src/impl.rs Replaces local Handle with BlasHandle, adds rocblas_unwrap helper, and updates all functions to use the new handle type

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@zluda-violet zluda-violet requested a review from vosen December 19, 2025 00:14
Copy link
Owner

@vosen vosen left a comment

Choose a reason for hiding this comment

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

This is a good start, but there are subtle issues with this approach which need to be resolved.

  • Most importantly, it's not clear what is the extent of the handle layout compatibility that we guarantee. PR comment says that cuBLAS handle can be passed to cuBLASLt. Does it work the other way around? The code here implies so, but if it does not, then the code probably can be simplified.
    Anyway, this behavior is really non-obvious and it must be covered by a test (both cublas handle into cublaslt and cublaslt handle into cublas)
  • The memory layout of BlasHandles is wrong. Rust only guarantees ordering of types with repr(C) and BlasHandles has no such attribute, so it can legally be { rocblas, hipblas_lt } in zluda_blas and { hipblas_lt, rocblas } in zluda_blaslt. And just marking the types repr(C) will not resolve the issue , because repr(C) is not transitive: OnceLock<rocblas_handle> can have different size and layout between zluda_blas and zluda_blaslt. The solution would be indirection: Box<T> is guaranteed to have the same layout as *mut T, which transitively if T is Sized is the same as usize. If the cublaslt handle is not guaranteed to be cublas compatible then you could have your blas handle type be [repr(C)] { Box<BlasLtHandle>, ... <Blas fields> } and blas_lt handle be [repr(C)] { Box<BlasLtHandle> } and it's going to be guaranteed to have a compatible layout

@zluda-violet
Copy link
Collaborator Author

A cublasHandle_t is a valid cublasLtHandle_t, but a cublasLtHandle_t is not a valid cublasHandle_t. I was using the OnceLock to avoid always creating a hipblasLtHandle_t in zluda_blas::create_v2, but the overhead is low and zluda_blas already has a transitive dependency on hipblasLt through zluda_common.

Even though it is not valid, a user could theoretically pass a cublasLtHandle_t into cublas, so I've added a placeholder rocblas_handle that will be initialized to null to BlasLtHandle.

@zluda-violet
Copy link
Collaborator Author

I've changed the representation of the blas library handles to once again be separate. Now, BlasHandle includes an embedded BlasLtHandle (as a RwLock<Option<BlasLtHandle>>). This means that, when you pass a BlasHandle into zluda_blaslt, there will be some slight overhead as it first tries to interpret the handle as a BlasLtHandle, then as a BlasHandle and then extracting the BlasLtHandle. However, there should be no overhead in the case of passing in a BlasLtHandle, which should be most common.

@zluda-violet
Copy link
Collaborator Author

I've updated this again to try to fix the memory layout issues. The hipblasLt handle is now managed by zluda_blaslt, which zluda_blas now has a runtime dependency on.

@zluda-violet zluda-violet requested a review from vosen January 14, 2026 23:05
@vosen vosen merged commit e68e855 into vosen:master Feb 18, 2026
7 checks passed
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