在Intel Opencl中将类传递给内核 [英] Passing Class to a Kernel in Intel Opencl

查看:84
本文介绍了在Intel Opencl中将类传递给内核的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

过去的几周以来,我一直在研究c/c ++ OpenCL解决方案.对于我的解决方案,我需要将类从我的CPU(主机)传递到GPU(设备).当我尝试将类作为参数传递时,出现错误未知类型标识符类".我怀疑英特尔平台上的OpenCL是否允许我们将类传递给内核,或者是否有其他解决方法可供使用.在CUDA中,我看到了一些示例,它在该平台上工作得很好.但是,关于OpenCL,我找不到任何引用,并且没有与此查询相关的示例.对于在此问题上的任何帮助,我将非常感谢.我已经在英特尔网站上发布了相同的问题,但无济于事.如果有人足够友好地帮助我了解我要去哪里出了问题或应该如何进行,我将非常感谢您.

I have been working on an c/c++ OpenCL solution for the past few weeks now. For my solution, I need to pass a class from my CPU(Host) to GPU(Device). When I try to pass the class as an argument it gives an error "Unknown Type-Identifier Class". My doubt whether OpenCL on Intel Platform does it allow us to pass a class to kernel or any work around is available for it. In CUDA I have seen some examples and it works perfectly fine for the platform. However, with respect to OpenCL I am not able to find any references and No examples related to this query. I would be really thankful to any help with regards to this issue. I have posted the same question on Intel website but to no avail. If someone would be kind enough to help me understand where I am going wrong or how I should proceed with this I would be really thankful to you.

//主机代码

#include<stdio.h>
#include<iostream>
#include"CL/cl.h"


class test
{
public:
    cl_int a;
    cl_char b;
};

int main()
{
    test *tempstruct = new test;

    cl_platform_id platfrom_id;
    cl_device_id device_id; // compute device id 
    cl_context context; // compute context
    cl_command_queue commands; // compute command queue
    cl_program program; // compute program
    cl_kernel kernel; // compute kernel

    int err;

    err = clGetPlatformIDs(1, &platfrom_id, NULL);
    if (err != CL_SUCCESS)
    {
        printf("Error: Failed to create a platfrom group!\n");
        return -1;
    }

    err = clGetDeviceIDs(platfrom_id, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL);

    if (err != CL_SUCCESS)
    {
        printf("Error: Failed to create a device group!\n");
        return -1;
    }

    context = clCreateContext(0, 1, &device_id, NULL, NULL, NULL);

    if (!context)
    {
        printf("Error: Failed to create a compute context!\n");
        return -1;
    }

    commands = clCreateCommandQueue(context, device_id, 0, NULL);

    if (!commands)
    {
        printf("Error: Failed to create a command commands!\n");
        return -1;
    }

    #define MAX_SOURCE_SIZE (0x100000) 
    FILE *fp, *fp1;
    char filename[] = "Template.cl";
    fp = fopen(filename, "r");
    if (fp == NULL)
    {
        printf("\n file  not found \n");
        return -1;
    }
    char * source_str = (char*)malloc(MAX_SOURCE_SIZE);
    size_t size = fread(source_str, 1, MAX_SOURCE_SIZE, fp);
    fclose(fp);

    cl_mem classobj = clCreateBuffer(context, CL_MEM_USE_HOST_PTR, sizeof(tempstruct), &tempstruct, &err);

    if (err != CL_SUCCESS)
    {
        printf("Error: Failed to allocate device memory!\n");
        return -1;
    }

    program = clCreateProgramWithSource(context, 1, (const char **)& source_str, (const size_t *)&size, &err);

    if (!program)
    {
        printf("Error: Failed to create program with source!\n");
        return -1;
    }

    err = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);

    if (err != CL_SUCCESS)
    {
        printf("Error: Failed to build program executable!\n");
        return -1;
    }


    test  *resptr = (test *)clEnqueueMapBuffer(commands, classobj, CL_TRUE, CL_MAP_WRITE, NULL, sizeof(test), NULL, NULL, NULL, &err);
    // INITIALISATION OF CLASS

    tempstruct->a = 10;
    if (!resptr)
    {
        printf("Error: Failed to create enqueuemapbuffer!\n");
        return -1;
    }

    err = clEnqueueUnmapMemObject(commands, classobj, resptr, 0, NULL, NULL);

    if (err != CL_SUCCESS)
    {
        printf("Error: Failed to write to source array!\n");
        return -1;
    }

    kernel = clCreateKernel(program, "CLASS", &err);
    if (err != CL_SUCCESS)
    {
        printf("Error: Failed to create compute kernel!\n");
        return -1;
    }

    err = clSetKernelArg(kernel, 0, sizeof(cl_mem), &classobj);

    if (err != CL_SUCCESS)
    {
        printf("Error: Failed to set kernel arguments! %d\n", err);
        return -1;
    }

    size_t globalsize = 1;
    size_t local = 1;

    err = clEnqueueNDRangeKernel(commands, kernel, 1, NULL, &globalsize, &local, 0, NULL, NULL);
    if (err)
    {
        printf("Error: Failed to execute nd range!\n");
        return -1;
    }

    test  *resptr1 = (test *)clEnqueueMapBuffer(commands, classobj, CL_TRUE, CL_MAP_READ, NULL, sizeof(test), NULL, NULL, NULL, &err);

    err = clEnqueueUnmapMemObject(commands, classobj, resptr1, 0, NULL, NULL);
    if (err != CL_SUCCESS)
    {
        printf("Error: Failed to read output array! %d\n", err);
        return -1;
    }

    // again i am printing the class value

    printf("\n in cpu side = %d\n", tempstruct->a);

}


//HOST END


//DEVICE SIDE(KERNEL CODE)

 // filename :  Template.cl

class test
{
public:
    cl_int a;
    cl_char b;
};

__kernel void CLASS(__global test *inclass )
{
   inclass->a = 10;
    printf("\n in kernel side = %d \n",inclass->a);
}

//内核结束

错误:

我仅在内核方面面临所有这些错误

I am facing these all errors at kernel side only

1)错误Tempalte.CL未知类型名称'test'
2)错误Tempalte.CL预期为';'在顶级声明符之后
3)错误Tempalte.CL程序范围变量需要在常量地址空间中声明
4)错误Tempalte.CL未知类型名称'class'

1) Error Tempalte.CL unknown type name 'test'
2) Error Tempalte.CL expected ';' after top level declarator
3) Error Tempalte.CL program scope variables are required to be declared in constant address space
4) Error Tempalte.CL unknown type name 'class'

查询:

Q)我的主要问题是如何将CLASS传递给Intel体系结构的内核
*我已经成功地将类传递给了AMD的内核.每当我在Intel方面尝试使用相同的代码时,都会显示上述四个错误.
*是否有其他方法可以将类传递给Intel中的内核,或者可以将类传递给Intel体系结构中的内核?

Q)My main Question is How to Pass a CLASS to kernel in Intel architecture
* I have successfully passed class to kernel in AMD. whenever I tried with same code in Intel side it shows the above four errors.
* Is there any alternative method to pass class to kernel in Intel or is it possible to pass class to kernel in Intel architecture ?

推荐答案

OpenCL使用C99.因此,您可以将结构而不是类传递给内核.

OpenCL uses C99. So you can pass structs, but not classes, to the kernel.

正如huseyin tugrul buyukisik所说,您可以使用SYCL,它支持c ++ 14(或其附近).

As huseyin tugrul buyukisik says, you can use SYCL, which supports c++14 (or thereabouts).

或者,如果您想同时支持NVIDIA®CUDA™和OpenCL,则只能在NVIDIA®CUDA™中编写它,然后使用 https://bitbucket.org/hughperkins/eigen/src/eigen-cl/unsupported/test /cuda-on-cl/?at = eigen-cl

Alternatively, if you want to support both NVIDIA® CUDA™ and OpenCL, you could write it only in NVIDIA® CUDA™, and then use https://github.com/hughperkins/cuda-on-cl to run the NVIDIA® CUDA™ code on OpenCL 1.2 GPU devices. Full disclosure: I'm the author of cuda-on-cl, and it's a bit of a work-in-progress for now. It does work though, with some caveats/limitations. It can handle full-blown C++11, templates, classes etc. For example, it can be used to compile and run Eigen on OpenCL 1.2 GPUs https://bitbucket.org/hughperkins/eigen/src/eigen-cl/unsupported/test/cuda-on-cl/?at=eigen-cl

这篇关于在Intel Opencl中将类传递给内核的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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