123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455 |
- #.rst:
- # FindComputeCpp
- #---------------
- #
- # 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.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- #########################
- # FindComputeCpp.cmake
- #########################
- #
- # Tools for finding and building with ComputeCpp.
- #
- # 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
- cmake_minimum_required(VERSION 3.4.3)
- include(FindPackageHandleStandardArgs)
- include(ComputeCppIRMap)
- set(COMPUTECPP_USER_FLAGS "" CACHE STRING "User flags for compute++")
- separate_arguments(COMPUTECPP_USER_FLAGS)
- mark_as_advanced(COMPUTECPP_USER_FLAGS)
- set(COMPUTECPP_BITCODE "spir64" CACHE STRING
- "Bitcode type to use as SYCL target in compute++")
- mark_as_advanced(COMPUTECPP_BITCODE)
- include(CMakeFindDependencyMacro)
- find_dependency(OpenCL REQUIRED)
- # 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()
- # Used for running executables on the host
- set(computecpp_host_find_hint ${computecpp_find_hint})
- 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()
- find_program(ComputeCpp_DEVICE_COMPILER_EXECUTABLE compute++
- HINTS ${computecpp_host_find_hint}
- PATH_SUFFIXES bin
- NO_SYSTEM_ENVIRONMENT_PATH)
- find_program(ComputeCpp_INFO_EXECUTABLE computecpp_info
- HINTS ${computecpp_host_find_hint}
- PATH_SUFFIXES bin
- NO_SYSTEM_ENVIRONMENT_PATH)
- 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_d 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(STATUS "platform - your system is not officially supported")
- 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}")
- include(ComputeCppCompilerChecks)
- 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}"
- 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_ir
- ####################
- #
- # Adds a custom target for running compute++ and adding a dependency for the
- # resulting integration header and kernel binary.
- #
- # 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_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)
- # 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(outputDeviceFile ${baseSyclName}.${IR_MAP_${COMPUTECPP_BITCODE}})
- set(depFileName ${baseSyclName}.sycl.d)
- 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>>)
- # 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})
- if(TARGET ${library})
- list(APPEND ir_dependencies ${library})
- endif()
- endforeach()
- endif()
- # 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} ${outputDeviceFile})
- set(generate_depfile -MMD -MF ${depFileName} -MT ${relOutputFile})
- set(enable_depfile DEPFILE ${depFileName})
- endif()
- # Add custom command for running compute++
- add_custom_command(
- OUTPUT ${outputDeviceFile} ${outputSyclFile}
- COMMAND ${ComputeCpp_DEVICE_COMPILER_EXECUTABLE}
- ${COMPUTECPP_DEVICE_COMPILER_FLAGS}
- ${generated_include_directories}
- ${generated_compile_definitions}
- -sycl-ih ${outputSyclFile}
- -o ${outputDeviceFile}
- -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}")
- # Name: (user-defined name)_(source file)_(counter)_ih
- set(headerTargetName
- ${SDK_BUILD_IR_TARGET}_${sourceFileName}_${SDK_BUILD_IR_COUNTER}_ih)
- if(NOT MSVC)
- # Add a custom target for the generated integration header
- add_custom_target(${headerTargetName} DEPENDS ${outputDeviceFile} ${outputSyclFile})
- add_dependencies(${SDK_BUILD_IR_TARGET} ${headerTargetName})
- endif()
- # 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 dependancy on that new command.
- #
- # TARGET : Name of the target to add SYCL to.
- # SOURCES : Source files to be compiled for SYCL.
- #
- 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_target_properties(${SDK_ADD_SYCL_TARGET} PROPERTIES LINKER_LANGUAGE CXX)
- # 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()
- 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()
- 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)
|