| #.rst: |
| # FindComputeCpp |
| #--------------- |
| # |
| # Copyright 2016 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_PACKAGE_ROOT_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) |
| |
| set(COMPUTECPP_USER_FLAGS "" CACHE STRING "User flags for compute++") |
| mark_as_advanced(COMPUTECPP_USER_FLAGS) |
| |
| # Find OpenCL package |
| 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") |
| 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() |
| |
| # 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") |
| endif() |
| endif() |
| |
| set(COMPUTECPP_USER_FLAGS |
| -sycl-compress-name |
| -Wall |
| -no-serial-memop |
| -DEIGEN_NO_ASSERTION_CHECKING=1 |
| ) |
| |
| #################### |
| # __build_sycl |
| #################### |
| # |
| # 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. |
| # |
| function(__build_spir targetName sourceFile binaryDir fileCounter) |
| |
| # Retrieve source file name. |
| get_filename_component(sourceFileName ${sourceFile} NAME) |
| |
| # Set the path to the Sycl file. |
| set(outputSyclFile ${binaryDir}/${sourceFileName}.sycl) |
| |
| # 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}) |
| endforeach() |
| endif() |
| |
| set(COMPUTECPP_DEVICE_COMPILER_FLAGS |
| ${COMPUTECPP_DEVICE_COMPILER_FLAGS} |
| ${COMPUTECPP_USER_FLAGS}) |
| # Convert argument list format |
| separate_arguments(COMPUTECPP_DEVICE_COMPILER_FLAGS) |
| |
| # Add custom command for running compute++ |
| add_custom_command( |
| OUTPUT ${outputSyclFile} |
| COMMAND ${COMPUTECPP_DEVICE_COMPILER} |
| ${COMPUTECPP_DEVICE_COMPILER_FLAGS} |
| -isystem ${COMPUTECPP_INCLUDE_DIRECTORY} |
| ${COMPUTECPP_PLATFORM_SPECIFIC_ARGS} |
| ${device_compiler_includes} |
| -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} |
| COMMENT "Building ComputeCpp integration header file ${outputSyclFile}") |
| |
| # Add a custom target for the generated integration header |
| add_custom_target(${targetName}_integration_header DEPENDS ${outputSyclFile}) |
| |
| # 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") |
| endif() |
| |
| endfunction() |
| |
| ####################### |
| # add_sycl_to_target |
| ####################### |
| # |
| # Adds a SYCL compilation custom command associated with an existing |
| # target and sets a dependency 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. |
| # |
| function(add_sycl_to_target targetName binaryDir sourceFiles) |
| |
| 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() |
| |
| # Link with the ComputeCpp runtime library |
| target_link_libraries(${targetName} PUBLIC ${COMPUTECPP_RUNTIME_LIBRARY} |
| PUBLIC ${OpenCL_LIBRARIES}) |
| |
| endfunction() |