Not including all program groups in pipeline creation


I was having an issue with the optixTrace call in my OpitX 7.0.0 app, however I finally found the problem was the miss program group not being included in the OptiX pipeline creation. Since I was following the optixWhitted sample, I wonder why it works fine without including the radiance_miss_prog_group and occlusion_miss_prog_group in the std::vector program_groups variable that is later used to the optixPipelineCreate call.

Looking for differences with my app, I found that my miss program is defined in a different .cu file (and different OptixModule), whereas in the sample it shares the same module with the rest of hitgroup programs. If I do the same in my app, it also works fine without having to include the miss program group in the optixPipelineCreate call. My question is if this is the expected behaviour.

Thanks in advance!

My environment:
Windows 10, x64
Nvidia GTX 750Ti
Driver version: 441.87
CUDA 10.1
OptiX 7.0.0


What is the issue you’re seeing when you say it’s not working, and what is the behavior when it is working but the miss programs are not there?

I’m totally unsure whether I’m reading or understanding the question correctly at all, but this might just boil down to whether the miss program is called or not? If you have null pointers in your SBT, then those programs are silently not called. Bad pointers in your SBT will only cause problems if the program is invoked, so you can leave the miss programs out, even if you include pointers to them, if all pixels in the image hit something. Would that explain what you’re seeing?


Hi @dhart!

I’m sorry about my question being a little bit confusing, I will try to explain better:

For now, let’s forget about my application and focus on the optixWhitted sample. In the optixWhitted.cpp, the optixPipeline is created this way:

OPTIX_CHECK_LOG( optixPipelineCreate(
        static_cast<unsigned int>( program_groups.size() ),
        &state.pipeline ) );

where program_groups is supposed to contain all needed OptixProgramGroups. Those are created in these funcions:

createCameraProgram( state, program_groups );
createGlassSphereProgram( state, program_groups );
createMetalSphereProgram( state, program_groups );
createFloorProgram( state, program_groups );
createMissProgram( state, program_groups );

If you check them, they create different OptixProgramGroup variables and push_back() them into the program_groups vector, except the last function, where the “program_groups” input argument is unused.

The sample works perfectly fine, and the miss program is being invoked well (I tried to change background colour and works perfectly), but I would expect it to give an error because of the miss programs not being included in the program_groups variable that is later used to the optixPipelineCreate call.

The problem I had with my application was that, like in this sample, I forgot to push_back() my miss program into the program_groups vector, however, I got a “cudaErrorLaunchFailure” after the optixLaunch call. Once I added the miss program to the program_groups vector, my app run without errors.

Trying to understand better why the optixWhitted sample works without miss programs being included in the optixPipelineCreate call, I did a little bit of research and I found that in my app, the miss program is written in a separate .cu file, whereas in the optixWhitted it shares the same .cu with the rest of hitgroup programs. After moving my miss program to the same .cu as my intersection program, I was able to run the application fine without having to include the miss program in the program_groups vectors used for pipeline creation.

In my test, I had no geometry, so the miss program was being invoked for all rays.

I hope it is more clear now, but let me know if you want me to explain something better.

Thanks for your time, I really appreciate!

PD: sorry for the super-long post ;)

Gah, this is definitely a bug in the whitted sample! I’m fixing it now.

This makes complete sense today, I was low on sleep yesterday. No apology necessary, thank you for the clear explanation.

This behavior is known, but I wouldn’t say it’s expected. It’s a bit like deleting and then de-referencing a pointer; sometimes it’ll work accidentally because the data is still in memory, but it’s definitely not recommended or correct. The reason this behavior is accidentally working is because OptiX compiles & links everything in the compilation unit whether you asked for it or not, but it can’t link something from another compilation unit unless you’ve asked for it explicitly. We are someday probably going to optimize this so that things you didn’t list explicitly won’t end up compiled & linked. (Currently unused functions in your pipeline can affect the performance of your pipeline.) When this optimization happens, then you will get an error if you forget to put one of the programs in program groups list. I’ll check whether this is something that OptiX could throw an error for, and if so add it to our todo list.


Thank you very much for the explanation @dhart, I understand it better now.

Regards :)