Home | History | Annotate | Download | only in cmake
      1 #.rst:
      2 # FindComputeCpp
      3 #---------------
      4 #
      5 #   Copyright 2016 Codeplay Software Ltd.
      6 #
      7 #   Licensed under the Apache License, Version 2.0 (the "License");
      8 #   you may not use these files except in compliance with the License.
      9 #   You may obtain a copy of the License at
     10 #
     11 #       http://www.apache.org/licenses/LICENSE-2.0
     12 #
     13 #
     14 #   Unless required by applicable law or agreed to in writing, software
     15 #   distributed under the License is distributed on an "AS IS" BASIS,
     16 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     17 #   See the License for the specific language governing permissions and
     18 #   limitations under the License.
     19 
     20 #########################
     21 #  FindComputeCpp.cmake
     22 #########################
     23 #
     24 #  Tools for finding and building with ComputeCpp.
     25 #
     26 #  User must define COMPUTECPP_PACKAGE_ROOT_DIR pointing to the ComputeCpp
     27 #   installation.
     28 #
     29 #  Latest version of this file can be found at:
     30 #    https://github.com/codeplaysoftware/computecpp-sdk
     31 
     32 # Require CMake version 3.2.2 or higher
     33 cmake_minimum_required(VERSION 3.2.2)
     34 
     35 # Check that a supported host compiler can be found
     36 if(CMAKE_COMPILER_IS_GNUCXX)
     37     # Require at least gcc 4.8
     38     if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
     39       message(FATAL_ERROR
     40         "host compiler - Not found! (gcc version must be at least 4.8)")
     41     # Require the GCC dual ABI to be disabled for 5.1 or higher
     42     elseif (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5.1)
     43       set(COMPUTECPP_DISABLE_GCC_DUAL_ABI "True")
     44       message(STATUS
     45         "host compiler - gcc ${CMAKE_CXX_COMPILER_VERSION} (note pre 5.1 gcc ABI enabled)")
     46     else()
     47       message(STATUS "host compiler - gcc ${CMAKE_CXX_COMPILER_VERSION}")
     48     endif()
     49 elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
     50     # Require at least clang 3.6
     51     if (${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 3.6)
     52       message(FATAL_ERROR
     53         "host compiler - Not found! (clang version must be at least 3.6)")
     54     else()
     55       message(STATUS "host compiler - clang ${CMAKE_CXX_COMPILER_VERSION}")
     56     endif()
     57 else()
     58   message(WARNING
     59     "host compiler - Not found! (ComputeCpp supports GCC and Clang, see readme)")
     60 endif()
     61 
     62 set(COMPUTECPP_64_BIT_DEFAULT ON)
     63 option(COMPUTECPP_64_BIT_CODE "Compile device code in 64 bit mode"
     64         ${COMPUTECPP_64_BIT_DEFAULT})
     65 mark_as_advanced(COMPUTECPP_64_BIT_CODE)
     66 
     67 # Find OpenCL package
     68 find_package(OpenCL REQUIRED)
     69 
     70 # Find ComputeCpp packagee
     71 if(NOT COMPUTECPP_PACKAGE_ROOT_DIR)
     72   message(FATAL_ERROR
     73     "ComputeCpp package - Not found! (please set COMPUTECPP_PACKAGE_ROOT_DIR")
     74 else()
     75   message(STATUS "ComputeCpp package - Found")
     76 endif()
     77 option(COMPUTECPP_PACKAGE_ROOT_DIR "Path to the ComputeCpp Package")
     78 
     79 # Obtain the path to compute++
     80 find_program(COMPUTECPP_DEVICE_COMPILER compute++ PATHS
     81   ${COMPUTECPP_PACKAGE_ROOT_DIR} PATH_SUFFIXES bin)
     82 if (EXISTS ${COMPUTECPP_DEVICE_COMPILER})
     83   mark_as_advanced(COMPUTECPP_DEVICE_COMPILER)
     84   message(STATUS "compute++ - Found")
     85 else()
     86   message(FATAL_ERROR "compute++ - Not found! (${COMPUTECPP_DEVICE_COMPILER})")
     87 endif()
     88 
     89 # Obtain the path to computecpp_info
     90 find_program(COMPUTECPP_INFO_TOOL computecpp_info PATHS
     91   ${COMPUTECPP_PACKAGE_ROOT_DIR} PATH_SUFFIXES bin)
     92 if (EXISTS ${COMPUTECPP_INFO_TOOL})
     93   mark_as_advanced(${COMPUTECPP_INFO_TOOL})
     94   message(STATUS "computecpp_info - Found")
     95 else()
     96   message(FATAL_ERROR "computecpp_info - Not found! (${COMPUTECPP_INFO_TOOL})")
     97 endif()
     98 
     99 # Obtain the path to the ComputeCpp runtime library
    100 find_library(COMPUTECPP_RUNTIME_LIBRARY ComputeCpp PATHS ${COMPUTECPP_PACKAGE_ROOT_DIR}
    101   HINTS ${COMPUTECPP_PACKAGE_ROOT_DIR}/lib PATH_SUFFIXES lib
    102   DOC "ComputeCpp Runtime Library" NO_DEFAULT_PATH)
    103 
    104 if (EXISTS ${COMPUTECPP_RUNTIME_LIBRARY})
    105   mark_as_advanced(COMPUTECPP_RUNTIME_LIBRARY)
    106   message(STATUS "libComputeCpp.so - Found")
    107 else()
    108   message(FATAL_ERROR "libComputeCpp.so - Not found!")
    109 endif()
    110 
    111 # Obtain the ComputeCpp include directory
    112 set(COMPUTECPP_INCLUDE_DIRECTORY ${COMPUTECPP_PACKAGE_ROOT_DIR}/include/)
    113 if (NOT EXISTS ${COMPUTECPP_INCLUDE_DIRECTORY})
    114   message(FATAL_ERROR "ComputeCpp includes - Not found!")
    115 else()
    116   message(STATUS "ComputeCpp includes - Found")
    117 endif()
    118 
    119 # Obtain the package version
    120 execute_process(COMMAND ${COMPUTECPP_INFO_TOOL} "--dump-version"
    121   OUTPUT_VARIABLE COMPUTECPP_PACKAGE_VERSION
    122   RESULT_VARIABLE COMPUTECPP_INFO_TOOL_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE)
    123 if(NOT COMPUTECPP_INFO_TOOL_RESULT EQUAL "0")
    124   message(FATAL_ERROR "Package version - Error obtaining version!")
    125 else()
    126   mark_as_advanced(COMPUTECPP_PACKAGE_VERSION)
    127   message(STATUS "Package version - ${COMPUTECPP_PACKAGE_VERSION}")
    128 endif()
    129 
    130 # Obtain the device compiler flags
    131 execute_process(COMMAND ${COMPUTECPP_INFO_TOOL} "--dump-device-compiler-flags"
    132   OUTPUT_VARIABLE COMPUTECPP_DEVICE_COMPILER_FLAGS
    133   RESULT_VARIABLE COMPUTECPP_INFO_TOOL_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE)
    134 if(NOT COMPUTECPP_INFO_TOOL_RESULT EQUAL "0")
    135   message(FATAL_ERROR "compute++ flags - Error obtaining compute++ flags!")
    136 else()
    137   mark_as_advanced(COMPUTECPP_COMPILER_FLAGS)
    138   message(STATUS "compute++ flags - ${COMPUTECPP_DEVICE_COMPILER_FLAGS}")
    139 endif()
    140 
    141 set(COMPUTECPP_DEVICE_COMPILER_FLAGS ${COMPUTECPP_DEVICE_COMPILER_FLAGS} -sycl-compress-name -no-serial-memop -DEIGEN_NO_ASSERTION_CHECKING=1)
    142 
    143 # Check if the platform is supported
    144 execute_process(COMMAND ${COMPUTECPP_INFO_TOOL} "--dump-is-supported"
    145   OUTPUT_VARIABLE COMPUTECPP_PLATFORM_IS_SUPPORTED
    146   RESULT_VARIABLE COMPUTECPP_INFO_TOOL_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE)
    147 if(NOT COMPUTECPP_INFO_TOOL_RESULT EQUAL "0")
    148   message(FATAL_ERROR "platform - Error checking platform support!")
    149 else()
    150   mark_as_advanced(COMPUTECPP_PLATFORM_IS_SUPPORTED)
    151   if (COMPUTECPP_PLATFORM_IS_SUPPORTED)
    152     message(STATUS "platform - your system can support ComputeCpp")
    153   else()
    154     message(STATUS "platform - your system CANNOT support ComputeCpp")
    155   endif()
    156 endif()
    157 
    158 ####################
    159 #   __build_sycl
    160 ####################
    161 #
    162 #  Adds a custom target for running compute++ and adding a dependency for the
    163 #  resulting integration header.
    164 #
    165 #  targetName : Name of the target.
    166 #  sourceFile : Source file to be compiled.
    167 #  binaryDir : Intermediate directory to output the integration header.
    168 #
    169 function(__build_spir targetName sourceFile binaryDir)
    170 
    171   # Retrieve source file name.
    172   get_filename_component(sourceFileName ${sourceFile} NAME)
    173 
    174   # Set the path to the Sycl file.
    175   set(outputSyclFile ${binaryDir}/${sourceFileName}.sycl)
    176 
    177   # Add any user-defined include to the device compiler
    178   get_property(includeDirectories DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY
    179     INCLUDE_DIRECTORIES)
    180   set(device_compiler_includes "")
    181   foreach(directory ${includeDirectories})
    182     set(device_compiler_includes "-I${directory}" ${device_compiler_includes})
    183   endforeach()
    184   if (CMAKE_INCLUDE_PATH)
    185     foreach(directory ${CMAKE_INCLUDE_PATH})
    186       set(device_compiler_includes "-I${directory}"
    187         ${device_compiler_includes})
    188     endforeach()
    189   endif()
    190 
    191   # Convert argument list format
    192   separate_arguments(COMPUTECPP_DEVICE_COMPILER_FLAGS)
    193 
    194   # Add custom command for running compute++
    195   add_custom_command(
    196     OUTPUT ${outputSyclFile}
    197     COMMAND ${COMPUTECPP_DEVICE_COMPILER}
    198             ${COMPUTECPP_DEVICE_COMPILER_FLAGS}
    199             -isystem ${COMPUTECPP_INCLUDE_DIRECTORY}
    200             ${COMPUTECPP_PLATFORM_SPECIFIC_ARGS}
    201             ${device_compiler_includes}
    202             -o ${outputSyclFile}
    203             -c ${CMAKE_CURRENT_SOURCE_DIR}/${sourceFile}
    204     DEPENDS ${sourceFile}
    205     WORKING_DIRECTORY ${binaryDir}
    206   COMMENT "Building ComputeCpp integration header file ${outputSyclFile}")
    207 
    208   # Add a custom target for the generated integration header
    209   add_custom_target(${targetName}_integration_header DEPENDS ${outputSyclFile})
    210 
    211   # Add a dependency on the integration header
    212   add_dependencies(${targetName} ${targetName}_integration_header)
    213 
    214   # Set the host compiler C++ standard to C++11
    215   set_property(TARGET ${targetName} PROPERTY CXX_STANDARD 11)
    216 
    217   # Disable GCC dual ABI on GCC 5.1 and higher
    218   if(COMPUTECPP_DISABLE_GCC_DUAL_ABI)
    219     set_property(TARGET ${targetName} APPEND PROPERTY COMPILE_DEFINITIONS
    220       "_GLIBCXX_USE_CXX11_ABI=0")
    221   endif()
    222 
    223 endfunction()
    224 
    225 #######################
    226 #  add_sycl_to_target
    227 #######################
    228 #
    229 #  Adds a SYCL compilation custom command associated with an existing
    230 #  target and sets a dependancy on that new command.
    231 #
    232 #  targetName : Name of the target to add a SYCL to.
    233 #  sourceFile : Source file to be compiled for SYCL.
    234 #  binaryDir : Intermediate directory to output the integration header.
    235 #
    236 function(add_sycl_to_target targetName sourceFile binaryDir)
    237 
    238   # Add custom target to run compute++ and generate the integration header
    239   __build_spir(${targetName} ${sourceFile} ${binaryDir})
    240 
    241   # Link with the ComputeCpp runtime library
    242   target_link_libraries(${targetName} PUBLIC ${COMPUTECPP_RUNTIME_LIBRARY}
    243                         PUBLIC ${OpenCL_LIBRARIES})
    244 
    245 endfunction(add_sycl_to_target)
    246