Double Buffers in Optix
Hi All, I'd like to use a buffer that is made of doubles as my output for OptiX and OptiXPrime. But I haven't noticed any tutorials and can't find any buffer types that are double. Is there support for doubles? Thanks, Chris
Hi All,

I'd like to use a buffer that is made of doubles as my output for OptiX and OptiXPrime. But I haven't noticed any tutorials and can't find any buffer types that are double. Is there support for doubles?

Thanks,
Chris

#1
Posted 12/12/2017 12:00 AM   
For OptiX Prime there is no method to define the hit result formats. They are all hard-coded. For OptiX you can write any buffer format you'd like. While there is no pre-defined buffer format for doubles inside the RTformat enums (no RT_FORMAT_DOUBLE), there is the RT_FORMAT_USER enum which allows to define arbitrary buffer layouts, including whole structures. (Watch the CUDA data alignment rules though.) Means you could simply define something like this [code] optix::Buffer m_bufferDoubles; ... m_bufferDoubles = m_context->createBuffer(RT_BUFFER_OUTPUT, RT_FORMAT_USER); m_bufferDoubles->setElementSize(sizeof(double)); m_bufferDoubles->setSize(numberOfDoubles); // Example for a 1D buffer. (It's allowed for this size to be zero.) ... if (numberOfDoubles) { double* ptrDoubles = static_cast<double*>(m_bufferDoubles->map()); ... // Do something with the double data inside your buffer. m_bufferDoubles->unmap(); } [/code] That said, please note that the ray format, intersection distance, and the whole BVH traversal uses float precision internally in both OptiX and OptiX Prime APIs. You can't change that. The reason is simply performance. You could of course write device programs which use double precision elsewhere. You would need to change the nvcc command line options to retain the double precision calculations as needed. Carefully read the [b]nvcc --help[/b] for the --use_fast_math option, which is normally always recommended for OptiX device programs. Your code is going to get really slow, if the trigonometric functions don't use the fast approximation versions anymore. Additionally depending on the GPU you're using, double precision calculations can be comparably slow. Check the GPU specs before doing a purchase if your GPU compute use case requires double precision in device code!
For OptiX Prime there is no method to define the hit result formats. They are all hard-coded.

For OptiX you can write any buffer format you'd like. While there is no pre-defined buffer format for doubles inside the RTformat enums (no RT_FORMAT_DOUBLE), there is the RT_FORMAT_USER enum which allows to define arbitrary buffer layouts, including whole structures. (Watch the CUDA data alignment rules though.)

Means you could simply define something like this
optix::Buffer m_bufferDoubles;
...
m_bufferDoubles = m_context->createBuffer(RT_BUFFER_OUTPUT, RT_FORMAT_USER);
m_bufferDoubles->setElementSize(sizeof(double));
m_bufferDoubles->setSize(numberOfDoubles); // Example for a 1D buffer. (It's allowed for this size to be zero.)
...
if (numberOfDoubles)
{
double* ptrDoubles = static_cast<double*>(m_bufferDoubles->map());
... // Do something with the double data inside your buffer.
m_bufferDoubles->unmap();
}

That said, please note that the ray format, intersection distance, and the whole BVH traversal uses float precision internally in both OptiX and OptiX Prime APIs. You can't change that. The reason is simply performance.

You could of course write device programs which use double precision elsewhere. You would need to change the nvcc command line options to retain the double precision calculations as needed. Carefully read the nvcc --help for the --use_fast_math option, which is normally always recommended for OptiX device programs. Your code is going to get really slow, if the trigonometric functions don't use the fast approximation versions anymore.

Additionally depending on the GPU you're using, double precision calculations can be comparably slow.
Check the GPU specs before doing a purchase if your GPU compute use case requires double precision in device code!

#2
Posted 12/12/2017 09:05 AM   
Thanks for the reply and the tips about double precision! I think I read somewhere that you guys don't comment on upcoming releases but, in case you can, are there any plans to make double precision an option internally? I'm researching writing a radar/communications simulation and in general single precision just doesn't cut it. I'm confident I've found a work-around but I figured I'd ask anyway. Thanks again for the quick reply! -Chris
Thanks for the reply and the tips about double precision!

I think I read somewhere that you guys don't comment on upcoming releases but, in case you can, are there any plans to make double precision an option internally? I'm researching writing a radar/communications simulation and in general single precision just doesn't cut it. I'm confident I've found a work-around but I figured I'd ask anyway.

Thanks again for the quick reply!

-Chris

#3
Posted 12/12/2017 03:13 PM   
There are no changes to the internal data formats in the upcoming version. If you have double precision input values for your geometry, you would need to adjust AABB sizes in the bounding box program to be sure that they actually contain the data, which means the AABB needs to round up to the outsides a little to make sure the double precision geometry is properly contained. Then you could write your intersection program to use double precision, if that's what you need, and since the resulting intersection distance is float, you would need to put the double precision result into an attribute to have that available inside the closest hit or any hit programs. Depending on the floating point ranges involved in the scene, you might also need to check if the floating point t_min and t_max values on the ray require similar rounding to make sure the interval covers the proper range. The rest would work as usual. In your closest hit program store the required data into the per ray payload and the ray generation program would finally output it to the double precision output buffer.
There are no changes to the internal data formats in the upcoming version.

If you have double precision input values for your geometry, you would need to adjust AABB sizes in the bounding box program to be sure that they actually contain the data, which means the AABB needs to round up to the outsides a little to make sure the double precision geometry is properly contained.
Then you could write your intersection program to use double precision, if that's what you need, and since the resulting intersection distance is float, you would need to put the double precision result into an attribute to have that available inside the closest hit or any hit programs.
Depending on the floating point ranges involved in the scene, you might also need to check if the floating point t_min and t_max values on the ray require similar rounding to make sure the interval covers the proper range.
The rest would work as usual. In your closest hit program store the required data into the per ray payload and the ray generation program would finally output it to the double precision output buffer.

#4
Posted 12/13/2017 08:17 AM   
Scroll To Top

Add Reply