13

gmp 型 (mpz_t、mpq_t、…) のようなカスタム型を OpenCL カーネルで使用することは可能ですか?

このようなものを作成するには (このカーネルは という理由だけでビルドされません#include <gmp.h>) :

#include <gmp.h>
__カーネルスクエア(
   __グローバル mpz_t* 入力、
   __グローバル mpz_t 番号、
   __global int* 出力、
   const unsigned int カウント)
{
   int i = get_global_id(0);
   if(i < カウント)
       出力[i] = mpz_divisible_p(数値,入力[i]);
}

おそらく、 ?の 4 番目のパラメーター ( options ) に異なる引数を追加することによってclBuildProgram

または、OpenCL には既に大きな数を処理できる型がありますか?

4

4 に答える 4

21

通常、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;
}

ただし、OpenCL 内外で同じ定義を維持する必要があることは明らかです。また、タイプがデバイスとホストの両方で同じサイズであることを確認してください ( a を使用するsizeof(my_struct)とうまくいくはずです)。場合によっては、サイズが一致するように定義を調整する必要がありました。

于 2010-07-22T12:20:34.683 に答える
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;
}

ホスト

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;
}

出力

0 ☺</p>

1 ☻</p>

2 ♥</p>

3 ♦</p>

4♣</p>

于 2013-08-23T22:07:42.870 に答える
4

カスタム型を使用できますが、カーネルで使用されるものはすべて、OpenCL 用に特別に作成する必要があります。より大きな精度の数値を実装する方法については、おそらくこの Web サイトを確認してください: FP128

編集: NVIDIA の CUDA SDK には複素数のデータ型があります。これは理想的ではありませんが、OpenCL がどのように機能するかについていくつかのアイデアを提供する可能性があります。

于 2010-03-14T18:43:29.750 に答える