OpenCL Vector添加程序 [英] OpenCL Vector add program

查看:128
本文介绍了OpenCL Vector添加程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我绝对不熟悉OpenCL编程.我已经可以正常安装OpenCL库和驱动程序.但是我尝试运行的程序未产生预期的输出(输出全为零).这只是一个简单的vector_add程序. 预先感谢您的建议.

I'm absolutely new to OpenCL programming. I have a working installation of OpenCL library and drivers. But the program I'm trying to run is not producing expected output (Output is all zeros). It is just a simple vector_add program. Thanks in advance for suggestions.

int main(int argc, char** argv)
{
cout << "Hello OpenCL" << endl;

vector<Platform> all_platforms;
int err = Platform::get(&all_platforms);
cout << "Getting Platform ... Error code " << err << endl;
if (all_platforms.size()==0)
    (cout << "No platforms" << endl, exit(0));
cout << "Platform info : " << all_platforms[0].getInfo<CL_PLATFORM_NAME>() << endl;
Platform default_platform = all_platforms[0];
cout << "Defaulting to it ..." << endl;

vector<Device> all_devices;
err = default_platform.getDevices(CL_DEVICE_TYPE_GPU, &all_devices);
cout << "Getting devices ... Error code : " << err << endl;
if (all_devices.size()==0)
    (cout << "No devices" << endl, exit(0));
Device default_device = all_devices[0];
cout << all_devices.size() << " devices & " << "Device info : " << all_devices[0].getInfo<CL_DEVICE_NAME>() << endl;
cout << "Defaulting to it ..." << endl;

Context context(default_device);
Program::Sources sources;

std::string kernel_code=
        "   void kernel simple_add(global const int* A, global const int* B, global int* C){"
        "   unsigned int i = get_global_id(0);  "
        "       C[i]=A[i]+B[i];                 "
        "   }                                                                               ";

sources.push_back(make_pair(kernel_code.c_str(), kernel_code.length()+1));
Program program(context, sources);

if (program.build(all_devices)==CL_SUCCESS)
    cout << "Built Successfully" << endl;

Buffer buffer_A(context,CL_MEM_READ_WRITE,sizeof(int)*10);
Buffer buffer_B(context,CL_MEM_READ_WRITE,sizeof(int)*10);
Buffer buffer_C(context,CL_MEM_READ_WRITE,sizeof(int)*10);

int A[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int B[] = {0, 1, 2, 0, 1, 2, 0, 1, 2, 0};

CommandQueue queue(context,default_device);
queue.enqueueWriteBuffer(buffer_A,CL_TRUE,0,sizeof(int)*10,A); // load data from host to device
queue.enqueueWriteBuffer(buffer_B,CL_TRUE,0,sizeof(int)*10,B);

Kernel kernel(program, "vector_add");
kernel.setArg(0, buffer_A);
kernel.setArg(1, buffer_B);
kernel.setArg(2, buffer_C);

queue.enqueueNDRangeKernel(kernel,cl::NullRange,cl::NDRange(10),cl::NullRange);
queue.finish();

int *C = new int[10];
queue.enqueueReadBuffer(buffer_C, CL_TRUE, 0, 10 * sizeof(int), C);

for (int i=0;i<10;i++)
    std::cout << A[i] << " + " << B[i] << " = " << C[i] << std::endl;

return 0;
}

推荐答案

正如注释中指出的那样,在使用OpenCL API函数时,您应该始终检查错误代码.这可以通过在C ++包装器中启用异常处理来实现:

As pointed out in the comments, you should always check the error codes when using OpenCL API functions. This can be achieved by enabling exception handling in the C++ wrapper:

#define __CL_ENABLE_EXCEPTIONS      // with cl.hpp
//#define CL_HPP_ENABLE_EXCEPTIONS  // with cl2.hpp

#include <CL/cl.hpp>

int main(int argc, char *argv[])
{
  try
  {
    // OpenCL code here
  }
  catch (cl::Error& err)
  {
    cout << err.what() << " failed with error code " << err.err() << endl;
  }
}

如果这样做,您将收到有关代码几个问题的有用信息.

If you do this, you will receive useful information about a couple of issues with your code.

clCreateKernel函数返回CL_INVALID_NAME.在内核中,您使用名称simple_add定义了内核函数,但是随后您尝试使用名称vector_add创建一个内核对象.

The clCreateKernel function returns CL_INVALID_NAME. In your kernel, you define the kernel function with the name simple_add, but then you try and create a kernel object using the name vector_add.

如果您的OpenCL平台具有多个设备,则在构建内核程序时也可能会收到错误消息.这是因为您正在使用单个设备创建OpenCL上下文,但是随后尝试为设备列表构建程序:

If you have an OpenCL platform with multiple devices, you may also receive an error when building your kernel program. This is because you are creating an OpenCL context with a single device, but then trying to build the program for a list of devices:

Context context(default_device);
// ...
if (program.build(all_devices)==CL_SUCCESS)
  cout << "Built Successfully" << endl;

最简单的解决方法是从build函数中删除参数,因为默认情况下它将为上下文中的所有设备构建程序(这几乎总是您真正想要的):

The simplest fix is just to remove the argument from the build function, since by default it will build the program for all devices in the context (which is almost always what you actually want):

if (program.build()==CL_SUCCESS)
  cout << "Built Successfully" << endl;

这篇关于OpenCL Vector添加程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆