| 3777 | #endif // CUDA_VERSION >= 11000 |
| 3778 | |
| 3779 | bool CUDABlas::DoBlasLtMatmul( |
| 3780 | Stream* stream, const blas::IBlasLtMatmulPlan* plan, |
| 3781 | const HostOrDeviceScalar<void>& alpha, DeviceMemoryBase a, |
| 3782 | DeviceMemoryBase b, const HostOrDeviceScalar<void>& beta, |
| 3783 | DeviceMemoryBase c, ScratchAllocator* scratch_allocator, |
| 3784 | const blas::IBlasLtMatmulAlgorithm* algorithm, DeviceMemoryBase bias, |
| 3785 | blas::ProfileResult* output_profile_result) { |
| 3786 | #if CUDA_VERSION >= 11000 |
| 3787 | const auto& cuda_plan = *static_cast<const CUDABlasLtMatmulPlan*>(plan); |
| 3788 | HostOrDeviceScalar<void> alpha_cast = alpha; |
| 3789 | HostOrDeviceScalar<void> beta_cast = beta; |
| 3790 | if (cuda_plan.c_type() == blas::DataType::kHalf && |
| 3791 | cuda_plan.scale_type() == blas::DataType::kFloat) { |
| 3792 | // The given alpha and beta types are F16 (they always match c), but F32* |
| 3793 | // computation type requires that they be F32, so we must cast them. |
| 3794 | if (alpha.is_pointer() || beta.is_pointer()) { |
| 3795 | // We cannot easily convert a pointer to f16 memory to a pointer to f32 |
| 3796 | // memory from here, so we don't support this for now. |
| 3797 | return false; |
| 3798 | } |
| 3799 | alpha_cast = HostOrDeviceScalar<void>( |
| 3800 | static_cast<float>(alpha.value<Eigen::half>())); |
| 3801 | beta_cast = |
| 3802 | HostOrDeviceScalar<void>(static_cast<float>(beta.value<Eigen::half>())); |
| 3803 | } |
| 3804 | |
| 3805 | std::unique_ptr<GpuTimer, GpuTimerDeleter> timer; |
| 3806 | if (output_profile_result) { |
| 3807 | timer.reset(new GpuTimer(parent_)); |
| 3808 | if (!timer->Init() || !timer->Start(AsGpuStream(stream))) { |
| 3809 | return false; |
| 3810 | } |
| 3811 | } |
| 3812 | |
| 3813 | bool err_on_failure = timer != nullptr; |
| 3814 | bool result = DoBlasLtMatmulInternal(stream, err_on_failure, plan, alpha_cast, |
| 3815 | a, b, beta_cast, c, c, scratch_allocator, |
| 3816 | algorithm, bias); |
| 3817 | |
| 3818 | if (timer && result) { |
| 3819 | // GpuTimer will CHECK-fail if we Stop() it while the stream is in an error |
| 3820 | // state. |
| 3821 | if (!timer->Stop(AsGpuStream(stream))) { |
| 3822 | return false; |
| 3823 | } |
| 3824 | output_profile_result->set_is_valid(true); |
| 3825 | output_profile_result->set_algorithm(algorithm->index()); |
| 3826 | output_profile_result->set_elapsed_time_in_ms( |
| 3827 | timer->GetElapsedMilliseconds()); |
| 3828 | } |
| 3829 | return result; |
| 3830 | #else // if CUDA_VERSION < 11000 |
| 3831 | return false; |
| 3832 | #endif |
| 3833 | } |
| 3834 | |
| 3835 | port::Status CUDABlas::GetVersion(string *version) { |
| 3836 | absl::MutexLock lock(&mu_); |
nothing calls this directly
no test coverage detected