| 42 | } |
| 43 | |
| 44 | CorexKernelCommand::CorexKernelCommand(const void *func, void **params, bool deep_copy) |
| 45 | : CorexCommand(kCommandPropertyDeactivatable), func_(func), params_(params) |
| 46 | { |
| 47 | if (!deep_copy) return; |
| 48 | if (params == nullptr) { |
| 49 | XWARN("kernel_args of %p is nullptr", func); |
| 50 | return; |
| 51 | } |
| 52 | |
| 53 | cudaKernel_t kernel = nullptr; |
| 54 | cudaError_t res = RtDriver::GetKernel(&kernel, func); |
| 55 | if (res != cudaSuccess) RtDriver::GetLastError(); |
| 56 | XASSERT(kernel != nullptr, "fail to get kernel for func %p", func); |
| 57 | |
| 58 | std::vector<size_t> offsets; |
| 59 | std::vector<size_t> sizes; |
| 60 | |
| 61 | param_cnt_ = 0; |
| 62 | while (true) { |
| 63 | size_t offset = 0, size = 0; |
| 64 | CUresult res = Driver::KernelGetParamInfo(CUkernel(kernel), param_cnt_, &offset, &size); |
| 65 | if (res != CUDA_SUCCESS || size == 0) break; |
| 66 | offsets.push_back(offset); |
| 67 | sizes.push_back(size); |
| 68 | ++param_cnt_; |
| 69 | } |
| 70 | |
| 71 | if (param_cnt_ == 0) { |
| 72 | XWARN("kernel %p has no params", func); |
| 73 | return; |
| 74 | } |
| 75 | |
| 76 | deep_copy_ = true; |
| 77 | params_ = (void **)malloc(param_cnt_ * sizeof(void *)); |
| 78 | // Allocate a continuous buffer for all of the params |
| 79 | // buffer size = last param offset + last param size |
| 80 | size_t buffer_size = offsets.back() + sizes.back(); |
| 81 | param_data_ = (char *)malloc(buffer_size); |
| 82 | |
| 83 | for (size_t i = 0; i < param_cnt_; ++i) { |
| 84 | size_t offset = offsets[i]; |
| 85 | size_t size = sizes[i]; |
| 86 | params_[i] = (void*)¶m_data_[offset]; |
| 87 | memcpy(params_[i], params[i], size); |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | CorexKernelCommand::~CorexKernelCommand() |
| 92 | { |
nothing calls this directly
no outgoing calls
no test coverage detected