// Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #if defined(PADDLE_WITH_CUDA) #include #include "paddle/phi/backends/dynload/cublas.h" #include "paddle/phi/core/enforce.h" namespace at::cuda::blas { namespace { inline cublasOperation_t to_cublas_op(char trans) { switch (trans) { case 'T': case 't': return CUBLAS_OP_T; case 'N': case 'n': return CUBLAS_OP_N; case 'C': case 'c': return CUBLAS_OP_C; default: PADDLE_THROW(common::errors::InvalidArgument( "at::cuda::blas::gemm: invalid transpose character '%c'", trans)); } } } // namespace /* ───────────── gemm ───────────── */ template <> void gemm(CUDABLAS_GEMM_ARGTYPES(double)) { cublasHandle_t handle = at::cuda::getCurrentCUDABlasHandle(); cublasOperation_t opa = to_cublas_op(transa); cublasOperation_t opb = to_cublas_op(transb); PADDLE_ENFORCE_GPU_SUCCESS(phi::dynload::cublasDgemm(handle, opa, opb, static_cast(m), static_cast(n), static_cast(k), &alpha, a, static_cast(lda), b, static_cast(ldb), &beta, c, static_cast(ldc))); } /* ───────────── gemm ───────────── */ template <> void gemm(CUDABLAS_GEMM_ARGTYPES(float)) { cublasHandle_t handle = at::cuda::getCurrentCUDABlasHandle(); cublasOperation_t opa = to_cublas_op(transa); cublasOperation_t opb = to_cublas_op(transb); PADDLE_ENFORCE_GPU_SUCCESS(phi::dynload::cublasSgemm(handle, opa, opb, static_cast(m), static_cast(n), static_cast(k), &alpha, a, static_cast(lda), b, static_cast(ldb), &beta, c, static_cast(ldc))); } /* ───────────── gemm> ───────────── */ template <> void gemm>(CUDABLAS_GEMM_ARGTYPES(c10::complex)) { cublasHandle_t handle = at::cuda::getCurrentCUDABlasHandle(); cublasOperation_t opa = to_cublas_op(transa); cublasOperation_t opb = to_cublas_op(transb); PADDLE_ENFORCE_GPU_SUCCESS(phi::dynload::cublasZgemm( handle, opa, opb, static_cast(m), static_cast(n), static_cast(k), reinterpret_cast(&alpha), reinterpret_cast(a), static_cast(lda), reinterpret_cast(b), static_cast(ldb), reinterpret_cast(&beta), reinterpret_cast(c), static_cast(ldc))); } /* ───────────── gemm> ───────────── */ template <> void gemm>(CUDABLAS_GEMM_ARGTYPES(c10::complex)) { cublasHandle_t handle = at::cuda::getCurrentCUDABlasHandle(); cublasOperation_t opa = to_cublas_op(transa); cublasOperation_t opb = to_cublas_op(transb); PADDLE_ENFORCE_GPU_SUCCESS(phi::dynload::cublasCgemm( handle, opa, opb, static_cast(m), static_cast(n), static_cast(k), reinterpret_cast(&alpha), reinterpret_cast(a), static_cast(lda), reinterpret_cast(b), static_cast(ldb), reinterpret_cast(&beta), reinterpret_cast(c), static_cast(ldc))); } /* ───────────── gemm ───────────── */ template <> void gemm(CUDABLAS_GEMM_ARGTYPES(at::Half)) { cublasHandle_t handle = at::cuda::getCurrentCUDABlasHandle(); cublasOperation_t opa = to_cublas_op(transa); cublasOperation_t opb = to_cublas_op(transb); // Use cublasGemmEx with FP32 compute for Half inputs float alpha_f = alpha; float beta_f = beta; PADDLE_ENFORCE_GPU_SUCCESS( phi::dynload::cublasGemmEx(handle, opa, opb, static_cast(m), static_cast(n), static_cast(k), &alpha_f, a, CUDA_R_16F, static_cast(lda), b, CUDA_R_16F, static_cast(ldb), &beta_f, c, CUDA_R_16F, static_cast(ldc), CUDA_R_32F, CUBLAS_GEMM_DEFAULT_TENSOR_OP)); } /* ───────────── gemm ───────────── */ template <> void gemm(CUDABLAS_GEMM_ARGTYPES(at::BFloat16)) { cublasHandle_t handle = at::cuda::getCurrentCUDABlasHandle(); cublasOperation_t opa = to_cublas_op(transa); cublasOperation_t opb = to_cublas_op(transb); // Use cublasGemmEx with FP32 compute for BFloat16 inputs float alpha_f = alpha; float beta_f = beta; PADDLE_ENFORCE_GPU_SUCCESS( phi::dynload::cublasGemmEx(handle, opa, opb, static_cast(m), static_cast(n), static_cast(k), &alpha_f, a, CUDA_R_16BF, static_cast(lda), b, CUDA_R_16BF, static_cast(ldb), &beta_f, c, CUDA_R_16BF, static_cast(ldc), CUDA_R_32F, CUBLAS_GEMM_DEFAULT_TENSOR_OP)); } } // namespace at::cuda::blas #endif // PADDLE_WITH_CUDA