mitsuba-renderer / drjit

Dr.Jit — A Just-In-Time-Compiler for Differentiable Rendering
BSD 3-Clause "New" or "Revised" License
593 stars 43 forks source link

dr.gather(mi.Vector3f, ...) with empty indices crashes #169

Closed lkskstlr closed 1 year ago

lkskstlr commented 1 year ago

I found the below crash, which is easy enough to work around but still wanted to post it for reference.

Thanks Lukas

import mitsuba as mi

mi.set_variant("cuda_ad_rgb")
import drjit as dr

print(f"{mi.variant()=}")
print(f"{mi.__version__=}")
print(f"{dr.__version__=}")

x = dr.linspace(mi.Float, 0, 1)
v = dr.linspace(mi.Vector3f, 0, 1)
idx = dr.zeros(mi.UInt32, 0)

# Works fine
print(dr.gather(type(x), x, idx).numpy())

# Will crash
print(dr.gather(type(v), v, idx).numpy())
mi.variant()='cuda_ad_rgb'
mi.__version__='3.3.0'
dr.__version__='0.4.2'
[]

Critical Dr.Jit compiler failure: jit_eval_literal(): unsupported variable type!
[1]    210609 IOT instruction (core dumped)  python tests/mitsuba_crash_01.py
njroussel commented 1 year ago

Hi @lkskstlr

The dr.linspace function is meant to be used on 1-dimensional types (documentation). We unfortunately don't type check the arguments :slightly_frowning_face:.

lkskstlr commented 1 year ago

Hi @njroussel,

thanks for the quick answer. Good to know for the linspace. The linspace was only for the example, as said the main thing is the crash on the gather.

Here is the code with zeros instead of linspace:

import mitsuba as mi

mi.set_variant("cuda_ad_rgb")
import drjit as dr

print(f"{mi.variant()=}")
print(f"{mi.__version__=}")
print(f"{dr.__version__=}")

x = dr.zeros(mi.Float, 1)
v = dr.zeros(mi.Vector3f, 1)
idx = dr.zeros(mi.UInt32, 0)

print(x, v)

# Works fine
print(dr.gather(type(x), x, idx).numpy())

# Will crash
print(dr.gather(type(v), v, idx).numpy())
mi.variant()='cuda_ad_rgb'
mi.__version__='3.3.0'
dr.__version__='0.4.2'
[0.0] [[0.0, 0.0, 0.0]]
[]

Critical Dr.Jit compiler failure: jit_eval_literal(): unsupported variable type!
[1]    228864 IOT instruction (core dumped)  python tests/mitsuba_crash_01.py
njroussel commented 1 year ago

Sorry, I read through it too quickly and didn't pay attention to the title. I thought the issue was caused by the partially uninitialized Vector3f.

I'm able to reproduce the issue. The gather operation seems fine, it's actually the numpy conversion that is causing a crash. In any case, I don't think we want to actively support empty variables in all DrJit operations but rather leave this checking to the user.

However, I do not have the same error message as you. Are you using a custom build? What platform are you executing the reproducer on? On my end the error message is a bit more explicit about the fact that there is an operation involving a 0-sized variable.

lkskstlr commented 1 year ago

@njroussel thanks for looking into it. Yes, I am using a custom build on the platform shown below.

Makes sense that you don't want to support this, I am already checking for it now and will close the issue.

Have a nice week Lukas

lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.2 LTS
Release:        22.04
Codename:       jammy

nvidia-smi -L         
GPU 0: NVIDIA GeForce RTX 3090 (UUID: GPU-40c9d0bd-8236-b770-e451-c49f2ac87239)
GPU 1: NVIDIA GeForce RTX 3090 (UUID: GPU-2899accb-22e8-cae2-8a12-1bc832b6b816)
njroussel commented 1 year ago

Great !

For anyone wondering about how to check for a variable's vectorization size/width, there are multiple ways to do it but I'd recommend using dr.width(your_variable).