Cycles: Enable OIDN 2.3 lazy device module loading

This enables the new lazy module loading behavior introduced in OIDN 2.3,
without breaking compatibility with older versions of OIDN (using separate
code paths).

Also, the detection of OIDN support for devices is now much cleaner, and
devices do not need to be matched by PCI address or device name anymore.

Pull Request: https://projects.blender.org/blender/blender/pulls/121362
This commit is contained in:
Attila Áfra
2024-05-07 14:07:39 +02:00
committed by Brecht Van Lommel
parent afa828ffca
commit 26c93c8359
9 changed files with 75 additions and 22 deletions
+4
View File
@@ -165,7 +165,11 @@ void device_cuda_info(vector<DeviceInfo> &devices)
(unsigned int)pci_location[2]);
# if defined(WITH_OPENIMAGEDENOISE)
# if OIDN_VERSION >= 20300
if (oidnIsCUDADeviceSupported(num)) {
# else
if (OIDNDenoiserGPU::is_device_supported(info)) {
# endif
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
}
# endif
+4
View File
@@ -186,7 +186,11 @@ void device_hip_info(vector<DeviceInfo> &devices)
# if defined(WITH_OPENIMAGEDENOISE)
/* Check first if OIDN supports it, not doing so can crash the HIP driver with
* "hipErrorNoBinaryForGpu: Unable to find code object for all current devices". */
# if OIDN_VERSION >= 20300
if (hipSupportsDeviceOIDN(num) && oidnIsHIPDeviceSupported(num)) {
# else
if (hipSupportsDeviceOIDN(num) && OIDNDenoiserGPU::is_device_supported(info)) {
# endif
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
}
# endif
+4
View File
@@ -57,7 +57,11 @@ void device_metal_info(vector<DeviceInfo> &devices)
info.denoisers = DENOISER_NONE;
info.id = id;
# if defined(WITH_OPENIMAGEDENOISE)
# if OIDN_VERSION >= 20300
if (oidnIsMetalDeviceSupported(device)) {
# else
if (OIDNDenoiserGPU::is_device_supported(info)) {
# endif
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
}
# endif
+11 -2
View File
@@ -93,8 +93,12 @@ Device *device_oneapi_create(const DeviceInfo &info, Stats &stats, Profiler &pro
}
#ifdef WITH_ONEAPI
static void device_iterator_cb(
const char *id, const char *name, int num, bool hwrt_support, void *user_ptr)
static void device_iterator_cb(const char *id,
const char *name,
int num,
bool hwrt_support,
bool oidn_support,
void *user_ptr)
{
vector<DeviceInfo> *devices = (vector<DeviceInfo> *)user_ptr;
@@ -109,10 +113,15 @@ static void device_iterator_cb(
info.has_nanovdb = true;
# if defined(WITH_OPENIMAGEDENOISE)
# if OIDN_VERSION >= 20300
if (oidn_support) {
# else
if (OIDNDenoiserGPU::is_device_supported(info)) {
# endif
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
}
# endif
(void)oidn_support;
info.has_gpu_queue = true;
+13 -1
View File
@@ -17,6 +17,13 @@
# include "bvh/embree.h"
# endif
# if defined(WITH_OPENIMAGEDENOISE)
# include <OpenImageDenoise/config.h>
# if OIDN_VERSION >= 20300
# include "util/openimagedenoise.h"
# endif
# endif
# include "kernel/device/oneapi/globals.h"
# include "kernel/device/oneapi/kernel.h"
@@ -1107,12 +1114,17 @@ void OneapiDevice::iterate_devices(OneAPIDeviceIteratorCallback cb, void *user_p
bool hwrt_support = rtcIsSYCLDeviceSupported(device);
# else
bool hwrt_support = false;
# endif
# if defined(WITH_OPENIMAGEDENOISE) && OIDN_VERSION >= 20300
bool oidn_support = oidnIsSYCLDeviceSupported(&device);
# else
bool oidn_support = false;
# endif
std::string id = "ONEAPI_" + platform_name + "_" + name;
if (device.has(sycl::aspect::ext_intel_pci_address)) {
id.append("_" + device.get_info<sycl::ext::intel::info::device::pci_address>());
}
(cb)(id.c_str(), name.c_str(), num, hwrt_support, user_ptr);
(cb)(id.c_str(), name.c_str(), num, hwrt_support, oidn_support, user_ptr);
num++;
}
}
+6 -2
View File
@@ -14,8 +14,12 @@ CCL_NAMESPACE_BEGIN
class DeviceQueue;
typedef void (*OneAPIDeviceIteratorCallback)(
const char *id, const char *name, int num, bool hwrt_support, void *user_ptr);
typedef void (*OneAPIDeviceIteratorCallback)(const char *id,
const char *name,
int num,
bool hwrt_support,
bool oidn_support,
void *user_ptr);
class OneapiDevice : public Device {
private:
+4
View File
@@ -79,7 +79,11 @@ void device_optix_info(const vector<DeviceInfo> &cuda_devices, vector<DeviceInfo
# endif
info.denoisers |= DENOISER_OPTIX;
# if defined(WITH_OPENIMAGEDENOISE)
# if OIDN_VERSION >= 20300
if (oidnIsCUDADeviceSupported(info.num)) {
# else
if (OIDNDenoiserGPU::is_device_supported(info)) {
# endif
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
}
# endif
+28 -13
View File
@@ -15,7 +15,6 @@
# include "session/buffers.h"
# include "util/array.h"
# include "util/log.h"
# include "util/openimagedenoise.h"
# include "kernel/device/cpu/compat.h"
# include "kernel/device/cpu/kernel.h"
@@ -28,6 +27,7 @@
CCL_NAMESPACE_BEGIN
# if OIDN_VERSION < 20300
static const char *oidn_device_type_to_string(const OIDNDeviceType type)
{
switch (type) {
@@ -37,26 +37,40 @@ static const char *oidn_device_type_to_string(const OIDNDeviceType type)
return "CPU";
/* The initial GPU support was added in OIDN 2.0. */
# if OIDN_VERSION_MAJOR >= 2
# if OIDN_VERSION_MAJOR >= 2
case OIDN_DEVICE_TYPE_SYCL:
return "SYCL";
case OIDN_DEVICE_TYPE_CUDA:
return "CUDA";
case OIDN_DEVICE_TYPE_HIP:
return "HIP";
# endif
# endif
/* The Metal support was added in OIDN 2.2. */
# if (OIDN_VERSION_MAJOR > 2) || ((OIDN_VERSION_MAJOR == 2) && (OIDN_VERSION_MINOR >= 2))
# if (OIDN_VERSION_MAJOR > 2) || ((OIDN_VERSION_MAJOR == 2) && (OIDN_VERSION_MINOR >= 2))
case OIDN_DEVICE_TYPE_METAL:
return "METAL";
# endif
# endif
}
return "UNKNOWN";
}
# endif
bool OIDNDenoiserGPU::is_device_supported(const DeviceInfo &device)
{
# if OIDN_VERSION >= 20300
if (device.type == DEVICE_MULTI) {
for (const DeviceInfo &multi_device : device.multi_devices) {
if (multi_device.type != DEVICE_CPU && multi_device.denoisers & DENOISER_OPENIMAGEDENOISE) {
return true;
}
}
return false;
}
return device.denoisers & DENOISER_OPENIMAGEDENOISE;
# else
if (device.type == DEVICE_MULTI) {
for (const DeviceInfo &multi_device : device.multi_devices) {
if (multi_device.type != DEVICE_CPU && is_device_supported(multi_device)) {
@@ -72,23 +86,23 @@ bool OIDNDenoiserGPU::is_device_supported(const DeviceInfo &device)
int device_type = OIDN_DEVICE_TYPE_DEFAULT;
switch (device.type) {
# ifdef OIDN_DEVICE_SYCL
# ifdef OIDN_DEVICE_SYCL
case DEVICE_ONEAPI:
device_type = OIDN_DEVICE_TYPE_SYCL;
break;
# endif
# ifdef OIDN_DEVICE_HIP
# endif
# ifdef OIDN_DEVICE_HIP
case DEVICE_HIP:
device_type = OIDN_DEVICE_TYPE_HIP;
break;
# endif
# ifdef OIDN_DEVICE_CUDA
# endif
# ifdef OIDN_DEVICE_CUDA
case DEVICE_CUDA:
case DEVICE_OPTIX:
device_type = OIDN_DEVICE_TYPE_CUDA;
break;
# endif
# ifdef OIDN_DEVICE_METAL
# endif
# ifdef OIDN_DEVICE_METAL
case DEVICE_METAL: {
const int num_devices = oidnGetNumPhysicalDevices();
VLOG_DEBUG << "Found " << num_devices << " OIDN device(s)";
@@ -107,7 +121,7 @@ bool OIDNDenoiserGPU::is_device_supported(const DeviceInfo &device)
VLOG_DEBUG << "No matched OIDN device found";
return false;
}
# endif
# endif
case DEVICE_CPU:
/* This is the GPU denoiser - CPU devices shouldn't end up here. */
assert(0);
@@ -142,6 +156,7 @@ bool OIDNDenoiserGPU::is_device_supported(const DeviceInfo &device)
}
VLOG_DEBUG << "No matched OIDN device found";
return false;
# endif
}
OIDNDenoiserGPU::OIDNDenoiserGPU(Device *path_trace_device, const DenoiseParams &params)
+1 -4
View File
@@ -7,13 +7,10 @@
#if defined(WITH_OPENIMAGEDENOISE)
# include "integrator/denoiser_gpu.h"
# include "util/openimagedenoise.h"
# include "util/thread.h"
# include "util/unique_ptr.h"
typedef struct OIDNDeviceImpl *OIDNDevice;
typedef struct OIDNFilterImpl *OIDNFilter;
typedef struct OIDNBufferImpl *OIDNBuffer;
CCL_NAMESPACE_BEGIN
/* Implementation of a GPU denoiser which uses OpenImageDenoise library. */