Pregunta

¿Es posible utilizar tipos personalizados en el núcleo, como OpenCL tipos GMP (mpz_t, mpq_t, ...)?

Para tener algo como esto (este núcleo no construye sólo por #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]);
}

Tal vez mediante la adición de diferentes argumentos para el cuarto parámetro ( Opciones ) de clBuildProgram?

¿O OpenCL ya tienen tipos que pueden manejar grande números?

¿Fue útil?

Solución

Puede utilizar tipos personalizados, pero cualquier cosa usada en el kernel necesita ser escrita específicamente para OpenCL. Echa un vistazo a este sitio web tal vez por la forma de aplicar los números más grandes de precisión: FP128

Editar:. CUDA de NVIDIA SDK tiene un tipo de datos complejo número, no es ideal, pero puede darle algunas ideas sobre cómo van sobre ella, OpenCL debe ser similar

Otros consejos

En general, se puede utilizar cualquier tipo en un programa OpenCL. Sin embargo, dado que las importaciones no funcionan, usted tiene que volver a definirlos dentro del mismo programa. Por ejemplo:

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

Sin embargo, es obvio que necesita para mantener las definiciones dentro y fuera de la misma OpenCL. También asegúrese de que el tipo tiene el mismo tamaño en ambos dispositivos y host (usando un sizeof(my_struct) debe hacer el truco). En algunos casos he tenido que ajustar las definiciones, a tener tamaños coincidentes.

He utilizado la respuesta de VHristov y comentario de Dietr para obtener mina de trabajo. Este código funciona para mí en OpenCL 1.2

kernel

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

host

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

salida

0 ☺

1 ☻

2 ♥

3 ♦

4 ♣

Si desea incluir archivos de cabecera en el archivo del kernel, se puede añadir el -l dir como argumento para clBuildProgram, donde dir es el directorio con los archivos de cabecera .

Más explicación aquí: incluyen cabeceras a OpenCL archivo .cl

Fuente: http: // www .khronos.org / registro / cl / SDK / 1.0 / docs / hombre / XHTML / clBuildProgram.html

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top