Hi,
I’m currently running into an issue when trying to build a custom PyOptiX application. I started from the triangle.py example and then successfully modified the raygen and rayhit CUDA functions to what I wanted.
I then tried implementing changing vertices in the program duration by rebuilding or updating the GAS (tried both, and had the same issue with both). Strange square artefacts started appearing on my application on the first frame after GAS update. When trying to investigate, the validation mode always crashes at the first frame after GAS update. The error comes from one of the ray reflections implemented on my custom kernels, and hints at the fact that the triangle vertices are invalid (NaN in the reflexion vector coordinates).
To get back to a minimal example of the bug, I re-used the original raygen and rayhit CUDA functions so that my only modifications to the triangle.py example are the update() function that updates the GAS. The validation mode no longer crashes because there’s no secondary hit anymore, but strange artefacts appear in the geometry, which indicate that the vertex data is incorrect and would crash my more complicated closest_hit function.
Here is the picture of my scene before the GAS update (no artefact):
Here is the picture of my scene after the GAS update:
Here is how I build the Acceleration object :
class AccelState:
def __init__(self, ctx):
self.accel_options = optix.AccelBuildOptions(
buildFlags = int(optix.BUILD_FLAG_ALLOW_RANDOM_VERTEX_ACCESS | optix.BUILD_FLAG_ALLOW_UPDATE),
operation = optix.BUILD_OPERATION_BUILD
)
self.vertices = cp.array( [
-0.1, 0.1, -0.1,
0.1, 0.00, -0.1,
-0.1,-0.1, -0.1,
-1.0,-1.0,-1.0,
-1.0,-1.0, 1.0,
-1.0, 1.0, 1.0,
1.0, 1.0,-1.0,
-1.0,-1.0,-1.0,
-1.0, 1.0,-1.0,
1.0,-1.0, 1.0,
-1.0,-1.0,-1.0,
1.0,-1.0,-1.0,
1.0, 1.0,-1.0,
1.0,-1.0,-1.0,
-1.0,-1.0,-1.0,
-1.0,-1.0,-1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0,-1.0,
1.0,-1.0, 1.0,
-1.0,-1.0, 1.0,
-1.0,-1.0,-1.0,
-1.0, 1.0, 1.0,
-1.0,-1.0, 1.0,
1.0,-1.0, 1.0,
1.0, 1.0, 1.0,
1.0,-1.0,-1.0,
1.0, 1.0,-1.0,
1.0,-1.0,-1.0,
1.0, 1.0, 1.0,
1.0,-1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0,-1.0,
-1.0, 1.0,-1.0,
1.0, 1.0, 1.0,
-1.0, 1.0,-1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
1.0,-1.0, 1.0
], dtype = 'f4')
self.triangle_input_flags = [ optix.GEOMETRY_FLAG_NONE, optix.GEOMETRY_FLAG_DISABLE_ANYHIT ]
self.triangle_input = optix.BuildInputTriangleArray()
self.triangle_input.vertexFormat = optix.VERTEX_FORMAT_FLOAT3
self.triangle_input.numVertices = len( self.vertices )
self.triangle_input.vertexBuffers = [ self.vertices.data.ptr ]
self.triangle_input.flags = self.triangle_input_flags
self.triangle_input.numSbtRecords = 1;
self.gas_buffer_sizes = ctx.accelComputeMemoryUsage( [self.accel_options], [self.triangle_input] )
self.d_temp_buffer_gas = cp.cuda.alloc( self.gas_buffer_sizes.tempSizeInBytes )
self.d_gas_output_buffer = cp.cuda.alloc( self.gas_buffer_sizes.outputSizeInBytes)
self.gas_handle = ctx.accelBuild(
0, # CUDA stream
[ self.accel_options ],
[ self.triangle_input ],
self.d_temp_buffer_gas.ptr,
self.gas_buffer_sizes.tempSizeInBytes,
self.d_gas_output_buffer.ptr,
self.gas_buffer_sizes.outputSizeInBytes,
[] # emitted properties
)
#return (gas_handle, d_gas_output_buffer)
def update(self, ctx):
self.accel_options = optix.AccelBuildOptions(
buildFlags = int(optix.BUILD_FLAG_ALLOW_RANDOM_VERTEX_ACCESS | optix.BUILD_FLAG_ALLOW_UPDATE),
operation = optix.BUILD_OPERATION_UPDATE
)
self.gas_handle = ctx.accelBuild(
0, # CUDA stream
[ self.accel_options ],
[ self.triangle_input ],
self.d_temp_buffer_gas.ptr,
self.gas_buffer_sizes.tempSizeInBytes,
self.d_gas_output_buffer.ptr,
self.gas_buffer_sizes.outputSizeInBytes,
[] # emitted properties
)
And here is how I use that object :
def main():
triangle_cu = os.path.join(os.path.dirname(__file__), 'triangle.cu')
triangle_ptx = compile_cuda( triangle_cu )
ctx = create_ctx()
acc_state = AccelState(ctx)
pipeline_options = set_pipeline_options()
module = create_module( ctx, pipeline_options, triangle_ptx )
prog_groups = create_program_groups( ctx, module )
pipeline = create_pipeline( ctx, prog_groups, pipeline_options )
sbt = create_sbt( prog_groups )
euler = np.array([0.0, 0.0, 0.0])
r = R.from_euler('xyz', [[0, 0, 0]], degrees=True)
pygame.init()
screen = pygame.display.set_mode((pix_width, pix_height))
pygame.event.set_grab(not pygame.event.get_grab())
pygame.mouse.set_visible(False)
i = 0
while True:
i = i + 1
for event in pygame.event.get():
if event.type == pygame.MOUSEMOTION:
mov = pygame.mouse.get_rel()
euler += np.array([-mov[1], mov[0], 0.0]) / 3.0
r = R.from_euler('xyz', [euler], degrees=True)
pix = launch( pipeline, sbt, acc_state.gas_handle, np.zeros(3), r )
img = pygame.image.frombytes(pix.tobytes(), (pix_width, pix_height), "RGBA")
screen.blit(img, (0, 0))
pygame.display.flip()
#acc_state.update(ctx)
pygame.quit()
#print( "Total number of log messages: {}".format( logger.num_mssgs ) )
pix = pix.reshape( ( pix_height, pix_width, 4 ) ) # PIL expects [ y, x ] resolution
img = ImageOps.flip( Image.fromarray( pix, 'RGBA' ) ) # PIL expects y = 0 at bottom
img.show()
img.save( 'my.png' )
if __name__ == "__main__":
main()
You can find my complete main.py code in this gist.
Software versions:
➜ cudafe++ --version
cudafe: NVIDIA (R) Cuda Language Front End
Portions Copyright (c) 2005-2023 NVIDIA Corporation
Portions Copyright (c) 1988-2018 Edison Design Group Inc.
Based on Edison Design Group C/C++ Front End, version 6.3 (Jan 6 2023 16:45:23)
Cuda compilation tools, release 12.0, V12.0.140
OptiX SDK version: NVIDIA-OptiX-SDK-8.0.0-linux64-x86_64
PyOptiX bindings : got from git clone https://github.com/NVIDIA/otk-pyoptix
CMake Output from OptiX 8.0 compilation :
-- The C compiler identification is GNU 12.3.0
-- The CXX compiler identification is GNU 12.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/gcc-12 - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/g++-12 - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Deprecation Warning at CMakeLists.txt:94 (cmake_policy):
Compatibility with CMake < 3.5 will be removed from a future version of
CMake.
Update the VERSION argument <min> value or use a ...<max> suffix to tell
CMake that the project does not need compatibility with older versions.
-- Performing Test OPTIX_CXX_ACCEPTS_NO_CPP
-- Performing Test OPTIX_CXX_ACCEPTS_NO_CPP - Success
-- Performing Test OPTIX_CXX_ACCEPTS_NO_UNUSED_RESULT
-- Performing Test OPTIX_CXX_ACCEPTS_NO_UNUSED_RESULT - Success
-- Performing Test SSE_41_AVAILABLE
-- Performing Test SSE_41_AVAILABLE - Success
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Found CUDA: /usr (found suitable version "12.0", minimum required is "5.0")
-- Unsetting values associated with OptiX code generation
-- Resetting CUDA_NVRTC_FLAGS
sutil OPTIXIR
ptx_files = /home/alex/softwares/NVIDIA-OptiX-SDK-8.0.0-linux64-x86_64/SDK/build/lib/ptx/./sutil_generated_camera.cu.optixir;/home/alex/softwares/NVIDIA-OptiX-SDK-8.0.0-linux64-x86_64/SDK/build/lib/ptx/./sutil_gen
erated_geometry.cu.optixir;/home/alex/softwares/NVIDIA-OptiX-SDK-8.0.0-linux64-x86_64/SDK/build/lib/ptx/./sutil_generated_shading.cu.optixir;/home/alex/softwares/NVIDIA-OptiX-SDK-8.0.0-linux64-x86_64/SDK/build/lib
/ptx/./sutil_generated_sphere.cu.optixir;/home/alex/softwares/NVIDIA-OptiX-SDK-8.0.0-linux64-x86_64/SDK/build/lib/ptx/./sutil_generated_whitted.cu.optixir
-- Found OpenGL: /usr/lib/x86_64-linux-gnu/libOpenGL.so
CMake Deprecation Warning at support/GLFW/CMakeLists.txt:5 (cmake_minimum_required):
Compatibility with CMake < 3.5 will be removed from a future version of
CMake.
Update the VERSION argument <min> value or use a ...<max> suffix to tell
CMake that the project does not need compatibility with older versions.
-- Found Vulkan: /usr/lib/x86_64-linux-gnu/libvulkan.so
-- Using X11 for window creation
-- Found X11: /usr/include
-- Looking for XOpenDisplay in /usr/lib/x86_64-linux-gnu/libX11.so;/usr/lib/x86_64-linux-gnu/libXext.so
-- Looking for XOpenDisplay in /usr/lib/x86_64-linux-gnu/libX11.so;/usr/lib/x86_64-linux-gnu/libXext.so - found
-- Looking for gethostbyname
-- Looking for gethostbyname - found
-- Looking for connect
-- Looking for connect - found
-- Looking for remove
-- Looking for remove - found
-- Looking for shmat
-- Looking for shmat - found
-- Configuring done (1.9s)
-- Generating done (0.1s)
-- Build files have been written to: /home/alex/softwares/NVIDIA-OptiX-SDK-8.0.0-linux64-x86_64/SDK/build
Would appreciate some competent help on fixing this, please let me know if I can give any additional information!
Thank you,
Alex