| 260 | } |
| 261 | |
| 262 | port::Status GpuExecutor::GetKernel(const MultiKernelLoaderSpec& spec, |
| 263 | KernelBase* kernel) { |
| 264 | GpuKernel* cuda_kernel = AsGpuKernel(kernel); |
| 265 | CUmodule module; |
| 266 | const string *kernelname; |
| 267 | |
| 268 | VLOG(3) << "GetKernel on kernel " << kernel << " : " << kernel->name(); |
| 269 | |
| 270 | if (spec.has_cuda_cubin_in_memory()) { |
| 271 | absl::MutexLock lock{&in_memory_modules_mu_}; |
| 272 | kernelname = &spec.cuda_cubin_in_memory().kernelname(); |
| 273 | const char *cubin = spec.cuda_cubin_in_memory().bytes(); |
| 274 | TF_RETURN_IF_ERROR(LoadModuleFromCuBin(cubin, &module)); |
| 275 | kernel_to_gpu_binary_[kernel] = cubin; |
| 276 | } else if (spec.has_cuda_ptx_in_memory()) { |
| 277 | kernelname = &spec.cuda_ptx_in_memory().kernelname(); |
| 278 | |
| 279 | if (cc_major_ == 0 && cc_minor_ == 0) { |
| 280 | return port::InternalError("Compute capability not set"); |
| 281 | } |
| 282 | |
| 283 | const char *ptx = spec.cuda_ptx_in_memory().text(cc_major_, cc_minor_); |
| 284 | if (ptx == nullptr) { |
| 285 | ptx = spec.cuda_ptx_in_memory().default_text(); |
| 286 | } |
| 287 | if (ptx == nullptr) { |
| 288 | LOG(FATAL) << "Loader spec has no ptx for kernel " << *kernelname; |
| 289 | } |
| 290 | |
| 291 | absl::MutexLock lock{&in_memory_modules_mu_}; |
| 292 | TF_RETURN_IF_ERROR(LoadModuleFromPtx(ptx, &module)); |
| 293 | kernel_to_gpu_binary_[kernel] = ptx; |
| 294 | } else { |
| 295 | return port::InternalError("No method of loading CUDA kernel provided"); |
| 296 | } |
| 297 | VLOG(2) << "getting function " << *kernelname << " from module " << module; |
| 298 | if (!GpuDriver::GetModuleFunction(context_, module, kernelname->c_str(), |
| 299 | cuda_kernel->gpu_function_ptr())) { |
| 300 | return port::InternalError("Could not find the corresponding function"); |
| 301 | } |
| 302 | |
| 303 | // We have to trust the kernel loader spec arity because there doesn't appear |
| 304 | // to be a way to reflect on the number of expected arguments w/the CUDA API. |
| 305 | cuda_kernel->set_arity(spec.arity()); |
| 306 | |
| 307 | KernelMetadata kernel_metadata; |
| 308 | if (!GetKernelMetadata(cuda_kernel, &kernel_metadata)) { |
| 309 | LOG(WARNING) << "unable to get metadata for kernel " << *kernelname; |
| 310 | } |
| 311 | kernel->set_metadata(kernel_metadata); |
| 312 | kernel->set_name(*kernelname); |
| 313 | return port::Status::OK(); |
| 314 | } |
| 315 | |
| 316 | bool GpuExecutor::UnloadGpuBinary(const void* gpu_binary) { |
| 317 | auto module_it = gpu_binary_to_module_.find(gpu_binary); |
nothing calls this directly
no test coverage detected