【问题标题】:Error CL_INVALID_KERNEL_NAME when I use cl_khr_fp64 in a kernel在内核中使用 cl_khr_fp64 时出现错误 CL_INVALID_KERNEL_NAME
【发布时间】:2019-04-30 22:32:46
【问题描述】:

我在 OpenCL 内核中有一个错误,当我尝试使用 cl_khr_fp64 扩展时,内核编译并且构建日志为空,但是当我调用 @ 987654321@,我有 CL_INVALID_KERNEL_NAME 错误。

失败的来源:

#pragma OPENCL EXTENSION cl_khr_fp64 : enable

__kernel void simple( __global char *x, __global char *y ){
int id = get_global_id(0);
y[id]=2*x[id];
}

这个源码编译正确:

__kernel void simple( __global char *x, __global char *y ){
int id = get_global_id(0);
y[id]=2*x[id];
}

我将 OpenCL 1.0CL_DEVICE_EXTENSIONS 中具有 cl_khr_fp64Tesla C1060 一起使用,驱动程序 280.13 和CL_PLATFORM_VERSION=OpenCL 1.1 CUDA 4.0.1

【问题讨论】:

  • 澄清一下——你知道你的编译在第一种情况下是成功的,因为你正在检查 clBuildProgram 设置的错误代码,对吗?
  • 编译步骤返回CL_SUCCESS,但我也检查了构建日志
  • 你是说如果你简单地删除 cl_khr_fp64 这一行,clCreateKernel 就会返回 CL_SUCCESS?
  • 我认为Zhen是说两种情况下编译都成功,但是当他在第一种情况下调用clCreateKernel(..., "simple", ...)时,他得到CL_INVALID_KERNEL_NAME。第二种情况成功。甄,这是你的情况吗?
  • @James 就是这样。两个示例都可以编译,但是使用 cl_khr_fp64 我在 clCreateKernel 上得到 CL_INVALID_KERNEL_NAME。

标签: opencl


【解决方案1】:

问题是在调用 clCreateProgramWithSource 之前,我们从源代码中删除了换行符。例如:来源:

"__kernel void f( __global char *x ){\nint id = get_global_id(0);\nx[id]=2;\n}"

变成:

"__kernel void simple( __global char *x, __global char *y ){"
"int id = get_global_id(0);"
"x[id]=2;}"

在我们添加预处理指令之前,它不会导致任何问题。

实际上是 OpenCL 预处理器需要换行符。所以,应该写成:

"__kernel void simple( __global char *x, __global char *y ){\n"
"int id = get_global_id(0);\n"
"x[id]=2;}\n"

【讨论】:

    【解决方案2】:

    这是一直困扰我的事情之一。我认为的问题是先前编译的代码被缓存在某处并被重用。因此,您的新更改会产生奇怪的错误。

    要修复它(不是“真正的解决方案”,但它适用于我)尝试更改您的程序名称(可能还有内核名称),例如如果程序是 a.out,那么下次编译时将其设置为 a2.out 并查看它是否已修复。我希望这会有所帮助。

    如果您找到更好的解决方案,请告诉我们。

    【讨论】:

      【解决方案3】:

      几天前我也遇到了这样的错误,我只是解决了。所以我在这里分享我的解决方案,虽然它很连贯,但我仍然不知道为什么。

      static inline void CreateOCLKernels()
      {
          std::cout << "ocl lowlevelengine: Creating ocl kernels ...\n";
          filterSubsample_ocl_kernel = clCreateKernel(program, "filterSubsampleUChar4Kernel", &clError);
          checkErr(clError, "clCreateKernel0");
          filterSubsampleWithHoles_float4_ocl_kernel = clCreateKernel(program, "filterSubsampleWithHolesFloat4Kernel", &clError);
          checkErr(clError, "clCreateKernel1");
          filterSubsampleWithHoles_float_ocl_kernel = clCreateKernel(program, "filterSubsampleWithHolesFloatKernel", &clError);
          checkErr(clError, "clCreateKernel2");
          gradientX_ocl_kernel = clCreateKernel(program, "gradientXKernel", &clError);
          checkErr(clError, "clCreateKernel3");
          gradientY_ocl_kernel = clCreateKernel(program, "gradientYKernel", &clError);
          checkErr(clError, "clCreateKernel4");
          //type-dependent ocl memset kernels
          memset_ocl_kernel_Vector4s = clCreateKernel(program, "memsetKernelVector4s", &clError);
          checkErr(clError, "clCreateKernel5");
      }
      

      这是我的原始代码,它是由某个类的构造函数调用的静态函数。可以毫无疑问地调用构造函数。但是,每次调用上述函数时,我都会收到 opencl 找不到内核“filterSubsampleUChar4Kernel”导致的错误“无效内核名称”。 我已经尝试了很多,但都没有奏效。但是今天,非常偶尔,我尝试更改函数名称并成功。 我所做的只是将“filterSubsampleUChar4Kernel”更改为“filterSubsampleKernel”。我还尝试更改其他名称,例如。 “filterSubsampleKernel_test”、“filterSubsample1Kernel”。但他们没有工作。这很连线,不是吗?

      【讨论】:

        【解决方案4】:

        我猜你是用字符串写 OpenCL 代码的。比如

        std::string code =
        "#pragma OPENCL EXTENSION cl_khr_fp64 : enable"
        "__kernel void simple( __global char *x, __global char *y )"
        "{"
        "int id = get_global_id(0);"
        "y[id]=2*x[id];"
        "}"
        

        只需在 #pragma 行的末尾添加“\n

        std::string code =
        "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n"
        "__kernel void simple( __global char *x, __global char *y )"
        "{"
        "int id = get_global_id(0);"
        "y[id]=2*x[id];"
        "}"
        

        【讨论】:

          猜你喜欢
          • 2019-05-17
          • 2013-01-27
          • 2021-09-25
          • 2023-02-18
          • 1970-01-01
          • 2020-05-30
          • 1970-01-01
          • 1970-01-01
          • 2019-04-24
          相关资源
          最近更新 更多