| 403 | } |
| 404 | |
| 405 | port::Status GpuExecutor::Launch(Stream* stream, const ThreadDim& thread_dims, |
| 406 | const BlockDim& block_dims, |
| 407 | const KernelBase& kernel, |
| 408 | const KernelArgsArrayBase& args) { |
| 409 | CHECK_EQ(kernel.Arity(), args.number_of_arguments()); |
| 410 | CUstream custream = AsGpuStreamValue(stream); |
| 411 | const GpuKernel* cuda_kernel = AsGpuKernel(&kernel); |
| 412 | CUfunction cufunc = cuda_kernel->AsGpuFunctionHandle(); |
| 413 | |
| 414 | // Only perform/print the occupancy check once. Even just checking to see |
| 415 | // whether we've done an occupancy check on this kernel before isn't free |
| 416 | // (because we have to synchronize), so we only do this at -v 2+. |
| 417 | if (VLOG_IS_ON(2)) { |
| 418 | absl::MutexLock lock(&launched_kernels_mu_); |
| 419 | if (!launched_kernels_.count(cufunc)) { |
| 420 | VlogOccupancyInfo(kernel, thread_dims, block_dims); |
| 421 | // TODO(rspringer): Remove elements from launched_kernels_...if we ever |
| 422 | // expose a kernel/module deallocation method. |
| 423 | launched_kernels_.insert(cufunc); |
| 424 | } |
| 425 | } |
| 426 | |
| 427 | if (cuda_kernel->GetPreferredCacheConfig() != |
| 428 | KernelCacheConfig::kNoPreference) { |
| 429 | GpuDriver::FuncSetCacheConfig(cufunc, cuda_kernel->GetGpuCacheConfig()); |
| 430 | } |
| 431 | |
| 432 | void **kernel_params = const_cast<void **>(args.argument_addresses().data()); |
| 433 | |
| 434 | return GpuDriver::LaunchKernel( |
| 435 | context_, cufunc, block_dims.x, block_dims.y, block_dims.z, thread_dims.x, |
| 436 | thread_dims.y, thread_dims.z, args.number_of_shared_bytes(), custream, |
| 437 | kernel_params, nullptr /* = extra */); |
| 438 | } |
| 439 | |
| 440 | port::Status GpuExecutor::LaunchExecutableGraph(Stream* main_stream, |
| 441 | void* graph_exec) { |
nothing calls this directly
no test coverage detected