mitsuba-renderer / mitsuba3

Mitsuba 3: A Retargetable Forward and Inverse Renderer
https://www.mitsuba-renderer.org/
Other
2.1k stars 249 forks source link

illegal memory access when large amount of spheres. #1115

Closed free7187 closed 7 months ago

free7187 commented 8 months ago

Summary

illegal memory access when large amount of spheres.

System configuration

System information:

OS: Windows-10 CPU: Intel64 Family 6 Model 183 Stepping 1, GenuineIntel GPU: NVIDIA GeForce RTX 4090 Python: 3.10.9 | packaged by Anaconda, Inc. | (main, Mar 1 2023, 18:18:15) [MSC v.1916 64 bit (AMD64)] NVidia driver: 536.25 CUDA: 11.8.89 LLVM: 15.-1.-1

Dr.Jit: 0.4.4 Mitsuba: 3.5.0 Is custom build? False Compiled with: MSVC 19.38.33133.0 Variants: scalar_rgb scalar_spectral cuda_ad_rgb llvm_ad_rgb

Description

When I use python mitsuba to load a dict that contains about 10000 spheres, and render, I get

Critical Dr.Jit compiler failure: cuda_check(): API error 0700 (CUDA_ERROR_ILLEGAL_ADDRESS): "an illegal memory access was encountered" in D:\hch\experiment\3d_face\differentiable_boi_skin\mitsuba3\ext\drjit\ext\drjit-core\src\init.cpp:448.

with path integrator, 512 resolution and 16 spp, use cuda_ad_rgb.

Steps to reproduce

  1. use python to create a dict that contains about 10000 spheres with random translate transform in xyz range (-1, 1).
  2. load_dict and render
Speierers commented 8 months ago

Hi @free7187,

Could you maybe provide a simple reproducer for this issue? It is otherwise difficult to guess what's going wrong here.

Also, could you clarify whether those are mesh spheres or analytical spheres?

learner-shx commented 8 months ago

Hi @free7187,

Could you maybe provide a simple reproducer for this issue? It is otherwise difficult to guess what's going wrong here.

Also, could you clarify whether those are mesh spheres or analytical spheres?

Hi @Speierers, Sorry for unclear description, here is an example code to reproduce the issue.

import sys
sys.path.insert(0, "./mitsuba3/build/Release/python")
import mitsuba as mi
import drjit as dr

import time
import random

class SceneDescFactory:
    def __init__(self, spp, res, max_depth, integrator):
        self.scene_desc = {}
        # init scene
        self.init_scene_desc(spp, res, max_depth, integrator)

    def init_scene_desc(self, spp, res, max_depth, integrator):
        self.scene_desc = {
            "type": "scene",
            "sensor": {
                "type": "perspective",
                "fov_axis": "smaller",
                "near_clip": 0.001,
                "far_clip": 100,
                "focus_distance": 1000,
                "fov": 39.3077,
                "to_world": mi.ScalarTransform4f.look_at(
                    origin  =(0, 0, 4), 
                    target  =(0, 0, 0), 
                    up      =(0, 1, 0)
                    ),
                "sampler":{
                    "type": "independent",
                    "sample_count": spp
                },
                "film": {
                    "type": "hdrfilm",
                    "width": res,
                    "height": res,
                    "rfilter": {
                        "type": "tent"
                    },
                    "pixel_format": "rgb",
                    "component_format": "float32"
                }
            },
            "integrator": {
                "type": "direct",
            }
        }

    def merge_desc(self, *desc_list):
        merged_desc = {}
        for desc in desc_list:
            merged_desc = {**merged_desc, **desc}
        return merged_desc

    def get_debug_light_desc(self):
        light_desc = {
            "light": {
                "type": "obj",
                "filename": r".\mitsuba3\tutorials\scenes\meshes\cbox_luminaire.obj",
                "to_world": mi.ScalarTransform4f.translate((0, -0.01, 0)),
                "bsdf": {
                    "type": "diffuse",
                    "reflectance": {
                        "type": "rgb",
                        "value": [1, 1, 1]
                    }
                },
                "emitter": {
                    "type": "area",
                    "radiance": {
                        "type": "rgb",
                        "value": [18.387, 13.9873, 6.75357]
                    }
                }
            }
        }
        return light_desc

    def get_sphere_desc(self, index):
        sphere_desc = {
            f"sphere_{index}": {
                "type": "sphere",

                "bsdf": {
                    "type": "diffuse",
                    "reflectance": {
                        "type": "rgb",
                        "value": [0.105421, 0.37798, 0.076425]
                    }
                }
            }
        }
        return sphere_desc

    def get_scene_desc(self):
        return self.scene_desc

    def add_sphere(self, index):
        self.scene_desc[f"shpere_{index}"] = self.get_sphere_desc(index)[f"sphere_{index}"]

    def add_debug_light(self):
        self.scene_desc = self.merge_desc(self.scene_desc, 
                                          self.get_debug_light_desc())

mi.set_variant('cuda_ad_rgb')

sdf = SceneDescFactory(512, 512, 5, "prb")

start_time = time.time()
print(time.time() - start_time, " ----- editting sdf")
for i in range(10000):
    sdf.add_sphere(i)
sdf.add_debug_light()
dic = sdf.get_scene_desc()

print(time.time() - start_time, " ----- loading scene desc")
scene = mi.load_dict(sdf.get_scene_desc())
print(time.time() - start_time, " ----- traversing scene")
params = mi.traverse(scene)
print(time.time() - start_time, " ----- rendering")
image_ref = mi.render(scene, spp=512)
print(time.time() - start_time, " ----- end initial render" )

mi.Bitmap(image_ref[:, :, :]).write("test_sphere_ref.exr")

Place the file in mitsuba3's parent directory to assure it can find the relative paths correctly. Then it can be run. Thank you!

Speierers commented 8 months ago

Thanks for the reproducer. Before trying to run it next week, can you check whether this issue persist if all the spheres don't overlap perfectly? Also does this issue also occur on LLVM mode?

learner-shx commented 8 months ago

Thanks for the reproducer. Before trying to run it next week, can you check whether this issue persist if all the spheres don't overlap perfectly? Also does this issue also occur on LLVM mode?

I tried set to_world with random translate, the problem was gone, thank you.

njroussel commented 7 months ago

I can't reproduce this on either Embree/OptiX. I'll close this for now.

It's still quite likely that there is an underlying issue, if anyone comes across something similar we'll need to dig into this further.