Add Chromium-only Blender WebEngine parity work

This commit is contained in:
mes123456
2026-08-12 04:47:48 -04:00
commit 9fd26010f6
18225 changed files with 11622124 additions and 0 deletions

View File

@@ -0,0 +1,183 @@
/* SPDX-FileCopyrightText: 2021-2022 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0 */
#include "device/oneapi/device.h"
#include "device/device.h"
#include "util/log.h"
#ifdef WITH_ONEAPI
# include "device/oneapi/device_impl.h"
# include "integrator/denoiser_oidn_gpu.h" // IWYU pragma: keep
# include "util/string.h"
# ifdef __linux__
# include <dlfcn.h>
# endif
#endif /* WITH_ONEAPI */
CCL_NAMESPACE_BEGIN
bool device_oneapi_init()
{
#if !defined(WITH_ONEAPI)
return false;
#else
/* NOTE(@nsirgien): we need to enable JIT cache from here and
* right now this cache policy is controlled by env. variables. */
/* NOTE(@xavierh-intel) we enable the use of copy engine, incl. for fill
* operations as it lowers the overhead from zeCommandListAppendMemoryFill
* when running paths_array kernels on Linux+A750.
* All these env variable can be set beforehand by end-users and
* will in that case -not- be overwritten. */
/* By default, enable only Level-Zero and if all devices are allowed, also CUDA and HIP.
* OpenCL backend isn't currently well supported. */
# ifdef _WIN32
if (getenv("SYCL_CACHE_PERSISTENT") == nullptr) {
_putenv_s("SYCL_CACHE_PERSISTENT", "1");
}
if (getenv("SYCL_CACHE_THRESHOLD") == nullptr) {
_putenv_s("SYCL_CACHE_THRESHOLD", "0");
}
if (getenv("ONEAPI_DEVICE_SELECTOR") == nullptr) {
if (getenv("CYCLES_ONEAPI_ALL_DEVICES") == nullptr) {
_putenv_s("ONEAPI_DEVICE_SELECTOR", "level_zero:*");
}
else {
_putenv_s("ONEAPI_DEVICE_SELECTOR", "!opencl:*");
}
}
/* SYSMAN is needed for free_memory queries. */
if (getenv("ZES_ENABLE_SYSMAN") == nullptr) {
_putenv_s("ZES_ENABLE_SYSMAN", "1");
}
if (getenv("UR_L0_USE_COPY_ENGINE") == nullptr) {
_putenv_s("UR_L0_USE_COPY_ENGINE", "1");
}
if (getenv("UR_L0_USE_COPY_ENGINE_FOR_FILL") == nullptr) {
_putenv_s("UR_L0_USE_COPY_ENGINE_FOR_FILL", "1");
}
# elif __linux__
setenv("SYCL_CACHE_PERSISTENT", "1", false);
setenv("SYCL_CACHE_THRESHOLD", "0", false);
if (getenv("CYCLES_ONEAPI_ALL_DEVICES") == nullptr) {
setenv("ONEAPI_DEVICE_SELECTOR", "level_zero:*", false);
}
else {
setenv("ONEAPI_DEVICE_SELECTOR", "!opencl:*", false);
}
/* SYSMAN is needed for free_memory queries. */
setenv("ZES_ENABLE_SYSMAN", "1", false);
setenv("UR_L0_USE_COPY_ENGINE", "1", false);
setenv("UR_L0_USE_COPY_ENGINE_FOR_FILL", "1", false);
# endif
return true;
#endif
}
unique_ptr<Device> device_oneapi_create(const DeviceInfo &info,
Stats &stats,
Profiler &profiler,
bool headless)
{
#ifdef WITH_ONEAPI
return make_unique<OneapiDevice>(info, stats, profiler, headless);
#else
(void)info;
(void)stats;
(void)profiler;
(void)headless;
LOG_FATAL << "Requested to create oneAPI device while not enabled for this build.";
return nullptr;
#endif
}
#ifdef WITH_ONEAPI
static void device_iterator_cb(const char *id,
const char *name,
const int num,
bool hwrt_support,
bool oidn_support,
bool has_execution_optimization,
void *user_ptr)
{
vector<DeviceInfo> *devices = (vector<DeviceInfo> *)user_ptr;
DeviceInfo info;
info.type = DEVICE_ONEAPI;
info.description = name;
info.num = num;
/* NOTE(@nsirgien): Should be unique at least on proper oneapi installation. */
info.id = id;
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;
/* NOTE(@nsirgien): oneAPI right now is focused on one device usage. In future it maybe will
* change, but right now peer access from one device to another device is not supported. */
info.has_peer_memory = false;
/* NOTE(@nsirgien): Seems not possible to know from SYCL/oneAPI or Level0. */
info.display_device = false;
# ifdef WITH_EMBREE_GPU
info.use_hardware_raytracing = hwrt_support;
# else
info.use_hardware_raytracing = false;
(void)hwrt_support;
# endif
info.has_execution_optimization = has_execution_optimization;
devices->push_back(info);
LOG_INFO << "Added device \"" << info.description << "\" with id \"" << info.id << "\".";
if (info.denoisers & DENOISER_OPENIMAGEDENOISE) {
LOG_INFO << "Device with id \"" << info.id << "\" supports "
<< denoiserTypeToHumanReadable(DENOISER_OPENIMAGEDENOISE) << ".";
}
}
#endif
void device_oneapi_info(vector<DeviceInfo> &devices)
{
#ifdef WITH_ONEAPI
OneapiDevice::iterate_devices(device_iterator_cb, &devices);
#else /* WITH_ONEAPI */
(void)devices;
#endif /* WITH_ONEAPI */
}
string device_oneapi_capabilities()
{
string capabilities;
#ifdef WITH_ONEAPI
char *c_capabilities = OneapiDevice::device_capabilities();
if (c_capabilities) {
capabilities = c_capabilities;
free(c_capabilities);
}
#endif
return capabilities;
}
CCL_NAMESPACE_END

View File

@@ -0,0 +1,29 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: Apache-2.0 */
#pragma once
#include "util/string.h"
#include "util/unique_ptr.h"
#include "util/vector.h"
CCL_NAMESPACE_BEGIN
class Device;
class DeviceInfo;
class Profiler;
class Stats;
bool device_oneapi_init();
unique_ptr<Device> device_oneapi_create(const DeviceInfo &info,
Stats &stats,
Profiler &profiler,
bool headless);
void device_oneapi_info(vector<DeviceInfo> &devices);
string device_oneapi_capabilities();
CCL_NAMESPACE_END

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,175 @@
/* SPDX-FileCopyrightText: 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0 */
#ifdef WITH_ONEAPI
# include "device/device.h"
# include "device/oneapi/device.h"
# include "device/oneapi/queue.h"
# include "kernel/device/oneapi/kernel.h"
# include "util/map.h"
# include "util/unique_ptr.h"
CCL_NAMESPACE_BEGIN
class DeviceQueue;
using OneAPIDeviceIteratorCallback =
void (*)(const char *, const char *, const int, bool, bool, bool, void *);
class OneapiDevice : public GPUDevice {
private:
SyclQueue *device_queue_ = nullptr;
# ifdef WITH_EMBREE_GPU
RTCDevice embree_device = nullptr;
# if RTC_VERSION >= 40400
RTCTraversable embree_traversable = nullptr;
# else
RTCScene embree_traversable = nullptr;
# endif
# if RTC_VERSION >= 40302
thread_mutex scene_data_mutex;
vector<RTCScene> all_embree_scenes;
# endif
# endif
using ConstMemMap = map<string, unique_ptr<device_vector<uchar>>>;
ConstMemMap const_mem_map_;
void *kg_memory_ = nullptr;
void *kg_memory_device_ = nullptr;
size_t kg_memory_size_ = 0;
size_t max_memory_on_device_ = 0;
std::string oneapi_error_string_;
bool use_hardware_raytracing = false;
unsigned int kernel_features = 0;
int scene_max_shaders_ = 0;
/* On some driver versions, usage of Intel oneAPI extension for host->GPU copy optimization
* is causing crashes and failures. As a result, to ensure functionality, we disable
* this extension as a workaround. This class member variable is controlling this behavior
* and is set appropriately during device enumeration, based on the presented devices
* and their driver version (at the moment not checked, no public driver with a fix exists yet).
*/
bool use_intel_copy_optimization = true;
size_t get_free_mem() const;
public:
BVHLayoutMask get_bvh_layout_mask(const uint requested_features) const override;
OneapiDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler, bool headless);
~OneapiDevice() override;
# ifdef WITH_EMBREE_GPU
void build_bvh(BVH *bvh, Progress &progress, bool refit) override;
# endif
bool check_peer_access(Device *peer_device) override;
bool load_kernels(const uint requested_features) override;
void reserve_private_memory(const uint kernel_features);
string oneapi_error_message();
int scene_max_shaders();
void *kernel_globals_device_pointer();
/* All memory types. */
void mem_alloc(device_memory &mem) override;
void mem_copy_to(device_memory &mem) override;
void mem_move_to_host(device_memory &mem) override;
void mem_copy_from(device_memory &mem,
const size_t y,
size_t w,
const size_t h,
size_t elem,
void *host_pointer);
void mem_copy_from(
device_memory &mem, const size_t y, size_t w, const size_t h, size_t elem) override;
void mem_copy_from(device_memory &mem);
void mem_zero(device_memory &mem) override;
void mem_free(device_memory &mem) override;
device_ptr mem_alloc_sub_ptr(device_memory &mem, const size_t offset, size_t /*size*/) override;
/* Global memory. */
void global_alloc(device_memory &mem);
void global_copy_to(device_memory &mem);
void global_free(device_memory &mem);
/* Image memory. */
void image_alloc(device_image &mem);
void image_copy_to(device_image &mem);
void image_free(device_image &mem);
/* Host side memory, override for more efficient copies. */
void *host_alloc(const MemoryType type, const size_t size) override;
void host_free(const MemoryType type, void *host_pointer, const size_t size) override;
/* Device side memory. */
void get_device_memory_info(size_t &total, size_t &free) override;
bool alloc_device(void *&device_pointer, const size_t size) override;
void free_device(void *device_pointer) override;
/* Shared memory. */
bool shared_alloc(void *&shared_pointer, const size_t size) override;
void shared_free(void *shared_pointer) override;
void *shared_to_device_pointer(const void *shared_pointer) override;
/* Memory copy. */
void copy_host_to_device(void *device_pointer, void *host_pointer, const size_t size) override;
void const_copy_to(const char *name, void *host, const size_t size) override;
/* Graphics resources interoperability. */
bool should_use_graphics_interop(const GraphicsInteropDevice &interop_device,
const bool log) override;
unique_ptr<DeviceQueue> gpu_queue_create() override;
/* NOTE(@nsirgien): Create this methods to avoid some compilation problems on Windows with host
* side compilation (MSVC). */
void *usm_aligned_alloc_host(const size_t memory_size, const size_t alignment);
void usm_free(void *usm_ptr);
static void architecture_information(const SyclDevice *device, string &name, bool &is_optimized);
static char *device_capabilities();
static void iterate_devices(OneAPIDeviceIteratorCallback cb, void *user_ptr);
size_t get_memcapacity();
int get_num_multiprocessors();
int get_max_num_threads_per_multiprocessor();
bool queue_synchronize(SyclQueue *queue);
bool kernel_globals_size(size_t &kernel_global_size);
void set_global_memory(SyclQueue *queue,
void *kernel_globals,
const char *memory_name,
void *memory_device_pointer);
bool enqueue_kernel(KernelContext *kernel_context,
const int kernel,
const size_t global_size,
const size_t local_size,
void **args);
void get_adjusted_global_and_local_sizes(SyclQueue *queue,
const DeviceKernel kernel,
size_t &kernel_global_size,
size_t &kernel_local_size);
SyclQueue *sycl_queue();
protected:
bool can_use_hardware_raytracing_for_features(const uint requested_features) const;
void check_usm(SyclQueue *queue, const void *usm_ptr, bool allow_host);
bool create_queue(SyclQueue *&external_queue,
const int device_index,
void *embree_device,
bool *multiple_level_zero_platforms_detected_pointer);
void free_queue(SyclQueue *queue);
void *usm_aligned_alloc_host(SyclQueue *queue, const size_t memory_size, const size_t alignment);
void *usm_alloc_device(SyclQueue *queue, const size_t memory_size);
void usm_free(SyclQueue *queue, void *usm_ptr);
bool usm_memcpy(SyclQueue *queue, void *dest, void *src, const size_t num_bytes);
bool usm_memset(SyclQueue *queue, void *usm_ptr, unsigned char value, const size_t num_bytes);
};
CCL_NAMESPACE_END
#endif

View File

@@ -0,0 +1,168 @@
/* SPDX-FileCopyrightText: 2025 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0 */
#if defined(WITH_ONEAPI) && defined(SYCL_LINEAR_MEMORY_INTEROP_AVAILABLE)
# include "device/oneapi/graphics_interop.h"
# include "device/oneapi/device.h"
# include "device/oneapi/device_impl.h"
# include "device/oneapi/queue.h"
# include "session/display_driver.h"
# ifdef _WIN32
# include "util/windows.h"
# else
# include <unistd.h>
# endif
CCL_NAMESPACE_BEGIN
OneapiDeviceGraphicsInterop::OneapiDeviceGraphicsInterop(OneapiDeviceQueue *queue)
: queue_(queue), device_(static_cast<OneapiDevice *>(queue->device))
{
}
OneapiDeviceGraphicsInterop::~OneapiDeviceGraphicsInterop()
{
free();
}
void OneapiDeviceGraphicsInterop::set_buffer(GraphicsInteropBuffer &interop_buffer)
{
if (interop_buffer.is_empty()) {
free();
return;
}
need_zero_ |= interop_buffer.take_zero();
if (!interop_buffer.has_new_handle()) {
return;
}
free();
if (interop_buffer.get_type() != GraphicsInteropDevice::VULKAN) {
/* SYCL only supports interop with Vulkan and D3D. */
LOG_ERROR
<< "oneAPI interop set_buffer called for invalid graphics API. Only Vulkan is supported.";
return;
}
# ifdef _WIN32
/* import_external_memory will not take ownership of the handle. */
vulkan_windows_handle_ = reinterpret_cast<void *>(interop_buffer.take_handle());
auto sycl_mem_handle_type =
sycl::ext::oneapi::experimental::external_mem_handle_type::win32_nt_handle;
sycl::ext::oneapi::experimental::external_mem_descriptor<
sycl::ext::oneapi::experimental::resource_win32_handle>
sycl_external_mem_descriptor{{vulkan_windows_handle_}, sycl_mem_handle_type};
# else
/* import_external_memory will take ownership of the file descriptor. */
auto sycl_mem_handle_type = sycl::ext::oneapi::experimental::external_mem_handle_type::opaque_fd;
sycl::ext::oneapi::experimental::external_mem_descriptor<
sycl::ext::oneapi::experimental::resource_fd>
sycl_external_mem_descriptor{{static_cast<int>(interop_buffer.take_handle())},
sycl_mem_handle_type};
# endif
sycl::queue *sycl_queue = reinterpret_cast<sycl::queue *>(device_->sycl_queue());
try {
sycl_external_memory_ = sycl::ext::oneapi::experimental::import_external_memory(
sycl_external_mem_descriptor, *sycl_queue);
}
catch (sycl::exception &e) {
# ifdef _WIN32
CloseHandle(HANDLE(vulkan_windows_handle_));
vulkan_windows_handle_ = nullptr;
# else
close(sycl_external_mem_descriptor.external_resource.file_descriptor);
# endif
LOG_ERROR << "Error importing Vulkan memory: " << e.what();
return;
}
buffer_size_ = interop_buffer.get_size();
/* Like the CUDA/HIP backend, we map the buffer persistently. */
try {
sycl_memory_ptr_ = sycl::ext::oneapi::experimental::map_external_linear_memory(
sycl_external_memory_, 0, buffer_size_, *sycl_queue);
}
catch (sycl::exception &e) {
try {
sycl::ext::oneapi::experimental::release_external_memory(sycl_external_memory_, *sycl_queue);
}
catch (sycl::exception &e) {
LOG_ERROR << "Could not release external Vulkan memory: " << e.what();
}
sycl_external_memory_ = {};
buffer_size_ = 0;
/* Only need to close Windows handle, as file descriptor is owned by compute API. */
# ifdef _WIN32
CloseHandle(HANDLE(vulkan_windows_handle_));
vulkan_windows_handle_ = nullptr;
# endif
LOG_ERROR << "Error mapping external Vulkan memory: " << e.what();
return;
}
}
device_ptr OneapiDeviceGraphicsInterop::map()
{
if (sycl_memory_ptr_ && need_zero_) {
try {
/* We do not wait on the returned event here, as CUDA also uses "cuMemsetD8Async". */
sycl::queue *sycl_queue = reinterpret_cast<sycl::queue *>(device_->sycl_queue());
sycl_queue->memset(sycl_memory_ptr_, 0, buffer_size_);
}
catch (sycl::exception &e) {
LOG_ERROR << "Error clearing external Vulkan memory: " << e.what();
return device_ptr(0);
}
need_zero_ = false;
}
return reinterpret_cast<device_ptr>(sycl_memory_ptr_);
}
void OneapiDeviceGraphicsInterop::unmap() {}
void OneapiDeviceGraphicsInterop::free()
{
if (sycl_external_memory_.raw_handle) {
sycl::queue *sycl_queue = reinterpret_cast<sycl::queue *>(device_->sycl_queue());
try {
sycl::ext::oneapi::experimental::unmap_external_linear_memory(sycl_memory_ptr_, *sycl_queue);
}
catch (sycl::exception &e) {
LOG_ERROR << "Could not unmap external Vulkan memory: " << e.what();
}
try {
sycl::ext::oneapi::experimental::release_external_memory(sycl_external_memory_, *sycl_queue);
}
catch (sycl::exception &e) {
LOG_ERROR << "Could not release external Vulkan memory: " << e.what();
}
sycl_memory_ptr_ = {};
sycl_external_memory_ = {};
}
# ifdef _WIN32
if (vulkan_windows_handle_) {
CloseHandle(HANDLE(vulkan_windows_handle_));
vulkan_windows_handle_ = nullptr;
}
# endif
buffer_size_ = 0;
need_zero_ = false;
}
CCL_NAMESPACE_END
#endif

View File

@@ -0,0 +1,61 @@
/* SPDX-FileCopyrightText: 2025 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0 */
#if defined(WITH_ONEAPI) && defined(SYCL_LINEAR_MEMORY_INTEROP_AVAILABLE)
# include <sycl/sycl.hpp>
# include "device/graphics_interop.h"
# include "session/display_driver.h"
# include "device/oneapi/device.h"
# include "device/oneapi/queue.h"
CCL_NAMESPACE_BEGIN
class OneapiDevice;
class OneapiDeviceQueue;
class OneapiDeviceGraphicsInterop : public DeviceGraphicsInterop {
public:
explicit OneapiDeviceGraphicsInterop(OneapiDeviceQueue *queue);
OneapiDeviceGraphicsInterop(const OneapiDeviceGraphicsInterop &other) = delete;
OneapiDeviceGraphicsInterop(OneapiDeviceGraphicsInterop &&other) noexcept = delete;
~OneapiDeviceGraphicsInterop() override;
OneapiDeviceGraphicsInterop &operator=(const OneapiDeviceGraphicsInterop &other) = delete;
OneapiDeviceGraphicsInterop &operator=(OneapiDeviceGraphicsInterop &&other) = delete;
void set_buffer(GraphicsInteropBuffer &interop_buffer) override;
device_ptr map() override;
void unmap() override;
protected:
OneapiDeviceQueue *queue_ = nullptr;
OneapiDevice *device_ = nullptr;
/* Size of the buffer in bytes. */
size_t buffer_size_ = 0;
/* The destination was requested to be cleared. */
bool need_zero_ = false;
/* OneAPI resources. */
sycl::ext::oneapi::experimental::external_mem sycl_external_memory_{};
void *sycl_memory_ptr_ = nullptr;
/* Vulkan handle to free. */
# ifdef _WIN32
void *vulkan_windows_handle_ = nullptr;
# endif
void free();
};
CCL_NAMESPACE_END
#endif

View File

@@ -0,0 +1,173 @@
/* SPDX-FileCopyrightText: 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0 */
#ifdef WITH_ONEAPI
# include "device/oneapi/queue.h"
# include "device/oneapi/device_impl.h"
# include "device/oneapi/graphics_interop.h"
# include "util/log.h"
# include "kernel/device/oneapi/kernel.h"
CCL_NAMESPACE_BEGIN
struct KernelExecutionInfo {
double elapsed_summary = 0.0;
int enqueue_count = 0;
};
/* OneapiDeviceQueue */
OneapiDeviceQueue::OneapiDeviceQueue(OneapiDevice *device)
: DeviceQueue(device), oneapi_device_(device)
{
}
int OneapiDeviceQueue::num_concurrent_states(const size_t state_size) const
{
int num_states = 4 * num_concurrent_busy_states(state_size);
LOG_TRACE << "GPU queue concurrent states: " << num_states << ", using up to "
<< string_human_readable_size(num_states * state_size);
return num_states;
}
int OneapiDeviceQueue::num_concurrent_busy_states(const size_t /*state_size*/) const
{
const int max_num_threads = oneapi_device_->get_num_multiprocessors() *
oneapi_device_->get_max_num_threads_per_multiprocessor();
return 4 * max(8 * max_num_threads, 65536);
}
int OneapiDeviceQueue::num_sort_partitions(int max_num_paths, uint /*max_scene_shaders*/) const
{
int sort_partition_elements = (oneapi_device_->get_max_num_threads_per_multiprocessor() >= 128) ?
65536 :
8192;
/* Sort partitioning with local sorting on Intel GPUs is currently the most effective solution no
* matter the number of shaders. */
return max(max_num_paths / sort_partition_elements, 1);
}
void OneapiDeviceQueue::init_execution()
{
oneapi_device_->load_image_info(nullptr);
SyclQueue *device_queue = oneapi_device_->sycl_queue();
void *kg_dptr = oneapi_device_->kernel_globals_device_pointer();
assert(device_queue);
assert(kg_dptr);
kernel_context_ = make_unique<KernelContext>();
kernel_context_->queue = device_queue;
kernel_context_->kernel_globals = kg_dptr;
debug_init_execution();
}
void OneapiDeviceQueue::load_image_info()
{
oneapi_device_->load_image_info(this);
}
bool OneapiDeviceQueue::enqueue(DeviceKernel kernel,
const int signed_kernel_work_size,
const DeviceKernelArguments &_args)
{
if (oneapi_device_->have_error()) {
return false;
}
/* Update image info in case memory moved to host. */
if (oneapi_device_->load_image_info(nullptr)) {
if (!synchronize()) {
return false;
}
}
void **args = const_cast<void **>(_args.values);
debug_enqueue_begin(kernel, signed_kernel_work_size);
assert(signed_kernel_work_size >= 0);
size_t kernel_global_size = (size_t)signed_kernel_work_size;
size_t kernel_local_size;
assert(kernel_context_);
kernel_context_->scene_max_shaders = oneapi_device_->scene_max_shaders();
oneapi_device_->get_adjusted_global_and_local_sizes(
kernel_context_->queue, kernel, kernel_global_size, kernel_local_size);
/* Call the oneAPI kernel DLL to launch the requested kernel. */
bool is_finished_ok = oneapi_device_->enqueue_kernel(
kernel_context_.get(), kernel, kernel_global_size, kernel_local_size, args);
if (is_finished_ok == false) {
oneapi_device_->set_error("oneAPI kernel \"" + std::string(device_kernel_as_string(kernel)) +
"\" execution error: got runtime exception \"" +
oneapi_device_->oneapi_error_message() + "\"");
}
debug_enqueue_end();
return is_finished_ok;
}
bool OneapiDeviceQueue::synchronize()
{
if (oneapi_device_->have_error()) {
return false;
}
bool is_finished_ok = oneapi_device_->queue_synchronize(oneapi_device_->sycl_queue());
if (is_finished_ok == false) {
oneapi_device_->set_error("oneAPI unknown kernel execution error: got runtime exception \"" +
oneapi_device_->oneapi_error_message() + "\"");
}
debug_synchronize();
return !(oneapi_device_->have_error());
}
void OneapiDeviceQueue::zero_to_device(device_memory &mem)
{
oneapi_device_->mem_zero(mem);
}
void OneapiDeviceQueue::copy_to_device(device_memory &mem)
{
oneapi_device_->mem_copy_to(mem);
}
void OneapiDeviceQueue::copy_from_device(device_memory &mem)
{
oneapi_device_->mem_copy_from(mem);
}
void *OneapiDeviceQueue::copy_from_device_synchronized(device_memory &mem,
vector<uint8_t> &storage)
{
if (mem.memory_size() == 0) {
return nullptr;
}
storage.resize(mem.memory_size());
oneapi_device_->mem_copy_from(mem, 0, 0, 0, 0, storage.data());
synchronize();
return storage.data();
}
# ifdef SYCL_LINEAR_MEMORY_INTEROP_AVAILABLE
unique_ptr<DeviceGraphicsInterop> OneapiDeviceQueue::graphics_interop_create()
{
return make_unique<OneapiDeviceGraphicsInterop>(this);
}
# endif
CCL_NAMESPACE_END
#endif /* WITH_ONEAPI */

View File

@@ -0,0 +1,62 @@
/* SPDX-FileCopyrightText: 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0 */
#pragma once
#ifdef WITH_ONEAPI
# include "device/memory.h"
# include "device/queue.h"
# include "kernel/device/oneapi/kernel.h"
# include "util/unique_ptr.h"
CCL_NAMESPACE_BEGIN
class OneapiDevice;
class device_memory;
/* Base class for OneAPI queues. */
class OneapiDeviceQueue : public DeviceQueue {
public:
explicit OneapiDeviceQueue(OneapiDevice *device);
int num_concurrent_states(const size_t state_size) const override;
int num_concurrent_busy_states(const size_t state_size) const override;
int num_sort_partitions(int max_num_paths, uint max_scene_shaders) const override;
void init_execution() override;
void load_image_info() override;
bool enqueue(DeviceKernel kernel,
const int kernel_work_size,
const DeviceKernelArguments &args) override;
bool synchronize() override;
void zero_to_device(device_memory &mem) override;
void copy_to_device(device_memory &mem) override;
void copy_from_device(device_memory &mem) override;
void *copy_from_device_synchronized(device_memory &mem, vector<uint8_t> &storage) override;
bool supports_local_atomic_sort() const override
{
return true;
}
# ifdef SYCL_LINEAR_MEMORY_INTEROP_AVAILABLE
unique_ptr<DeviceGraphicsInterop> graphics_interop_create() override;
# endif
protected:
OneapiDevice *oneapi_device_;
unique_ptr<KernelContext> kernel_context_;
};
CCL_NAMESPACE_END
#endif /* WITH_ONEAPI */