SetAcceleration fails after upgrading from 3.9.1 to 4.0.0

Hi,

After updating the version of Optix from 3.9.1 to 4.0.0 I’m experiencing error in SetAcceleration.
the error is :
{m_message=“Invalid context (Details: Function “_rtGeometryGroupValidate” caught exception: Validation error: Traverser not set, [1704431])” …} optix::Exception &

what should I do?

asi.

rtGeometryGroupValidate checks the GeometryGroup node for completeness.
In that old API you would have normally set the acceleration traverser and builder (something like “Bvh” or “Trbvh”).
Please check if you did everything to build the proper acceleration structure for that GeometryGroup before calling rtGeometryGroupValidate.

Newer OptiX version do not need to set the acceleration traverser. That is always derived from the acceleration builder type.

OptiX 4.0.0 was a pretty big change over OptiX 3.9.1 because the OptiX core implementation was completely rearchitected.
Note that it OptiX 4 dropped support for Fermi GPUs. It supports Kepler to Pascal GPU architectures.
Given that, OptiX 5 also supports Kepler, it doesn’t make sense to use OptiX 4 at all when migrating from 3.9.1.
In any case, when moving to a newer major OptiX SDK version it’s recommended to use the newest available OptiX SDK release, in your case 4.1.1. Maybe it was a bug fixed in later versions?
That said, at this time I would also skip OptiX 5 completely because that doesn’t support the hardware acceleration introduced by the RT cores inside the Turing and Ampere RTX boards

  • If you still need to support Fermi GPU just stay with OptiX 3.9.1.
  • If you need to support Kepler GPUs, stay with OptiX 5.1.x.
  • For anything newer and especially for RTX hardware acceleration, use either OptiX 6.5.0 or OptiX 7.x

Note that OptiX 7 uses a very different header-only host and device API which is explicit, more modern and flexible, multi-threading safe, and provides overall faster performance. These support the Maxwell GPU architecture and newer and the core OptiX implementation ships with the display driver. Means any improvements in the OptiX core will automatically effect existing OptiX 6.5 or 7.x applications without the need to recompile or ship newer libraries.
https://raytracing-docs.nvidia.com
https://forums.developer.nvidia.com/t/porting-to-optix-7/79249

so, in optix 4.0.0 we can remove the set acceleration?

You need to set the acceleration builder for sure. It depends on what the OptiX 4 API requires if there is still a rtAccelerationSetTraverser call. I don’t have any OptiX 4 documentation installed. It doesn’t exist inside OptiX 5.1.0 anymore.
And of course you need to set the acceleration structures to all OptiX nodes with “Group” in the name to build a valid OptiX render graph. (See rtGeometryGroupSetAcceleration and rtGroupSetAcceleration).

Again, please do not use OptiX 4.0.0 at all. It’s from 2016 and had six updates. Instead just skip the whole OptiX major 4 versions altogether. It doesn’t make any sense using that today given that OptiX 5.1.x supports Kepler GPUs as well and more GPU architectures. For current RTX boards even that doesn’t make sense. I cannot support that.

I’m using now optix 5.1.0 as you suggested and I have an error in the function :rtProgramCreateFromPTXFile. the ptx is triangle_mesh of NVIDIA.
what should I do.

Start by providing the usual system configuration information with any OptiX issue:
OS version, installed GPU(s), display driver version, OptiX version (major.minor.micro), CUDA Toolkit version used to compile the input PTX code, host compiler version.

Have you read the OptiX Release Notes for the version you’re targeting?
It contains information about which GPU architecture, minimum display driver version, and CUDA toolkit versions are supported for each individual OptiX version.
Maybe your display drivers are too old?

Then add all necessary information required to understand what you did, what happened instead of the expected result, and what you already tried to resolve it. That includes providing exact error and warning messages.

For example:
With which CUDA toolkit did you generate the PTX code?
What was the target streaming multiprocessor version? (Try building for Kepler (SM 3.0) if it was lower.)
Can the issue be reproduced with one of the OptiX SDK examples?

these are the properties of my configuration:
cuda version 7.0
optix version 5.1.0
windows 10
GPU NVIDIA GFORCE GTX 960 - Maxwell
driver 456.55
visual studio 2013

I read the notes provided by nvidia 5.1.0.
this problem didn’t show when the compilation was done with 3.9.1 optix. I didn’t change the cuda version on my computer.
the compilation succeeded however when running the program the error showed up.
it did not succeeded to create the program from the ptx file and it happens only with triangle_mesh.cu with the functions inside it (mesh_bounds and mesh_intersect).
hope that the provided details will help to understand the problem.

thanks,

asi.

CUDA 7.0 isn’t producing the best code from my experience. For OptiX 5 on MSVS 2013 I would use CUDA 9.0 (but not 9.2).

You didn’t answer the last two questions:
What was the target streaming multiprocessor version? (Try building for Kepler (SM 3.0) if it was lower.)
Maybe post the resulting PTX code as well.

Can the issue be reproduced with one of the OptiX SDK examples?
All OptiX SDK 5.1.0 example programs using the OptiXMesh helper class (e.g. optixMeshViewer, optixDynamicGeometry) as well as optixPrimitiveIndexOffsets are using the triangle_mesh.cu code.
I’m able to build and run the OptiX SDK 5.1.0 examples just fine using MSVS 2015 and CUDA 10.2 (actually too new for OptiX 5.1.0) on a Quadro P6000 (Pascal) with 451.48 drivers. I don’t have older versions.

when running the program the error showed up.

I assume you’re actually running the program from within the debugger, right?
Again, what exact error is returned by the failing rtProgramCreateFromPTXFile?

  • RT_ERROR_INVALID_CONTEXT
  • RT_ERROR_INVALID_VALUE
  • RT_ERROR_MEMORY_ALLOCATION_FAILED
  • RT_ERROR_INVALID_SOURCE
  • RT_ERROR_FILE_NOT_FOUND

//
// Generated by NVIDIA NVVM Compiler
//
// Compiler Build ID: CL-19324574
these line where copied from the ptx triangle_mesh
// Cuda compilation tools, release 7.0, V7.0.27
// Based on LLVM 3.4svn
//

.version 4.2
.target sm_20
.address_size 64

the ERROR -
m_message=“Unknown error (Details: Function “_rtProgramCreateFromPTXFile” caught exception: Compile Error: All calls to rtPotentialIntersection must be paired with
a call to rtReportIntersection)”

Ok, that’s the right information for a developer forum question.

Means you compiled with CUDA 7.0 for SM 2.0 (Fermi) for 64-bit. That’s ok.
You could use SM 3.0 (Kepler) here because lower architectures aren’t supported by OptiX 5.

The error message indicates an error inside the intersection shader.
I have seen that long ago when moving from very old OptiX SDKs to newer ones.

The newer OptiX SDKs added a check which makes sure that all calls to rtReportIntersection are only happening inside a code block which is guarded by an rtPotentialIntersection conditional. That was not the case in very early SDK versions.

The mesh_intersect shader in OptiX SDK 3.9.1 looks fine on first glance. Maybe yours is even older?

Please compare all occurrences of the rtPotentialIntersection and rtReportIntersection calls in your mesh_intersect() shader against the implementation in OptiX 5.1.0 which didn’t show that issue.

The structure must always be

if (rtPotentialIntersection(t))
{
  // Calculate vertex attributes here!
  // They are only valid between an rtPotentialIntersection and rtReportIntersection pair.
  ...
  rtReportIntersection(materialIndex);
}

Finally, if you’re working on a Maxwell board and do not need to support older GPU architectures, you can also use OptiX 6.5.0, or long term even port to OptiX 7.

hi, I changed the sm to 3.0
and now the error is "+ sFilePath const std::basic_string<char,std::char_traits,std::allocator > &
"
I also noticed that although optix 5.1 utilizes the optix51.dll and optixu1.dll after compilation optix1.dll is being added to the directory. maybe it change something ?

You would need to provide much more information to let outsiders grasp what you did and and why anything happens with your code.
Means I have not the slightest idea where that error comes from or why there is any error like this.
(sFilePath is not appearing inside the OptiX SDK 5.1.0 source files.)

Is that from your own program?
Did the CUDA to PTX compilation fail and this time a *.ptx file wasn’t found or what?

Let’s take a step back:
Are you able to build and run the OptiX SDK 5.1.0 examples yourself, like the optixMeshViewer?
If yes, then there shouldn’t be a problem getting your older OptiX program to be ported.

I would recommend fixing the original intersection shader error first, before changing more things.
After that works, you can try changing all CUDA to PTX compilation steps to SM 3.0.
After that works, you can update to the CUDA 9.0 toolkit.
After that works, you can update to OptiX 6.5.0 because you’re on a Maxwell GPU.
After that works, you can change the implementation to use built-in triangles and attribute programs instead of the custom triangle primitives for better performance, esp. on RTX boards.

I also noticed that although optix 5.1 utilizes the optix51.dll and optixu1.dll after compilation optix1.dll is being added to the directory. maybe it change something ?

OptiX 5.1.0 based application must link against the optix.51.lib and optionally against the optixu.1.lib if you’re using that. Both are inside the OptiX SDK 5.1.0\lib64 folder.
Then OptiX 5.1.0 based applications need to be shipped with the optix.51.dll and optionally the optixu.1.dll from the OptiX SDK 5.1.0\bin64 folder.

The optix.1.dll is from a previous OptiX version (like 3.9.1) and you should neither link to any optix.1.lib in your OpitX 5.1.0 based project, nor should there be any includes or other dependencies from previous OptiX versions left in your whole project, including potential post-build steps which copy DLLs around, if that is done.

The easiest way to determine if there is an unwanted dependency would be to rename all older OptiX SDK folders and then rebuild your whole project source.
If the project is using CMake, delete the project’s CMake cache and configure and generate your whole solution from scratch. Don’t forget to pick x64 as architecture.
If either fails because of missing includes or libraries, you need to fix your project.
Means if it’s CMake based fix the scripts setting these folders and libraries .
If it’s a plain MSVS solution, look through all include directories and link libraries settings (for all build targets!) and replace all old versions with the new paths and names, until the project builds again. (That is easier to do inside another text editor, not the MSVS IDE, on the *.vcproj text file.)

below is the code of triangle_mesh maybe something is wrong there?

#include <optix_cuda.h>
#include <optixu/optixu_math_namespace.h>
#include <optixu/optixu_matrix.h>
#include <optixu/optixu_aabb.h>
#include “helpers.h”

// Ray data
rtDeclareVariable( optix::Ray, ray, rtCurrentRay, );

// Attributes to communicate with shader programs
rtDeclareVariable( float2, texcoord, attribute texcoord, );
rtDeclareVariable( float3, geometric_normal, attribute geometric_normal, );
rtDeclareVariable( uint, geometric_uniqueID, attribute geometric_uniqueID, );
rtDeclareVariable( uint, geometric_inclusionID, attribute geometric_inclusionID, );
rtDeclareVariable( unsigned char, geometric_inclusionDescription, attribute geometric_inclusionDescription, );
rtDeclareVariable( float, geometric_cloudAbsorptionFactor, attribute geometric_cloudAbsorptionFactor, );
rtDeclareVariable( int, geometric_facetID, attribute geometric_facetID, );

// Externally set API vars
rtDeclareVariable( uint, m_ID, , ) = 0; //u // the unique ID of the object (unsigned int)
rtDeclareVariable( uint, m_uInclusionID, , ) = 0; //u // the inclusion ID of the object (unsigned int)
rtDeclareVariable( unsigned char, m_cIncDescription, , ) = 0;//u // uchar simulating Inclusion::DescriptionEnum
rtDeclareVariable( float, m_fCloudAbsorptionFactor, , ) = 1.f; // 1 / [ % of absorption relative to regular diamond ] ^ 4 , relevant only if geometric_inclusionDescription == eCloud

// Geometry description
rtBuffer vertex_buffer; // vertex list
rtBuffer texcoord_buffer; // texture-map coords for each vertex. ** May alternatively be empty if texture doesnt exist **
rtBuffer vindex_buffer; // facets list (each int3 holds indexes of vertices composing a single triangle facet)
rtBuffer material_buffer; // material index for each facet. ** May alternatively be empty if all facets are same material **
rtBuffer facet_id_buffer; // id for each facet. ** May alternatively be empty if no ids are provided **

// This is to be plugged into an RTgeometry object to represent
// a triangle mesh with a vertex buffer of triangle soup (triangle list)
// with an interleaved position, normal, texturecoordinate layout.
RT_PROGRAM void mesh_intersect( int primIdx )
{
const int3& v_idx = vindex_buffer[primIdx];

const float3& p0 = vertex_buffer[v_idx.x];
const float3& p1 = vertex_buffer[v_idx.y];
const float3& p2 = vertex_buffer[v_idx.z];

// Intersect ray with triangle
volatile float fZero = 0.f;
float3 n = make_float3( fZero, fZero, fZero );
float t = RT_DEFAULT_MAX,				// ray parametric equation:  origin + t * direction
	fBeta = fZero, fGamma = fZero;		// barycentric coordinates of intersection point
if ( TriangleIntersection( ray, p0, p1, p2, n, t, fBeta, fGamma ) )
{
	if ( rtPotentialIntersection( t ) )
	{
		// Geometric Attributes
		geometric_normal = intrinsicNormalize( n );
		geometric_uniqueID = m_ID;
		geometric_inclusionID = m_uInclusionID;
		geometric_inclusionDescription = m_cIncDescription;
		geometric_cloudAbsorptionFactor = m_fCloudAbsorptionFactor;
		if ( facet_id_buffer.size() == 0 )  //u
			geometric_facetID = 0;
		else
			geometric_facetID = facet_id_buffer[primIdx];

		// Texture
		if ( texcoord_buffer.size() == 0 )  //u
		{
			texcoord = make_float2( fZero, fZero );
		}
		else
		{
			const float2& t0 = texcoord_buffer[v_idx.x];
			const float2& t1 = texcoord_buffer[v_idx.y];
			const float2& t2 = texcoord_buffer[v_idx.z];
			texcoord = t1*fBeta + ( t2*fGamma ) + t0*( 1.f - fBeta - fGamma );
		}

		if ( material_buffer.size() == 0 ) //u
			rtReportIntersection( 0 );  //u
		else
			rtReportIntersection( material_buffer[primIdx] );
	}
}

}

RT_PROGRAM void mesh_bounds (int primIdx, float result[6])
{
const int3& v_idx = vindex_buffer[primIdx];

const float3& v0 = vertex_buffer[ v_idx.x ];
const float3& v1 = vertex_buffer[ v_idx.y ];
const float3& v2 = vertex_buffer[ v_idx.z ];

const float3 n = cross( v1 - v0, v2 - v0 );
const float  fPseudoArea = dot( n, n );

optix::Aabb* aabb = ( optix::Aabb* )result;
if ( fPseudoArea > 0.0f && !isinf( fPseudoArea ) )
{
	aabb->m_min = fminf( v0, v1, v2 );
	aabb->m_max = fmaxf( v0, v1, v2 );
}
else 
	aabb->invalidate();

}

Yes, that intersection shader is exactly the problem.

As explained before, rtPotentialIntersection and rtReportIntersection need to be paired exactly. But that shader contains two invocations of rtReportIntersection for one rtPotentialIntersection which is not matching the stricter requirements in newer OptiX SDKs.

You would need to change this code:

if ( material_buffer.size() == 0 ) //u
    rtReportIntersection( 0 );  //u
else
    rtReportIntersection( material_buffer[primIdx] );

to something like this:

 int materialIndex = 0;
 if (material_buffer.size() != 0)
 {
     materialIndex = material_buffer[primIdx];
 }
 // or this: const int materialIndex = (material_buffer.size() == 0) ? 0 : material_buffer[primIdx];
 rtReportIntersection(materialIndex); 

Also what’s up with all the rtBuffer declarations?
They are missing the type and size template arguments. I’m not sure why this is working at all.
As said before, compare your shaders with the implementation in OptiX 3.9.1 or OptiX 5.1.0.
For one example:

rtBuffer vertex_buffer;

should be declared as:

rtBuffer<float3, 1> vertex_buffer;  // float3, 1D buffer, or this:
rtBuffer<float3>    vertex_buffer;  // 1D is the default rtBuffer dimension, this works as well.

If that all works, make your way though the other changes until you arrive at OptiX 6.5.0.
(If you’re using Selector nodes those are not supported inside OptiX 6 and higher.)

thanks. this bug is solved.
now I have another bug in a different cu function :

“Unknown Value when trying to figure out pointer space for ray payload argument to rt_trace”

what does this mean?

It’s not possible to tell what exactly is wrong without seeing the failing code.
Does that error message actually say rt_trace or rtTrace?

I would guess you’re trying to use a pointer to some OptiX variable or attribute declared with rtDeclareVariable, which is simply not allowed.

Please read the OptiX 5.1.0 Programming Guide chapter 4.1.2 Communication through variables which explains this and one possible solution.
If it’s that case, either change your code to use call-by-value arguments, or if you must use a pointer, use a local copy of the declared variable and a pointer to that local copy as shown in the programming guide.