OpenCL内核中的自定义类型

Stu*_*der 11 types gmp opencl

是否可以在OpenCL内核中使用自定义类型,如gmp类型(mpz_t,mpq_t,...)?

有这样的东西(这个内核不仅仅因为而构建#include <gmp.h>):

#include <gmp.h>
__kernel square(
   __global mpz_t* input,
   __global mpz_t number,
   __global int* output,
   const unsigned int count)
{
   int i = get_global_id(0);
   if(i < count)
       output[i] = mpz_divisible_p(number,input[i]);
}

也许通过向第四个参数(选项)添加不同的参数clBuildProgram

或者OpenCL是否已经拥有可以处理数字的类型?

VHr*_*tov 20

通常,您可以在OpenCL程序中使用任何类型.但由于导入不起作用,您必须在同一程序中重新定义它们.例如:

typedef char my_char[8];

typedef struct tag_my_struct
{
    long int        id;
    my_char         chars[2];
    int             numerics[4]
    float           decimals[4];
} my_struct;

__kernel void foo(__global my_struct * input,
                  __global int * output)
{
    int gid = get_global_id(0);
    output[gid] = input[gid].numerics[3]== 2 ? 1 : 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,您显然需要保持OpenCL内外的定义相同.还要确保类型在设备和主机上具有相同的大小(使用sizeof(my_struct)应该做的技巧).在某些情况下,我必须调整定义,以获得匹配的大小.

  • 为了确保大小相同的类型,最好在主机代码中使用cl_*类型(cl_int,cl_long,cl_float2等). (6认同)

小智 7

我用VHristov的回答和dietr的评论来让我的工作.这段代码适用于OpenCL 1.2

核心

typedef struct tag_my_struct{
  int a;
  char b;
}my_struct;

__kernel void myKernel(__global my_struct *myStruct)
{
    int gid = get_global_id(0);
    (myStruct+gid)->a = gid;
    (myStruct+gid)->b = gid + 1;
}
Run Code Online (Sandbox Code Playgroud)

主办

typedef struct tag_my_struct{
  cl_int a;
  cl_char b;
}my_struct;

void runCode() 
{
    cl_int status = 0;
    my_struct* ms = new my_struct[5];

    cl_mem mem = clCreateBuffer(*context, 0, sizeof(my_struct)*5, NULL, &status);
    clEnqueueWriteBuffer(*queue, mem, CL_TRUE, 0, sizeof(my_struct)*5, &ms, 0, NULL, NULL);

    status = clSetKernelArg(*kernel, 0, sizeof(ms), &mem);

    size_t global[] = {5};
    status = clEnqueueNDRangeKernel(*queue, *kernel, 1, NULL, global, NULL, 0, NULL, NULL);

    status = clEnqueueReadBuffer(*queue, mem, CL_TRUE, 0, sizeof(my_struct)*5, ms, 0, NULL, NULL);

    for(int i = 0; i < 5; i++)
        cout << (ms+i)->a << " " << (ms+i)->b << endl;
}
Run Code Online (Sandbox Code Playgroud)

产量

0☺

1☻

2♥

3♦

4♣

  • 为什么要使用`(myStruct + gid) - > a = gid;`而不是`myStruct [gid] .a = gid;`.对我来说这看起来很丑陋(但是会给出相同的结果) (5认同)

Ada*_* S. 4

您可以使用自定义类型,但内核中使用的任何内容都需要专门为 OpenCL 编写。查看此网站也许可以了解如何实现更高精度的数字:FP128

编辑:NVIDIA 的 CUDA SDK 有一个复杂的数字数据类型,它并不理想,但可能会给你一些关于他们如何处理它的想法,OpenCL 应该类似。