Reputation: 2007
So I want to define a struct thats usable on both the host and on the device in openCL that makes use of the built in openCL float4 datatypes.
On the host side, the framework comes with a cl_float4 type but on the device it's just float4.
So if I create a struct like this...
typedef struct
{
cl_float4 a, b;
} MyStruct;
...and then try to pass that struct into a kernel (via a buffer) I get an error.
If I declare it as follows...
typedef struct
{
float4 a,b;
}
...that would work on the device but doesn't work on the host.
So is there a way to get it so that I can make use of openCLs built in vector types on both sides of my program within the same structs?
Upvotes: 0
Views: 1790
Reputation: 86
I'd avoid this approach unless you're very careful with your struct definition. The data structure alignment rules of your OpenCL device's architecture may very well be different than those of your OpenCL host's architecture. See this Wikipedia article for an overview on data structure alignment.
TLDR: the size of your struct may vary from device to host, as might the offsets from of each struct's member from the beginning of the struct. If this happens your program will break. Even if you get away with this on your current host/device combination it's not guaranteed to work on other hardware combinations.
Upvotes: 0
Reputation: 9925
The C preprocessor can help you here, by treating the code differently depending on whether it is being compiled on the host or the device.
Here's some possible solutions:
typedef struct
{
#ifdef __OPENCL_C_VERSION__
float4
#else
cl_float4
#endif
a, b;
} MyStruct;
or:
#ifdef __OPENCL_C_VERSION__
typedef float4 cl_float4;
#endif
typedef struct
{
cl_float4 a, b;
} MyStruct;
or:
#ifndef __OPENCL_C_VERSION__
typedef cl_float4 float4;
#endif
typedef struct
{
float4 a, b;
} MyStruct;
or just use cl_float4
, and compile the OpenCL code like this:
clBuildProgram(program, 1, &device, "-Dcl_float4=float4", NULL, NULL);
Upvotes: 4