Class 在英特尔Opencl中将类传递给内核

Class 在英特尔Opencl中将类传递给内核,class,opencl,intel,Class,Opencl,Intel,在过去的几周里,我一直在研究c/c++OpenCL解决方案。对于我的解决方案,我需要将一个类从CPU(主机)传递到GPU(设备)。当我试图将该类作为参数传递时,它会给出一个错误“未知类型标识符类”。我怀疑英特尔平台上的OpenCL是否允许我们将一个类传递给内核,或者它是否有任何解决方法。在CUDA中,我看到了一些示例,它在平台上运行得非常好。然而,关于OpenCL,我找不到任何引用,也找不到与此查询相关的示例。我真的非常感谢在这个问题上的任何帮助。我已经在英特尔网站上发布了同样的问题,但没有结果

在过去的几周里,我一直在研究c/c++OpenCL解决方案。对于我的解决方案,我需要将一个类从CPU(主机)传递到GPU(设备)。当我试图将该类作为参数传递时,它会给出一个错误“未知类型标识符类”。我怀疑英特尔平台上的OpenCL是否允许我们将一个类传递给内核,或者它是否有任何解决方法。在CUDA中,我看到了一些示例,它在平台上运行得非常好。然而,关于OpenCL,我找不到任何引用,也找不到与此查询相关的示例。我真的非常感谢在这个问题上的任何帮助。我已经在英特尔网站上发布了同样的问题,但没有结果。如果有人能帮助我理解我哪里出了问题,或者我该如何处理这件事,我将非常感谢你

//主机端代码

#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);
}
#包括
#包括
#包括“CL/CL.h”
课堂测试
{
公众:
cl_INTA;
cl_char b;
};
int main()
{
test*tempstruct=新测试;
cl_平台_id platfrom_id;
cl\U设备\U id设备\U id;//计算设备id
cl_context context;//计算上下文
cl_命令_队列命令;//计算命令队列
cl_程序;//计算程序
cl_内核;//计算内核
INTERR;
err=clGetPlatformIDs(1,&platfrom_id,NULL);
如果(错误!=CL_成功)
{
printf(“错误:无法从组创建平台!\n”);
返回-1;
}
err=clgetDeviceID(platfrom\u id,CL\u DEVICE\u TYPE\u GPU,1,&DEVICE\u id,NULL);
如果(错误!=CL_成功)
{
printf(“错误:无法创建设备组!\n”);
返回-1;
}
context=clCreateContext(0、1和设备标识,NULL、NULL、NULL);
如果(!上下文)
{
printf(“错误:无法创建计算上下文!\n”);
返回-1;
}
commands=clCreateCommandQueue(上下文,设备id,0,NULL);
如果(!命令)
{
printf(“错误:无法创建命令命令!\n”);
返回-1;
}
#定义最大源大小(0x100000)
文件*fp,*fp1;
char filename[]=“Template.cl”;
fp=fopen(文件名,“r”);
如果(fp==NULL)
{
printf(“\n找不到文件\n”);
返回-1;
}
char*source\u str=(char*)malloc(最大源大小);
size\u t size=fread(source\u str,1,MAX\u source\u size,fp);
fclose(fp);
cl_mem classobj=clCreateBuffer(上下文,cl_mem_USE_HOST_PTR,sizeof(tempstruct),&tempstruct,&err);
如果(错误!=CL_成功)
{
printf(“错误:无法分配设备内存!\n”);
返回-1;
}
program=clCreateProgramWithSource(上下文,1,(常量字符**)和源代码(常量大小*)&大小和错误);
如果(!程序)
{
printf(“错误:无法使用源创建程序!\n”);
返回-1;
}
err=clBuildProgram(程序,1和设备id,NULL,NULL,NULL);
如果(错误!=CL_成功)
{
printf(“错误:无法生成程序可执行文件!\n”);
返回-1;
}
test*resptr=(test*)clEnqueueMapBuffer(命令、classobj、CL_TRUE、CL_MAP_WRITE、NULL、sizeof(test)、NULL、NULL、NULL和err);
//类的初始化
tempstruct->a=10;
如果(!resptr)
{
printf(“错误:无法创建enqueuemapbuffer!\n”);
返回-1;
}
err=clenqueunmapmemobject(命令,classobj,resptr,0,NULL,NULL);
如果(错误!=CL_成功)
{
printf(“错误:无法写入源数组!\n”);
返回-1;
}
kernel=clCreateKernel(程序,“类”&错误);
如果(错误!=CL_成功)
{
printf(“错误:无法创建计算内核!\n”);
返回-1;
}
err=clSetKernelArg(kernel,0,sizeof(cl_mem),&classobj);
如果(错误!=CL_成功)
{
printf(“错误:设置内核参数失败!%d\n”,错误);
返回-1;
}
大小\u t globalsize=1;
局部尺寸=1;
err=clEnqueueNDRangeKernel(命令,kernel,1,NULL,&globalsize,&local,0,NULL,NULL);
如果(错误)
{
printf(“错误:无法执行nd范围!\n”);
返回-1;
}
test*resptr1=(test*)clenqueueemapbuffer(命令、classobj、CL_TRUE、CL_MAP_READ、NULL、sizeof(test)、NULL、NULL、NULL和err);
err=clenqueunmapmemobject(命令,classobj,resptr1,0,NULL,NULL);
如果(错误!=CL_成功)
{
printf(“错误:读取输出数组失败!%d\n”,错误);
返回-1;
}
//我再次打印类值
printf(“\n在cpu端=%d\n”,tempstruct->a);
}
//主机端
//设备端(内核代码)
//文件名:Template.cl
课堂测试
{
公众:
cl_INTA;
cl_char b;
};
__内核无效类(uu全局测试*inclass)
{
inclass->a=10;
printf(“\n在内核端=%d\n”,包含类->a);
}
//内核端

错误:

我只在内核端面对这些错误

1) 错误Tempalte.CL未知类型名称“test”
2) 错误Tempalte.CL应为“;”在顶级声明器之后
3) Error Tempalte.CL程序作用域变量需要在常量地址空间中声明
4) 错误Tempalte.CL未知类型名称“class”

查询:

Q) 我的主要问题是如何在英特尔体系结构中将类传递给内核
*我已经在AMD中成功地将类传递给内核。每当我在Intel端尝试使用相同的代码时,它都会显示上述四个错误。

*在英特尔体系结构中,是否有其他方法将类传递给内核,或者是否有可能将类传递给内核

OpenCL使用C99。因此,您可以向内核传递结构,但不能传递类

正如huseyin tugrul buyukisik所说,您可以使用SYCL,它支持c++14(或类似的版本)

或者,如果您希望同时支持NVIDIA®CUDA™ 和OpenCL,您只能在NVIDIA®CUDA中编写™, 然后用于运行NVIDIA®CUDA™ OpenCL1.2GPU设备上的代码。充分披露:我不是
typedef struct Warrior_tag
{
    int id;
    float hp;
    int strength;
    int dexterity;
    int constitution;
} Warrior;

typedef struct Mage_tag
{
    int id;
    Warrior summoned_warriors[90];
} Mage; 
// should be more than 32*90 + 32*90 => 5760(2.8k *2) => 8192(4k*2) bytes
// because id + padding = 90 warriors or it doesn't work in runtime
// reversing order of fields should make it 4k + 4 bytes


__kernel void test0(__global Warrior * warriors)
{
    int id=get_global_id(0);
    Warrior battal_gazi = warriors[0];
    Warrior achilles = warriors[1];
    Warrior aramis = warriors[2];
    Warrior hattori_hanzo = warriors[3];
    Warrior ip_man = warriors[4];

    Mage nakano = (Mage){0,{battal_gazi, achilles}};
    Mage gul_dan = (Mage){0,{aramis , hattori_hanzo,ip_man  }};
}