OpenCL clBuildProgram缓存源,如果#include'd源更改,则不会重新编译

时间:2015-07-10 10:29:45

标签: opencl

我用opencl实现了一个项目。我有一个包含内核函数的文件,内核使用的函数包含在一个单独的头文件中,但是当我更改包含的文件时,有时更改会被应用,有时它们不是,这让我感到困惑如果应用程序有错误。

我检查了stackoverflow中的其他帖子,看到nvidia传递-I{include directory}有严重问题,所以我更改了它并明确地给出了头文件地址,但是opencl编译器仍然无法找到错误头文件包含在内核文件名中。

另外,我使用的是nvidia gtx 980,我在计算机上安装了CUDA 7.0。

任何人都有相同的经历吗?我该如何解决?

所以,假设我有一个像这样的内核:

#include "../../src/cl/test_kernel_include.cl"

void __kernel test_kernel(
  __global int* result,
  int n
  )
{
  int thread_idx = get_global_id(0);
  result[thread_idx] = test_func();
}

test_kernel_include.cl如下:

int test_func()
{
  return 1;
}

然后我运行代码,得到一个数组,其中所有成员都等于1,正如我们所期望的那样。现在,我将test_kernel_include.cl更改为:

int test_func()
{
  return 2;
}

但结果仍然是一个数组,其中所有成员都等于1,它应该更改为2,但它们不是。objMail.Recipients(x).Address

2 个答案:

答案 0 :(得分:10)

在平台初始化之前执行此操作:

setenv("CUDA_CACHE_DISABLE", "1", 1);

它将禁用构建的缓存机制。 它也适用于OpenCL平台,即使它说的是CUDA。

答案 1 :(得分:8)

为了改善内核编译时间,NVIDIA实现了一种缓存方案,将编译后的内核二进制文件存储到磁盘中,并在下次编译相同内核时加载。在内核源代码上计算一些哈希值,然后将其用作编译内核缓存的索引。

不幸的是,这些哈希不包含主内核源包含的任何头文件。这意味着当您在包含的头文件中更改某些内容时,驱动程序将基本上忽略该更改并从磁盘重新加载以前的内核二进制文件(除非主内核源代码中的内容也发生了更改)。

在Linux系统上,可以在struct { . . . unsigned int fieldof3bits : 3; . . . } newdatatypename; 中找到内核缓存。如果在更改其中一个包含文件后删除此目录,则应强制驱动程序实际重新编译OpenCL内核。