【问题标题】:Compile and build .cl file using NVIDIA's nvcc Compiler?使用 NVIDIA 的 nvcc 编译器编译和构建 .cl 文件?
【发布时间】:2012-10-15 06:36:40
【问题描述】:

是否可以使用 NVIDIA 的 nvcc 编译器编译 .cl 文件?我正在尝试设置 Visual Studio 2010 在 CUDA 平台下编写 Opencl 代码。但是当我选择 CUDA C/C++ Compiler 来编译和构建 .cl 文件时,它给了我类似 nvcc 不存在的错误。有什么问题?

【问题讨论】:

  • 是的,您可以使用 nvcc 编译 cl。不要给出nvcc 的名称,而是给出nvcc 二进制文件的完整路径。
  • 谢谢艾哈迈德。我真的很感谢你的帮助。但是如果我必须使用nvidia的gpu进行opencl编码,我是否也必须安装CUDA 4.2??还是GPU计算SDK就足够了??
  • 你需要一个工具包,比如 4.2 工具包,来获取 nvcc。 GPU Computing SDK 不包含工具包中的工具,例如 nvcc。
  • @RobertCrovella 您能否提供您在答案中使用的确切命令和工具版本?我得到“nvcc fatal : Don't know what to do with 'inc.cl'”,可能它无法识别扩展名(.cu 文件编译得很好)? Ubuntu 16.10、nvcc V8.0.44、375.39、NVS 5400M。这个问题也提到了错误:stackoverflow.com/questions/22730484/…
  • 如果文件符合 C 标准,则需要使用 .c 命名文件,否则使用 .cpp 命名文件。然后nvcc myapp.cpp -o myapp -lOpenCL 应该可以工作。如果你有一个文件myapp.cl,否则它是一个正确的 OpenCL 源文件,你也应该能够做到nvcc -x cu myapp.cl -o myapp -lOpenCL

标签: opencl gpgpu nvidia gpu


【解决方案1】:

您应该可以使用nvcc 编译 OpenCL 代码。通常,我建议使用 .c 的文件扩展名作为 C 兼容代码,.cpp 用于 C++ 兼容代码 (*),但是 nvcc 具有文件扩展名覆盖选项 (-x ...),以便我们可以修改行为。这是一个使用 CUDA 8.0.61、RHEL 7、Tesla K20x 的工作示例:

$ cat t4.cpp
#include <CL/opencl.h>
#include <stdint.h>
#include <stdio.h>
#include <inttypes.h>
#include <stdlib.h>

const char source[] =
"__kernel void test_rotate(__global ulong *d_count, ulong loops, ulong patt)"
"{"
"  ulong n = patt;"
"  for (ulong i = 0; i<loops; i++)"
"    n &= (107 << (patt+(i%7)));"
"  d_count[0] = n + loops;"
"}"
;

int main(int argc, char *argv[])
{
  cl_platform_id platform;
  cl_device_id device;
  cl_context context;
  cl_command_queue queue1, queue2;
  cl_program program;
  cl_mem mem1, mem2;
  cl_kernel kernel;

  bool two_kernels = false;
  unsigned long long loops = 1000;
  if (argc > 1) loops *= atoi(argv[1]);
  if (argc > 2) two_kernels = true;
  if (two_kernels) printf("running two kernels\n");
  else printf("running one kernel\n");
  printf("running  %lu loops\n", loops);
  unsigned long long pattern = 1;
  clGetPlatformIDs(1, &platform, NULL);
  clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 1, &device, NULL);
  context = clCreateContext(NULL, 1, &device, NULL, NULL, NULL);
  queue1 = clCreateCommandQueue(context, device, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, NULL);
  queue2 = clCreateCommandQueue(context, device, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, NULL);

  const char *sources[1] = {source};
  program = clCreateProgramWithSource(context, 1, sources, NULL, NULL);
  clBuildProgram(program, 1, &device, NULL, NULL, NULL);
  mem1 = clCreateBuffer(context, CL_MEM_READ_WRITE, 1*sizeof(cl_ulong), NULL, NULL);
  mem2 = clCreateBuffer(context, CL_MEM_READ_WRITE, 1*sizeof(cl_ulong), NULL, NULL);
  kernel = clCreateKernel(program, "test_rotate", NULL);
  const size_t work_size[1] = {1};
  clSetKernelArg(kernel, 0, sizeof(mem1), &mem1);
  clSetKernelArg(kernel, 1, sizeof(loops), &loops);
  clSetKernelArg(kernel, 2, sizeof(pattern), &pattern);

  clEnqueueNDRangeKernel(queue1, kernel, 1, NULL, work_size, work_size, 0, NULL, NULL);
  if (two_kernels){
    clSetKernelArg(kernel, 0, sizeof(mem2), &mem2);
    clSetKernelArg(kernel, 1, sizeof(loops), &loops);
    clSetKernelArg(kernel, 2, sizeof(pattern), &pattern);

    clEnqueueNDRangeKernel(queue2, kernel, 1, NULL, work_size, work_size, 0, NULL, NULL);
    }
  cl_ulong *buf1 = (cl_ulong *)clEnqueueMapBuffer(queue1, mem1, true, CL_MAP_READ, 0, 1*sizeof(cl_ulong), 0, NULL, NULL, NULL);
  cl_ulong *buf2 = (cl_ulong *)clEnqueueMapBuffer(queue2, mem2, true, CL_MAP_READ, 0, 1*sizeof(cl_ulong), 0, NULL, NULL, NULL);
  printf("result1: %lu\n", buf1[0]);
  printf("result2: %lu\n", buf2[0]);
  clEnqueueUnmapMemObject(queue1, mem1, buf1, 0, NULL, NULL);
  clEnqueueUnmapMemObject(queue2, mem2, buf2, 0, NULL, NULL);
  return 0;
}
$ nvcc -arch=sm_35 -o t4 t4.cpp -lOpenCL
$ ./t4
running one kernel
running  1000 loops
result1: 1000
result2: 0
$ cp t4.cpp t4.cl
$ nvcc -arch=sm_35 -x cu -o t4 t4.cl -lOpenCL
$ ./t4
running one kernel
running  1000 loops
result1: 1000
result2: 0
$

请注意,这里的代码没有做任何明智或重要的事情,所以我宁愿避免提问。这只是为了演示编译符合 C++ 标准的 OpenCL 代码。

(*)(因为此类文件也可以由普通主机编译器轻松处理,例如 gnu 编译器,带有适当的包含和链接选项开关。)

【讨论】:

  • 谢谢,这行得通!我来自 OpenCL,没有得到 nvcc 的单一来源氛围 :-) 考虑在您回复 cmets 时提及,我以为我被忽略了 ;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-09
  • 2016-12-17
  • 2015-04-30
  • 2018-02-02
  • 1970-01-01
  • 2010-10-05
相关资源
最近更新 更多