-
Notifications
You must be signed in to change notification settings - Fork 37
Expand file tree
/
Copy pathIntelSYCLConfig.cmake
More file actions
360 lines (272 loc) · 11.4 KB
/
Copy pathIntelSYCLConfig.cmake
File metadata and controls
360 lines (272 loc) · 11.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
#
# Modifications, Copyright (C) 2022 Intel Corporation
#
# This software and the related documents are Intel copyrighted materials, and
# your use of them is governed by the express license under which they were
# provided to you ("License"). Unless the License provides otherwise, you may not
# use, modify, copy, publish, distribute, disclose or transmit this software or
# the related documents without Intel's prior written permission.
#
# This software and the related documents are provided as is, with no express
# or implied warranties, other than those that are expressly stated in the
# License.
#
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
IntelSYCLConfig
-------
Library to verify SYCL compatibility of CMAKE_CXX_COMPILER
and passes relevant compiler flags.
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``IntelSYCL_FOUND``
True if the system has the SYCL library.
``SYCL_LANGUAGE_VERSION``
The SYCL language spec version by Compiler.
``SYCL_INCLUDE_DIR``
Include directories needed to use SYCL.
``SYCL_IMPLEMENTATION_ID``
The SYCL compiler variant.
``SYCL_FLAGS``
SYCL specific flags for the compiler.
``IntelSYCL::SYCL_CXX``
Target for using Intel SYCL (DPC++). The following properties are defined
for the target: ``INTERFACE_COMPILE_OPTIONS``, ``INTERFACE_LINK_OPTIONS``,
``INTERFACE_INCLUDE_DIRECTORIES``, and ``INTERFACE_LINK_DIRECTORIES``
Cache Variables
^^^^^^^^^^^^^^^
The following cache variable may also be set:
``SYCL_LANGUAGE_VERSION``
The SYCL language spec version by Compiler.
.. Note::
1. User needs to set -DCMAKE_CXX_COMPILER or environment of
CXX pointing to SYCL compatible compiler ( eg: icx, clang++, icpx)
2. Add this package to user's Cmake config file.
.. code-block:: cmake
find_package(IntelSYCL REQUIRED)
3. Add sources to target through add_sycl_to_target()
.. code-block:: cmake
# Compile specific sources for SYCL and build target for SYCL
add_executable(target_proj A.cpp B.cpp offload1.cpp offload2.cpp)
add_sycl_to_target(TARGET target_proj SOURCES offload1.cpp offload2.cpp)
#]=======================================================================]
include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
# TODO add dependency package module checks, if any
endif()
# TODO: can't use find_program to override the CMAKE_CXX_COMPILER as
# Platform/ files are executed, potentially for a different compiler.
# Safer approach is to make user to define CMAKE_CXX_COMPILER.
string(COMPARE EQUAL "${CMAKE_CXX_COMPILER}" "" nocmplr)
if(nocmplr)
set(IntelSYCL_FOUND False)
set(SYCL_REASON_FAILURE "SYCL: CMAKE_CXX_COMPILER not set!!")
set(IntelSYCL_NOT_FOUND_MESSAGE "${SYCL_REASON_FAILURE}")
endif()
# Check if a Compiler ID is being set. project() should be set prior to find_package()
if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "x")
set(IntelSYCL_FOUND False)
set(SYCL_REASON_FAILURE "CMake CXX Compiler family is not set. Please make sure find_package(IntelSYCL) is called after project()!!")
set(IntelSYCL_NOT_FOUND_MESSAGE "${SYCL_REASON_FAILURE}")
return()
endif()
# Check for known compiler family that supports SYCL
if( NOT "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang" AND
NOT "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xIntelLLVM")
set(IntelSYCL_FOUND False)
set(SYCL_REASON_FAILURE "Unsupported compiler family ${CMAKE_CXX_COMPILER_ID} and compiler ${CMAKE_CXX_COMPILER}!!")
set(IntelSYCL_NOT_FOUND_MESSAGE "${SYCL_REASON_FAILURE}")
return()
endif()
# Assume that CXX Compiler supports SYCL and then test to verify.
set(SYCL_COMPILER ${CMAKE_CXX_COMPILER})
# Function to write a test case to verify SYCL features.
function(SYCL_FEATURE_TEST_WRITE src)
set(pp_if "#if")
set(pp_endif "#endif")
set(SYCL_TEST_CONTENT "")
string(APPEND SYCL_TEST_CONTENT "#include <iostream>\nusing namespace std;\n")
string(APPEND SYCL_TEST_CONTENT "int main(){\n")
# Feature tests goes here
string(APPEND SYCL_TEST_CONTENT "${pp_if} defined(SYCL_LANGUAGE_VERSION)\n")
string(APPEND SYCL_TEST_CONTENT "cout << \"SYCL_LANGUAGE_VERSION=\"<<SYCL_LANGUAGE_VERSION<<endl;\n")
string(APPEND SYCL_TEST_CONTENT "${pp_endif}\n")
string(APPEND SYCL_TEST_CONTENT "return 0;}\n")
file(WRITE ${src} "${SYCL_TEST_CONTENT}")
endfunction()
# Function to Build the feature check test case.
function(SYCL_FEATURE_TEST_BUILD TEST_SRC_FILE TEST_EXE)
# Convert CXX Flag string to list
set(SYCL_CXX_FLAGS_LIST "${SYCL_CXX_FLAGS}")
separate_arguments(SYCL_CXX_FLAGS_LIST)
# Spawn a process to build the test case.
execute_process(
COMMAND "${SYCL_COMPILER}"
${SYCL_CXX_FLAGS_LIST}
${TEST_SRC_FILE}
"-o"
${TEST_EXE}
WORKING_DIRECTORY ${SYCL_TEST_DIR}
OUTPUT_VARIABLE output ERROR_VARIABLE output
OUTPUT_FILE ${SYCL_TEST_DIR}/Compile.log
RESULT_VARIABLE result
TIMEOUT 60
)
# Verify if test case build properly.
if(result)
message("SYCL feature test compile failed!")
message("compile output is: ${output}")
endif()
# TODO: what to do if it doesn't build
endfunction()
# Function to run the test case to generate feature info.
function(SYCL_FEATURE_TEST_RUN TEST_EXE)
# Spawn a process to run the test case.
execute_process(
COMMAND ${TEST_EXE}
WORKING_DIRECTORY ${SYCL_TEST_DIR}
OUTPUT_VARIABLE output ERROR_VARIABLE output
RESULT_VARIABLE result
TIMEOUT 60
)
# Verify the test execution output.
if(test_result)
set(IntelSYCL_FOUND False)
set(SYCL_REASON_FAILURE "SYCL: feature test execution failed!!")
endif()
# TODO: what iff the result is false.. error or ignore?
set( test_result "${result}" PARENT_SCOPE)
set( test_output "${output}" PARENT_SCOPE)
endfunction()
# Function to extract the information from test execution.
function(SYCL_FEATURE_TEST_EXTRACT test_output)
string(REGEX REPLACE "\n" ";" test_output_list "${test_output}")
set(SYCL_LANGUAGE_VERSION "")
foreach(strl ${test_output_list})
if(${strl} MATCHES "^SYCL_LANGUAGE_VERSION=([A-Za-z0-9_]+)$")
string(REGEX REPLACE "^SYCL_LANGUAGE_VERSION=" "" extracted_sycl_lang "${strl}")
set(SYCL_LANGUAGE_VERSION ${extracted_sycl_lang})
endif()
endforeach()
set(SYCL_LANGUAGE_VERSION "${SYCL_LANGUAGE_VERSION}" PARENT_SCOPE)
endfunction()
if(SYCL_COMPILER)
# TODO ensure CMAKE_LINKER and CMAKE_CXX_COMPILER are same/supports SYCL.
# set(CMAKE_LINKER ${SYCL_COMPILER})
# use REALPATH to resolve symlinks
get_filename_component(_REALPATH_SYCL_COMPILER "${SYCL_COMPILER}" REALPATH)
get_filename_component(SYCL_BIN_DIR "${_REALPATH_SYCL_COMPILER}" DIRECTORY)
get_filename_component(SYCL_PACKAGE_DIR "${SYCL_BIN_DIR}" DIRECTORY CACHE)
# Find Include path from binary
find_file(SYCL_INCLUDE_DIR
NAMES
include
HINTS
${SYCL_PACKAGE_DIR} $ENV{SYCL_INCLUDE_DIR_HINT}
NO_DEFAULT_PATH
)
# Find Library directory
find_file(SYCL_LIBRARY_DIR
NAMES
lib lib64
HINTS
${SYCL_PACKAGE_DIR} $ENV{SYCL_LIBRARY_DIR_HINT}
NO_DEFAULT_PATH
)
endif()
set(SYCL_FLAGS "")
set(SYCL_LINK_FLAGS "")
# Based on Compiler ID, add support for SYCL
if( "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang" OR
"x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xIntelLLVM")
list(APPEND SYCL_FLAGS "-fsycl")
list(APPEND SYCL_LINK_FLAGS "-fsycl")
endif()
# TODO verify if this is needed
# Windows: Add Exception handling
if(WIN32)
list(APPEND SYCL_FLAGS "/EHsc")
endif()
set(SYCL_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SYCL_FLAGS}")
# And now test the assumptions.
# Create a clean working directory.
set(SYCL_TEST_DIR "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/TESTSYCL")
file(REMOVE_RECURSE ${SYCL_TEST_DIR})
file(MAKE_DIRECTORY ${SYCL_TEST_DIR})
# Create the test source file
set(TEST_SRC_FILE "${SYCL_TEST_DIR}/sycl_features.cpp")
set(TEST_EXE "${TEST_SRC_FILE}.exe")
SYCL_FEATURE_TEST_WRITE(${TEST_SRC_FILE})
# Build the test and create test executable
SYCL_FEATURE_TEST_BUILD(${TEST_SRC_FILE} ${TEST_EXE})
# Execute the test to extract information
SYCL_FEATURE_TEST_RUN(${TEST_EXE})
# Extract test output for information
SYCL_FEATURE_TEST_EXTRACT(${test_output})
# As per specification, all the SYCL compatible compilers should
# define macro SYCL_LANGUAGE_VERSION
string(COMPARE EQUAL "${SYCL_LANGUAGE_VERSION}" "" nosycllang)
if(nosycllang)
set(IntelSYCL_FOUND False)
set(SYCL_REASON_FAILURE "SYCL: It appears that the ${CMAKE_CXX_COMPILER} does not support SYCL")
set(IntelSYCL_NOT_FOUND_MESSAGE "${SYCL_REASON_FAILURE}")
endif()
# Placeholder for identifying various implementations of SYCL compilers.
# for now, set to the CMAKE_CXX_COMPILER_ID
set(SYCL_IMPLEMENTATION_ID "${CMAKE_CXX_COMPILER_ID}")
message(DEBUG "The SYCL compiler is ${SYCL_COMPILER}")
message(DEBUG "The SYCL Flags are ${SYCL_FLAGS}")
message(DEBUG "The SYCL Language Version is ${SYCL_LANGUAGE_VERSION}")
add_library(IntelSYCL::SYCL_CXX INTERFACE IMPORTED)
set_property(TARGET IntelSYCL::SYCL_CXX PROPERTY
INTERFACE_COMPILE_OPTIONS ${SYCL_FLAGS})
set_property(TARGET IntelSYCL::SYCL_CXX PROPERTY
INTERFACE_LINK_OPTIONS ${SYCL_LINK_FLAGS})
set_property(TARGET IntelSYCL::SYCL_CXX PROPERTY
INTERFACE_INCLUDE_DIRECTORIES ${SYCL_INCLUDE_DIR})
set_property(TARGET IntelSYCL::SYCL_CXX PROPERTY
INTERFACE_LINK_DIRECTORIES ${SYCL_LIBRARY_DIR})
find_package_handle_standard_args(
IntelSYCL
FOUND_VAR IntelSYCL_FOUND
REQUIRED_VARS SYCL_INCLUDE_DIR SYCL_LIBRARY_DIR SYCL_FLAGS
VERSION_VAR SYCL_LANGUAGE_VERSION
REASON_FAILURE_MESSAGE "${SYCL_REASON_FAILURE}")
# Include in Cache
set(SYCL_LANGUAGE_VERSION "${SYCL_LANGUAGE_VERSION}" CACHE STRING "SYCL Language version")
function(add_sycl_to_target)
set(one_value_args TARGET)
set(multi_value_args SOURCES)
cmake_parse_arguments(SYCL
""
"${one_value_args}"
"${multi_value_args}"
${ARGN})
get_target_property(__sycl_cxx_options IntelSYCL::SYCL_CXX INTERFACE_COMPILE_OPTIONS)
get_target_property(__sycl_cxx_include_directories IntelSYCL::SYCL_CXX INTERFACE_INCLUDE_DIRECTORIES)
if(NOT ${ARGC})
message(FATAL_ERROR " add_sycl_to_target() does not have any arguments")
elseif(${ARGC} EQUAL 1)
message(WARNING "add_sycl_to_target() have only one argument specified.. assuming the target to be ${ARGV}.
Adding sycl to all sources but that may effect compilation times")
set(SYCL_TARGET ${ARGV})
endif()
if(NOT SYCL_SOURCES)
message(WARNING "add_sycl_to_target() does not have sources specified.. Adding sycl to all sources but that may effect compilation times")
target_compile_options(${SYCL_TARGET} PUBLIC ${__sycl_cxx_options})
target_include_directories(${SYCL_TARGET} PUBLIC ${__sycl_cxx_include_directories})
endif()
foreach(source ${SYCL_SOURCES})
set_source_files_properties(${source} PROPERTIES COMPILE_OPTIONS "${__sycl_cxx_options}")
set_source_files_properties(${source} PROPERTIES INCLUDE_DIRECTORIES "${__sycl_cxx_include_directories}")
endforeach()
get_target_property(__sycl_link_options
IntelSYCL::SYCL_CXX INTERFACE_LINK_OPTIONS)
target_link_options(${SYCL_TARGET} PRIVATE "${__sycl_link_options}")
get_target_property(__sycl_link_directories
IntelSYCL::SYCL_CXX INTERFACE_LINK_DIRECTORIES)
target_link_directories(${SYCL_TARGET} PUBLIC "${__sycl_link_directories}")
endfunction(add_sycl_to_target)