I have defined a new type as struct in a separate file and the file is included for further reference. Then i am sending the use-defined type as kernel arguments , but i am getting the error:
--- build log ---
:6:42: error: unknown type name 'SimParams'
__constant SimParams* params,
Any hint to get around this issue ?
The OpenCL C compiler has no access to your struct definition. While it does have some #include capabilities, I’d start by just repeating your struct definition inside the kernel source. Also, you have to be super careful about element alignment when using structs, because they have to line up between your host and your compute device. If possible, stick with basic parameter types and vector parameter types if you can before moving to using a struct.
I am doing it as follows:
typedef struct SimParams
The above is declared in a separate file. I declare an object of the above type , initialize some values, create a device buffer of the above type and then send the struct type as kernel arguments. Then again i am defining the following inside the kernel source:
const char source =
"typedef struct SimParams
" float4 gravity;
" float globalDamping;
" float noiseFreq;
" float noiseAmp;
" float4 cursorPos;
" float time;
" float4 noiseSpeed;
Is that what you meant? Now it not complaining.
Is this the only way to get it done. A bit complex , dont you think ?
Yes, that’s what I meant. Perhaps more complex that you’d like, but using #include files in OpenCL can be equally tricky.
One approach that I have used is to create a #include file that has just my types in it and is included from the host. Then this header and the .cl source file(s) are passed to clCreateProgramFromSource as multiple strings (or concatenated into one string). That way you don’t need to mess with #include in CL source, but you get the same effect. The downside is that you then need to package the header and .cl files with your application, but each OS usually has a way to do this sort of resource packaging.
The common source approach does suffer from the problem that the types in the host API and the kernel language differ, so you may need to introduce some typedef’ing to get things to work. Also, exercise caution around struct alignment and packing – the OpenCL spec doesn’t contain explicit guarantees about how structs are laid out.
One last note, don’t try to pass structs to your kernels by value. Put them in buffer objects and pass those to the kernels as typed pointers.