[SYCL] Rebasing the SYCL support branch on top of the Einge upstream master branch.

* Unifying all loadLocalTile from lhs and rhs to an extract_block function.
* Adding get_tensor operation which was missing in TensorContractionMapper.
* Adding the -D method missing from cmake for Disable_Skinny Contraction operation.
* Wrapping all the indices in TensorScanSycl into Scan parameter struct.
* Fixing typo in Device SYCL
* Unifying load to private register for tall/skinny no shared
* Unifying load to vector tile for tensor-vector/vector-tensor operation
* Removing all the LHS/RHS class for extracting data from global
* Removing Outputfunction from TensorContractionSkinnyNoshared.
* Combining the local memory version of tall/skinny and normal tensor contraction into one kernel.
* Combining the no-local memory version of tall/skinny and normal tensor contraction into one kernel.
* Combining General Tensor-Vector and VectorTensor contraction into one kernel.
* Making double buffering optional for Tensor contraction when local memory is version is used.
* Modifying benchmark to accept custom Reduction Sizes
* Disabling AVX optimization for SYCL backend on the host to allow SSE optimization to the host
* Adding Test for SYCL
* Modifying SYCL CMake
This commit is contained in:
Mehdi Goli
2019-11-28 10:08:54 +00:00
parent ea51a9eace
commit 00f32752f7
56 changed files with 7336 additions and 4826 deletions

View File

@@ -113,111 +113,28 @@ macro(ei_add_test_internal testname testname_with_suffix)
add_dependencies("Build${current_subproject}" ${targetname})
set_property(TEST ${testname_with_suffix} PROPERTY LABELS "${current_subproject}")
endif()
endmacro()
# SYCL
macro(ei_add_test_internal_sycl testname testname_with_suffix)
set(targetname ${testname_with_suffix})
if(EIGEN_ADD_TEST_FILENAME_EXTENSION)
set(filename ${testname}.${EIGEN_ADD_TEST_FILENAME_EXTENSION})
else()
set(filename ${testname}.cpp)
endif()
set( include_file "${CMAKE_CURRENT_BINARY_DIR}/inc_${filename}")
set( bc_file "${CMAKE_CURRENT_BINARY_DIR}/${filename}.sycl")
set( host_file "${CMAKE_CURRENT_SOURCE_DIR}/${filename}")
if(NOT EIGEN_SYCL_TRISYCL)
include_directories( SYSTEM ${COMPUTECPP_PACKAGE_ROOT_DIR}/include)
add_custom_command(
OUTPUT ${include_file}
COMMAND ${CMAKE_COMMAND} -E echo "\\#include \\\"${host_file}\\\"" > ${include_file}
COMMAND ${CMAKE_COMMAND} -E echo "\\#include \\\"${bc_file}\\\"" >> ${include_file}
DEPENDS ${filename} ${bc_file}
COMMENT "Building ComputeCpp integration header file ${include_file}"
)
# Add a custom target for the generated integration header
add_custom_target("${testname}_integration_header_sycl" DEPENDS ${include_file})
add_executable(${targetname} ${include_file})
add_dependencies(${targetname} "${testname}_integration_header_sycl")
else()
add_executable(${targetname} ${host_file})
endif()
add_sycl_to_target(${targetname} ${CMAKE_CURRENT_BINARY_DIR} ${filename})
if (targetname MATCHES "^eigen2_")
add_dependencies(eigen2_buildtests ${targetname})
else()
add_dependencies(buildtests ${targetname})
endif()
if(EIGEN_NO_ASSERTION_CHECKING)
ei_add_target_property(${targetname} COMPILE_FLAGS "-DEIGEN_NO_ASSERTION_CHECKING=1")
else()
if(EIGEN_DEBUG_ASSERTS)
ei_add_target_property(${targetname} COMPILE_FLAGS "-DEIGEN_DEBUG_ASSERTS=1")
endif()
endif()
ei_add_target_property(${targetname} COMPILE_FLAGS "-DEIGEN_TEST_MAX_SIZE=${EIGEN_TEST_MAX_SIZE}")
if(MSVC AND NOT EIGEN_SPLIT_LARGE_TESTS)
ei_add_target_property(${targetname} COMPILE_FLAGS "/bigobj")
endif()
# let the user pass flags.
if(${ARGC} GREATER 2)
ei_add_target_property(${targetname} COMPILE_FLAGS "${ARGV2}")
endif()
if(EIGEN_TEST_CUSTOM_CXX_FLAGS)
ei_add_target_property(${targetname} COMPILE_FLAGS "${EIGEN_TEST_CUSTOM_CXX_FLAGS}")
endif()
if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)
target_link_libraries(${targetname} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})
endif()
if(EXTERNAL_LIBS)
target_link_libraries(${targetname} ${EXTERNAL_LIBS})
endif()
if(EIGEN_TEST_CUSTOM_LINKER_FLAGS)
target_link_libraries(${targetname} ${EIGEN_TEST_CUSTOM_LINKER_FLAGS})
endif()
if(${ARGC} GREATER 3)
set(libs_to_link ${ARGV3})
# it could be that some cmake module provides a bad library string " " (just spaces),
# and that severely breaks target_link_libraries ("can't link to -l-lstdc++" errors).
# so we check for strings containing only spaces.
string(STRIP "${libs_to_link}" libs_to_link_stripped)
string(LENGTH "${libs_to_link_stripped}" libs_to_link_stripped_length)
if(${libs_to_link_stripped_length} GREATER 0)
# notice: no double quotes around ${libs_to_link} here. It may be a list.
target_link_libraries(${targetname} ${libs_to_link})
endif()
endif()
add_test(${testname_with_suffix} "${targetname}")
# Specify target and test labels according to EIGEN_CURRENT_SUBPROJECT
get_property(current_subproject GLOBAL PROPERTY EIGEN_CURRENT_SUBPROJECT)
if ((current_subproject) AND (NOT (current_subproject STREQUAL "")))
set_property(TARGET ${targetname} PROPERTY LABELS "Build${current_subproject}")
add_dependencies("Build${current_subproject}" ${targetname})
set_property(TEST ${testname_with_suffix} PROPERTY LABELS "${current_subproject}")
endif()
endmacro()
if(EIGEN_SYCL)
# Force include of the SYCL file at the end to avoid errors.
set_property(TARGET ${targetname} PROPERTY COMPUTECPP_INCLUDE_AFTER 1)
# Set COMPILE_FLAGS to COMPILE_DEFINITIONS instead to avoid having to duplicate the flags
# to the device compiler.
get_target_property(target_compile_flags ${targetname} COMPILE_FLAGS)
separate_arguments(target_compile_flags)
foreach(flag ${target_compile_flags})
if(${flag} MATCHES "^-D.*")
string(REPLACE "-D" "" definition_flag ${flag})
set_property(TARGET ${targetname} APPEND PROPERTY COMPILE_DEFINITIONS ${definition_flag})
list(REMOVE_ITEM target_compile_flags ${flag})
endif()
endforeach()
set_property(TARGET ${targetname} PROPERTY COMPILE_FLAGS ${target_compile_flags})
# Link against pthread and add sycl to target
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(${targetname} Threads::Threads)
add_sycl_to_target(TARGET ${targetname} SOURCES ${filename})
endif(EIGEN_SYCL)
endmacro(ei_add_test_internal)
# Macro to add a test
#
# the unique mandatory parameter testname must correspond to a file
@@ -296,40 +213,6 @@ macro(ei_add_test testname)
endif()
endmacro()
macro(ei_add_test_sycl testname)
get_property(EIGEN_TESTS_LIST GLOBAL PROPERTY EIGEN_TESTS_LIST)
set(EIGEN_TESTS_LIST "${EIGEN_TESTS_LIST}${testname}\n")
set_property(GLOBAL PROPERTY EIGEN_TESTS_LIST "${EIGEN_TESTS_LIST}")
if(EIGEN_ADD_TEST_FILENAME_EXTENSION)
set(filename ${testname}.${EIGEN_ADD_TEST_FILENAME_EXTENSION})
else()
set(filename ${testname}.cpp)
endif()
file(READ "${filename}" test_source)
set(parts 0)
string(REGEX MATCHALL "CALL_SUBTEST_[0-9]+|EIGEN_TEST_PART_[0-9]+|EIGEN_SUFFIXES(;[0-9]+)+"
occurrences "${test_source}")
string(REGEX REPLACE "CALL_SUBTEST_|EIGEN_TEST_PART_|EIGEN_SUFFIXES" "" suffixes "${occurrences}")
list(REMOVE_DUPLICATES suffixes)
if(EIGEN_SPLIT_LARGE_TESTS AND suffixes)
add_custom_target(${testname})
foreach(suffix ${suffixes})
ei_add_test_internal_sycl(${testname} ${testname}_${suffix}
"${ARGV1} -DEIGEN_TEST_PART_${suffix}=1" "${ARGV2}")
add_dependencies(${testname} ${testname}_${suffix})
endforeach()
else()
set(symbols_to_enable_all_parts "")
foreach(suffix ${suffixes})
set(symbols_to_enable_all_parts
"${symbols_to_enable_all_parts} -DEIGEN_TEST_PART_${suffix}=1")
endforeach()
ei_add_test_internal_sycl(${testname} ${testname} "${ARGV1} ${symbols_to_enable_all_parts}" "${ARGV2}")
endif()
endmacro()
# adds a failtest, i.e. a test that succeed if the program fails to compile
# note that the test runner for these is CMake itself, when passed -DEIGEN_FAILTEST=ON
# so here we're just running CMake commands immediately, we're not adding any targets.

View File

@@ -2,7 +2,7 @@
# FindComputeCpp
#---------------
#
# Copyright 2016 Codeplay Software Ltd.
# Copyright 2016-2018 Codeplay Software Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use these files except in compliance with the License.
@@ -23,244 +23,421 @@
#
# Tools for finding and building with ComputeCpp.
#
# User must define COMPUTECPP_PACKAGE_ROOT_DIR pointing to the ComputeCpp
# installation.
# User must define ComputeCpp_DIR pointing to the ComputeCpp
# installation.
#
# Latest version of this file can be found at:
# https://github.com/codeplaysoftware/computecpp-sdk
# Require CMake version 3.2.2 or higher
cmake_minimum_required(VERSION 3.2.2)
# Check that a supported host compiler can be found
if(CMAKE_COMPILER_IS_GNUCXX)
# Require at least gcc 4.8
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
message(FATAL_ERROR
"host compiler - Not found! (gcc version must be at least 4.8)")
else()
message(STATUS "host compiler - gcc ${CMAKE_CXX_COMPILER_VERSION}")
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# Require at least clang 3.6
if (${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 3.6)
message(FATAL_ERROR
"host compiler - Not found! (clang version must be at least 3.6)")
else()
message(STATUS "host compiler - clang ${CMAKE_CXX_COMPILER_VERSION}")
endif()
else()
message(WARNING
"host compiler - Not found! (ComputeCpp supports GCC and Clang, see readme)")
endif()
set(COMPUTECPP_64_BIT_DEFAULT ON)
option(COMPUTECPP_64_BIT_CODE "Compile device code in 64 bit mode"
${COMPUTECPP_64_BIT_DEFAULT})
mark_as_advanced(COMPUTECPP_64_BIT_CODE)
option(COMPUTECPP_DISABLE_GCC_DUAL_ABI "Compile with pre-5.1 ABI" OFF)
mark_as_advanced(COMPUTECPP_DISABLE_GCC_DUAL_ABI)
cmake_minimum_required(VERSION 3.4.3)
include(FindPackageHandleStandardArgs)
set(COMPUTECPP_USER_FLAGS "" CACHE STRING "User flags for compute++")
separate_arguments(COMPUTECPP_USER_FLAGS)
mark_as_advanced(COMPUTECPP_USER_FLAGS)
# Find OpenCL package
set(COMPUTECPP_BITCODE "spir64" CACHE STRING
"Bitcode type to use as SYCL target in compute++")
mark_as_advanced(COMPUTECPP_BITCODE)
find_package(OpenCL REQUIRED)
# Find ComputeCpp packagee
if(NOT COMPUTECPP_PACKAGE_ROOT_DIR)
message(FATAL_ERROR
"ComputeCpp package - Not found! (please set COMPUTECPP_PACKAGE_ROOT_DIR")
else()
message(STATUS "ComputeCpp package - Found")
# Find ComputeCpp package
if(DEFINED ComputeCpp_DIR)
set(computecpp_find_hint ${ComputeCpp_DIR})
elseif(DEFINED ENV{COMPUTECPP_DIR})
set(computecpp_find_hint $ENV{COMPUTECPP_DIR})
endif()
# Obtain the path to compute++
find_program(COMPUTECPP_DEVICE_COMPILER compute++ PATHS
${COMPUTECPP_PACKAGE_ROOT_DIR} PATH_SUFFIXES bin)
if (EXISTS ${COMPUTECPP_DEVICE_COMPILER})
mark_as_advanced(COMPUTECPP_DEVICE_COMPILER)
message(STATUS "compute++ - Found")
else()
message(FATAL_ERROR "compute++ - Not found! (${COMPUTECPP_DEVICE_COMPILER})")
endif()
# Used for running executables on the host
set(computecpp_host_find_hint ${computecpp_find_hint})
# Obtain the path to computecpp_info
find_program(COMPUTECPP_INFO_TOOL computecpp_info PATHS
${COMPUTECPP_PACKAGE_ROOT_DIR} PATH_SUFFIXES bin)
if (EXISTS ${COMPUTECPP_INFO_TOOL})
mark_as_advanced(${COMPUTECPP_INFO_TOOL})
message(STATUS "computecpp_info - Found")
else()
message(FATAL_ERROR "computecpp_info - Not found! (${COMPUTECPP_INFO_TOOL})")
endif()
# Obtain the path to the ComputeCpp runtime library
find_library(COMPUTECPP_RUNTIME_LIBRARY ComputeCpp PATHS ${COMPUTECPP_PACKAGE_ROOT_DIR}
HINTS ${COMPUTECPP_PACKAGE_ROOT_DIR}/lib PATH_SUFFIXES lib
DOC "ComputeCpp Runtime Library" NO_DEFAULT_PATH)
if (EXISTS ${COMPUTECPP_RUNTIME_LIBRARY})
mark_as_advanced(COMPUTECPP_RUNTIME_LIBRARY)
message(STATUS "libComputeCpp.so - Found")
else()
message(FATAL_ERROR "libComputeCpp.so - Not found!")
endif()
# Obtain the ComputeCpp include directory
set(COMPUTECPP_INCLUDE_DIRECTORY ${COMPUTECPP_PACKAGE_ROOT_DIR}/include/)
if (NOT EXISTS ${COMPUTECPP_INCLUDE_DIRECTORY})
message(FATAL_ERROR "ComputeCpp includes - Not found!")
else()
message(STATUS "ComputeCpp includes - Found")
endif()
# Obtain the package version
execute_process(COMMAND ${COMPUTECPP_INFO_TOOL} "--dump-version"
OUTPUT_VARIABLE COMPUTECPP_PACKAGE_VERSION
RESULT_VARIABLE COMPUTECPP_INFO_TOOL_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT COMPUTECPP_INFO_TOOL_RESULT EQUAL "0")
message(FATAL_ERROR "Package version - Error obtaining version!")
else()
mark_as_advanced(COMPUTECPP_PACKAGE_VERSION)
message(STATUS "Package version - ${COMPUTECPP_PACKAGE_VERSION}")
endif()
# Obtain the device compiler flags
execute_process(COMMAND ${COMPUTECPP_INFO_TOOL} "--dump-device-compiler-flags"
OUTPUT_VARIABLE COMPUTECPP_DEVICE_COMPILER_FLAGS
RESULT_VARIABLE COMPUTECPP_INFO_TOOL_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT COMPUTECPP_INFO_TOOL_RESULT EQUAL "0")
message(FATAL_ERROR "compute++ flags - Error obtaining compute++ flags!")
else()
mark_as_advanced(COMPUTECPP_COMPILER_FLAGS)
message(STATUS "compute++ flags - ${COMPUTECPP_DEVICE_COMPILER_FLAGS}")
endif()
# Check if the platform is supported
execute_process(COMMAND ${COMPUTECPP_INFO_TOOL} "--dump-is-supported"
OUTPUT_VARIABLE COMPUTECPP_PLATFORM_IS_SUPPORTED
RESULT_VARIABLE COMPUTECPP_INFO_TOOL_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT COMPUTECPP_INFO_TOOL_RESULT EQUAL "0")
message(FATAL_ERROR "platform - Error checking platform support!")
else()
mark_as_advanced(COMPUTECPP_PLATFORM_IS_SUPPORTED)
if (COMPUTECPP_PLATFORM_IS_SUPPORTED)
message(STATUS "platform - your system can support ComputeCpp")
else()
message(STATUS "platform - your system CANNOT support ComputeCpp")
if(CMAKE_CROSSCOMPILING)
# ComputeCpp_HOST_DIR is used to find executables that are run on the host
if(DEFINED ComputeCpp_HOST_DIR)
set(computecpp_host_find_hint ${ComputeCpp_HOST_DIR})
elseif(DEFINED ENV{COMPUTECPP_HOST_DIR})
set(computecpp_host_find_hint $ENV{COMPUTECPP_HOST_DIR})
endif()
endif()
set(COMPUTECPP_USER_FLAGS
-sycl-compress-name
-Wall
-no-serial-memop
-DEIGEN_NO_ASSERTION_CHECKING=1
find_program(ComputeCpp_DEVICE_COMPILER_EXECUTABLE compute++
HINTS ${computecpp_host_find_hint}
PATH_SUFFIXES bin)
find_program(ComputeCpp_INFO_EXECUTABLE computecpp_info
HINTS ${computecpp_host_find_hint}
PATH_SUFFIXES bin)
find_library(COMPUTECPP_RUNTIME_LIBRARY
NAMES ComputeCpp ComputeCpp_vs2015
HINTS ${computecpp_find_hint}
PATH_SUFFIXES lib
DOC "ComputeCpp Runtime Library")
find_library(COMPUTECPP_RUNTIME_LIBRARY_DEBUG
NAMES ComputeCpp ComputeCpp_vs2015_d
HINTS ${computecpp_find_hint}
PATH_SUFFIXES lib
DOC "ComputeCpp Debug Runtime Library")
find_path(ComputeCpp_INCLUDE_DIRS
NAMES "CL/sycl.hpp"
HINTS ${computecpp_find_hint}/include
DOC "The ComputeCpp include directory")
get_filename_component(ComputeCpp_INCLUDE_DIRS ${ComputeCpp_INCLUDE_DIRS} ABSOLUTE)
get_filename_component(computecpp_canonical_root_dir "${ComputeCpp_INCLUDE_DIRS}/.." ABSOLUTE)
set(ComputeCpp_ROOT_DIR "${computecpp_canonical_root_dir}" CACHE PATH
"The root of the ComputeCpp install")
if(NOT ComputeCpp_INFO_EXECUTABLE)
message(WARNING "Can't find computecpp_info - check ComputeCpp_DIR")
else()
execute_process(COMMAND ${ComputeCpp_INFO_EXECUTABLE} "--dump-version"
OUTPUT_VARIABLE ComputeCpp_VERSION
RESULT_VARIABLE ComputeCpp_INFO_EXECUTABLE_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT ComputeCpp_INFO_EXECUTABLE_RESULT EQUAL "0")
message(WARNING "Package version - Error obtaining version!")
endif()
execute_process(COMMAND ${ComputeCpp_INFO_EXECUTABLE} "--dump-is-supported"
OUTPUT_VARIABLE COMPUTECPP_PLATFORM_IS_SUPPORTED
RESULT_VARIABLE ComputeCpp_INFO_EXECUTABLE_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT ComputeCpp_INFO_EXECUTABLE_RESULT EQUAL "0")
message(WARNING "platform - Error checking platform support!")
else()
mark_as_advanced(COMPUTECPP_PLATFORM_IS_SUPPORTED)
if (COMPUTECPP_PLATFORM_IS_SUPPORTED)
message(STATUS "platform - your system can support ComputeCpp")
else()
message(WARNING "platform - your system CANNOT support ComputeCpp")
endif()
endif()
endif()
find_package_handle_standard_args(ComputeCpp
REQUIRED_VARS ComputeCpp_ROOT_DIR
ComputeCpp_DEVICE_COMPILER_EXECUTABLE
ComputeCpp_INFO_EXECUTABLE
COMPUTECPP_RUNTIME_LIBRARY
COMPUTECPP_RUNTIME_LIBRARY_DEBUG
ComputeCpp_INCLUDE_DIRS
VERSION_VAR ComputeCpp_VERSION)
mark_as_advanced(ComputeCpp_ROOT_DIR
ComputeCpp_DEVICE_COMPILER_EXECUTABLE
ComputeCpp_INFO_EXECUTABLE
COMPUTECPP_RUNTIME_LIBRARY
COMPUTECPP_RUNTIME_LIBRARY_DEBUG
ComputeCpp_INCLUDE_DIRS
ComputeCpp_VERSION)
if(NOT ComputeCpp_FOUND)
return()
endif()
list(APPEND COMPUTECPP_DEVICE_COMPILER_FLAGS -O2 -mllvm -inline-threshold=1000 -intelspirmetadata)
mark_as_advanced(COMPUTECPP_DEVICE_COMPILER_FLAGS)
if(CMAKE_CROSSCOMPILING)
if(NOT COMPUTECPP_DONT_USE_TOOLCHAIN)
list(APPEND COMPUTECPP_DEVICE_COMPILER_FLAGS --gcc-toolchain=${COMPUTECPP_TOOLCHAIN_DIR})
endif()
list(APPEND COMPUTECPP_DEVICE_COMPILER_FLAGS --sysroot=${COMPUTECPP_SYSROOT_DIR})
list(APPEND COMPUTECPP_DEVICE_COMPILER_FLAGS -target ${COMPUTECPP_TARGET_TRIPLE})
endif()
list(APPEND COMPUTECPP_DEVICE_COMPILER_FLAGS -sycl-target ${COMPUTECPP_BITCODE})
message(STATUS "compute++ flags - ${COMPUTECPP_DEVICE_COMPILER_FLAGS}")
if(NOT TARGET OpenCL::OpenCL)
add_library(OpenCL::OpenCL UNKNOWN IMPORTED)
set_target_properties(OpenCL::OpenCL PROPERTIES
IMPORTED_LOCATION "${OpenCL_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${OpenCL_INCLUDE_DIRS}"
)
endif()
if(NOT TARGET ComputeCpp::ComputeCpp)
add_library(ComputeCpp::ComputeCpp UNKNOWN IMPORTED)
set_target_properties(ComputeCpp::ComputeCpp PROPERTIES
IMPORTED_LOCATION_DEBUG "${COMPUTECPP_RUNTIME_LIBRARY_DEBUG}"
IMPORTED_LOCATION_RELWITHDEBINFO "${COMPUTECPP_RUNTIME_LIBRARY_DEBUG}"
IMPORTED_LOCATION "${COMPUTECPP_RUNTIME_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${ComputeCpp_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "OpenCL::OpenCL"
)
endif()
# This property allows targets to specify that their sources should be
# compiled with the integration header included after the user's
# sources, not before (e.g. when an enum is used in a kernel name, this
# is not technically valid SYCL code but can work with ComputeCpp)
define_property(
TARGET PROPERTY COMPUTECPP_INCLUDE_AFTER
BRIEF_DOCS "Include integration header after user source"
FULL_DOCS "Changes compiler arguments such that the source file is
actually the integration header, and the .cpp file is included on
the command line so that it is seen by the compiler first. Enables
non-standards-conformant SYCL code to compile with ComputeCpp."
)
define_property(
TARGET PROPERTY INTERFACE_COMPUTECPP_FLAGS
BRIEF_DOCS "Interface compile flags to provide compute++"
FULL_DOCS "Set additional compile flags to pass to compute++ when compiling
any target which links to this one."
)
define_property(
SOURCE PROPERTY COMPUTECPP_SOURCE_FLAGS
BRIEF_DOCS "Source file compile flags for compute++"
FULL_DOCS "Set additional compile flags for compiling the SYCL integration
header for the given source file."
)
####################
# __build_sycl
# __build_ir
####################
#
# Adds a custom target for running compute++ and adding a dependency for the
# resulting integration header.
#
# targetName : Name of the target.
# sourceFile : Source file to be compiled.
# binaryDir : Intermediate directory to output the integration header.
# fileCounter : Counter included in name of custom target. Different counter
# values prevent duplicated names of custom target when source files with the same name,
# but located in different directories, are used for the same target.
# TARGET : Name of the target.
# SOURCE : Source file to be compiled.
# COUNTER : Counter included in name of custom target. Different counter
# values prevent duplicated names of custom target when source files with
# the same name, but located in different directories, are used for the
# same target.
#
function(__build_spir targetName sourceFile binaryDir fileCounter)
function(__build_ir)
set(options)
set(one_value_args
TARGET
SOURCE
COUNTER
)
set(multi_value_args)
cmake_parse_arguments(SDK_BUILD_IR
"${options}"
"${one_value_args}"
"${multi_value_args}"
${ARGN}
)
get_filename_component(sourceFileName ${SDK_BUILD_IR_SOURCE} NAME)
# Retrieve source file name.
get_filename_component(sourceFileName ${sourceFile} NAME)
# Set the path to the integration header.
# The .sycl filename must depend on the target so that different targets
# using the same source file will be generated with a different rule.
set(baseSyclName ${CMAKE_CURRENT_BINARY_DIR}/${SDK_BUILD_IR_TARGET}_${sourceFileName})
set(outputSyclFile ${baseSyclName}.sycl)
set(depFileName ${baseSyclName}.sycl.d)
# Set the path to the Sycl file.
set(outputSyclFile ${binaryDir}/${sourceFileName}.sycl)
set(include_directories "$<TARGET_PROPERTY:${SDK_BUILD_IR_TARGET},INCLUDE_DIRECTORIES>")
set(compile_definitions "$<TARGET_PROPERTY:${SDK_BUILD_IR_TARGET},COMPILE_DEFINITIONS>")
set(generated_include_directories
$<$<BOOL:${include_directories}>:-I\"$<JOIN:${include_directories},\"\t-I\">\">)
set(generated_compile_definitions
$<$<BOOL:${compile_definitions}>:-D$<JOIN:${compile_definitions},\t-D>>)
# Add any user-defined include to the device compiler
set(device_compiler_includes "")
get_property(includeDirectories DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY
INCLUDE_DIRECTORIES)
foreach(directory ${includeDirectories})
set(device_compiler_includes "-I${directory}" ${device_compiler_includes})
endforeach()
get_target_property(targetIncludeDirectories ${targetName} INCLUDE_DIRECTORIES)
foreach(directory ${targetIncludeDirectories})
set(device_compiler_includes "-I${directory}" ${device_compiler_includes})
endforeach()
if (CMAKE_INCLUDE_PATH)
foreach(directory ${CMAKE_INCLUDE_PATH})
set(device_compiler_includes "-I${directory}"
${device_compiler_includes})
# Obtain language standard of the file
set(device_compiler_cxx_standard)
get_target_property(targetCxxStandard ${SDK_BUILD_IR_TARGET} CXX_STANDARD)
if (targetCxxStandard MATCHES 17)
set(device_compiler_cxx_standard "-std=c++1z")
elseif (targetCxxStandard MATCHES 14)
set(device_compiler_cxx_standard "-std=c++14")
elseif (targetCxxStandard MATCHES 11)
set(device_compiler_cxx_standard "-std=c++11")
elseif (targetCxxStandard MATCHES 98)
message(FATAL_ERROR "SYCL applications cannot be compiled using C++98")
else ()
set(device_compiler_cxx_standard "")
endif()
get_property(source_compile_flags
SOURCE ${SDK_BUILD_IR_SOURCE}
PROPERTY COMPUTECPP_SOURCE_FLAGS
)
separate_arguments(source_compile_flags)
if(source_compile_flags)
list(APPEND computecpp_source_flags ${source_compile_flags})
endif()
list(APPEND COMPUTECPP_DEVICE_COMPILER_FLAGS
${device_compiler_cxx_standard}
${COMPUTECPP_USER_FLAGS}
${computecpp_source_flags}
)
set(ir_dependencies ${SDK_BUILD_IR_SOURCE})
get_target_property(target_libraries ${SDK_BUILD_IR_TARGET} LINK_LIBRARIES)
if(target_libraries)
foreach(library ${target_libraries})
list(APPEND ir_dependencies ${library})
endforeach()
endif()
set(COMPUTECPP_DEVICE_COMPILER_FLAGS
${COMPUTECPP_DEVICE_COMPILER_FLAGS}
${COMPUTECPP_USER_FLAGS})
# Convert argument list format
separate_arguments(COMPUTECPP_DEVICE_COMPILER_FLAGS)
# Depfile support was only added in CMake 3.7
# CMake throws an error if it is unsupported by the generator (i. e. not ninja)
if((NOT CMAKE_VERSION VERSION_LESS 3.7.0) AND
CMAKE_GENERATOR MATCHES "Ninja")
file(RELATIVE_PATH relOutputFile ${CMAKE_BINARY_DIR} ${outputSyclFile})
set(generate_depfile -MMD -MF ${depFileName} -MT ${relOutputFile})
set(enable_depfile DEPFILE ${depFileName})
endif()
# Add custom command for running compute++
add_custom_command(
OUTPUT ${outputSyclFile}
COMMAND ${COMPUTECPP_DEVICE_COMPILER}
COMMAND ${ComputeCpp_DEVICE_COMPILER_EXECUTABLE}
${COMPUTECPP_DEVICE_COMPILER_FLAGS}
-isystem ${COMPUTECPP_INCLUDE_DIRECTORY}
${COMPUTECPP_PLATFORM_SPECIFIC_ARGS}
${device_compiler_includes}
${generated_include_directories}
${generated_compile_definitions}
-o ${outputSyclFile}
-c ${CMAKE_CURRENT_SOURCE_DIR}/${sourceFile}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${sourceFile}
IMPLICIT_DEPENDS CXX "${CMAKE_CURRENT_SOURCE_DIR}/${sourceFile}"
WORKING_DIRECTORY ${binaryDir}
-c ${SDK_BUILD_IR_SOURCE}
${generate_depfile}
DEPENDS ${ir_dependencies}
IMPLICIT_DEPENDS CXX ${SDK_BUILD_IR_SOURCE}
${enable_depfile}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Building ComputeCpp integration header file ${outputSyclFile}")
# Add a custom target for the generated integration header
add_custom_target(${targetName}_integration_header DEPENDS ${outputSyclFile})
# Name: (user-defined name)_(source file)_(counter)_ih
set(headerTargetName
${SDK_BUILD_IR_TARGET}_${sourceFileName}_${SDK_BUILD_IR_COUNTER}_ih)
# Add a dependency on the integration header
add_dependencies(${targetName} ${targetName}_integration_header)
# Set the host compiler C++ standard to C++11
set_property(TARGET ${targetName} PROPERTY CXX_STANDARD 11)
# Disable GCC dual ABI on GCC 5.1 and higher
if(COMPUTECPP_DISABLE_GCC_DUAL_ABI)
set_property(TARGET ${targetName} APPEND PROPERTY COMPILE_DEFINITIONS
"_GLIBCXX_USE_CXX11_ABI=0")
if(NOT MSVC)
# Add a custom target for the generated integration header
add_custom_target(${headerTargetName} DEPENDS ${outputSyclFile})
add_dependencies(${SDK_BUILD_IR_TARGET} ${headerTargetName})
endif()
endfunction()
# This property can be set on a per-target basis to indicate that the
# integration header should appear after the main source listing
get_target_property(includeAfter ${SDK_ADD_SYCL_TARGET} COMPUTECPP_INCLUDE_AFTER)
if(includeAfter)
# Change the source file to the integration header - e.g.
# g++ -c source_file_name.cpp.sycl
get_target_property(current_sources ${SDK_BUILD_IR_TARGET} SOURCES)
# Remove absolute path to source file
list(REMOVE_ITEM current_sources ${SDK_BUILD_IR_SOURCE})
# Remove relative path to source file
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" ""
rel_source_file ${SDK_BUILD_IR_SOURCE}
)
list(REMOVE_ITEM current_sources ${rel_source_file})
# Add SYCL header to source list
list(APPEND current_sources ${outputSyclFile})
set_property(TARGET ${SDK_BUILD_IR_TARGET}
PROPERTY SOURCES ${current_sources})
# CMake/gcc don't know what language a .sycl file is, so tell them
set_property(SOURCE ${outputSyclFile} PROPERTY LANGUAGE CXX)
set(includedFile ${SDK_BUILD_IR_SOURCE})
set(cppFile ${outputSyclFile})
else()
set_property(SOURCE ${outputSyclFile} PROPERTY HEADER_FILE_ONLY ON)
set(includedFile ${outputSyclFile})
set(cppFile ${SDK_BUILD_IR_SOURCE})
endif()
# Force inclusion of the integration header for the host compiler
if(MSVC)
# Group SYCL files inside Visual Studio
source_group("SYCL" FILES ${outputSyclFile})
if(includeAfter)
# Allow the source file to be edited using Visual Studio.
# It will be added as a header file so it won't be compiled.
set_property(SOURCE ${SDK_BUILD_IR_SOURCE} PROPERTY HEADER_FILE_ONLY true)
endif()
# Add both source and the sycl files to the VS solution.
target_sources(${SDK_BUILD_IR_TARGET} PUBLIC ${SDK_BUILD_IR_SOURCE} ${outputSyclFile})
set(forceIncludeFlags "/FI${includedFile} /TP")
else()
set(forceIncludeFlags "-include ${includedFile} -x c++")
endif()
set_property(
SOURCE ${cppFile}
APPEND_STRING PROPERTY COMPILE_FLAGS "${forceIncludeFlags}"
)
endfunction(__build_ir)
#######################
# add_sycl_to_target
#######################
#
# Adds a SYCL compilation custom command associated with an existing
# target and sets a dependency on that new command.
# target and sets a dependancy on that new command.
#
# targetName : Name of the target to add a SYCL to.
# binaryDir : Intermediate directory to output the integration header.
# sourceFiles : Source files to be compiled for SYCL.
# TARGET : Name of the target to add SYCL to.
# SOURCES : Source files to be compiled for SYCL.
#
function(add_sycl_to_target targetName binaryDir sourceFiles)
function(add_sycl_to_target)
set(options)
set(one_value_args
TARGET
)
set(multi_value_args
SOURCES
)
cmake_parse_arguments(SDK_ADD_SYCL
"${options}"
"${one_value_args}"
"${multi_value_args}"
${ARGN}
)
set(sourceFiles ${sourceFiles} ${ARGN})
set(fileCounter 0)
# Add custom target to run compute++ and generate the integration header
foreach(sourceFile ${sourceFiles})
__build_spir(${targetName} ${sourceFile} ${binaryDir} ${fileCounter})
math(EXPR fileCounter "${fileCounter} + 1")
endforeach()
# If the CXX compiler is set to compute++ enable the driver.
get_filename_component(cmakeCxxCompilerFileName "${CMAKE_CXX_COMPILER}" NAME)
if("${cmakeCxxCompilerFileName}" STREQUAL "compute++")
if(MSVC)
message(FATAL_ERROR "The compiler driver is not supported by this system,
revert the CXX compiler to your default host compiler.")
endif()
# Link with the ComputeCpp runtime library
target_link_libraries(${targetName} PUBLIC ${COMPUTECPP_RUNTIME_LIBRARY}
PUBLIC ${OpenCL_LIBRARIES})
get_target_property(includeAfter ${SDK_ADD_SYCL_TARGET} COMPUTECPP_INCLUDE_AFTER)
if(includeAfter)
list(APPEND COMPUTECPP_USER_FLAGS -fsycl-ih-last)
endif()
list(INSERT COMPUTECPP_DEVICE_COMPILER_FLAGS 0 -sycl-driver)
# Prepend COMPUTECPP_DEVICE_COMPILER_FLAGS and append COMPUTECPP_USER_FLAGS
foreach(prop COMPILE_OPTIONS INTERFACE_COMPILE_OPTIONS)
get_target_property(target_compile_options ${SDK_ADD_SYCL_TARGET} ${prop})
if(NOT target_compile_options)
set(target_compile_options "")
endif()
set_property(
TARGET ${SDK_ADD_SYCL_TARGET}
PROPERTY ${prop}
${COMPUTECPP_DEVICE_COMPILER_FLAGS}
${target_compile_options}
${COMPUTECPP_USER_FLAGS}
)
endforeach()
else()
set(fileCounter 0)
list(INSERT COMPUTECPP_DEVICE_COMPILER_FLAGS 0 -sycl)
# Add custom target to run compute++ and generate the integration header
foreach(sourceFile ${SDK_ADD_SYCL_SOURCES})
if(NOT IS_ABSOLUTE ${sourceFile})
set(sourceFile "${CMAKE_CURRENT_SOURCE_DIR}/${sourceFile}")
endif()
__build_ir(
TARGET ${SDK_ADD_SYCL_TARGET}
SOURCE ${sourceFile}
COUNTER ${fileCounter}
)
MATH(EXPR fileCounter "${fileCounter} + 1")
endforeach()
endif()
endfunction()
set_property(TARGET ${SDK_ADD_SYCL_TARGET}
APPEND PROPERTY LINK_LIBRARIES ComputeCpp::ComputeCpp)
set_property(TARGET ${SDK_ADD_SYCL_TARGET}
APPEND PROPERTY INTERFACE_LINK_LIBRARIES ComputeCpp::ComputeCpp)
endfunction(add_sycl_to_target)