我尝试使用 LD_PRELOAD 技巧,以窃取 CUDA驱动程序API调用(cu *函数)。我首先为cuLaunchKernel实现了一个简单的存根函数,如下所示:
#define _GNU_SOURCE
#include <cuda.h>
#include <dlfcn.h>
#include <stdio.h>
//#include <cuda_runtime.h>
//#include <driver_types.h>
void cuLaunchKernelHelper (CUstream hStream);
CUresult cuLaunchKernel (CUfunction f, unsigned int gridDimX, unsigned int gridDimY, unsigned int gridDimZ, unsigned int blockDimX, unsigned int blockDimY, unsigned int blockDimZ, unsigned int sharedMemBytes, CUstream hStream, void** kernelParams, void** extra) {
void* handle;
CUresult (*function)(CUfunction f,
unsigned int gridDimX, unsigned int gridDimY, unsigned int gridDimZ,
unsigned int blockDimX, unsigned int blockDimY, unsigned int blockDimZ,
unsigned int sharedMemBytes, CUstream hStream, void** kernelParams, void** extra);
*(void **)(&function) = dlsym (RTLD_NEXT, "cuLaunchKernel");
cuLaunchKernelHelper (hStream);
(*function)(f, gridDimX, gridDimY, gridDimZ, blockDimX, blockDimY, blockDimZ, sharedMemBytes, hStream, kernelParams, extra);
}
void cuLaunchKernelHelper (CUstream hStream) {
// Nothing
printf ("cuLaunchHelper\n");
}
之后,我在CUDA样本中运行矩阵乘法示例,如下所示:
LD_PRELOAD="stub.so" ./matrixMul
不幸的是,没有任何反应。我无法捕获这个CUDA电话。现在我想知道,我需要考虑CUDA二进制代码的具体内容吗?
答案 0 :(得分:1)
现在我想知道,我需要考虑CUDA二进制代码的具体内容吗?
是。您需要确保应用LD_PRELOAD
技巧的代码实际调用cuLaunchKernel
并动态链接到CUDA驱动程序API库。您会发现使用nvcc编译的运行时API应用程序(这是您将遇到的大量CUDA代码)使用编译器生成的样板,该样板解析为已弃用的cuLaunch
API,而不是cuLaunchKernel
。这就是为什么你什么也看不见,因为你的代码拦截了一个API,你在测试的应用程序中没有调用它,也没有动态链接到驱动程序库。
正如评论中所指出的,如果您使用驱动程序API应用程序,例如here列出的任何示例,它应该按预期工作。