incompatible declaration with callable functions

I have the following piece of code:

rtDeclareVariable(
	rtCallableProgramX<float(float3, float3, float3)>, BRDF, , );

RT_CALLABLE_PROGRAM float BRDF(float3 incoming, float3 outgoing, float3 normal) {
	return dot(normal, outgoing);
}

which generates the following error when i try to compile it:

Error:		declaration is incompatible with "optix::boundCallableProgramId<float (float3, float3, float3)> BRDF"

The error message implies something is wrong with the function signature, but i cannot for the life of me figure out what that might be, despite looking at both the documentation and examples. What am i doing wrong?

Kind regards,
Erik

Could you try if following this comment inside the OptiX rtCallableProgramX documentation helps?
“Unless compatibility with SM_10 is needed, new code should #define RT_USE_TEMPLATED_RTCALLABLEPROGRAM and rely on the new templated version of rtCallableProgram instead of directly using rtCallableProgramX.”

Actually please have a look into the optixCallablePrograms example to find the declaration for a bound callable program and bindless callable program IDs in a buffer.

There is CUDA code with rtCallableProgram( float3, shade_normal, ( const float3 ) );
For your case that should be rtCallableProgram( float, BRDF_Function, (float3, float3, float3) );

Don’t name the function the same!

I would generally recommend to use bindless callable programs for these kind of functions.
Then you can have a bunch of different functions for sampling and evaluation of BSDFs as callable program IDs in buffers and simply index them just like a function table.

Things like this:
rtBuffer<rtCallableProgramId<float(float3, float3, float3)> > BRDF_Functions; // Whole array of functions.
rtDeclareVariable(rtCallableProgramId<float(float3, float3, float3)>, BRDF_Function, , ); // Single bindless callable program variable.

Hi!

Thanks for the help! I’ve gotten rid of the error messages, and i think i understand the general idea. However, the ptx-file that results doesn’t contain my function. Upon googling, i found this thread that recommended adding the flag -rdc==true. This results in the ptx code being generated - however, upon compiling the project, the following (longish) errors result:

Severity	Code	Description	Project	File	Line	Suppression State
Error		Unknown symbol '_rt_buffer_get_64'	EMRT	C:\source\EMRT\tracer\EMRT\ptxas C	1	
Error	MSB3721	The command ""C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin\nvcc.exe" -dlink -o x64\Debug\EMRT.device-link.obj -Xcompiler "/EHsc /W3 /nologo /Od /Zi /RTC1 /MDd /GR" -LC:\source\EMRT\tracer\optix\lib64 -LC:\source\EMRT\tracer\lib -L"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\x64" optix.1.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib optixu.1.lib "assimp-vc140-mt.lib" blas_win64_MT.lib lapack_win64_MT.lib  -gencode=arch=compute_30,code=sm_30  --machine 64 C:\source\EMRT\tracer\x64\Debug\brdf.ptx C:\source\EMRT\tracer\x64\Debug\constantbg.ptx C:\source\EMRT\tracer\x64\Debug\depthmap.ptx C:\source\EMRT\tracer\x64\Debug\draw_color.ptx C:\source\EMRT\tracer\x64\Debug\normal_shader.ptx C:\source\EMRT\tracer\x64\Debug\pinhole_camera.ptx C:\source\EMRT\tracer\x64\Debug\sphere.ptx C:\source\EMRT\tracer\x64\Debug\spherecenter.ptx C:\source\EMRT\tracer\x64\Debug\triangle_mesh.ptx" exited with code 255.	EMRT	C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\BuildCustomizations\CUDA 8.0.targets	773	
Error		Label expected for argument 0 of instruction 'call'	EMRT	C:\source\EMRT\tracer\EMRT\ptxas C	1	
Error		Label expected for argument 0 of instruction 'call'	EMRT	C:\source\EMRT\tracer\EMRT\ptxas C	1	
Error		Function '_rt_trace_64' not declared in this scope	EMRT	C:\source\EMRT\tracer\EMRT\ptxas C	1	
Error		Function '_rt_buffer_get_64' not declared in this scope	EMRT	C:\source\EMRT\tracer\EMRT\ptxas C	1	
Error		Call target not recognized	EMRT	C:\source\EMRT\tracer\EMRT\ptxas C	1	
Error		Call target not recognized	EMRT	C:\source\EMRT\tracer\EMRT\ptxas C	1	
Error		Call target not recognized	EMRT	C:\source\EMRT\tracer\EMRT\ptxas C	1

…Which tells me enough that there is something wrong with function scope, but not enough to help me resolve it. Do you by any chance have any ideas of where to start digging, or something i can read to try to understand the process better?

Kind Regards,
Erik

Right, CUDA 8.0 needs the “–relocatable-device-code=true” or -rdc=true to force code generation of callable programs.

“nvcc.exe” -dlink -o x64\Debug\EMRT.device-link.obj" …

Are you trying to link the OptiX PTX shaders into a CUDA obj?
That’s not how the OptiX programs work. After compiling the CUDA code to PTX source you’re done.

The resulting OptiX specific PTX code needs to be used inside the rtProgramCreateFromPTXFile() or rtProgramCreateFromPTXString() calls at runtime inside your application, resp. their C++ API wrappers createProgramFromPTXFile() and createProgramFromPTXString(). You’ll find these inside the OptiX headers and examples.

OptiX will decompose the PTX code and replace the OptiX specific intrinsics (e.g. _rt_trace_64, _rt_buffer_get_64 and the like) with actual PTX code when generating the ray tracing kernel.

Just debug through some of the simple OptiX examples to see how the PTX code is used.
The OptiX Programming Guide explains more of these topics about the host API.

Also make sure the PTX code has been generated without any debug information (nvcc -g or -G options).

I basically only turned on the -rdc=true flag in Visual studio. Linking was turned on by defauly, and didn’t cause any issues until i set the rdc flag. Turning linking off solved it. Thanks!

Kind regards,
Erik