Blender 2.8: Cycles OptiX packaging

Dear Developers,

I’m involved in packaging Blender for the openSUSE eco system, based here and was asked to add OptiX support for Cycles. Further investigation revealed, that - unlike CUDA - OptiX support requires a working CUDA stack during build time, which in turn requires a working nvidia driver installed.

A public packaging/build infrastructure like OBS, which generates all builds of the distribution cannot provide such an environment for a multitude of reasons (starting with non-free NVidia driver code).

The best way to deal with this issue would be a deferred compilation of Cycles IMHO.

Is there anything, I’m missing? Opinions?

AFAIK to build Blender with Optix enabled is need use CUDA SDK and Optix Library, i build my Blender on VM without OpenGL support and surely without NVidia drivers installed, yoyu can check my compiled Blender from here. Fork is not mine, i only compiled this Blender branch/fork.

Building Blender with Optix support does not require a working CUDA stack or NVIDIA driver any more than CUDA support.

What it requires is the Optix SDK, and specifically the header files in the SDK.
https://wiki.blender.org/wiki/Building_Blender/CUDA

Unfortunately downloading that SDK requires singing up for an NVIDIA developer account, and redistributing the headers is not permitted by the license.

1 Like

Hey, thanks for the hints, @NiCapp and @brecht, much appreciated.

My build mods:

Index: blender-git.spec
===================================================================
--- blender-git.spec    (revision 111)
+++ blender-git.spec    (working copy)
@@ -58,6 +58,7 @@
 Source0:        %{_origname}-%{version}.tar.xz
 Source1:        %{name}.appdata.xml
 Source2:        SUSE-NVIDIA-GPU-rendering.txt
+Source3:        nvidia-optix-7.0.tar.xz
 %if %{with python_36}
 Patch1:         make_python_3.6_compatible.patch
 %endif
@@ -216,7 +217,7 @@
 %lang_package
 
 %prep
-%setup -q -n %{_origname}-%{version}
+%setup -q -n %{_origname}-%{version} -a3
 %if %{with python_36}
 %patch1 -p1
 %endif
@@ -357,7 +358,9 @@
       -DCYCLES_CUDA_BINARIES:BOOL=ON \
       -DCYCLES_CUBIN_COMPILER:BOOL=OFF \
       -DCYCLES_CUDA_BINARIES_ARCH="sm_30;sm_35;sm_37;sm_50;sm_52;sm_60;sm_61;sm_70;sm_75" \
-      -DWITH_CYCLES_DEVICE_OPTIX:BOOL=OFF
+      -DWITH_CYCLES_DEVICE_OPTIX:BOOL=ON \
+      -DOPTIX_ROOT_DIR:STRING="$(pwd)/nvidia-optix-7.0" \
+      -DOPTIX_INCLUDE_DIR:STRING="$(pwd)/nvidia-optix-7.0/include"
 
 make %{?_smp_mflags}

that result in:

[   14s] -- Found OptiX: /home/abuild/rpmbuild/BUILD/blender-2.83~git.20200403T103721.fe7ea8a24c8/build/nvidia-optix-7.0/include  

But fails with:

[   22s] [  2%] Generating kernel_optix.ptx
[   22s] cd "/home/abuild/rpmbuild/BUILD/blender-2.83~git.20200403T103721.fe7ea8a24c8/intern/cycles/kernel" && --ptx -arch=sm_30 -I /home/abuild/rpmbuild/BUILD/blender-2.83~git.20200403T103721.fe7ea8a24c8/build/nvidia-optix-7.0/include -I /home/abuild/rpmbuild/BUILD/blender-2.83~git.20200403T103721.fe7ea8a24c8/intern/cycles/kernel/.. -I /home/abuild/rpmbuild/BUILD/blender-2.83~git.20200403T103721.fe7ea8a24c8/intern/cycles/kernel/kernels/cuda --use_fast_math -o /home/abuild/rpmbuild/BUILD/blender-2.83~git.20200403T103721.fe7ea8a24c8/build/intern/cycles/kernel/kernel_optix.ptx kernels/optix/kernel_optix.cu
[   22s] /bin/sh: --ptx: command not found
[   22s] make[2]: *** [intern/cycles/kernel/CMakeFiles/cycles_kernel_optix.dir/build.make:284: intern/cycles/kernel/kernel_optix.ptx] Error 127
[   22s] make[2]: Leaving directory '/home/abuild/rpmbuild/BUILD/blender-2.83~git.20200403T103721.fe7ea8a24c8/build'
[   22s] make[1]: *** [CMakeFiles/Makefile2:3621: intern/cycles/kernel/CMakeFiles/cycles_kernel_optix.dir/all] Error 2

The build tries to call nvcc (I guess), but that isn’t available at build time. This is the reason for my statement above.

@brecht Without defining OPTIX_INCLUDE_DIR, the result is:

[   14s] -- Could NOT find OptiX (missing: OPTIX_INCLUDE_DIR) 
[   14s] -- OptiX not found, disabling it from Cycles

While at it, due to the license issues, my first attempt was to supply the SDK include tree, which might be a feasible workaround, but that fails in the same way…

Ah yes, we don’t yet support runtime compilation for Optix.

I plan to add that still, but not exactly sure when.

These seems cmake messages though, not runtime builds, looks like the NVCC is not found, try setting -DCUDA_NVCC_EXECUTABLE=/where/ever/nvcc/lives/at/build/time/nvcc

That would be great, @brecht.

Guess, basic infrastructure is in place but as always, the devil is in the details…
Will keep the bug on hold until then. A brief notice, when you’re ready for testing, is much appreciated.

Thanks, @LazyDodo, the matter is, at the time and place, when and where such distribution packages are build, nvcc cannot exist for a multitude of reasons (with the foremost: legal aka NVidia License Agreement). In fact, that’s the way, CUDA works for Blender: whenever you attempt to run Cycles on a new Blender build, it attempts to compile the module first, which is - as usual being expected from this project :wink: - a very smart way to solve such issues. Of course, this comes with a prize: these modules must be created even more carefully than others, given the variants (CUDA versions) available today.

Could the nvidia driver exist? cause we do have a compiler based on the nvrtc library

Soory, @LazyDodo, I don’t get your question. As written before, it’s not possible to officially build Blender with the drivers installed for any Linux distribution. That is a restriction of the build systems, that disallow builds with non-free drivers installed (and typically are done in virtualized build environments, where such drivers won’t fit). Specialized builds are possible of course, but these would make the whole package non-free, since NVidia’s License Agreement forbids publishing the sources (headers et al).

Take it as an unfortunate legal and technical interaction.

At the moment, @brecht has mangled the OptiX integration into Cycles into a runtime dependency, all will be well again. You will not notice anything apart from a small delay on the first usage. And for the impatient ones, you can always use the precompiled packages from blender.org.

I took a quick look, D7400 does the trick on windows, but i don’t have linux to test on.

edit: brecht was quick on the review, diff has landed in master already.

HI @brecht, any advances on this front?

FYI, Blender 3.1.0 still requires the OptiX includes to be in place on build time.

I tried to fake it (by providing OPTIX_ROOT_DIR and OPTIX_VERSION), but that ended in:

[  242s] cd /home/abuild/rpmbuild/BUILD/blender-3.1.0/build/intern/cycles/device && /usr/bin/c++ -DBOOST_ALL_NO_LIB -DBOOST_ATOMIC_DYN_LINK -DBOOST_ATOMIC_NO_LIB -DBOOST_CHRONO_DYN_LINK -DBOOST_CHRONO_NO_LIB -DBOOST_DATE_TIME_DYN_LINK -DBOOST_DATE_TIME_NO_LIB -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_FILESYSTEM_NO_LIB -DBOOST_IOSTREAMS_DYN_LINK -DBOOST_IOSTREAMS_NO_LIB -DBOOST_LOCALE_DYN_LINK -DBOOST_LOCALE_NO_LIB -DBOOST_REGEX_DYN_LINK -DBOOST_REGEX_NO_LIB -DBOOST_SYSTEM_DYN_LINK -DBOOST_SYSTEM_NO_LIB -DBOOST_THREAD_DYN_LINK -DBOOST_THREAD_NO_LIB -DBOOST_WAVE_DYN_LINK -DBOOST_WAVE_NO_LIB -DCCL_NAMESPACE_BEGIN="namespace ccl {" -DCCL_NAMESPACE_END=} -DCYCLES_GFLAGS_NAMESPACE=gflags -DEMBREE_STATIC_LIB -DGLEW_NO_GLU -DGOOGLE_GLOG_DLL_DECL="" -DNDEBUG -DOIDN_STATIC_LIB -DOSL_STATIC_BUILD -DOSL_STATIC_LIBRARY -DWITH_BLENDER_GUARDEDALLOC -DWITH_CUDA -DWITH_CUDA_DYNLOAD -DWITH_CYCLES_LOGGING -DWITH_EMBREE -DWITH_GL_PROFILE_CORE -DWITH_KERNEL_AVX -DWITH_KERNEL_AVX2 -DWITH_KERNEL_SSE2 -DWITH_KERNEL_SSE3 -DWITH_KERNEL_SSE41 -DWITH_OPENGL -DWITH_OPENIMAGEDENOISE -DWITH_OPENSUBDIV -DWITH_OPTIX -DWITH_OSL -DWITH_SYSTEM_PUGIXML -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -D__LITTLE_ENDIAN__ -D__MMX__ -D__SSE2__ -D__SSE__ -I/home/abuild/rpmbuild/BUILD/blender-3.1.0/intern/cycles/../atomic -I/home/abuild/rpmbuild/BUILD/blender-3.1.0/intern/cycles/device/.. -I/home/abuild/rpmbuild/BUILD/blender-3.1.0/intern/cycles/device/../../glew-mx -I/home/abuild/rpmbuild/BUILD/blender-3.1.0/intern/cycles/device/../../../extern/cuew/include -isystem /home/abuild/rpmbuild/BUILD/blender-3.1.0/build/optix -isystem /home/abuild/rpmbuild/BUILD/blender-3.1.0/extern/glog/include -isystem /home/abuild/rpmbuild/BUILD/blender-3.1.0/extern/gflags/src -isystem /usr/include/OpenImageIO -isystem /usr/include/OpenEXR -isystem /usr/include/Imath -isystem /home/abuild/rpmbuild/BUILD/blender-3.1.0/intern/cycles/device/../../../extern/clew/include -Wuninitialized -Wredundant-decls -Wall -Wno-invalid-offsetof -Wno-sign-compare -Wlogical-op -Winit-self -Wmissing-include-dirs -Wno-div-by-zero -Wtype-limits -Werror=return-type -Wno-char-subscripts -Wno-unknown-pragmas -Wpointer-arith -Wunused-parameter -Wwrite-strings -Wundef -Wformat-signedness -Wrestrict -Wno-suggest-override -Wuninitialized -Wundef -Wmissing-declarations -Wimplicit-fallthrough=5  -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -Werror=return-type -flto=auto -g -fPIC -fopenmp -fopenmp -msse -pipe -fPIC -funsigned-char -fno-strict-aliasing  -msse2 -fmacro-prefix-map="/home/abuild/rpmbuild/BUILD/blender-3.1.0/"="" -fmacro-prefix-map="/home/abuild/rpmbuild/BUILD/blender-3.1.0/build/"="" -fno-trapping-math -fno-math-errno -fno-signed-zeros -fno-signaling-nans -fno-rounding-math -mfpmath=sse -Werror=float-conversion -Werror=double-promotion -Wno-error=unused-macros -Wno-maybe-uninitialized -O2 -DNDEBUG -std=c++17 -MD -MT intern/cycles/device/CMakeFiles/cycles_device.dir/optix/queue.cpp.o -MF CMakeFiles/cycles_device.dir/optix/queue.cpp.o.d -o CMakeFiles/cycles_device.dir/optix/queue.cpp.o -c /home/abuild/rpmbuild/BUILD/blender-3.1.0/intern/cycles/device/optix/queue.cpp
[  242s] cc1plus: warning: /home/abuild/rpmbuild/BUILD/blender-3.1.0/build/optix: No such file or directory [-Wmissing-include-dirs]
[  242s] cc1plus: warning: /home/abuild/rpmbuild/BUILD/blender-3.1.0/build/optix: No such file or directory [-Wmissing-include-dirs]
[  242s] cc1plus: warning: /home/abuild/rpmbuild/BUILD/blender-3.1.0/build/optix: No such file or directory [-Wmissing-include-dirs]
[  242s] In file included from /home/abuild/rpmbuild/BUILD/blender-3.1.0/intern/cycles/device/../device/optix/device_impl.h:24,
[  242s]                  from /home/abuild/rpmbuild/BUILD/blender-3.1.0/intern/cycles/device/optix/device.cpp:21:
[  242s] /home/abuild/rpmbuild/BUILD/blender-3.1.0/intern/cycles/device/../device/optix/util.h:29:12: fatal error: optix_stubs.h: No such file or directory
[  242s]    29 | #  include <optix_stubs.h>
[  242s]       |            ^~~~~~~~~~~~~~~
[  242s] compilation terminated.
[  242s] In file included from /home/abuild/rpmbuild/BUILD/blender-3.1.0/intern/cycles/device/../device/optix/device_impl.h:24,
[  242s]                  from /home/abuild/rpmbuild/BUILD/blender-3.1.0/intern/cycles/device/optix/device_impl.cpp:20:
[  242s] /home/abuild/rpmbuild/BUILD/blender-3.1.0/intern/cycles/device/../device/optix/util.h:29:12: fatal error: optix_stubs.h: No such file or directory
[  242s]    29 | #  include <optix_stubs.h>
[  242s]       |            ^~~~~~~~~~~~~~~
[  242s] compilation terminated.
[  242s] make[2]: *** [intern/cycles/device/CMakeFiles/cycles_device.dir/build.make:415: intern/cycles/device/CMakeFiles/cycles_device.dir/optix/device.cpp.o] Error 1
[  242s] make[2]: *** Waiting for unfinished jobs....
[  242s] make[2]: *** [intern/cycles/device/CMakeFiles/cycles_device.dir/build.make:429: intern/cycles/device/CMakeFiles/cycles_device.dir/optix/device_impl.cpp.o] Error 1
[  242s] In file included from /home/abuild/rpmbuild/BUILD/blender-3.1.0/intern/cycles/device/../device/optix/device_impl.h:24,
[  242s]                  from /home/abuild/rpmbuild/BUILD/blender-3.1.0/intern/cycles/device/optix/queue.cpp:20:
[  242s] /home/abuild/rpmbuild/BUILD/blender-3.1.0/intern/cycles/device/../device/optix/util.h:29:12: fatal error: optix_stubs.h: No such file or directory
[  242s]    29 | #  include <optix_stubs.h>
[  242s]       |            ^~~~~~~~~~~~~~~
[  242s] compilation terminated.
[  242s] make[2]: *** [intern/cycles/device/CMakeFiles/cycles_device.dir/build.make:443: intern/cycles/device/CMakeFiles/cycles_device.dir/optix/queue.cpp.o] Error 1
[  245s] make[2]: Leaving directory '/home/abuild/rpmbuild/BUILD/blender-3.1.0/build'
[  245s] make[1]: *** [CMakeFiles/Makefile2:3444: intern/cycles/device/CMakeFiles/cycles_device.dir/all] Error 2
[  245s] make[1]: *** Waiting for unfinished jobs....

Any ideas?

OptiX runtime kernel compilation is now supported. But you’re always going to need the OptiX header files to compile Blender/Cycles with OptiX support, which is where your error is.

The progress is that there is now an easy download link for the OptiX SDK with headers:
https://developer.download.nvidia.com/redist/optix/v7.3/OptiX-7.3.0-Include.zip

However I’m not really sure how you got to that error even, CMake configuration should already disable OptiX when it can’t find the SDK.

Thanks, @brecht

OptiX runtime kernel compilation is now supported. But you’re always going to need the OptiX header files to compile Blender/Cycles with OptiX support, which is where your error is.

The progress is that there is now an easy download link for the OptiX SDK with headers:
https://developer.download.nvidia.com/redist/optix/v7.3/OptiX-7.3.0-Include.zip

Here we’re ending in a Catch 22: even the referenced includes clearly states:

 * Copyright (c) 2021 NVIDIA Corporation.  All rights reserved.
 *
 * NVIDIA Corporation and its licensors retain all intellectual property and proprietary
 * rights in and to this software, related documentation and any modifications thereto.
 * Any use, reproduction, disclosure or distribution of this software and related
 * documentation without an express license agreement from NVIDIA Corporation is strictly
 * prohibited.

therefore, we are not allowed to build Blender based on these headers and still call it Open Source. My cheeky attempt has already been rejected.

Since you already have solved this partway, wouldn’t it be possible to do it the cuda style, meaning we just specify a bunch of config variables during build, and require the system being set up in a specific way (on users side with cuda and OptiX). For cuda, this is working fine already since long, just OptiX isn’t up to the task yet, and I get regular requests for it.

BTW, with providing the includes in a test build (well, I used 7.4 headers), I managed to build 3.1.0 with proper OptiX support. It just cannot be distributed that way.

However I’m not really sure how you got to that error even, CMake configuration should already disable OptiX when it can’t find the SDK.

This was an attempt to fake the includes. But since you access more headers during build (e.g. optix_stubs.h here), this attempt failed miserable.

Doing what we do for CUDA would effectively be making a copy of the OptiX headers, which we can’t do.

In the rejection it says “You are redistributing the headers”, which I don’t think is true?

It gets packaged in the source rpm, hence unfortunately yes.

Would it then help to have a Blender build option to download the SDK as part of the build? Though I guess downloading files as part of a build may not be allowed?

Yes, this is part of the idea of a reproducible build.

I will try that approach in a minute (well after my next meeting…) :wink:
Taking that route, it will not package the files at least.

Thanks for your suuport @brecht much appreciated.

It does not matter when or how the headers are added to the build. The headers become part of the packaged binary, just a little bit transformed by the compiler.

As long as NVidia does not provide the headers in a redistributable way, or Blender finds another way to include Optix support, there is no legal way to distribute such a Blender build. (Probably NVidia could do it, which would imply an “express agreement”.)

I’ve forwarded the concern to contacts at NVIDIA. Not sure I exactly agree with the interpretation, but I’m not qualified to convince people about legal interpretations of licenses.

1 Like

@Brecht, I tried your suggested approach, and it works for a local build, but Factory builds are done with no internet connectivity, hence this approach failed as well (on top of the concerns, that Stefan raised).

Consequently, we’re back on square one, and I have to tell people, that we cannot provide Blender including OptiX support for openSUSE Tumbleweed without going through further loops.

The “simplest” solution would be, that NVidia changes the copyright in order to allow unrestricted redistribution of the OptiX headers package.