可以获取正在运行的CUDA内核名称的线程吗?

时间:2019-12-30 16:28:14

标签: reflection cuda gpgpu

假设某个内核(名为__global__的{​​{1}}函数)正在CUDA设备上运行。并假设内核调用了foo函数__device__,该函数有时在其他内核中被调用,即bar的代码在编译时不知道内核是否为bar或其他的东西。

foo内运行foo的线程能否获得名称“ foo”,内核的签名或其他标识符,最好是易于理解的内核?

如有必要,假定代码已使用bar--debug和/或--device-debug中的任何一个进行编译。

1 个答案:

答案 0 :(得分:1)

内核可以读取特殊寄存器%gridid。 %gridid在每次启动时都是唯一的。如果有性能,那么一个简单的内核序言可以在每个内核启动中使用一个线程,使用 func 和%gridid输出gridid全局函数映射。或者,可以使用CUPTI SDK活动API来收集此信息。 CUpti_ActivityKernel2事件包含每次启动的元数据,包括gridId和CUfunction名称。

下面是读取%gridid的示例。

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <stdio.h>
#include <stdint.h>

cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size);

static __device__ __inline__ uint64_t __gridid()
{
    uint64_t gridid;
    asm volatile("mov.u64 %0, %%gridid;" : "=l"(gridid));
    return gridid;
}

__device__ void devPrintName()
{
    static const char* name = __func__;
    printf("%llu %s\n", __gridid(), name);
}

__global__ void globPrintName()
{
    static const char* name = __func__;
    printf("%llu %s\n", __gridid(), name);
    devPrintName();
}

int main()
{
    for (int i = 0; i < 4; ++i)
    {
        globPrintName<<<1,1,0>>>();
        cudaDeviceReset();
    }
    return 0;
}

此示例输出

1 globPrintName
1 devPrintName
2 globPrintName
2 devPrintName
3 globPrintName
3 devPrintName
4 globPrintName
4 devPrintName