9# include <sycl/sycl.hpp>
15# ifdef WITH_EMBREE_GPU
19# if defined(WITH_OPENIMAGEDENOISE)
20# include <OpenImageDenoise/config.h>
21# if OIDN_VERSION >= 20300
31# if defined(WITH_EMBREE_GPU) && defined(EMBREE_SYCL_SUPPORT) && !defined(SYCL_LANGUAGE_VERSION)
34extern "C" RTCDevice rtcNewSYCLDevice(sycl::context context,
const char *config);
35extern "C" bool rtcIsSYCLDeviceSupported(
const sycl::device sycl_device);
36extern "C" void rtcSetDeviceSYCLDevice(RTCDevice device,
const sycl::device sycl_device);
41static std::vector<sycl::device> available_sycl_devices(
bool *multiple_dgpus_detected);
42static int parse_driver_build_version(
const sycl::device &device);
44static void queue_error_cb(
const char *message,
void *user_ptr)
47 *
reinterpret_cast<std::string *
>(user_ptr) = message;
52 :
GPUDevice(info, stats, profiler, headless)
55 static_assert(
sizeof(texMemObject) ==
56 sizeof(sycl::ext::oneapi::experimental::sampled_image_handle));
57 static_assert(
sizeof(arrayMemObject) ==
58 sizeof(sycl::ext::oneapi::experimental::image_mem_handle));
60 need_texture_info =
false;
63 oneapi_set_error_cb(queue_error_cb, &oneapi_error_string_);
65 bool is_finished_ok = create_queue(device_queue_,
67# ifdef WITH_EMBREE_GPU
68 use_hardware_raytracing ? (
void *)&embree_device :
nullptr,
72 &is_several_intel_dgpu_devices_detected);
74 if (is_finished_ok ==
false) {
75 set_error(
"oneAPI queue initialization error: got runtime exception \"" +
76 oneapi_error_string_ +
"\"");
84# ifdef WITH_EMBREE_GPU
85 use_hardware_raytracing = use_hardware_raytracing && (embree_device !=
nullptr);
87 use_hardware_raytracing =
false;
90 if (use_hardware_raytracing) {
91 LOG_INFO <<
"oneAPI will use hardware ray tracing for intersection acceleration.";
94 size_t globals_segment_size;
95 is_finished_ok = kernel_globals_size(globals_segment_size);
96 if (is_finished_ok ==
false) {
97 set_error(
"oneAPI constant memory initialization got runtime exception \"" +
98 oneapi_error_string_ +
"\"");
101 LOG_TRACE <<
"Successfully created global/constant memory segment (kernel globals object)";
104 kg_memory_ = usm_aligned_alloc_host(device_queue_, globals_segment_size, 16);
105 usm_memset(device_queue_, kg_memory_, 0, globals_segment_size);
107 kg_memory_device_ = usm_alloc_device(device_queue_, globals_segment_size);
109 kg_memory_size_ = globals_segment_size;
111 max_memory_on_device_ = get_memcapacity();
115 const char *headroom_str = getenv(
"CYCLES_ONEAPI_MEMORY_HEADROOM");
116 if (headroom_str !=
nullptr) {
117 const long long override_headroom = (
float)atoll(headroom_str);
118 device_working_headroom = override_headroom;
119 device_texture_headroom = override_headroom;
121 LOG_TRACE <<
"oneAPI memory headroom size: "
125OneapiDevice::~OneapiDevice()
127# ifdef WITH_EMBREE_GPU
129 rtcReleaseDevice(embree_device);
134 usm_free(device_queue_, kg_memory_);
135 usm_free(device_queue_, kg_memory_device_);
137 const_mem_map_.clear();
140 free_queue(device_queue_);
144bool OneapiDevice::check_peer_access(
Device * )
149bool OneapiDevice::can_use_hardware_raytracing_for_features(
const uint requested_features)
const
153# if defined(RTC_VERSION) && RTC_VERSION < 40100
156 (void)requested_features;
161BVHLayoutMask OneapiDevice::get_bvh_layout_mask(
const uint requested_features)
const
163 return (use_hardware_raytracing &&
164 can_use_hardware_raytracing_for_features(requested_features)) ?
169# ifdef WITH_EMBREE_GPU
173 BVHEmbree *
const bvh_embree =
static_cast<BVHEmbree *
>(bvh);
175 bvh_embree->refit(progress);
178 bvh_embree->build(progress, &stats, embree_device,
true);
181# if RTC_VERSION >= 40302
183 all_embree_scenes.push_back(bvh_embree->scene);
187# if RTC_VERSION >= 40400
188 embree_traversable = rtcGetSceneTraversable(bvh_embree->scene);
190 embree_traversable = bvh_embree->scene;
192# if RTC_VERSION >= 40302
193 RTCError error_code = bvh_embree->offload_scenes_to_gpu(all_embree_scenes);
194 if (error_code != RTC_ERROR_NONE) {
196 string_printf(
"BVH failed to migrate to the GPU due to Embree library error (%s)",
197 bvh_embree->get_error_string(error_code)));
199 all_embree_scenes.clear();
209size_t OneapiDevice::get_free_mem()
const
215 const sycl::device &device =
reinterpret_cast<sycl::queue *
>(device_queue_)->get_device();
216 const bool is_integrated_gpu = device.get_info<sycl::info::device::host_unified_memory>();
217 if (device.has(sycl::aspect::ext_intel_free_memory) && is_integrated_gpu ==
false) {
218 return device.get_info<sycl::ext::intel::info::device::free_memory>();
221 if (device_mem_in_use < max_memory_on_device_) {
222 return max_memory_on_device_ - device_mem_in_use;
227bool OneapiDevice::load_kernels(
const uint requested_features)
237 kernel_features |= requested_features;
239 bool is_finished_ok = oneapi_run_test_kernel(device_queue_);
240 if (is_finished_ok ==
false) {
241 set_error(
"oneAPI test kernel execution: got a runtime exception \"" + oneapi_error_string_ +
245 LOG_INFO <<
"Test kernel has been executed successfully for \"" << info.
description <<
"\"";
248 if (use_hardware_raytracing && !can_use_hardware_raytracing_for_features(requested_features)) {
250 <<
"Hardware ray tracing disabled, not supported yet by oneAPI for requested features.";
251 use_hardware_raytracing =
false;
254 is_finished_ok = oneapi_load_kernels(
255 device_queue_, (
const unsigned int)requested_features, use_hardware_raytracing);
256 if (is_finished_ok ==
false) {
257 set_error(
"oneAPI kernels loading: got a runtime exception \"" + oneapi_error_string_ +
"\"");
260 LOG_INFO <<
"Kernels loading (compilation) has been done for \"" << info.
description <<
"\"";
263 if (is_finished_ok) {
264 reserve_private_memory(requested_features);
265 is_finished_ok = !have_error();
268 return is_finished_ok;
271void OneapiDevice::reserve_private_memory(
const uint kernel_features)
273 size_t free_before = get_free_mem();
290 queue->init_execution();
294 queue->enqueue(test_kernel, 1, args);
295 queue->synchronize();
298 size_t free_after = get_free_mem();
300 LOG_INFO <<
"For kernel execution were reserved "
305void OneapiDevice::get_device_memory_info(
size_t &total,
size_t &
free)
307 free = get_free_mem();
308 total = max_memory_on_device_;
311bool OneapiDevice::alloc_device(
void *&device_pointer,
const size_t size)
313 bool allocation_success =
false;
314 device_pointer = usm_alloc_device(device_queue_,
size);
315 if (device_pointer !=
nullptr) {
316 allocation_success =
true;
319 if (!oneapi_zero_memory_on_device(device_queue_, device_pointer,
size)) {
320 set_error(
"oneAPI memory operation error: got runtime exception \"" + oneapi_error_string_ +
322 usm_free(device_queue_, device_pointer);
324 device_pointer =
nullptr;
325 allocation_success =
false;
329 return allocation_success;
332void OneapiDevice::free_device(
void *device_pointer)
334 usm_free(device_queue_, device_pointer);
337bool OneapiDevice::shared_alloc(
void *&shared_pointer,
const size_t size)
339 shared_pointer = usm_aligned_alloc_host(device_queue_,
size, 64);
340 return shared_pointer !=
nullptr;
343void OneapiDevice::shared_free(
void *shared_pointer)
345 usm_free(device_queue_, shared_pointer);
348void *OneapiDevice::shared_to_device_pointer(
const void *shared_pointer)
352 return const_cast<void *
>(shared_pointer);
355void OneapiDevice::copy_host_to_device(
void *device_pointer,
void *host_pointer,
const size_t size)
357 usm_memcpy(device_queue_, device_pointer, host_pointer,
size);
361SyclQueue *OneapiDevice::sycl_queue()
363 return device_queue_;
366string OneapiDevice::oneapi_error_message()
368 return string(oneapi_error_string_);
371int OneapiDevice::scene_max_shaders()
373 return scene_max_shaders_;
376void *OneapiDevice::kernel_globals_device_pointer()
378 return kg_memory_device_;
381void *OneapiDevice::host_alloc(
const MemoryType type,
const size_t size)
385# ifdef SYCL_EXT_ONEAPI_COPY_OPTIMIZE
388 if (is_several_intel_dgpu_devices_detected ==
false && host_pointer) {
391 sycl::queue *queue =
reinterpret_cast<sycl::queue *
>(device_queue_);
394 if (queue->get_backend() == sycl::backend::ext_oneapi_level_zero) {
395 sycl::ext::oneapi::experimental::prepare_for_device_copy(host_pointer,
size, *queue);
404void OneapiDevice::host_free(
const MemoryType type,
void *host_pointer,
const size_t size)
406# ifdef SYCL_EXT_ONEAPI_COPY_OPTIMIZE
407 if (is_several_intel_dgpu_devices_detected ==
false) {
409 sycl::queue *queue =
reinterpret_cast<sycl::queue *
>(device_queue_);
412 if (queue->get_backend() == sycl::backend::ext_oneapi_level_zero) {
413 sycl::ext::oneapi::experimental::release_from_device_copy(host_pointer, *queue);
425 assert(!
"mem_alloc not supported for textures.");
428 assert(!
"mem_alloc not supported for global memory.");
432 LOG_TRACE <<
"OneapiDevice::mem_alloc: \"" << mem.
name <<
"\", "
443 LOG_TRACE <<
"OneapiDevice::mem_copy_to: \"" << mem.
name <<
"\", "
464 generic_copy_to(mem);
471 LOG_TRACE <<
"OneapiDevice::mem_move_to_host: \"" << mem.
name <<
"\", "
495void OneapiDevice::mem_copy_from(
496 device_memory &mem,
const size_t y,
size_t w,
const size_t h,
size_t elem)
499 assert(!
"mem_copy_from not supported for textures.");
502 const size_t size = (
w > 0 || h > 0 || elem > 0) ? (elem *
w * h) : mem.
memory_size();
503 const size_t offset = elem *
y *
w;
506 LOG_TRACE <<
"OneapiDevice::mem_copy_from: \"" << mem.
name <<
"\" object of "
509 <<
" data " <<
size <<
" bytes";
522 char *shifted_host =
reinterpret_cast<char *
>(mem.
host_pointer) + offset;
523 char *shifted_device =
reinterpret_cast<char *
>(mem.
device_pointer) + offset;
524 bool is_finished_ok = usm_memcpy(device_queue_, shifted_host, shifted_device,
size);
525 if (is_finished_ok ==
false) {
526 set_error(
"oneAPI memory operation error: got runtime exception \"" +
527 oneapi_error_string_ +
"\"");
536 LOG_TRACE <<
"OneapiDevice::mem_zero: \"" << mem.
name <<
"\", "
555 bool is_finished_ok = usm_memset(
557 if (is_finished_ok ==
false) {
558 set_error(
"oneAPI memory operation error: got runtime exception \"" + oneapi_error_string_ +
566 LOG_TRACE <<
"OneapiDevice::mem_free: \"" << mem.
name <<
"\", "
590void OneapiDevice::const_copy_to(
const char *
name,
void *host,
const size_t size)
594 LOG_TRACE <<
"OneapiDevice::const_copy_to \"" <<
name <<
"\" object "
598 if (strcmp(
name,
"data") == 0) {
600 KernelData *
const data =
static_cast<KernelData *
>(host);
604 scene_max_shaders_ =
data->max_shaders;
606# ifdef WITH_EMBREE_GPU
607 if (embree_traversable !=
nullptr) {
611 data->device_bvh = embree_traversable;
616 ConstMemMap::iterator
i = const_mem_map_.find(
name);
619 if (
i == const_mem_map_.end()) {
622 data_ptr->alloc(
size);
623 data = data_ptr.get();
624 const_mem_map_.insert(ConstMemMap::value_type(
name, std::move(data_ptr)));
627 data =
i->second.get();
632 data->copy_to_device();
634 set_global_memory(device_queue_, kg_memory_,
name, (
void *)
data->device_pointer);
636 usm_memcpy(device_queue_, kg_memory_device_, kg_memory_, kg_memory_size_);
644 LOG_TRACE <<
"OneapiDevice::global_alloc \"" << mem.
name <<
"\" object "
649 generic_copy_to(mem);
653 usm_memcpy(device_queue_, kg_memory_device_, kg_memory_, kg_memory_size_);
662 generic_copy_to(mem);
673static sycl::ext::oneapi::experimental::image_descriptor image_desc(
const device_texture &mem)
676 sycl::image_channel_type channel_type;
680 channel_type = sycl::image_channel_type::unorm_int8;
683 channel_type = sycl::image_channel_type::unorm_int16;
686 channel_type = sycl::image_channel_type::fp32;
689 channel_type = sycl::image_channel_type::fp16;
695 sycl::ext::oneapi::experimental::image_descriptor param;
699 param.channel_type = channel_type;
712 sycl::addressing_mode address_mode = sycl::addressing_mode::none;
715 address_mode = sycl::addressing_mode::repeat;
718 address_mode = sycl::addressing_mode::clamp_to_edge;
721 address_mode = sycl::addressing_mode::clamp;
724 address_mode = sycl::addressing_mode::mirrored_repeat;
731 sycl::filtering_mode filter_mode;
733 filter_mode = sycl::filtering_mode::nearest;
736 filter_mode = sycl::filtering_mode::linear;
740 sycl::image_channel_type channel_type;
744 channel_type = sycl::image_channel_type::unorm_int8;
747 channel_type = sycl::image_channel_type::unorm_int16;
750 channel_type = sycl::image_channel_type::fp32;
753 channel_type = sycl::image_channel_type::fp16;
760 sycl::queue *queue =
reinterpret_cast<sycl::queue *
>(device_queue_);
764 sycl::ext::oneapi::experimental::image_mem_handle memHandle{0};
765 sycl::ext::oneapi::experimental::image_descriptor desc{};
768 const sycl::device &device =
reinterpret_cast<sycl::queue *
>(queue)->get_device();
769 const size_t max_width = device.get_info<sycl::info::device::image2d_max_width>();
770 const size_t max_height = device.get_info<sycl::info::device::image2d_max_height>();
774 string_printf(
"Maximum GPU 2D texture size exceeded (max %zux%zu, found %zux%zu)",
783 desc = sycl::ext::oneapi::experimental::image_descriptor(
790 sycl::ext::oneapi::experimental::image_mem_handle memHandle =
791 sycl::ext::oneapi::experimental::alloc_image_mem(desc, *queue);
792 if (!memHandle.raw_handle) {
793 set_error(
"GPU texture allocation failed: Raw handle is null");
798 queue->ext_oneapi_copy(mem.
host_pointer, memHandle, desc);
805 cmem = &device_mem_map[&mem];
807 cmem->array = (arrayMemObject)(memHandle.raw_handle);
811 desc = sycl::ext::oneapi::experimental::image_descriptor(
813 cmem = generic_alloc(mem);
821 queue->wait_and_throw();
826 sycl::ext::oneapi::experimental::bindless_image_sampler samp(
827 address_mode, sycl::coordinate_normalization_mode::normalized, filter_mode);
830 sycl::ext::oneapi::experimental::sampled_image_handle imgHandle;
832 if (memHandle.raw_handle) {
834 imgHandle = sycl::ext::oneapi::experimental::create_image(memHandle, samp, desc, *queue);
838 imgHandle = sycl::ext::oneapi::experimental::create_image(
843 cmem = &device_mem_map[&mem];
844 cmem->texobject = (texMemObject)(imgHandle.raw_handle);
856 if (slot >= texture_info.size()) {
858 texture_info.resize(slot + 128);
860 texture_info[slot] = tex_info;
861 need_texture_info =
true;
864 catch (sycl::exception
const &
e) {
865 set_error(
"GPU texture allocation failed: runtime exception \"" +
string(
e.what()) +
"\"");
877 sycl::ext::oneapi::experimental::image_descriptor desc = image_desc(mem);
879 sycl::queue *queue =
reinterpret_cast<sycl::queue *
>(device_queue_);
884 const Mem &cmem = device_mem_map[&mem];
885 sycl::ext::oneapi::experimental::image_mem_handle image_handle{
886 (sycl::ext::oneapi::experimental::image_mem_handle::raw_handle_type)cmem.array};
887 queue->ext_oneapi_copy(mem.
host_pointer, image_handle, desc);
889# ifdef WITH_CYCLES_DEBUG
890 queue->wait_and_throw();
893 catch (sycl::exception
const &
e) {
894 set_error(
"oneAPI texture copy error: got runtime exception \"" +
string(
e.what()) +
"\"");
898 generic_copy_to(mem);
907 DCHECK(device_mem_map.find(&mem) != device_mem_map.end());
908 const Mem &cmem = device_mem_map[&mem];
910 sycl::queue *queue =
reinterpret_cast<sycl::queue *
>(device_queue_);
912 if (cmem.texobject) {
914 sycl::ext::oneapi::experimental::sampled_image_handle image(cmem.texobject);
915 sycl::ext::oneapi::experimental::destroy_image_handle(image, *queue);
920 sycl::ext::oneapi::experimental::image_mem_handle imgHandle{
921 (sycl::ext::oneapi::experimental::image_mem_handle::raw_handle_type)cmem.array};
925 sycl::ext::oneapi::experimental::free_image_mem(
926 imgHandle, sycl::ext::oneapi::experimental::image_type::standard, *queue);
928 catch (sycl::exception
const &
e) {
929 set_error(
"oneAPI texture deallocation error: got runtime exception \"" +
930 string(
e.what()) +
"\"");
936 device_mem_map.erase(device_mem_map.find(&mem));
947 return make_unique<OneapiDeviceQueue>(
this);
953# ifdef SYCL_LINEAR_MEMORY_INTEROP_AVAILABLE
960 const sycl::device &device =
reinterpret_cast<sycl::queue *
>(device_queue_)->get_device();
961 if (!device.has(sycl::aspect::ext_oneapi_external_memory_import)) {
967 sycl::detail::uuid_type uuid = device.get_info<sycl::ext::intel::info::device::uuid>();
968 const bool found = (uuid.size() == interop_device.
uuid.size() &&
969 memcmp(uuid.data(), interop_device.
uuid.data(), uuid.size()) == 0);
973 LOG_INFO <<
"Graphics interop: found matching Vulkan device for oneAPI";
976 LOG_INFO <<
"Graphics interop: no matching Vulkan device for oneAPI";
986 catch (sycl::exception &
e) {
987 LOG_ERROR <<
"Could not release external Vulkan memory: " <<
e.what();
993void *OneapiDevice::usm_aligned_alloc_host(
const size_t memory_size,
const size_t alignment)
996 return usm_aligned_alloc_host(device_queue_, memory_size, alignment);
999void OneapiDevice::usm_free(
void *usm_ptr)
1002 usm_free(device_queue_, usm_ptr);
1005void OneapiDevice::check_usm(SyclQueue *queue_,
const void *usm_ptr,
bool allow_host =
false)
1008 sycl::queue *queue =
reinterpret_cast<sycl::queue *
>(queue_);
1009 sycl::info::device_type device_type =
1010 queue->get_device().get_info<sycl::info::device::device_type>();
1011 sycl::usm::alloc usm_type =
get_pointer_type(usm_ptr, queue->get_context());
1013# ifndef WITH_ONEAPI_SYCL_HOST_TASK
1014 const sycl::usm::alloc main_memory_type = sycl::usm::alloc::device;
1016 const sycl::usm::alloc main_memory_type = sycl::usm::alloc::host;
1018 assert(usm_type == main_memory_type ||
1019 (usm_type == sycl::usm::alloc::host &&
1020 (allow_host || device_type == sycl::info::device_type::cpu)) ||
1021 usm_type == sycl::usm::alloc::unknown);
1030bool OneapiDevice::create_queue(SyclQueue *&external_queue,
1031 const int device_index,
1032 void *embree_device_pointer,
1033 bool *is_several_intel_dgpu_devices_detected_pointer)
1035 bool finished_correct =
true;
1036 *is_several_intel_dgpu_devices_detected_pointer =
false;
1039 std::vector<sycl::device> devices = available_sycl_devices(
1040 is_several_intel_dgpu_devices_detected_pointer);
1041 if (device_index < 0 || device_index >= devices.size()) {
1045 sycl::queue *created_queue =
nullptr;
1046 if (*is_several_intel_dgpu_devices_detected_pointer ==
false) {
1047 created_queue =
new sycl::queue(devices[device_index], sycl::property::queue::in_order());
1050 sycl::context device_context(devices[device_index]);
1051 created_queue =
new sycl::queue(
1052 device_context, devices[device_index], sycl::property::queue::in_order());
1053 LOG_TRACE <<
"Separate context was generated for the new queue, as several available SYCL "
1054 "devices were detected";
1056 external_queue =
reinterpret_cast<SyclQueue *
>(created_queue);
1058# ifdef WITH_EMBREE_GPU
1059 if (embree_device_pointer) {
1060 RTCDevice *device_object_ptr =
reinterpret_cast<RTCDevice *
>(embree_device_pointer);
1061 *device_object_ptr = rtcNewSYCLDevice(created_queue->get_context(),
"");
1062 if (*device_object_ptr ==
nullptr) {
1063 finished_correct =
false;
1064 oneapi_error_string_ =
1065 "Hardware Raytracing is not available; please install "
1066 "\"intel-level-zero-gpu-raytracing\" to enable it or disable Embree on GPU.";
1069 rtcSetDeviceSYCLDevice(*device_object_ptr, devices[device_index]);
1073 (void)embree_device_pointer;
1076 catch (
const sycl::exception &
e) {
1077 finished_correct =
false;
1078 oneapi_error_string_ =
e.what();
1080 return finished_correct;
1083void OneapiDevice::free_queue(SyclQueue *queue_)
1086 sycl::queue *queue =
reinterpret_cast<sycl::queue *
>(queue_);
1090void *OneapiDevice::usm_aligned_alloc_host(SyclQueue *queue_,
1092 const size_t alignment)
1095 sycl::queue *queue =
reinterpret_cast<sycl::queue *
>(queue_);
1096 return sycl::aligned_alloc_host(alignment, memory_size, *queue);
1099void *OneapiDevice::usm_alloc_device(SyclQueue *queue_,
size_t memory_size)
1102 sycl::queue *queue =
reinterpret_cast<sycl::queue *
>(queue_);
1113# ifndef WITH_ONEAPI_SYCL_HOST_TASK
1114 return sycl::malloc_device(memory_size, *queue);
1116 return sycl::malloc_host(memory_size, *queue);
1120void OneapiDevice::usm_free(SyclQueue *queue_,
void *usm_ptr)
1123 sycl::queue *queue =
reinterpret_cast<sycl::queue *
>(queue_);
1124 OneapiDevice::check_usm(queue_, usm_ptr,
true);
1125 sycl::free(usm_ptr, *queue);
1128bool OneapiDevice::usm_memcpy(SyclQueue *queue_,
void *dest,
void *src,
const size_t num_bytes)
1138 sycl::queue *queue =
reinterpret_cast<sycl::queue *
>(queue_);
1139 OneapiDevice::check_usm(queue_, dest,
true);
1140 OneapiDevice::check_usm(queue_, src,
true);
1145 if ((dest_type == sycl::usm::alloc::host || dest_type == sycl::usm::alloc::unknown) &&
1146 (src_type == sycl::usm::alloc::host || src_type == sycl::usm::alloc::unknown))
1148 memcpy(dest, src, num_bytes);
1153 sycl::event mem_event = queue->memcpy(dest, src, num_bytes);
1154# ifdef WITH_CYCLES_DEBUG
1158 mem_event.wait_and_throw();
1161 bool from_device_to_host = dest_type == sycl::usm::alloc::host &&
1162 src_type == sycl::usm::alloc::device;
1163 bool host_or_device_memop_with_offset = dest_type == sycl::usm::alloc::unknown ||
1164 src_type == sycl::usm::alloc::unknown;
1168 if (from_device_to_host || host_or_device_memop_with_offset) {
1174 catch (
const sycl::exception &
e) {
1175 oneapi_error_string_ =
e.what();
1180bool OneapiDevice::usm_memset(SyclQueue *queue_,
1182 unsigned char value,
1183 const size_t num_bytes)
1193 sycl::queue *queue =
reinterpret_cast<sycl::queue *
>(queue_);
1194 OneapiDevice::check_usm(queue_, usm_ptr,
true);
1196 sycl::event mem_event = queue->memset(usm_ptr, value, num_bytes);
1197# ifdef WITH_CYCLES_DEBUG
1201 mem_event.wait_and_throw();
1207 catch (
const sycl::exception &
e) {
1208 oneapi_error_string_ =
e.what();
1213bool OneapiDevice::queue_synchronize(SyclQueue *queue_)
1216 sycl::queue *queue =
reinterpret_cast<sycl::queue *
>(queue_);
1218 queue->wait_and_throw();
1221 catch (
const sycl::exception &
e) {
1222 oneapi_error_string_ =
e.what();
1227bool OneapiDevice::kernel_globals_size(
size_t &kernel_global_size)
1234void OneapiDevice::set_global_memory(SyclQueue *queue_,
1235 void *kernel_globals,
1236 const char *memory_name,
1237 void *memory_device_pointer)
1242 assert(memory_device_pointer);
1244 OneapiDevice::check_usm(queue_, memory_device_pointer,
true);
1245 OneapiDevice::check_usm(queue_, kernel_globals,
true);
1247 std::string matched_name(memory_name);
1250# define KERNEL_DATA_ARRAY(type, name) \
1251 else if (#name == matched_name) { \
1252 globals->__##name = (type *)memory_device_pointer; \
1257 else if (
"integrator_state" == matched_name) {
1262# include "kernel/data_arrays.h"
1264 std::cerr <<
"Can't found global/constant memory with name \"" << matched_name <<
"\"!"
1268# undef KERNEL_DATA_ARRAY
1271bool OneapiDevice::enqueue_kernel(KernelContext *kernel_context,
1273 const size_t global_size,
1274 const size_t local_size,
1277 return oneapi_enqueue_kernel(kernel_context,
1282 use_hardware_raytracing,
1286void OneapiDevice::get_adjusted_global_and_local_sizes(SyclQueue *queue,
1288 size_t &kernel_global_size,
1289 size_t &kernel_local_size)
1292 static const size_t preferred_work_group_size_intersect = 128;
1293 static const size_t preferred_work_group_size_shading = 256;
1294 static const size_t preferred_work_group_size_shading_simd8 = 64;
1297 static const size_t preferred_work_group_size_shader_evaluation = 256;
1300 static const size_t preferred_work_group_size_cryptomatte = 512;
1301 static const size_t preferred_work_group_size_default = 1024;
1303 const sycl::device &device =
reinterpret_cast<sycl::queue *
>(queue)->get_device();
1304 const size_t max_work_group_size = device.get_info<sycl::info::device::max_work_group_size>();
1306 size_t preferred_work_group_size = 0;
1315 preferred_work_group_size = preferred_work_group_size_intersect;
1327 const bool device_is_simd8 =
1328 (device.has(sycl::aspect::ext_intel_gpu_eu_simd_width) &&
1329 device.get_info<sycl::ext::intel::info::device::gpu_eu_simd_width>() == 8);
1330 preferred_work_group_size = (device_is_simd8) ? preferred_work_group_size_shading_simd8 :
1331 preferred_work_group_size_shading;
1335 preferred_work_group_size = preferred_work_group_size_cryptomatte;
1342 preferred_work_group_size = preferred_work_group_size_shader_evaluation;
1352 if (preferred_work_group_size == 0) {
1353 preferred_work_group_size = oneapi_suggested_gpu_kernel_size((
::DeviceKernel)kernel);
1357 if (preferred_work_group_size == 0) {
1358 preferred_work_group_size = preferred_work_group_size_default;
1361 kernel_local_size = std::min(max_work_group_size, preferred_work_group_size);
1365 kernel_global_size =
round_up(kernel_global_size, kernel_local_size);
1367# ifdef WITH_ONEAPI_SYCL_HOST_TASK
1378 kernel_global_size = 1;
1379 kernel_local_size = 1;
1383 assert(kernel_global_size % kernel_local_size == 0);
1388static const int lowest_supported_driver_version_win = 1018132;
1393static const int lowest_supported_driver_version_neo = 34177;
1395static const int lowest_supported_driver_version_neo = 34666;
1398int parse_driver_build_version(
const sycl::device &device)
1400 const std::string &driver_version = device.get_info<sycl::info::device::driver_version>();
1401 int driver_build_version = 0;
1403 size_t second_dot_position = driver_version.find(
'.', driver_version.find(
'.') + 1);
1404 if (second_dot_position != std::string::npos) {
1406 size_t third_dot_position = driver_version.find(
'.', second_dot_position + 1);
1407 if (third_dot_position != std::string::npos) {
1408 const std::string &third_number_substr = driver_version.substr(
1409 second_dot_position + 1, third_dot_position - second_dot_position - 1);
1410 const std::string &forth_number_substr = driver_version.substr(third_dot_position + 1);
1411 if (third_number_substr.length() == 3 && forth_number_substr.length() == 4) {
1412 driver_build_version = std::stoi(third_number_substr) * 10000 +
1413 std::stoi(forth_number_substr);
1419 else if (third_number_substr.length() == 5 && forth_number_substr.length() == 6) {
1420 driver_build_version = std::stoi(third_number_substr);
1424 const std::string &third_number_substr = driver_version.substr(second_dot_position + 1);
1425 driver_build_version = std::stoi(third_number_substr);
1428 catch (std::invalid_argument &) {
1432 if (driver_build_version == 0) {
1433 LOG_WARNING <<
"Unable to parse unknown Intel GPU driver version. \"" << driver_version
1434 <<
"\" does not match xx.xx.xxxxx (Linux), x.x.xxxx (L0),"
1435 <<
" xx.xx.xxx.xxxx (Windows) for device \""
1436 << device.get_info<sycl::info::device::name>() <<
"\".";
1439 return driver_build_version;
1442std::vector<sycl::device> available_sycl_devices(
bool *multiple_dgpus_detected =
nullptr)
1444 std::vector<sycl::device> available_devices;
1445 bool allow_all_devices =
false;
1446 if (getenv(
"CYCLES_ONEAPI_ALL_DEVICES") !=
nullptr) {
1447 allow_all_devices =
true;
1450 int level_zero_dgpu_counter = 0;
1452 const std::vector<sycl::platform> &oneapi_platforms = sycl::platform::get_platforms();
1454 for (
const sycl::platform &platform : oneapi_platforms) {
1458 if (platform.get_backend() == sycl::backend::opencl) {
1462 const std::vector<sycl::device> &oneapi_devices =
1463 (allow_all_devices) ? platform.get_devices(sycl::info::device_type::all) :
1464 platform.get_devices(sycl::info::device_type::gpu);
1466 for (
const sycl::device &device : oneapi_devices) {
1467 bool filter_out =
false;
1469 if (platform.get_backend() == sycl::backend::ext_oneapi_level_zero && device.is_gpu() &&
1470 device.get_info<sycl::info::device::host_unified_memory>() ==
false
1473 level_zero_dgpu_counter++;
1476 if (!allow_all_devices) {
1480 if (!device.is_gpu() || platform.get_backend() != sycl::backend::ext_oneapi_level_zero) {
1485 int number_of_eus = 96;
1486 int threads_per_eu = 7;
1487 if (device.has(sycl::aspect::ext_intel_gpu_eu_count)) {
1488 number_of_eus = device.get_info<sycl::ext::intel::info::device::gpu_eu_count>();
1490 if (device.has(sycl::aspect::ext_intel_gpu_hw_threads_per_eu)) {
1492 device.get_info<sycl::ext::intel::info::device::gpu_hw_threads_per_eu>();
1495 if (number_of_eus <= 96 && threads_per_eu == 7) {
1499 bool check_driver_version = !filter_out;
1501 if (check_driver_version &&
1502 device.get_info<sycl::info::device::vendor>().find(
"Intel") == std::string::npos)
1504 check_driver_version =
false;
1512# if __LIBSYCL_MAJOR_VERSION < 8
1513 if (check_driver_version &&
1514 !
string_startswith(device.get_info<sycl::info::device::driver_version>(),
"1.3."))
1516 check_driver_version =
false;
1519 if (check_driver_version) {
1520 int driver_build_version = parse_driver_build_version(device);
1521 const int lowest_supported_driver_version = (driver_build_version > 100000) ?
1522 lowest_supported_driver_version_win :
1523 lowest_supported_driver_version_neo;
1524 if (driver_build_version < lowest_supported_driver_version) {
1528 << device.get_info<sycl::info::device::name>()
1529 <<
"\" is too old. Expected \"" << lowest_supported_driver_version
1530 <<
"\" or newer, but got \"" << driver_build_version <<
"\".";
1544 for (
const sycl::device &already_available_device : available_devices) {
1545 std::array<sycl::device, 2> devices = {already_available_device, device};
1546 std::vector<sycl::ext::intel::info::device::uuid::return_type> uuids;
1547 for (
int i = 0;
i < 2;
i++) {
1550 if (devices[
i].has(sycl::aspect::ext_intel_device_info_uuid)) {
1551 uuids.push_back(devices[
i].get_info<sycl::ext::intel::info::device::uuid>());
1553 else if (devices[
i].get_platform().get_info<sycl::info::platform::vendor>() ==
1554 "Intel(R) Corporation")
1559 const std::string &device_name = devices[
i].get_info<sycl::info::device::name>();
1560 LOG_WARNING <<
"Despite expectation, Intel oneAPI device '" << device_name
1561 <<
"' is not supporting Intel SYCL UUID extension.";
1564 if (uuids.size() == 2) {
1565 if (uuids[0] == uuids[1]) {
1566 const std::string &device_name = device.get_info<sycl::info::device::name>();
1567 const std::string &platform_name =
1568 device.get_platform().get_info<sycl::info::platform::name>();
1570 <<
"Detecting that oneAPI device '" << device_name <<
"' of platform '"
1572 <<
"' is identical (by UUID comparison) to an already added device in the "
1573 "list of available devices, so it will not be added again.";
1582 available_devices.push_back(device);
1587 catch (sycl::exception &
e) {
1588 LOG_WARNING <<
"An error has been encountered while enumerating SYCL devices: " <<
e.what();
1591 if (multiple_dgpus_detected) {
1592 *multiple_dgpus_detected = level_zero_dgpu_counter > 1;
1595 return available_devices;
1598void OneapiDevice::architecture_information(
const SyclDevice *device,
1602 const sycl::ext::oneapi::experimental::architecture arch =
1603 reinterpret_cast<const sycl::device *
>(device)
1604 ->get_info<sycl::ext::oneapi::experimental::info::device::architecture>();
1606# define FILL_ARCH_INFO(architecture_code, is_arch_optimised) \
1607 case sycl::ext::oneapi::experimental::architecture ::architecture_code: \
1608 name = #architecture_code; \
1609 is_optimized = is_arch_optimised; \
1621 FILL_ARCH_INFO(intel_gpu_bdw,
false)
1622 FILL_ARCH_INFO(intel_gpu_skl,
false)
1623 FILL_ARCH_INFO(intel_gpu_kbl,
false)
1624 FILL_ARCH_INFO(intel_gpu_cfl,
false)
1625 FILL_ARCH_INFO(intel_gpu_apl,
false)
1626 FILL_ARCH_INFO(intel_gpu_glk,
false)
1627 FILL_ARCH_INFO(intel_gpu_whl,
false)
1628 FILL_ARCH_INFO(intel_gpu_aml,
false)
1629 FILL_ARCH_INFO(intel_gpu_cml,
false)
1630 FILL_ARCH_INFO(intel_gpu_icllp,
false)
1631 FILL_ARCH_INFO(intel_gpu_ehl,
false)
1632 FILL_ARCH_INFO(intel_gpu_tgllp,
false)
1633 FILL_ARCH_INFO(intel_gpu_rkl,
false)
1634 FILL_ARCH_INFO(intel_gpu_adl_s,
false)
1635 FILL_ARCH_INFO(intel_gpu_adl_p,
false)
1636 FILL_ARCH_INFO(intel_gpu_adl_n,
false)
1637 FILL_ARCH_INFO(intel_gpu_dg1,
false)
1638 FILL_ARCH_INFO(intel_gpu_dg2_g10,
true)
1639 FILL_ARCH_INFO(intel_gpu_dg2_g11,
true)
1640 FILL_ARCH_INFO(intel_gpu_dg2_g12,
true)
1641 FILL_ARCH_INFO(intel_gpu_pvc,
false)
1642 FILL_ARCH_INFO(intel_gpu_pvc_vg,
false)
1644 FILL_ARCH_INFO(intel_gpu_mtl_u,
true)
1645 FILL_ARCH_INFO(intel_gpu_mtl_h,
true)
1646 FILL_ARCH_INFO(intel_gpu_bmg_g21,
true)
1647 FILL_ARCH_INFO(intel_gpu_bmg_g31,
true)
1648 FILL_ARCH_INFO(intel_gpu_lnl_m,
true)
1649 FILL_ARCH_INFO(intel_gpu_ptl_h,
true)
1650 FILL_ARCH_INFO(intel_gpu_ptl_u,
true)
1654 is_optimized =
false;
1659char *OneapiDevice::device_capabilities()
1661 std::stringstream capabilities;
1663 const std::vector<sycl::device> &oneapi_devices = available_sycl_devices();
1664 for (
const sycl::device &device : oneapi_devices) {
1665# ifndef WITH_ONEAPI_SYCL_HOST_TASK
1666 const std::string &
name = device.get_info<sycl::info::device::name>();
1668 const std::string &
name =
"SYCL Host Task (Debug)";
1671 capabilities << std::string(
"\t") <<
name <<
"\n";
1672 capabilities <<
"\t\tsycl::info::platform::name\t\t\t"
1673 << device.get_platform().get_info<sycl::info::platform::name>() <<
"\n";
1676 bool is_optimised_for_arch;
1677 architecture_information(
1678 reinterpret_cast<const SyclDevice *
>(&device), arch_name, is_optimised_for_arch);
1679 capabilities <<
"\t\tsycl::info::device::architecture\t\t\t";
1680 capabilities << arch_name <<
"\n";
1681 capabilities <<
"\t\tsycl::info::device::is_cycles_optimized\t\t\t";
1682 capabilities << is_optimised_for_arch <<
"\n";
1684# define WRITE_ATTR(attribute_name, attribute_variable) \
1685 capabilities << "\t\tsycl::info::device::" #attribute_name "\t\t\t" << attribute_variable \
1687# define GET_ATTR(attribute) \
1689 capabilities << "\t\tsycl::info::device::" #attribute "\t\t\t" \
1690 << device.get_info<sycl::info::device ::attribute>() << "\n"; \
1692# define GET_INTEL_ATTR(attribute) \
1694 if (device.has(sycl::aspect::ext_intel_##attribute)) { \
1695 capabilities << "\t\tsycl::ext::intel::info::device::" #attribute "\t\t\t" \
1696 << device.get_info<sycl::ext::intel::info::device ::attribute>() << "\n"; \
1699# define GET_ASPECT(aspect_) \
1701 capabilities << "\t\tdevice::has(" #aspect_ ")\t\t\t" << device.has(sycl::aspect ::aspect_) \
1706 GET_ATTR(driver_version)
1707 GET_ATTR(max_compute_units)
1708 GET_ATTR(max_clock_frequency)
1709 GET_ATTR(global_mem_size)
1710 GET_INTEL_ATTR(pci_address)
1711 GET_INTEL_ATTR(gpu_eu_simd_width)
1712 GET_INTEL_ATTR(gpu_eu_count)
1713 GET_INTEL_ATTR(gpu_slices)
1714 GET_INTEL_ATTR(gpu_subslices_per_slice)
1715 GET_INTEL_ATTR(gpu_eu_count_per_subslice)
1716 GET_INTEL_ATTR(gpu_hw_threads_per_eu)
1717 GET_INTEL_ATTR(max_mem_bandwidth)
1718 GET_ATTR(max_work_group_size)
1719 GET_ATTR(max_work_item_dimensions)
1720 sycl::id<3> max_work_item_sizes =
1721 device.get_info<sycl::info::device::max_work_item_sizes<3>>();
1722 WRITE_ATTR(max_work_item_sizes[0], max_work_item_sizes.get(0))
1723 WRITE_ATTR(max_work_item_sizes[1], max_work_item_sizes.get(1))
1724 WRITE_ATTR(max_work_item_sizes[2], max_work_item_sizes.get(2))
1726 GET_ATTR(max_num_sub_groups)
1727 for (
size_t sub_group_size : device.get_info<sycl::info::device::sub_group_sizes>()) {
1728 WRITE_ATTR(sub_group_size[], sub_group_size)
1730 GET_ATTR(sub_group_independent_forward_progress)
1732 GET_ATTR(preferred_vector_width_char)
1733 GET_ATTR(preferred_vector_width_short)
1734 GET_ATTR(preferred_vector_width_int)
1735 GET_ATTR(preferred_vector_width_long)
1736 GET_ATTR(preferred_vector_width_float)
1737 GET_ATTR(preferred_vector_width_double)
1738 GET_ATTR(preferred_vector_width_half)
1740 GET_ATTR(address_bits)
1741 GET_ATTR(max_mem_alloc_size)
1742 GET_ATTR(mem_base_addr_align)
1743 GET_ATTR(error_correction_support)
1744 GET_ATTR(is_available)
1745 GET_ATTR(host_unified_memory)
1750 GET_ASPECT(atomic64)
1751 GET_ASPECT(usm_host_allocations)
1752 GET_ASPECT(usm_device_allocations)
1753 GET_ASPECT(usm_shared_allocations)
1754 GET_ASPECT(usm_system_allocations)
1756# ifdef __SYCL_ANY_DEVICE_HAS_ext_oneapi_non_uniform_groups__
1757 GET_ASPECT(ext_oneapi_non_uniform_groups)
1759# ifdef __SYCL_ANY_DEVICE_HAS_ext_oneapi_bindless_images__
1760 GET_ASPECT(ext_oneapi_bindless_images)
1762# ifdef __SYCL_ANY_DEVICE_HAS_ext_oneapi_interop_semaphore_import__
1763 GET_ASPECT(ext_oneapi_interop_semaphore_import)
1765# ifdef __SYCL_ANY_DEVICE_HAS_ext_oneapi_interop_semaphore_export__
1766 GET_ASPECT(ext_oneapi_interop_semaphore_export)
1769# undef GET_INTEL_ATTR
1773 capabilities <<
"\n";
1776 return ::strdup(capabilities.str().c_str());
1779void OneapiDevice::iterate_devices(OneAPIDeviceIteratorCallback cb,
void *user_ptr)
1782 std::vector<sycl::device> devices = available_sycl_devices();
1783 for (sycl::device &device : devices) {
1784 const std::string &platform_name =
1785 device.get_platform().get_info<sycl::info::platform::name>();
1786# ifndef WITH_ONEAPI_SYCL_HOST_TASK
1787 std::string
name = device.get_info<sycl::info::device::name>();
1789 std::string
name =
"SYCL Host Task (Debug)";
1791# ifdef WITH_EMBREE_GPU
1792 bool hwrt_support = rtcIsSYCLDeviceSupported(device);
1794 bool hwrt_support =
false;
1796# if defined(WITH_OPENIMAGEDENOISE) && OIDN_VERSION >= 20300
1797 bool oidn_support = oidnIsSYCLDeviceSupported(&device);
1799 bool oidn_support =
false;
1801 std::string
id =
"ONEAPI_" + platform_name +
"_" +
name;
1804 bool is_optimised_for_arch;
1805 architecture_information(
1806 reinterpret_cast<const SyclDevice *
>(&device), arch_name, is_optimised_for_arch);
1808 if (device.has(sycl::aspect::ext_intel_pci_address)) {
1809 id.append(
"_" + device.get_info<sycl::ext::intel::info::device::pci_address>());
1816 is_optimised_for_arch,
1822size_t OneapiDevice::get_memcapacity()
1824 return reinterpret_cast<sycl::queue *
>(device_queue_)
1826 .get_info<sycl::info::device::global_mem_size>();
1829int OneapiDevice::get_num_multiprocessors()
1831 const sycl::device &device =
reinterpret_cast<sycl::queue *
>(device_queue_)->get_device();
1832 if (device.has(sycl::aspect::ext_intel_gpu_eu_count)) {
1833 return device.get_info<sycl::ext::intel::info::device::gpu_eu_count>();
1835 return device.get_info<sycl::info::device::max_compute_units>();
1838int OneapiDevice::get_max_num_threads_per_multiprocessor()
1840 const sycl::device &device =
reinterpret_cast<sycl::queue *
>(device_queue_)->get_device();
1841 if (device.has(sycl::aspect::ext_intel_gpu_eu_simd_width) &&
1842 device.has(sycl::aspect::ext_intel_gpu_hw_threads_per_eu))
1844 return device.get_info<sycl::ext::intel::info::device::gpu_eu_simd_width>() *
1845 device.get_info<sycl::ext::intel::info::device::gpu_hw_threads_per_eu>();
1849 return device.get_info<sycl::info::device::max_work_group_size>();
void BLI_kdtree_nd_ free(KDTree *tree)
ATTR_WARN_UNUSED_RESULT const size_t num
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
void refit(btStridingMeshInterface *triangles, const btVector3 &aabbMin, const btVector3 &aabbMax)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
static PointerRNA * get_pointer_type(ButsContextPath *path, StructRNA *type)
bool use_hardware_raytracing
virtual void host_free(const MemoryType type, void *host_pointer, const size_t size)
virtual void build_bvh(BVH *bvh, Progress &progress, bool refit)
virtual void * host_alloc(const MemoryType type, const size_t size)
void mem_alloc(const size_t size)
void mem_free(const size_t size)
size_t memory_elements_size(const int elements)
device_ptr device_pointer
#define KERNEL_DATA_ARRAY(type, name)
#define KERNEL_FEATURE_NODE_RAYTRACE
#define KERNEL_FEATURE_MNEE
#define CCL_NAMESPACE_END
#define assert(assertion)
@ DEVICE_KERNEL_INTEGRATOR_QUEUED_PATHS_ARRAY
@ DEVICE_KERNEL_INTEGRATOR_SHADE_LIGHT
@ DEVICE_KERNEL_INTEGRATOR_SHADE_DEDICATED_LIGHT
@ DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE
@ DEVICE_KERNEL_SHADER_EVAL_DISPLACE
@ DEVICE_KERNEL_SHADER_EVAL_VOLUME_DENSITY
@ DEVICE_KERNEL_INTEGRATOR_INTERSECT_SUBSURFACE
@ DEVICE_KERNEL_INTEGRATOR_QUEUED_SHADOW_PATHS_ARRAY
@ DEVICE_KERNEL_INTEGRATOR_SHADE_SHADOW
@ DEVICE_KERNEL_INTEGRATOR_TERMINATED_PATHS_ARRAY
@ DEVICE_KERNEL_INTEGRATOR_INTERSECT_VOLUME_STACK
@ DEVICE_KERNEL_SHADER_EVAL_BACKGROUND
@ DEVICE_KERNEL_INTEGRATOR_COMPACT_SHADOW_PATHS_ARRAY
@ DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE
@ DEVICE_KERNEL_INTEGRATOR_INTERSECT_DEDICATED_LIGHT
@ DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_MNEE
@ DEVICE_KERNEL_INTEGRATOR_TERMINATED_SHADOW_PATHS_ARRAY
@ DEVICE_KERNEL_INTEGRATOR_ACTIVE_PATHS_ARRAY
@ DEVICE_KERNEL_INTEGRATOR_INIT_FROM_CAMERA
@ DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME_RAY_MARCHING
@ DEVICE_KERNEL_CRYPTOMATTE_POSTPROCESS
@ DEVICE_KERNEL_INTEGRATOR_COMPACT_PATHS_ARRAY
@ DEVICE_KERNEL_INTEGRATOR_INIT_FROM_BAKE
@ DEVICE_KERNEL_SHADER_EVAL_CURVE_SHADOW_TRANSPARENCY
@ DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME
@ DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW
@ DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST
@ DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND
#define DCHECK(expression)
string string_human_readable_size(size_t size)
string string_hex(const uint8_t *data, const size_t size)
string string_human_readable_number(size_t num)
bool string_startswith(const string_view s, const string_view start)
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
CCL_NAMESPACE_END IntegratorStateGPU * integrator_state
ccl_device_inline bool is_nanovdb_type(int type)
std::unique_lock< std::mutex > thread_scoped_lock
ccl_device_inline size_t round_up(const size_t x, const size_t multiple)