diff options
author | Xavier Hallade <xavier.hallade@intel.com> | 2022-06-29 13:58:04 +0300 |
---|---|---|
committer | Xavier Hallade <xavier.hallade@intel.com> | 2022-06-29 13:58:04 +0300 |
commit | a02992f1313811c9905e44dc95a0aee31d707f67 (patch) | |
tree | 2d1f59524e2a298bb530ad578a2d2b9e2c4a1432 /intern/cycles/kernel/CMakeLists.txt | |
parent | 302b04a5a3fc0e767ac784424f78ce2edf5d2844 (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.txt | 226 |
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 |