neural demosaicing/denoising for intel and amd

hi all,

as you might have seen, vkdt uses an external compiler to generate performant spir-v and a gpu dispatch schedule from onnx to implement fast inferencing. this is used in the joint demosaicing and denoising module, jddcnn. this one runs in 45ms on a 100MP bayer image/10ms for 16MP xtrans on an RTX4080S.
there is now also the open image denoise, oidn module. this is a direct implementation of attila afra’s excellent denoising system, currently using the sdr rgb → rgb model (i.e. no sidecar channels, low dynamic range, and no mosaic/raw data).

so far, vkdt shipped with optimised schedules for my nvidia gpu, but the compiler has now been released, so it’s now possible to create fast schedules for your own gpu!

some instructions and the source files can be found in the vkdt neural resource repository.

let me know if you’d like to try, i’d be happy to upstream good schedules for intel and amd, so everybody profits :slight_smile:

@niklasiivari i know you attempted to run this on intel before, i’m curious whether you’d still need the memory and subgroup changes from here to make it run!

4 Likes

Hi, thank you for your work on this, will definitely try it out when I have time and report back!

1 Like

I was trying to compile them for my RTX 3080. The ./compile-dnx.sh runs without problems after I compiled denox, but in the compile-vkdt.sh script it uses the vkdt-denox executable. Where can I find this? AFAIK it is not included in the regular vkdt build?

oops, seems the github repo is still private. i put a mirror here: hanatos/vkdt-denox: denox codegen for vkdt - Codeberg.org

if you manage to compile the module for the RTX 3080 i’d be curious to hear whether it’s any faster than the version currently checked into git as “nvidia”. this one i built for an RTX4080S and from what denox query-device-info can tell it’s equivalent to an RTX3080. so speed differences might be due to maybe memory bandwidth? don’t know whether the register file/shared memory grew between architectures. you can read out latencies with vkdt -d perf.

[perf] jddcnn   input   :	   9.115 ms
[perf] jddcnn   nxtrc3  :	   8.819 ms
[perf] jddcnn   weights :	   0.695 ms
[perf] jddcnn   nxtrc7  :	  14.428 ms
[perf] jddcnn   nxtrc8  :	  11.786 ms
[perf] jddcnn   nxtrc12 :	   4.498 ms
[perf] jddcnn   nxtrc15 :	   3.293 ms
[perf] jddcnn   nxtrc5  :	   2.517 ms
[perf] jddcnn   nxtrc18 :	   2.695 ms
[perf] jddcnn   nxtrc9  :	   1.808 ms
[perf] jddcnn   nxtrc16 :	   2.993 ms
[perf] jddcnn   nxtrc20 :	   2.665 ms
[perf] jddcnn   nxtrc11 :	   2.317 ms
[perf] jddcnn   nxtrc17 :	   9.355 ms
[perf] jddcnn   nxtrc9  :	   2.019 ms
[perf] jddcnn   nxtrc13 :	   1.975 ms
[perf] jddcnn   nxtrc19 :	   3.807 ms
[perf] jddcnn   nxtrc2  :	   2.261 ms
[perf] jddcnn   nxtrc0  :	   4.104 ms
[perf] jddcnn   nxtrc1  :	   7.444 ms
[perf] jddcnn   nxtrc12 :	   4.790 ms
[perf] jddcnn   nxtrc6  :	   7.494 ms
[perf] jddcnn   nxtrc10 :	  14.294 ms
[perf] jddcnn   nxtrc4  :	   7.222 ms
[perf] jddcnn   nxtrc14 :	   0.518 ms
[perf] jddcnn   output  :	   0.546 ms
[perf] sum jddcnn:	 133.462 ms

I applied the jddcnn preset but get a black image, what could be wrong?

Fuji X-T3 RAW file. In the graph if I bypass the jddcnn node it shows the image correctly

…if that is not a 100MP image the numbers look a bit on the slow side to me. how does it compare to master?

you’d need to install the weights files too, did you? the *.dat that can be found in bin/data/ after running compile-vkdt.sh need to go into ~/.config/vkdt/data/.

Yeah my bad, forgot to do that last step.

[perf] jddcnn   input   :	 1.333 ms
[perf] jddcnn   nxtrc3  :	 0.587 ms
[perf] jddcnn   weights :	 0.187 ms
[perf] jddcnn   nxtrc7  :	 1.309 ms
[perf] jddcnn   nxtrc8  :	 2.270 ms
[perf] jddcnn   nxtrc12 :	 0.746 ms
[perf] jddcnn   nxtrc15 :	 0.823 ms
[perf] jddcnn   nxtrc5  :	 0.446 ms
[perf] jddcnn   nxtrc18 :	 1.038 ms
[perf] jddcnn   nxtrc9  :	 0.400 ms
[perf] jddcnn   nxtrc16 :	 1.248 ms
[perf] jddcnn   nxtrc20 :	 0.696 ms
[perf] jddcnn   nxtrc11 :	 0.711 ms
[perf] jddcnn   nxtrc17 :	 0.814 ms
[perf] jddcnn   nxtrc9  :	 0.401 ms
[perf] jddcnn   nxtrc13 :	 0.809 ms
[perf] jddcnn   nxtrc19 :	 1.296 ms
[perf] jddcnn   nxtrc2  :	 0.462 ms
[perf] jddcnn   nxtrc0  :	 1.680 ms
[perf] jddcnn   nxtrc1  :	 0.997 ms
[perf] jddcnn   nxtrc12 :	 0.752 ms
[perf] jddcnn   nxtrc6  :	 1.540 ms
[perf] jddcnn   nxtrc10 :	 1.823 ms
[perf] jddcnn   nxtrc4  :	 0.938 ms
[perf] jddcnn   nxtrc14 :	 0.516 ms
[perf] jddcnn   output  :	 0.548 ms
[perf] sum jddcnn:	  24.373 ms

Much better

1 Like

yay, more like it! this is with your custom compile? how does the upstream vkdt/master version compare to that? (the weights should be in the release files for codeberg/vkdt-nn)

Yep. I tried with your release weights and while it worked at more or less the same speed ~22ms

I think I was able to compile for my RX7900XTX.

I had to increase the required fmt version to 11 (before I always got /app/vkdt-denox/codegen/compute_graph.cpp:6:10: fatal error: 'fmt/base.h' file not found) and remove the reweight step because it failed for byrn and xtrn.

I don’t understand the details but the LLM that guided me through this claims that “coop matrix commands are now used for everything”.

I couldn’t test the results yet, though. If it worked I could repeat this for my RX6600 (if 8GB VRAM are enough tu run this at all)

nice! did you manage to run it in vkdt? was it any faster than the generic code path? for intel this was like a 6x perf difference.

if it didn’t work, can you give some details about the blockers?

i’d be interested to see whether one schedule would perform well on both of these devices… don’t want to ship all that many kernels.

[edit] if you have a .dnx artifact for the RX7900XTX i can do the codegen and push for further testing.

1 Like

… and maybe some general context might be good here :slight_smile:

this compiler is a result of a recent paper:


with the aim of integrating inferencing directly into vulkan dispatches, without bloaty integration layers or external dependencies. this enables direct use of the engine’s resource management (can alias memory so it doesn’t cost like 4G extra, can directly use barriers in the command buffer instead of wacky semaphore constructs etc).

due to built-in autotuning, the inferencing is also faster than some alternatives, the notable exception is hand-optimised code on intel. some existing libraries/runtimes have shocking perf in this scenario (timings for various gpus in milliseconds, from table 2 in the paper):

as a side note: the teaser image above is tonemapped with spektrafilm portra 400, that’s included in the 1.6ms post processing :slight_smile:

the vkdt neural demosaicing networks are straight forward variations of the OIDN network evaluated above (use bayer/xtrans input instead of dense rgb).

3 Likes

Impressive!

I didn’t get it running yet. Using the weights files from the vkdt-nn repo (release 0.0.1 or 2.0), I get a very “red” picture when I select arch “auto” and glitch art for every other arch.
But the weights files are .dat files, how do I get to that from the files that I compiled?
(jddcnn-byrc-RX7900XTX.dnx jddcnn-byrn-RX7900XTX.dnx jddcnn-xtrc-RX7900XTX.dnx jddcnn-xtrn-RX7900XTX.dnx oidn-ldr-RX7900XTX.dnx oidn-ldrs-RX7900XTX.dnx)

Thanks,
Oskar

you’d need to run the codegen vkdt-denox on the dnx files, see the script in the vkdt-nn repo. it’ll create bin/data/*.dat to be copied to your local ~/.config/vkdt/data. but in this case you’d also need to generate the code and recompile vkdt/the module. if you want i can do that part (provide me with the dnx).

what was that about the reweighting that didn’t work? are we sure all the .dnx files are good?