linux - 如何在 Linux 中为 opencl 编程(安装英特尔 OpenCL SDK)准备 eclipse

标签 linux eclipse opencl opensuse

我在 OpenSUSE GNU/Linux 13.1 上安装了英特尔 OpenCL SDK。如何为 OpenCL 编程准备我的发行版附带的 Eclipse CDT IDE?

编辑:

在将包含路径 /opt/intel/opencl-xxx/inlcude 添加到项目并将 /opt/intel/opencl-xxx/lib64/libOpenCL.so 链接到之后/usr/lib64/libOpenCL.so,Eclipse 将找到 CL/cl.h 但 GCC 返回此错误:

Building file: ../src/HelloWorld.cpp
Invoking: GCC C++ Compiler
g++ -I/opt/intel/opencl-1.2-3.2.1.16712/include/ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/HelloWorld.d" -MT"src/HelloWorld.d" -o "src/HelloWorld.o" "../src/HelloWorld.cpp"
../src/HelloWorld.cpp:11:16: fatal error: cl.h: No such file or directory
 #include <cl.h>
                ^
compilation terminated.
make: *** [src/HelloWorld.o] Error 1

编辑 2:

Hello World .cpp :

#include <iostream>
#include <fstream>
#include <sstream>
#include <CL\cl.h>

const int ARRAY_SIZE = 1000;

cl_context CreateContext() {
    cl_int errNum;
    cl_uint numPlatforms;
    cl_platform_id firstPlatformId;
    cl_context context = NULL;
    errNum = clGetPlatformIDs(1, &firstPlatformId, &numPlatforms);
    if (errNum != CL_SUCCESS || numPlatforms <= 0) {
        std::cerr << "Failed to find any OpenCL platforms." << std::endl;
        return NULL;
    }
    cl_context_properties contextProperties[] = {
        CL_CONTEXT_PLATFORM,
        (cl_context_properties)firstPlatformId,
        0
    };
    context = clCreateContextFromType(contextProperties, CL_DEVICE_TYPE_GPU,
                                      NULL, NULL, &errNum);

    if (errNum != CL_SUCCESS) {
        std::cout << "Could not create GPU context, trying CPU..." << std::endl;
        context = clCreateContextFromType(contextProperties, CL_DEVICE_TYPE_CPU, NULL, NULL, &errNum);
        if (errNum != CL_SUCCESS) {
            std::cerr << "Failed to create an OpenCL GPU or CPU context." << std::endl;
            return NULL;
        }
    }
    return context;
}
cl_command_queue CreateCommandQueue(cl_context context, cl_device_id *device)
{
    cl_int errNum;
    cl_device_id *devices;
    cl_command_queue commandQueue = NULL;
    size_t deviceBufferSize = -1;
    errNum = clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, NULL, &deviceBufferSize);
    if (errNum != CL_SUCCESS) {
        std::cerr << "Failed call to clGetContextInfo(...,GL_CONTEXT_DEVICES,...)";
        return NULL;
    }
    if (deviceBufferSize <= 0) {
        std::cerr << "No devices available.";
        return NULL;
    }
    devices = new cl_device_id[deviceBufferSize / sizeof(cl_device_id)];
    errNum = clGetContextInfo(context, CL_CONTEXT_DEVICES, deviceBufferSize, devices,NULL);
    if (errNum != CL_SUCCESS) {
        delete [] devices;
        std::cerr << "Failed to get device IDs";
        return NULL;
    }
    commandQueue = clCreateCommandQueue(context, devices[0], 0, NULL);
    if (commandQueue == NULL) {
        delete [] devices;
        std::cerr << "Failed to create commandQueue for device 0";
        return NULL;
    }

    *device = devices[0];
    delete [] devices;
    return commandQueue;
}

cl_program CreateProgram(cl_context context, cl_device_id device, const char* fileName)

{

    cl_int errNum;

    cl_program program;



    std::ifstream kernelFile(fileName, std::ios::in);

    if (!kernelFile.is_open())

    {

        std::cerr << "Failed to open file for reading: " << fileName << std::endl;

        return NULL;

    }



    std::ostringstream oss;

    oss << kernelFile.rdbuf();



    std::string srcStdStr = oss.str();

    const char *srcStr = srcStdStr.c_str();

    program = clCreateProgramWithSource(context, 1,

                                        (const char**)&srcStr,

                                        NULL, NULL);

    if (program == NULL)

    {

        std::cerr << "Failed to create CL program from source." << std::endl;

        return NULL;

    }



    errNum = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);

    if (errNum != CL_SUCCESS)

    {

        char buildLog[16384];

        clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG,

                              sizeof(buildLog), buildLog, NULL);



        std::cerr << "Error in kernel: " << std::endl;

        std::cerr << buildLog;

        clReleaseProgram(program);

        return NULL;

    }



    return program;

}

bool CreateMemObjects(cl_context context, cl_mem memObjects[3],

                      float *a, float *b)

{

    memObjects[0] = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,

                                   sizeof(float) * ARRAY_SIZE, a, NULL);

    memObjects[1] = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,

                                   sizeof(float) * ARRAY_SIZE, b, NULL);

    memObjects[2] = clCreateBuffer(context, CL_MEM_READ_WRITE,

                                   sizeof(float) * ARRAY_SIZE, NULL, NULL);



    if (memObjects[0] == NULL || memObjects[1] == NULL || memObjects[2] == NULL)

    {

        std::cerr << "Error creating memory objects." << std::endl;

        return false;

    }



    return true;

}


void Cleanup(cl_context context, cl_command_queue commandQueue,

             cl_program program, cl_kernel kernel, cl_mem memObjects[3])

{

    for (int i = 0; i < 3; i++)

    {

        if (memObjects[i] != 0)

            clReleaseMemObject(memObjects[i]);

    }

    if (commandQueue != 0)

        clReleaseCommandQueue(commandQueue);



    if (kernel != 0)

        clReleaseKernel(kernel);



    if (program != 0)

        clReleaseProgram(program);



    if (context != 0)

        clReleaseContext(context);



}

int main(int argc, char** argv)

{

    cl_context context = 0;

    cl_command_queue commandQueue = 0;

    cl_program program = 0;

    cl_device_id device = 0;

    cl_kernel kernel = 0;

    cl_mem memObjects[3] = { 0, 0, 0 };

    cl_int errNum;



    // Create an OpenCL context on first available platform

    context = CreateContext();

    if (context == NULL)

    {

        std::cerr << "Failed to create OpenCL context." << std::endl;

        return 1;

    }



    // Create a command-queue on the first device available

    // on the created context

    commandQueue = CreateCommandQueue(context, &device);

    if (commandQueue == NULL)

    {

        Cleanup(context, commandQueue, program, kernel, memObjects);

        return 1;

    }



    // Create OpenCL program from HelloWorld.cl kernel source

    program = CreateProgram(context, device, "HelloWorld.cl");

    if (program == NULL)

    {

        Cleanup(context, commandQueue, program, kernel, memObjects);

        return 1;

    }



    // Create OpenCL kernel

    kernel = clCreateKernel(program, "hello_kernel", NULL);

    if (kernel == NULL)

    {

        std::cerr << "Failed to create kernel" << std::endl;

        Cleanup(context, commandQueue, program, kernel, memObjects);

        return 1;

    }



    // Create memory objects that will be used as arguments to

    // kernel.  First create host memory arrays that will be

    // used to store the arguments to the kernel

    float result[ARRAY_SIZE];

    float a[ARRAY_SIZE];

    float b[ARRAY_SIZE];

    for (int i = 0; i < ARRAY_SIZE; i++)

    {

        a[i] = (float)i;

        b[i] = (float)(i * 2);

    }



    if (!CreateMemObjects(context, memObjects, a, b))

    {

        Cleanup(context, commandQueue, program, kernel, memObjects);

        return 1;

    }



    // Set the kernel arguments (result, a, b)

    errNum = clSetKernelArg(kernel, 0, sizeof(cl_mem), &memObjects[0]);

    errNum |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &memObjects[1]);

    errNum |= clSetKernelArg(kernel, 2, sizeof(cl_mem), &memObjects[2]);

    if (errNum != CL_SUCCESS)

    {

        std::cerr << "Error setting kernel arguments." << std::endl;

        Cleanup(context, commandQueue, program, kernel, memObjects);

        return 1;

    }



    size_t globalWorkSize[1] = { ARRAY_SIZE };

    size_t localWorkSize[1] = { 1 };



    // Queue the kernel up for execution across the array

    errNum = clEnqueueNDRangeKernel(commandQueue, kernel, 1, NULL,

                                    globalWorkSize, localWorkSize,

                                    0, NULL, NULL);

    if (errNum != CL_SUCCESS)

    {

        std::cerr << "Error queuing kernel for execution." << std::endl;

        Cleanup(context, commandQueue, program, kernel, memObjects);

        return 1;

    }



    // Read the output buffer back to the Host

    errNum = clEnqueueReadBuffer(commandQueue, memObjects[2], CL_TRUE,

                                 0, ARRAY_SIZE * sizeof(float), result,

                                 0, NULL, NULL);

    if (errNum != CL_SUCCESS)

    {

        std::cerr << "Error reading result buffer." << std::endl;

        Cleanup(context, commandQueue, program, kernel, memObjects);

        return 1;

    }



    // Output the result buffer

    for (int i = 0; i < ARRAY_SIZE; i++)

    {

        std::cout << result[i] << " ";

    }

    std::cout << std::endl;

    std::cout << "Executed program succesfully." << std::endl;

    Cleanup(context, commandQueue, program, kernel, memObjects);



    return 0;

}

HelloWorld.cl:

__kernel void hello_kernel(
    __global const float *a,
    __global const float *b,
    __global float *result)
{
    int gid = get_global_id(0);
    result[gid] = a[gid] + b[gid];
} 

最佳答案

您只需要在项目中添加一个OpenCL include 目录并链接到一个libOpenCL。在我的例子中(Ubuntu 13.04)我需要添加 /opt/intel/opencl-1.xxxx/include到项目的包含路径,允许使用 #include <CL/cl.h> .

同时添加 /opt/intel/opencl-1.xxxx/lib64/添加到链接器搜索路径并将 OpenCL 添加到链接库。 enter image description here

应该这样做。

关于linux - 如何在 Linux 中为 opencl 编程(安装英特尔 OpenCL SDK)准备 eclipse,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21318112/

相关文章:

java - Eclipse 无法关闭 BEA WebLogic 服务器

Python Eclipse 类型转换智能感知解决方法

java - JavaCL 和 JogAmp JOCL 比较如何?

linux - 比较 2 个文件并仅删除重复行一次

linux - 在 Linux 中创建_singlethread_workqueue

linux - Bash Awk 划分得到不同的结果

c - 目标文件的未初始化变量未显示在 linux size 命令中

java - 在服务器上调试时找不到源 (Eclipse)

c - 包含 header OpenCL(32 位与 64 位)

linux - Racket - 导入 OpenCL