Skip to content

Commit 95eb592

Browse files
Vendor IntelDPCPPConfig.cmake
Two reasons to do this: 1. to allow for providing hint env variables to help cmake find `SYCL_INCLUDE_DIR` and `SYCL_LIBRARY_DIR` for custom layouts of DPC++ installed into Python environment with conda 2. To allow use of nightly sycl bundles to build dpctl (bundle does not include IntelDPCPPConig.cmake)
1 parent dca2ed4 commit 95eb592

File tree

2 files changed

+294
-1
lines changed

2 files changed

+294
-1
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ project(dpctl
88
set(CMAKE_CXX_STANDARD 17)
99
set(CMAKE_CXX_STANDARD_REQUIRED True)
1010

11-
find_package(IntelDPCPP REQUIRED)
11+
find_package(IntelDPCPP REQUIRED PATHS ${CMAKE_SOURCE_DIR}/cmake NO_DEFAULT_PATH)
1212

1313
add_subdirectory(libsyclinterface)
1414

cmake/IntelDPCPPConfig.cmake

Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2+
# file Copyright.txt or https://cmake.org/licensing for details.
3+
4+
#[=======================================================================[.rst:
5+
IntelDPCPPConfig
6+
-------
7+
8+
DPCPP Library to verify DPCPP/SYCL compatability of CMAKE_CXX_COMPILER
9+
and passes relevant compiler flags.
10+
11+
Result Variables
12+
^^^^^^^^^^^^^^^^
13+
14+
This will define the following variables:
15+
16+
``IntelDPCPP_FOUND``
17+
True if the system has the DPCPP library.
18+
``SYCL_LANGUAGE_VERSION``
19+
The SYCL language spec version by Compiler.
20+
``SYCL_INCLUDE_DIR``
21+
Include directories needed to use SYCL.
22+
``SYCL_IMPLEMENTATION_ID``
23+
The SYCL compiler variant.
24+
``SYCL_FLAGS``
25+
SYCL specific flags for the compiler.
26+
27+
Cache Variables
28+
^^^^^^^^^^^^^^^
29+
30+
The following cache variables may also be set:
31+
32+
``SYCL_INCLUDE_DIR``
33+
The directory containing ``sycl.hpp``.
34+
``SYCL_LIBRARY_DIR``
35+
The path to the SYCL library.
36+
``SYCL_FLAGS``
37+
SYCL specific flags for the compiler.
38+
``SYCL_LANGUAGE_VERSION``
39+
The SYCL language spec version by Compiler.
40+
41+
42+
.. note::
43+
44+
For now, user needs to set -DCMAKE_CXX_COMPILER or environment of
45+
CXX pointing to SYCL compatible compiler ( eg: icx, clang++, icpx)
46+
47+
Note: do not set to DPCPP compiler. If set to a Compiler family
48+
that supports dpcpp ( eg: IntelLLVM) both DPCPP and SYCL
49+
features are enabled.
50+
51+
And add this package to user's Cmake config file.
52+
53+
.. code-block:: cmake
54+
55+
find_package(IntelDPCPP REQUIRED)
56+
57+
#]=======================================================================]
58+
59+
include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
60+
61+
find_package(PkgConfig QUIET)
62+
if(PKG_CONFIG_FOUND)
63+
# TODO add dependency package module checks, if any
64+
endif()
65+
66+
67+
# TODO: can't use find_program to override the CMAKE_CXX_COMPILER as
68+
# Platform/ files are executed, potentially for a different compiler.
69+
# Safer approach is to make user to define CMAKE_CXX_COMPILER.
70+
71+
string(COMPARE EQUAL "${CMAKE_CXX_COMPILER}" "" nocmplr)
72+
if(nocmplr)
73+
set(IntelDPCPP_FOUND False)
74+
set(SYCL_REASON_FAILURE "SYCL: CMAKE_CXX_COMPILER not set!!")
75+
set(IntelDPCPP_NOT_FOUND_MESSAGE "${SYCL_REASON_FAILURE}")
76+
endif()
77+
78+
# Check for known compiler family that supports SYCL
79+
80+
if( NOT "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang" AND
81+
NOT "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xIntelLLVM")
82+
set(IntelDPCPP_FOUND False)
83+
set(SYCL_REASON_FAILURE "Unsupported compiler family ${CMAKE_CXX_COMPILER_ID} and compiler ${CMAKE_CXX_COMPILER}!!")
84+
set(IntelDPCPP_NOT_FOUND_MESSAGE "${SYCL_REASON_FAILURE}")
85+
return()
86+
endif()
87+
88+
# Assume that CXX Compiler supports SYCL and then test to verify.
89+
set(SYCL_COMPILER ${CMAKE_CXX_COMPILER})
90+
91+
92+
# Function to write a test case to verify SYCL features.
93+
94+
function(SYCL_FEATURE_TEST_WRITE src)
95+
96+
set(pp_if "#if")
97+
set(pp_endif "#endif")
98+
99+
set(SYCL_TEST_CONTENT "")
100+
string(APPEND SYCL_TEST_CONTENT "#include <iostream>\nusing namespace std;\n")
101+
string(APPEND SYCL_TEST_CONTENT "int main(){\n")
102+
103+
# Feature tests goes here
104+
105+
string(APPEND SYCL_TEST_CONTENT "${pp_if} defined(SYCL_LANGUAGE_VERSION)\n")
106+
string(APPEND SYCL_TEST_CONTENT "cout << \"SYCL_LANGUAGE_VERSION=\"<<SYCL_LANGUAGE_VERSION<<endl;\n")
107+
string(APPEND SYCL_TEST_CONTENT "${pp_endif}\n")
108+
109+
string(APPEND SYCL_TEST_CONTENT "return 0;}\n")
110+
111+
file(WRITE ${src} "${SYCL_TEST_CONTENT}")
112+
113+
endfunction()
114+
115+
# Function to Build the feature check test case.
116+
117+
function(SYCL_FEATURE_TEST_BUILD TEST_SRC_FILE TEST_EXE)
118+
119+
# Convert CXX Flag string to list
120+
set(SYCL_CXX_FLAGS_LIST "${SYCL_CXX_FLAGS}")
121+
separate_arguments(SYCL_CXX_FLAGS_LIST)
122+
123+
# Spawn a process to build the test case.
124+
execute_process(
125+
COMMAND "${SYCL_COMPILER}"
126+
${SYCL_CXX_FLAGS_LIST}
127+
${TEST_SRC_FILE}
128+
"-o"
129+
${TEST_EXE}
130+
WORKING_DIRECTORY ${SYCL_TEST_DIR}
131+
OUTPUT_VARIABLE output ERROR_VARIABLE output
132+
OUTPUT_FILE ${SYCL_TEST_DIR}/Compile.log
133+
RESULT_VARIABLE result
134+
TIMEOUT 20
135+
)
136+
137+
# Verify if test case build properly.
138+
if(result)
139+
message("SYCL feature test compile failed!")
140+
message("compile output is: ${output}")
141+
endif()
142+
143+
# TODO: what to do if it doesn't build
144+
145+
endfunction()
146+
147+
# Function to run the test case to generate feature info.
148+
149+
function(SYCL_FEATURE_TEST_RUN TEST_EXE)
150+
151+
# Spawn a process to run the test case.
152+
153+
execute_process(
154+
COMMAND ${TEST_EXE}
155+
WORKING_DIRECTORY ${SYCL_TEST_DIR}
156+
OUTPUT_VARIABLE output ERROR_VARIABLE output
157+
RESULT_VARIABLE result
158+
TIMEOUT 20
159+
)
160+
161+
# Verify the test execution output.
162+
if(test_result)
163+
set(IntelDPCPP_FOUND False)
164+
set(SYCL_REASON_FAILURE "SYCL: feature test execution failed!!")
165+
endif()
166+
# TODO: what iff the result is false.. error or ignore?
167+
168+
set( test_result "${result}" PARENT_SCOPE)
169+
set( test_output "${output}" PARENT_SCOPE)
170+
171+
endfunction()
172+
173+
174+
# Function to extract the information from test execution.
175+
function(SYCL_FEATURE_TEST_EXTRACT test_output)
176+
177+
string(REGEX REPLACE "\n" ";" test_output_list "${test_output}")
178+
179+
set(SYCL_LANGUAGE_VERSION "")
180+
foreach(strl ${test_output_list})
181+
if(${strl} MATCHES "^SYCL_LANGUAGE_VERSION=([A-Za-z0-9_]+)$")
182+
string(REGEX REPLACE "^SYCL_LANGUAGE_VERSION=" "" extracted_sycl_lang "${strl}")
183+
set(SYCL_LANGUAGE_VERSION ${extracted_sycl_lang})
184+
endif()
185+
endforeach()
186+
187+
set(SYCL_LANGUAGE_VERSION "${SYCL_LANGUAGE_VERSION}" PARENT_SCOPE)
188+
endfunction()
189+
190+
if(SYCL_COMPILER)
191+
# TODO ensure CMAKE_LINKER and CMAKE_CXX_COMPILER are same/supports SYCL.
192+
# set(CMAKE_LINKER ${SYCL_COMPILER})
193+
194+
# use REALPATH to resolve symlinks
195+
get_filename_component(_REALPATH_SYCL_COMPILER "${SYCL_COMPILER}" REALPATH)
196+
get_filename_component(SYCL_BIN_DIR "${_REALPATH_SYCL_COMPILER}" DIRECTORY)
197+
get_filename_component(SYCL_PACKAGE_DIR "${SYCL_BIN_DIR}" DIRECTORY CACHE)
198+
199+
# Find Include path from binary
200+
find_file(SYCL_INCLUDE_DIR
201+
NAMES
202+
include
203+
HINTS
204+
${SYCL_PACKAGE_DIR} ENV SYCL_INCLUDE_DIR_HINT
205+
NO_DEFAULT_PATH
206+
)
207+
208+
# Find Library directory
209+
find_file(SYCL_LIBRARY_DIR
210+
NAMES
211+
lib lib64
212+
HINTS
213+
${SYCL_PACKAGE_DIR} ENV SYCL_LIBRARY_DIR_HINT
214+
NO_DEFAULT_PATH
215+
)
216+
217+
endif()
218+
219+
220+
set(SYCL_FLAGS "")
221+
222+
# Based on Compiler ID, add support for SYCL
223+
if( "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang" OR
224+
"x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xIntelLLVM")
225+
set(SYCL_FLAGS "-fsycl ")
226+
endif()
227+
228+
# Based on Compiler ID, add support for DPCPP
229+
if( "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xIntelLLVM")
230+
set(SYCL_FLAGS "--dpcpp ${SYCL_FLAGS}")
231+
endif()
232+
233+
# TODO verify if this is needed
234+
# Windows: Add Exception handling
235+
if(WIN32)
236+
set(SYCL_FLAGS "${SYCL_FLAGS} /EHsc")
237+
endif()
238+
239+
set(SYCL_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SYCL_FLAGS}")
240+
241+
# And now test the assumptions.
242+
243+
# Create a clean working directory.
244+
set(SYCL_TEST_DIR "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/TESTSYCL")
245+
file(REMOVE_RECURSE ${SYCL_TEST_DIR})
246+
file(MAKE_DIRECTORY ${SYCL_TEST_DIR})
247+
248+
# Create the test source file
249+
set(TEST_SRC_FILE "${SYCL_TEST_DIR}/sycl_features.cpp")
250+
set(TEST_EXE "${TEST_SRC_FILE}.exe")
251+
SYCL_FEATURE_TEST_WRITE(${TEST_SRC_FILE})
252+
253+
# Build the test and create test executable
254+
SYCL_FEATURE_TEST_BUILD(${TEST_SRC_FILE} ${TEST_EXE})
255+
256+
# Execute the test to extract information
257+
SYCL_FEATURE_TEST_RUN(${TEST_EXE})
258+
259+
# Extract test output for information
260+
SYCL_FEATURE_TEST_EXTRACT(${test_output})
261+
262+
# As per specification, all the SYCL compatible compilers should
263+
# define macro SYCL_LANGUAGE_VERSION
264+
string(COMPARE EQUAL "${SYCL_LANGUAGE_VERSION}" "" nosycllang)
265+
if(nosycllang)
266+
set(IntelDPCPP_FOUND False)
267+
set(SYCL_REASON_FAILURE "SYCL: It appears that the ${CMAKE_CXX_COMPILER} does not support SYCL")
268+
set(IntelDPCPP_NOT_FOUND_MESSAGE "${SYCL_REASON_FAILURE}")
269+
endif()
270+
271+
# Placeholder for identifying various implemenations of SYCL compilers.
272+
# for now, set to the CMAKE_CXX_COMPILER_ID
273+
set(SYCL_IMPLEMENTATION_ID "${CMAKE_CXX_COMPILER_ID}")
274+
275+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SYCL_FLAGS}")
276+
277+
message(STATUS "Echo from ${CMAKE_CURRENT_SOURCE_DIR}/IntelDPCPPConfig.cmake")
278+
message(STATUS "The SYCL compiler is ${SYCL_COMPILER}")
279+
message(STATUS "The SYCL Flags are ${SYCL_FLAGS}")
280+
message(STATUS "The SYCL Language Version is ${SYCL_LANGUAGE_VERSION}")
281+
282+
find_package_handle_standard_args(
283+
IntelDPCPP
284+
FOUND_VAR IntelDPCPP_FOUND
285+
REQUIRED_VARS SYCL_INCLUDE_DIR SYCL_LIBRARY_DIR SYCL_FLAGS
286+
VERSION_VAR SYCL_LANGUAGE_VERSION
287+
REASON_FAILURE_MESSAGE "${SYCL_REASON_FAILURE}")
288+
289+
# Include in Cache
290+
set(SYCL_LANGUAGE_VERSION "${SYCL_LANGUAGE_VERSION}" CACHE STRING "SYCL Language version")
291+
set(SYCL_INCLUDE_DIR "${SYCL_INCLUDE_DIR}" CACHE FILEPATH "SYCL Include directory")
292+
set(SYCL_LIBRARY_DIR "${SYCL_LIBRARY_DIR}" CACHE FILEPATH "SYCL Library Directory")
293+
set(SYCL_FLAGS "${SYCL_FLAGS}" CACHE STRING "SYCL flags for the compiler")

0 commit comments

Comments
 (0)