Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Hallade <xavier.hallade@intel.com>2022-06-29 13:58:04 +0300
committerXavier Hallade <xavier.hallade@intel.com>2022-06-29 13:58:04 +0300
commita02992f1313811c9905e44dc95a0aee31d707f67 (patch)
tree2d1f59524e2a298bb530ad578a2d2b9e2c4a1432 /intern/cycles/kernel/CMakeLists.txt
parent302b04a5a3fc0e767ac784424f78ce2edf5d2844 (diff)
Cycles: Add support for rendering on Intel GPUs using oneAPI
This patch adds a new Cycles device with similar functionality to the existing GPU devices. Kernel compilation and runtime interaction happen via oneAPI DPC++ compiler and SYCL API. This implementation is primarly focusing on Intel® Arc™ GPUs and other future Intel GPUs. The first supported drivers are 101.1660 on Windows and 22.10.22597 on Linux. The necessary tools for compilation are: - A SYCL compiler such as oneAPI DPC++ compiler or https://github.com/intel/llvm - Intel® oneAPI Level Zero which is used for low level device queries: https://github.com/oneapi-src/level-zero - To optionally generate prebuilt graphics binaries: Intel® Graphics Compiler All are included in Linux precompiled libraries on svn: https://svn.blender.org/svnroot/bf-blender/trunk/lib The same goes for Windows precompiled binaries but for the graphics compiler, available as "Intel® Graphics Offline Compiler for OpenCL™ Code" from https://www.intel.com/content/www/us/en/developer/articles/tool/oneapi-standalone-components.html, for which path can be set as OCLOC_INSTALL_DIR. Being based on the open SYCL standard, this implementation could also be extended to run on other compatible non-Intel hardware in the future. Reviewed By: sergey, brecht Differential Revision: https://developer.blender.org/D15254 Co-authored-by: Nikita Sirgienko <nikita.sirgienko@intel.com> Co-authored-by: Stefan Werner <stefan.werner@intel.com>
Diffstat (limited to 'intern/cycles/kernel/CMakeLists.txt')
-rw-r--r--intern/cycles/kernel/CMakeLists.txt226
1 files changed, 226 insertions, 0 deletions
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index a07d7852211..ccd694dfdfd 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -37,6 +37,10 @@ set(SRC_KERNEL_DEVICE_OPTIX
device/optix/kernel_shader_raytrace.cu
)
+set(SRC_KERNEL_DEVICE_ONEAPI
+ device/oneapi/kernel.cpp
+)
+
set(SRC_KERNEL_DEVICE_CPU_HEADERS
device/cpu/compat.h
device/cpu/image.h
@@ -78,6 +82,17 @@ set(SRC_KERNEL_DEVICE_METAL_HEADERS
device/metal/globals.h
)
+set(SRC_KERNEL_DEVICE_ONEAPI_HEADERS
+ device/oneapi/compat.h
+ device/oneapi/context_begin.h
+ device/oneapi/context_end.h
+ device/oneapi/device_id.h
+ device/oneapi/globals.h
+ device/oneapi/image.h
+ device/oneapi/kernel.h
+ device/oneapi/kernel_templates.h
+)
+
set(SRC_KERNEL_CLOSURE_HEADERS
closure/alloc.h
closure/bsdf.h
@@ -687,6 +702,212 @@ if(WITH_CYCLES_DEVICE_OPTIX AND WITH_CYCLES_CUDA_BINARIES)
cycles_set_solution_folder(cycles_kernel_optix)
endif()
+if(WITH_CYCLES_DEVICE_ONEAPI)
+ if(WIN32)
+ set(cycles_kernel_oneapi_lib ${CMAKE_CURRENT_BINARY_DIR}/cycles_kernel_oneapi.dll)
+ else()
+ set(cycles_kernel_oneapi_lib ${CMAKE_CURRENT_BINARY_DIR}/cycles_kernel_oneapi.so)
+ endif()
+
+ set(cycles_oneapi_kernel_sources
+ ${SRC_KERNEL_DEVICE_ONEAPI}
+ ${SRC_KERNEL_HEADERS}
+ ${SRC_KERNEL_DEVICE_GPU_HEADERS}
+ ${SRC_KERNEL_DEVICE_ONEAPI_HEADERS}
+ ${SRC_UTIL_HEADERS}
+ )
+
+ # SYCL_CPP_FLAGS is a variable that the user can set to pass extra compiler options
+ set(sycl_compiler_flags
+ ${CMAKE_CURRENT_SOURCE_DIR}/${SRC_KERNEL_DEVICE_ONEAPI}
+ -fsycl
+ -fsycl-unnamed-lambda
+ -fdelayed-template-parsing
+ -mllvm -inlinedefault-threshold=300
+ -mllvm -inlinehint-threshold=400
+ -shared
+ -DWITH_ONEAPI
+ -ffast-math
+ -DNDEBUG
+ -O2
+ -o ${cycles_kernel_oneapi_lib}
+ -I${CMAKE_CURRENT_SOURCE_DIR}/..
+ -I${LEVEL_ZERO_INCLUDE_DIR}
+ ${LEVEL_ZERO_LIBRARY}
+ ${SYCL_CPP_FLAGS}
+ )
+
+
+ if (WITH_CYCLES_ONEAPI_SYCL_HOST_ENABLED)
+ list(APPEND sycl_compiler_flags -DWITH_ONEAPI_SYCL_HOST_ENABLED)
+ endif()
+
+ # Set defaults for spir64 and spir64_gen options
+ if (NOT DEFINED CYCLES_ONEAPI_SYCL_OPTIONS_spir64)
+ set(CYCLES_ONEAPI_SYCL_OPTIONS_spir64 "-options '-ze-opt-large-register-file -ze-opt-regular-grf-kernel integrator_intersect'")
+ endif()
+ if (NOT DEFINED CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen)
+ SET (CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen "${CYCLES_ONEAPI_SYCL_OPTIONS_spir64}" CACHE STRING "Extra build options for spir64_gen target")
+ endif()
+ # enabling zebin (graphics binary format with improved compatibility) on Windows only while support on Linux isn't available yet
+ if(WIN32)
+ string(PREPEND CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen "--format zebin ")
+ endif()
+ string(PREPEND CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen "-device ${CYCLES_ONEAPI_SPIR64_GEN_DEVICES} ")
+
+ if (WITH_CYCLES_ONEAPI_BINARIES)
+ # Iterate over all targest and their options
+ list (JOIN CYCLES_ONEAPI_SYCL_TARGETS "," targets_string)
+ list (APPEND sycl_compiler_flags -fsycl-targets=${targets_string})
+ foreach(target ${CYCLES_ONEAPI_SYCL_TARGETS})
+ if(DEFINED CYCLES_ONEAPI_SYCL_OPTIONS_${target})
+ list (APPEND sycl_compiler_flags -Xsycl-target-backend=${target} "${CYCLES_ONEAPI_SYCL_OPTIONS_${target}}")
+ endif()
+ endforeach()
+ else()
+ # If AOT is disabled, build for spir64
+ list(APPEND sycl_compiler_flags
+ -fsycl-targets=spir64
+ -Xsycl-target-backend=spir64 "${CYCLES_ONEAPI_SYCL_OPTIONS_spir64}")
+ endif()
+
+ if(WITH_NANOVDB)
+ list(APPEND sycl_compiler_flags
+ -DWITH_NANOVDB
+ -I"${NANOVDB_INCLUDE_DIR}")
+ endif()
+
+ if(WITH_CYCLES_DEBUG)
+ list(APPEND sycl_compiler_flags -DWITH_CYCLES_DEBUG)
+ endif()
+
+ get_filename_component(sycl_compiler_root ${SYCL_COMPILER} DIRECTORY)
+ get_filename_component(sycl_compiler_compiler_name ${SYCL_COMPILER} NAME_WE)
+
+ if(NOT OCLOC_INSTALL_DIR)
+ get_filename_component(OCLOC_INSTALL_DIR "${sycl_compiler_root}/../lib/ocloc" ABSOLUTE)
+ endif()
+ if(WITH_CYCLES_ONEAPI_BINARIES AND NOT EXISTS ${OCLOC_INSTALL_DIR})
+ message(FATAL_ERROR "WITH_CYCLES_ONEAPI_BINARIES requires ocloc but ${OCLOC_INSTALL_DIR} directory doesn't exist."
+ " A different ocloc directory can be set using OCLOC_INSTALL_DIR cmake variable.")
+ endif()
+
+ if(UNIX AND NOT APPLE)
+ if(NOT WITH_CXX11_ABI)
+ check_library_exists(sycl
+ _ZN2cl4sycl7handler22verifyUsedKernelBundleERKSs ${sycl_compiler_root}/../lib SYCL_NO_CXX11_ABI)
+ if(SYCL_NO_CXX11_ABI)
+ list(APPEND sycl_compiler_flags -D_GLIBCXX_USE_CXX11_ABI=0)
+ endif()
+ endif()
+ endif()
+
+ if(WIN32)
+ list(APPEND sycl_compiler_flags
+ -fms-extensions
+ -fms-compatibility
+ -D_WINDLL
+ -D_MBCS
+ -DWIN32
+ -D_WINDOWS
+ -D_CRT_NONSTDC_NO_DEPRECATE
+ -D_CRT_SECURE_NO_DEPRECATE
+ -DONEAPI_EXPORT)
+
+ if(sycl_compiler_compiler_name MATCHES "dpcpp")
+ # The oneAPI distribution calls the compiler "dpcpp" and comes with a script that sets environment variables.
+ add_custom_command(
+ OUTPUT ${cycles_kernel_oneapi_lib}
+ COMMAND "${sycl_compiler_root}/../../env/vars.bat"
+ COMMAND ${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}
+ DEPENDS ${cycles_oneapi_kernel_sources})
+ else()
+ # The open source SYCL compiler just goes by clang++ and does not have such a script.
+ # Set the variables manually.
+ string(REPLACE /Redist/ /Tools/ MSVC_TOOLS_DIR ${MSVC_REDIST_DIR})
+ if(NOT CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION) # case for Ninja on Windows
+ get_filename_component(cmake_mt_dir ${CMAKE_MT} DIRECTORY)
+ string(REPLACE /bin/ /Lib/ WINDOWS_KIT_DIR ${cmake_mt_dir})
+ get_filename_component(WINDOWS_KIT_DIR "${WINDOWS_KIT_DIR}/../" ABSOLUTE)
+ else()
+ set(WINDOWS_KIT_DIR ${WINDOWS_KITS_DIR}/Lib/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION})
+ endif()
+ list(APPEND sycl_compiler_flags
+ -L "${MSVC_TOOLS_DIR}/lib/x64"
+ -L "${WINDOWS_KIT_DIR}/um/x64"
+ -L "${WINDOWS_KIT_DIR}/ucrt/x64")
+ add_custom_command(
+ OUTPUT ${cycles_kernel_oneapi_lib}
+ COMMAND ${CMAKE_COMMAND} -E env
+ "LIB=${sycl_compiler_root}/../lib" # for compiler to find sycl.lib
+ "PATH=${OCLOC_INSTALL_DIR};${sycl_compiler_root}"
+ ${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}
+ DEPENDS ${cycles_oneapi_kernel_sources})
+ endif()
+ else()
+ list(APPEND sycl_compiler_flags -fPIC)
+
+ # avoid getting __FAST_MATH__ to be defined for the graphics compiler on CentOS 7 until the compile-time issue it triggers gets fixed.
+ if(WITH_CYCLES_ONEAPI_BINARIES)
+ list(APPEND sycl_compiler_flags -fhonor-nans)
+ endif()
+
+ # add $ORIGIN to cycles_kernel_oneapi.so rpath so libsycl.so and
+ # libpi_level_zero.so can be placed next to it and get found.
+ list(APPEND sycl_compiler_flags -Wl,-rpath,'$$ORIGIN')
+
+ # The oneAPI distribution calls the compiler "dpcpp" and comes with a script that sets environment variables.
+ if(sycl_compiler_compiler_name MATCHES "dpcpp")
+ add_custom_command(
+ OUTPUT ${cycles_kernel_oneapi_lib}
+ COMMAND bash -c \"source ${sycl_compiler_root}/../../env/vars.sh&&${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}\"
+ DEPENDS ${cycles_oneapi_kernel_sources})
+ else()
+ # The open source SYCL compiler just goes by clang++ and does not have such a script.
+ # Set the variables manually.
+ if(NOT IGC_INSTALL_DIR)
+ get_filename_component(IGC_INSTALL_DIR "${sycl_compiler_root}/../lib/igc" ABSOLUTE)
+ endif()
+ add_custom_command(
+ OUTPUT ${cycles_kernel_oneapi_lib}
+ COMMAND ${CMAKE_COMMAND} -E env
+ "LD_LIBRARY_PATH=${sycl_compiler_root}/../lib:${OCLOC_INSTALL_DIR}/lib:${IGC_INSTALL_DIR}/lib"
+ "PATH=${OCLOC_INSTALL_DIR}/bin:${sycl_compiler_root}:$ENV{PATH}" # env PATH is for compiler to find ld
+ ${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}
+ DEPENDS ${cycles_oneapi_kernel_sources})
+ endif()
+ endif()
+
+ # install dynamic libraries required at runtime
+ if(WIN32)
+ set(SYCL_RUNTIME_DEPENDENCIES
+ sycl.dll
+ pi_level_zero.dll
+ )
+ if(NOT WITH_BLENDER)
+ # For the Cycles standalone put libraries next to the Cycles application.
+ delayed_install("${sycl_compiler_root}" "${SYCL_RUNTIME_DEPENDENCIES}" ${CYCLES_INSTALL_PATH})
+ else()
+ # For Blender put the libraries next to the Blender executable.
+ #
+ # Note that the installation path in the delayed_install is relative to the versioned folder,
+ # which means we need to go one level up.
+ delayed_install("${sycl_compiler_root}" "${SYCL_RUNTIME_DEPENDENCIES}" "../")
+ endif()
+ elseif(UNIX AND NOT APPLE)
+ file(GLOB SYCL_RUNTIME_DEPENDENCIES
+ ${sycl_compiler_root}/../lib/libsycl.so
+ ${sycl_compiler_root}/../lib/libsycl.so.[0-9]
+ ${sycl_compiler_root}/../lib/libsycl.so.[0-9].[0-9].[0-9]-[0-9]
+ )
+ list(APPEND SYCL_RUNTIME_DEPENDENCIES ${sycl_compiler_root}/../lib/libpi_level_zero.so)
+ delayed_install("" "${SYCL_RUNTIME_DEPENDENCIES}" ${CYCLES_INSTALL_PATH}/lib)
+ endif()
+
+ delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${cycles_kernel_oneapi_lib}" ${CYCLES_INSTALL_PATH}/lib)
+ add_custom_target(cycles_kernel_oneapi ALL DEPENDS ${cycles_kernel_oneapi_lib})
+endif()
+
# OSL module
if(WITH_CYCLES_OSL)
@@ -752,6 +973,7 @@ cycles_add_library(cycles_kernel "${LIB}"
${SRC_KERNEL_DEVICE_HIP_HEADERS}
${SRC_KERNEL_DEVICE_OPTIX_HEADERS}
${SRC_KERNEL_DEVICE_METAL_HEADERS}
+ ${SRC_KERNEL_DEVICE_ONEAPI_HEADERS}
)
source_group("bake" FILES ${SRC_KERNEL_BAKE_HEADERS})
@@ -764,6 +986,7 @@ source_group("device\\gpu" FILES ${SRC_KERNEL_DEVICE_GPU_HEADERS})
source_group("device\\hip" FILES ${SRC_KERNEL_DEVICE_HIP} ${SRC_KERNEL_DEVICE_HIP_HEADERS})
source_group("device\\optix" FILES ${SRC_KERNEL_DEVICE_OPTIX} ${SRC_KERNEL_DEVICE_OPTIX_HEADERS})
source_group("device\\metal" FILES ${SRC_KERNEL_DEVICE_METAL} ${SRC_KERNEL_DEVICE_METAL_HEADERS})
+source_group("device\\oneapi" FILES ${SRC_KERNEL_DEVICE_ONEAPI} ${SRC_KERNEL_DEVICE_ONEAPI_HEADERS})
source_group("film" FILES ${SRC_KERNEL_FILM_HEADERS})
source_group("geom" FILES ${SRC_KERNEL_GEOM_HEADERS})
source_group("integrator" FILES ${SRC_KERNEL_INTEGRATOR_HEADERS})
@@ -782,6 +1005,9 @@ endif()
if(WITH_CYCLES_HIP)
add_dependencies(cycles_kernel cycles_kernel_hip)
endif()
+if(WITH_CYCLES_DEVICE_ONEAPI)
+ add_dependencies(cycles_kernel cycles_kernel_oneapi)
+endif()
# Install kernel source for runtime compilation