Bazelizing Open Image Denoise — Part 1: The journey begins

Vertexwahn
4 min readFeb 25, 2023

--

bazelizing, bazelization, to bazelize, bazelized: The act of converting some existing software artifact to be easily consumed by the Bazel build tool

How is denoising helpful?

Sometimes ray-traced images converge very slowly. Deep learning can help to implement denoisers that take as an input only a few samples and generate from that a denoised image. Usually, an offline renderer expects a certain number of samples that should be traced for each pixel (sample per pixel = ssp). The following figure shows how denoising can help to generate from a noisy image a denoised image:

The first row shows images rendered with different sample counts (1 spp, 2 spp, 4 spp, 8 spp, 16 spp. 32 spp). The second row shows the corresponding denoised images from the top row using Intel Open Image Denoise.

Denoising is quite often faster than using high sampling rates and can therefore be used for example as a preview to give a user a first impression of how the final rendered image will look like. This way long rendering times can be avoided.

Denoising open-source middleware

Intel Open Image Denoise is an open-source denoising library. Besides this, there is Nvidia’s OptiX denoiser which can also be integrated into own applications. Furthermore, there is a ton of papers and reference implementations of all kinds of denoisers around. I decided to give Open Image Denoise a try. In the following, I will only focus on this denoiser. If you know any other good denoisers that support ray tracing, have high quality, and come maybe also with Bazel support please let me know.

Open Image Denoise: From CMake to Bazel

The build system of Open Image Denoise is CMake. Instead of CMake I want to use Open Image Denoise using Bazel. This requires to bazelize Open Image Denoise first.

I made two attempts to do this:

  1. I create a branch named add-bazel-support of Open Image Denoise with Bazel support
  2. I created rules_oidn

First approach: Bazelizing Open Image Denoise

I forked the Open Image Denoise repository on GitHub and create in my fork a branch named add-bazel-support. I created also very early on a pull request to the official GitHub Open Imge Denosieproject to see If this would be accepted as an “official” change (additional support of Bazel build system). Unfortunately, there was no interest in having those changes in the official main branch and the PR was rejected.

Second approach: rules_odin

Since my changes were not going into the official main branch of oidn, I decided to create rules_oidn. This leaves the original repository untouched and gives Bazel users the opportunity to use Open Image Denoise within their Bazel builds. Nevertheless, this solution has some drawbacks. It is a bit more cumbersome since it makes things like debugging more difficult. I personally would prefer to add Bazel support directly to the official main branch, to be honest. The worst thing that could happen is that the Bazel build breaks in the future. In this case, Bazel support could easily be dropped (by deleting Bazel related files such as BUILD, WORKSPACE, etc.), if no one supports it further. In the best case, the library would spread more widely because there would be a second build system now in town.

Problems with both approaches

After I bazelized both approaches I was happy to try them out on some renderings. Unfortunately. it turned out that my denoised images contain always black stripes:

It seems that the black stripes are always 5 pixels wide followed by 3 correct-looking color stripes. I did go back to CMake to test the same data. If I run the CMake generated Visual Studio solution everything works as expected, i.e. there are very no black stipes, and the denoised image looks correct.

Outlook: Finding a needle in a haystack

Currently, I am not sure if there are any problems with handing over memory to ISPC or doing the Filter Operation, etc. Since I tested different image formats (OpenEXR, PFM), I assume that the error is not within my way of storing images. Nevertheless, it feels like finding a needle in a haystack. Regarding this, I opened also a question on StackOverflow.

I tried a few things to find the error. I did a debugging session where I tried to compare the CMake build to the Bazel build.

Debugging on Bazel vs. CMake build of oidn

Until now, I was not able to spot the difference between the CMake and Bazel build. My feeling is that is something small like some variable that should be set to 64 instead of 32. Not sure: we will see if this gets fixed in the future.

--

--