Skip to content

Commit fbb970c

Browse files
committed
[CMake] Parse kernel names using integration header rather than IR
The icpx (and other similar Intel binaries) don't allow the generation of IR output, so instead generate the list of kernel names using the integration header instead. For reference, the IH contains the following: ```c++ // names of all kernels defined in the corresponding source static constexpr const char* const kernel_names[] = { "_ZTSZZ4mainENKUlRN4sycl3_V17handlerEE_clES2_E8indexers" }; ``` which we can just search for.
1 parent ac9223f commit fbb970c

File tree

2 files changed

+34
-29
lines changed

2 files changed

+34
-29
lines changed

scripts/generate_kernel_header.py

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -62,44 +62,32 @@ def generate_header(output_file, kernel_name_dict):
6262
fout.write(rendered)
6363

6464

65-
def get_mangled_names(dpcxx_path, source_file, output_header):
65+
def get_mangled_names(source_file, output_header):
6666
"""Return a list of all the entry point names from a given sycl source file.
6767
6868
Filters out wrapper and offset handler entry points.
6969
"""
7070
output_dir = os.path.dirname(output_header)
71-
il_file = os.path.join(output_dir, os.path.basename(source_file) + ".ll")
72-
generate_il_command = f"""\
73-
{dpcxx_path} -S -fsycl -fsycl-device-code-split=off \
74-
-fsycl-device-only -o {il_file} {source_file}"""
75-
subprocess.run(generate_il_command, shell=True)
76-
kernel_line_regex = re.compile("define.*spir_kernel")
77-
definition_lines = []
78-
with open(il_file) as f:
71+
name = os.path.splitext(os.path.basename(source_file))[0]
72+
ih_file = os.path.join(output_dir, name, name + ".ih")
73+
definitions = []
74+
writing = False
75+
with open(ih_file) as f:
7976
lines = f.readlines()
8077
for line in lines:
81-
if kernel_line_regex.search(line) is not None:
82-
definition_lines.append(line)
78+
if "}" in line and writing:
79+
break
80+
# __pf_kernel_wrapper seems to be an internal function used by dpcpp
81+
if writing and "19__pf_kernel_wrapper" not in line:
82+
definitions.append(line.replace(",", "").strip()[1:-1])
83+
if "const char* const kernel_names[] = {" in line:
84+
writing = True
8385

84-
entry_point_names = []
85-
kernel_name_regex = re.compile(r"@(.*?)\(")
86-
for line in definition_lines:
87-
if kernel_name_regex.search(line) is None:
88-
continue
89-
match = kernel_name_regex.search(line)
90-
assert isinstance(match, re.Match)
91-
kernel_name = match.group(1)
92-
if "kernel_wrapper" not in kernel_name and "with_offset" not in kernel_name:
93-
entry_point_names.append(kernel_name)
94-
95-
os.remove(il_file)
96-
return entry_point_names
86+
return definitions
9787

9888

9989
def main():
10090
parser = argparse.ArgumentParser()
101-
parser.add_argument("--dpcxx_path",
102-
help="Full path to dpc++ compiler executable.")
10391
parser.add_argument(
10492
"-o",
10593
"--output",
@@ -112,7 +100,7 @@ def main():
112100
for source_file in args.source_files:
113101
program_name = os.path.splitext(os.path.basename(source_file))[0]
114102
mangled_names[program_name] = get_mangled_names(
115-
args.dpcxx_path, source_file, args.output)
103+
source_file, args.output)
116104
generate_header(args.output, mangled_names)
117105

118106

test/conformance/device_code/CMakeLists.txt

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ else()
1010
set(AMD_ARCH "${UR_CONFORMANCE_AMD_ARCH}")
1111
endif()
1212

13+
if (WIN32)
14+
set(NULDEV NUL)
15+
else()
16+
set(NULDEV /dev/null)
17+
endif()
18+
1319
cmake_path(GET UR_DPCXX EXTENSION EXE)
1420
cmake_path(REPLACE_FILENAME UR_DPCXX "clang-offload-extract${EXE}" OUTPUT_VARIABLE DEFAULT_EXTRACTOR_NAME)
1521
set(UR_DEVICE_CODE_EXTRACTOR "${DEFAULT_EXTRACTOR_NAME}" CACHE PATH "Path to clang-offload-extract")
@@ -100,6 +106,17 @@ macro(add_device_binary SOURCE_FILE)
100106
add_custom_target(generate_${KERNEL_NAME}_${TRIPLE} DEPENDS ${BIN_PATH})
101107
add_dependencies(generate_device_binaries generate_${KERNEL_NAME}_${TRIPLE})
102108
endforeach()
109+
110+
set(IH_PATH "${DEVICE_BINARY_DIR}/${KERNEL_NAME}.ih")
111+
add_custom_command(OUTPUT "${IH_PATH}"
112+
COMMAND ${UR_DPCXX} -fsycl -fsycl-device-code-split=off
113+
-fsycl-device-only -c -Xclang -fsycl-int-header="${IH_PATH}"
114+
${DPCXX_BUILD_FLAGS_LIST} ${SOURCE_FILE} -o ${NULDEV}
115+
116+
WORKING_DIRECTORY "${DEVICE_BINARY_DIR}"
117+
DEPENDS ${SOURCE_FILE}
118+
)
119+
list(APPEND DEVICE_IHS ${IH_PATH})
103120
list(APPEND DEVICE_CODE_SOURCES ${SOURCE_FILE})
104121
endmacro()
105122

@@ -127,8 +144,8 @@ set(KERNEL_HEADER ${UR_CONFORMANCE_DEVICE_BINARIES_DIR}/kernel_entry_points.h)
127144
add_custom_command(OUTPUT ${KERNEL_HEADER}
128145
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/scripts
129146
COMMAND ${Python3_EXECUTABLE} generate_kernel_header.py
130-
--dpcxx_path ${UR_DPCXX} -o ${KERNEL_HEADER} ${DEVICE_CODE_SOURCES}
147+
-o ${KERNEL_HEADER} ${DEVICE_CODE_SOURCES}
131148
DEPENDS ${PROJECT_SOURCE_DIR}/scripts/generate_kernel_header.py
132-
${DEVICE_CODE_SOURCES})
149+
${DEVICE_CODE_SOURCES} ${DEVICE_IHS})
133150
add_custom_target(kernel_names_header DEPENDS ${KERNEL_HEADER})
134151
add_dependencies(generate_device_binaries kernel_names_header)

0 commit comments

Comments
 (0)