Skip to content

Commit 77bb972

Browse files
authored
[SYCL][libdevice] Refactor cmake for imf SYCL device library (#6312)
This PR aims to refactor cmake building system for imf SYCL device library. Previously, the source of SYCL fallback device library has pre-assumption that all functions in the same fallback .spv or .o file must reside in single .cpp file. The reason is we need to use sycl compiler to build .spv or .o file with following commands: clang++ -fsycl -fsycl-device-only -fno-sycl-use-bitcode t.cpp -o t.spv clang++ -fsycl -c -fsycl-targets="..." t.cpp -o t.o However, imf fallback sources broke the pre-assumptions, all implementations reside in multiple .cpp files. Current building have to deal with multiple tools, for spv building, we have to do following: use "clang++ -fsycl -fsycl-device-only -c -emit-llvm" to generate LLVM .bc file for each .cpp use "llvm-link" to link multiple LLVM .bc into one LLVM .bc file use "llvm-spirv" to convert the LLVM .bc to spirv file For .o file, the steps are more complicated, we need to do following: use "clang++ -fsycl -fsycl-device-only -c -emit-llvm" to generate LLVM.bc for each .cpp Use "llvm-link" to link multiple LLVM .bc into one LLVM .bc file the steps 1,2 must be done for all sycl targets supported use clang-offload-bunlder to bundle different sycl target's LLVM .bc to final .objet file Current solution has following drawbacks: Too complicated, too much unnecessary work which is to emulate the work of simple “clang++ -fsycl …” command. This makes cmake hard to understand and maintain. Too fragile, clang driver may change the detail steps of simple “clang++ -fsycl…” and each tool used currently may update their option and usage which may lead to imf libdevice building failure. The more tools we deal with, the more risk we are in. So, we decide to use following solution: For building imf fallback spv or object file, we first combine all required .cpp into a “full” .cpp and then use simple “clang++ -fsycl …” command to build it. We will create a “libdevice” folder in build/lib and save the full .cpp file there. All imf fallback device library code will be organized to avoid code conflict, duplicate. Signed-off-by: jinge90 [email protected]
1 parent 4f9935a commit 77bb972

File tree

3 files changed

+148
-153
lines changed

3 files changed

+148
-153
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
set(imf_fp32_fallback_src_list imf_utils/integer_misc.cpp
2+
imf_utils/half_convert.cpp
3+
imf_utils/float_convert.cpp
4+
imf/imf_inline_fp32.cpp)
5+
6+
set(imf_fp64_fallback_src_list imf_utils/double_convert.cpp
7+
imf/imf_inline_fp64.cpp)
8+
9+
if (FP64 STREQUAL 0)
10+
set(imf_fallback_src_list ${imf_fp32_fallback_src_list})
11+
set(imf_fallback_dest ${DEST_DIR}/imf_fp32_fallback.cpp)
12+
else()
13+
set(imf_fallback_src_list ${imf_fp64_fallback_src_list})
14+
set(imf_fallback_dest ${DEST_DIR}/imf_fp64_fallback.cpp)
15+
endif()
16+
17+
set(flag 0)
18+
foreach(src ${imf_fallback_src_list})
19+
file(READ ${SRC_DIR}/${src} src_contents)
20+
if(flag STREQUAL 0)
21+
file(WRITE ${imf_fallback_dest} "${src_contents}")
22+
set(flag 1)
23+
else()
24+
file(APPEND ${imf_fallback_dest} "${src_contents}")
25+
endif()
26+
endforeach()

libdevice/cmake/modules/SYCLLibdevice.cmake

Lines changed: 117 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,7 @@ endif()
1313
set(install_dest_lib lib${LLVM_LIBDIR_SUFFIX})
1414

1515
set(clang $<TARGET_FILE:clang>)
16-
set(llvm-link $<TARGET_FILE:llvm-link>)
17-
set(llc $<TARGET_FILE:llc>)
18-
set(llvm-spirv $<TARGET_FILE:llvm-spirv>)
1916
set(llvm-ar $<TARGET_FILE:llvm-ar>)
20-
set(clang-offload-bundler $<TARGET_FILE:clang-offload-bundler>)
2117

2218
string(CONCAT sycl_targets_opt
2319
"-fsycl-targets="
@@ -120,162 +116,131 @@ add_fallback_devicelib(libsycl-fallback-complex-fp64 SRC fallback-complex-fp64.c
120116
add_fallback_devicelib(libsycl-fallback-cmath SRC fallback-cmath.cpp DEP ${cmath_obj_deps})
121117
add_fallback_devicelib(libsycl-fallback-cmath-fp64 SRC fallback-cmath-fp64.cpp DEP ${cmath_obj_deps})
122118

123-
# imf fallback is different, we have many separate sources instead of single one including all functions.
124-
# So, we need to combine all LLVM IR to a complete one and run llvm-spirv for it.
125119
file(MAKE_DIRECTORY ${obj_binary_dir}/libdevice)
126-
set(bc_binary_dir ${obj_binary_dir}/libdevice)
127-
128-
set(fallback-imf-src imf_utils/float_convert.cpp
129-
imf_utils/half_convert.cpp
130-
imf_utils/integer_misc.cpp
131-
imf/imf_inline_fp32.cpp)
132-
set(fallback-imf-fp64-src imf_utils/double_convert.cpp
133-
imf/imf_inline_fp64.cpp)
134-
set(wrapper-imf-src imf_wrapper.cpp imf_wrapper_fp64.cpp)
135-
set(imf-src ${wrapper-imf-src} ${fallback-imf-src} ${fallback-imf-fp64-src})
136-
137-
add_custom_target(imf-fallback-spv
138-
COMMAND ${llvm-spirv}
139-
${bc_binary_dir}/fallback-imf-spir64-unknown-unknown.bc
140-
-o ${spv_binary_dir}/libsycl-fallback-imf.spv)
141-
add_custom_target(imf-fp64-fallback-spv
142-
COMMAND ${llvm-spirv}
143-
${bc_binary_dir}/fallback-imf-fp64-spir64-unknown-unknown.bc
144-
-o ${spv_binary_dir}/libsycl-fallback-imf-fp64.spv)
145-
146-
add_dependencies(libsycldevice-spv imf-fallback-spv)
147-
add_dependencies(libsycldevice-spv imf-fp64-fallback-spv)
120+
set(imf_fallback_src_dir ${obj_binary_dir}/libdevice)
121+
set(imf_src_dir ${CMAKE_CURRENT_SOURCE_DIR})
122+
set(imf_fallback_fp32_deps device.h device_imf.hpp imf_half.hpp
123+
imf_utils/integer_misc.cpp
124+
imf_utils/float_convert.cpp
125+
imf_utils/half_convert.cpp
126+
imf/imf_inline_fp32.cpp)
127+
set(imf_fallback_fp64_deps device.h device_imf.hpp imf_half.hpp
128+
imf_utils/double_convert.cpp
129+
imf/imf_inline_fp64.cpp)
130+
set(imf_fp32_fallback_src ${imf_fallback_src_dir}/imf_fp32_fallback.cpp)
131+
set(imf_fp64_fallback_src ${imf_fallback_src_dir}/imf_fp64_fallback.cpp)
132+
133+
add_custom_command(OUTPUT ${imf_fp32_fallback_src}
134+
COMMAND ${CMAKE_COMMAND} -D SRC_DIR=${imf_src_dir}
135+
-D DEST_DIR=${imf_fallback_src_dir}
136+
-D FP64=0
137+
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/ImfSrcConcate.cmake
138+
DEPENDS ${imf_fallback_fp32_deps})
139+
140+
add_custom_command(OUTPUT ${imf_fp64_fallback_src}
141+
COMMAND ${CMAKE_COMMAND} -D SRC_DIR=${imf_src_dir}
142+
-D DEST_DIR=${imf_fallback_src_dir}
143+
-D FP64=1
144+
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/ImfSrcConcate.cmake
145+
DEPENDS ${imf_fallback_fp64_deps})
146+
147+
add_custom_target(get_imf_fallback_fp32 DEPENDS ${imf_fp32_fallback_src})
148+
add_custom_command(OUTPUT ${spv_binary_dir}/libsycl-fallback-imf.spv
149+
COMMAND ${clang} -fsycl-device-only -fno-sycl-use-bitcode
150+
${compile_opts} -I ${CMAKE_CURRENT_SOURCE_DIR}/imf
151+
${imf_fp32_fallback_src}
152+
-o ${spv_binary_dir}/libsycl-fallback-imf.spv
153+
DEPENDS ${imf_fallback_fp32_deps} get_imf_fallback_fp32
154+
VERBATIM)
155+
156+
add_custom_command(OUTPUT ${obj_binary_dir}/libsycl-fallback-imf.${lib-suffix}
157+
COMMAND ${clang} -fsycl -c
158+
${compile_opts} ${sycl_targets_opt}
159+
${imf_fp32_fallback_src} -I ${CMAKE_CURRENT_SOURCE_DIR}/imf
160+
-o ${obj_binary_dir}/libsycl-fallback-imf.${lib-suffix}
161+
DEPENDS ${imf_fallback_fp32_deps} get_imf_fallback_fp32
162+
VERBATIM)
163+
164+
add_custom_command(OUTPUT ${obj_binary_dir}/fallback-imf-fp32-host.${lib-suffix}
165+
COMMAND ${clang} -c -D__LIBDEVICE_HOST_IMPL__
166+
-I ${CMAKE_CURRENT_SOURCE_DIR}/imf
167+
${imf_fp32_fallback_src}
168+
-o ${obj_binary_dir}/fallback-imf-fp32-host.${lib-suffix}
169+
DEPENDS ${imf_fallback_fp32_deps} get_imf_fallback_fp32
170+
VERBATIM)
171+
172+
add_custom_target(get_imf_fallback_fp64 DEPENDS ${imf_fp64_fallback_src})
173+
add_custom_command(OUTPUT ${spv_binary_dir}/libsycl-fallback-imf-fp64.spv
174+
COMMAND ${clang} -fsycl-device-only -fno-sycl-use-bitcode
175+
${compile_opts} -I ${CMAKE_CURRENT_SOURCE_DIR}/imf
176+
${imf_fp64_fallback_src}
177+
-o ${spv_binary_dir}/libsycl-fallback-imf-fp64.spv
178+
DEPENDS ${imf_fallback_fp64_deps} get_imf_fallback_fp64
179+
VERBATIM)
180+
181+
add_custom_command(OUTPUT ${obj_binary_dir}/libsycl-fallback-imf-fp64.${lib-suffix}
182+
COMMAND ${clang} -fsycl -c -I ${CMAKE_CURRENT_SOURCE_DIR}/imf
183+
${compile_opts} ${sycl_targets_opt}
184+
${imf_fp64_fallback_src}
185+
-o ${obj_binary_dir}/libsycl-fallback-imf-fp64.${lib-suffix}
186+
DEPENDS ${imf_fallback_fp64_deps} get_imf_fallback_fp64
187+
VERBATIM)
188+
189+
add_custom_command(OUTPUT ${obj_binary_dir}/fallback-imf-fp64-host.${lib-suffix}
190+
COMMAND ${clang} -c -D__LIBDEVICE_HOST_IMPL__
191+
-I ${CMAKE_CURRENT_SOURCE_DIR}/imf
192+
${imf_fp64_fallback_src}
193+
-o ${obj_binary_dir}/fallback-imf-fp64-host.${lib-suffix}
194+
DEPENDS ${imf_fallback_fp64_deps} get_imf_fallback_fp64
195+
VERBATIM)
196+
197+
add_custom_target(imf_fallback_fp32_spv DEPENDS ${spv_binary_dir}/libsycl-fallback-imf.spv)
198+
add_custom_target(imf_fallback_fp32_obj DEPENDS ${obj_binary_dir}/libsycl-fallback-imf.${lib-suffix})
199+
add_custom_target(imf_fallback_fp32_host_obj DEPENDS ${obj_binary_dir}/fallback-imf-fp32-host.${lib-suffix})
200+
add_dependencies(libsycldevice-spv imf_fallback_fp32_spv)
201+
add_dependencies(libsycldevice-obj imf_fallback_fp32_obj)
202+
203+
add_custom_target(imf_fallback_fp64_spv DEPENDS ${spv_binary_dir}/libsycl-fallback-imf-fp64.spv)
204+
add_custom_target(imf_fallback_fp64_obj DEPENDS ${obj_binary_dir}/libsycl-fallback-imf-fp64.${lib-suffix})
205+
add_custom_target(imf_fallback_fp64_host_obj DEPENDS ${obj_binary_dir}/fallback-imf-fp64-host.${lib-suffix})
206+
add_dependencies(libsycldevice-spv imf_fallback_fp64_spv)
207+
add_dependencies(libsycldevice-obj imf_fallback_fp64_obj)
208+
209+
add_custom_command(OUTPUT ${obj_binary_dir}/imf-fp32-host.${lib-suffix}
210+
COMMAND ${clang} -c -D__LIBDEVICE_HOST_IMPL__
211+
${CMAKE_CURRENT_SOURCE_DIR}/imf_wrapper.cpp
212+
-o ${obj_binary_dir}/imf-fp32-host.${lib-suffix}
213+
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/imf_wrapper.cpp
214+
DEPENDS ${imf_obj_deps}
215+
VERBATIM)
216+
217+
add_custom_command(OUTPUT ${obj_binary_dir}/imf-fp64-host.${lib-suffix}
218+
COMMAND ${clang} -c -D__LIBDEVICE_HOST_IMPL__
219+
${CMAKE_CURRENT_SOURCE_DIR}/imf_wrapper_fp64.cpp
220+
-o ${obj_binary_dir}/imf-fp64-host.${lib-suffix}
221+
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/imf_wrapper_fp64.cpp
222+
DEPENDS ${imf_obj_deps}
223+
VERBATIM)
224+
225+
add_custom_target(imf_fp32_host_obj DEPENDS ${obj_binary_dir}/imf-fp32-host.${lib-suffix})
226+
add_custom_target(imf_fp64_host_obj DEPENDS ${obj_binary_dir}/imf-fp64-host.${lib-suffix})
227+
add_custom_target(imf_host_obj
228+
COMMAND ${llvm-ar} rcs ${obj_binary_dir}/${devicelib_host_static}
229+
${obj_binary_dir}/imf-fp32-host.${lib-suffix}
230+
${obj_binary_dir}/fallback-imf-fp32-host.${lib-suffix}
231+
${obj_binary_dir}/imf-fp64-host.${lib-suffix}
232+
${obj_binary_dir}/fallback-imf-fp64-host.${lib-suffix}
233+
DEPENDS imf_fp32_host_obj imf_fallback_fp32_host_obj imf_fp64_host_obj imf_fallback_fp64_host_obj
234+
VERBATIM)
235+
add_dependencies(libsycldevice-obj imf_host_obj)
148236
install(FILES ${spv_binary_dir}/libsycl-fallback-imf.spv
149237
${spv_binary_dir}/libsycl-fallback-imf-fp64.spv
150238
DESTINATION ${install_dest_spv}
151239
COMPONENT libsycldevice)
152240

153-
set(sycl_offload_targets sycl-spir64_x86_64-unknown-unknown
154-
sycl-spir64_gen-unknown-unknown
155-
sycl-spir64_fpga-unknown-unknown
156-
sycl-spir64-unknown-unknow
157-
host-x86_64-unknown-linux-gnu)
158-
159-
string(REPLACE ";" "," sycl_offload_targets "${sycl_offload_targets}")
160-
set(imf-offload-inputs ${bc_binary_dir}/fallback-imf-spir64-unknown-unknown.bc
161-
${bc_binary_dir}/fallback-imf-spir64_x86_64-unknown-unknown.bc
162-
${bc_binary_dir}/fallback-imf-spir64_gen-unknown-unknown.bc
163-
${bc_binary_dir}/fallback-imf-spir64_fpga-unknown-unknown.bc
164-
${bc_binary_dir}/fallback-imf-dummy-host.bc)
165-
string(REPLACE ";" "," imf-offload-inputs "${imf-offload-inputs}")
166-
add_custom_target(imf-fallback-obj
167-
COMMAND ${clang-offload-bundler} -type=o -targets=${sycl_offload_targets}
168-
-outputs=${obj_binary_dir}/libsycl-fallback-imf.${lib-suffix}
169-
-inputs=${imf-offload-inputs})
170-
171-
add_dependencies(libsycldevice-obj imf-fallback-obj)
172-
173-
set(imf-fp64-offload-inputs ${bc_binary_dir}/fallback-imf-fp64-spir64-unknown-unknown.bc
174-
${bc_binary_dir}/fallback-imf-fp64-spir64_x86_64-unknown-unknown.bc
175-
${bc_binary_dir}/fallback-imf-fp64-spir64_gen-unknown-unknown.bc
176-
${bc_binary_dir}/fallback-imf-fp64-spir64_fpga-unknown-unknown.bc
177-
${bc_binary_dir}/fallback-imf-fp64-dummy-host.bc)
178-
string(REPLACE ";" "," imf-fp64-offload-inputs "${imf-fp64-offload-inputs}")
179-
add_custom_target(imf-fp64-fallback-obj
180-
COMMAND ${clang-offload-bundler} -type=o -targets=${sycl_offload_targets}
181-
-outputs=${obj_binary_dir}/libsycl-fallback-imf-fp64.${lib-suffix}
182-
-inputs=${imf-fp64-offload-inputs})
183-
184-
add_dependencies(libsycldevice-obj imf-fp64-fallback-obj)
185-
186241
install(FILES ${obj_binary_dir}/libsycl-fallback-imf.${lib-suffix}
187242
${obj_binary_dir}/libsycl-fallback-imf-fp64.${lib-suffix}
243+
${obj_binary_dir}/${devicelib_host_static}
188244
DESTINATION ${install_dest_lib}
189245
COMPONENT libsycldevice)
190246

191-
function(add_devicelib_bc src_file sycl_target)
192-
cmake_parse_arguments(BC "" "" "DEPS;DEPED" ${ARGN})
193-
get_filename_component(fn ${src_file} NAME_WE)
194-
set(temp_bc_fn ${fn}-${sycl_target}.bc)
195-
set(devicelib-bc ${bc_binary_dir}/${temp_bc_fn})
196-
if(sycl_target STREQUAL "dummy-host")
197-
set(bc_compile_flags -c -emit-llvm)
198-
elseif(sycl_target STREQUAL "host")
199-
set(bc_compile_flags -c -emit-llvm -D__LIBDEVICE_HOST_IMPL__)
200-
else()
201-
set(bc_compile_flags -fsycl -fsycl-device-only -fsycl-targets=${sycl_target})
202-
endif()
203-
if (WIN32)
204-
list(APPEND bc_compile_flags -D_ALLOW_RUNTIME_LIBRARY_MISMATCH)
205-
list(APPEND bc_compile_flags -D_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH)
206-
endif()
207-
add_custom_command(OUTPUT ${devicelib-bc}
208-
COMMAND ${clang} ${bc_compile_flags}
209-
${CMAKE_CURRENT_SOURCE_DIR}/${src_file}
210-
-o ${devicelib-bc}
211-
MAIN_DEPENDENCY ${src_file}
212-
DEPENDS ${BC_DEPS}
213-
VERBATIM)
214-
add_custom_target(${temp_bc_fn} DEPENDS ${devicelib-bc})
215-
add_dependencies(${BC_DEPED} ${temp_bc_fn})
216-
endfunction()
217-
218-
function(merge_devicelib_bc bc_filename sycl_target)
219-
cmake_parse_arguments(FBC "" "" "SRCS;DEPS;DEPED" ${ARGN})
220-
set(bc_file_list)
221-
foreach(src ${FBC_SRCS})
222-
get_filename_component(fn ${src} NAME_WE)
223-
set(temp_bc_fn ${fn}-${sycl_target}.bc)
224-
list(APPEND bc_file_list ${bc_binary_dir}/${temp_bc_fn})
225-
endforeach()
226-
set(bc_target ${bc_filename}-${sycl_target})
227-
add_custom_target(${bc_target}
228-
COMMAND ${llvm-link} ${bc_file_list} -o ${bc_binary_dir}/${bc_target}.bc
229-
VERBATIM)
230-
foreach(src ${FBC_SRCS})
231-
add_devicelib_bc(${src} ${sycl_target}
232-
DEPS ${FBC_DEPS}
233-
DEPED ${bc_target})
234-
endforeach()
235-
foreach(deped ${FBC_DEPED})
236-
add_dependencies(${deped} ${bc_target})
237-
endforeach()
238-
endfunction()
239-
240-
set(imf_sycl_targets spir64_x86_64-unknown-unknown
241-
spir64_gen-unknown-unknown
242-
spir64_fpga-unknown-unknown
243-
spir64-unknown-unknown
244-
dummy-host)
245-
246-
foreach(imf_target ${imf_sycl_targets})
247-
if(imf_target STREQUAL "spir64-unknown-unknown")
248-
set(deped_list imf-fallback-obj imf-fallback-spv)
249-
set(deped64_list imf-fp64-fallback-obj imf-fp64-fallback-spv)
250-
else()
251-
set(deped_list imf-fallback-obj)
252-
set(deped64_list imf-fp64-fallback-obj)
253-
endif()
254-
merge_devicelib_bc(fallback-imf ${imf_target}
255-
SRCS ${fallback-imf-src}
256-
DEPS ${imf_obj_deps}
257-
DEPED ${deped_list})
258-
259-
merge_devicelib_bc(fallback-imf-fp64 ${imf_target}
260-
SRCS ${fallback-imf-fp64-src}
261-
DEPS ${imf_obj_deps}
262-
DEPED ${deped64_list})
263-
endforeach()
264-
265-
add_custom_target(imf-host-obj
266-
COMMAND ${llc} -filetype=obj
267-
${bc_binary_dir}/imf-host.bc -o
268-
${bc_binary_dir}/imf-host.${lib-suffix}
269-
COMMAND ${llvm-ar} rcs ${obj_binary_dir}/${devicelib_host_static} ${bc_binary_dir}/imf-host.${lib-suffix}
270-
VERBATIM)
271-
272-
add_dependencies(libsycldevice imf-host-obj)
273-
274-
install(FILES ${obj_binary_dir}/${devicelib_host_static}
275-
DESTINATION ${install_dest_lib}
276-
COMPONENT libsycldevice)
277-
278-
merge_devicelib_bc(imf host
279-
SRCS ${imf-src}
280-
DEPS ${imf_obj_deps}
281-
DEPED imf-host-obj)

libdevice/device.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@
3232
#endif // __SPIR__ || __LIBDEVICE_HOST_IMPL__
3333

3434
#ifdef __LIBDEVICE_HOST_IMPL__
35-
#define DEVICE_EXTERN_C __attribute__((weak)) EXTERN_C
35+
// For host implementation, all functions will be located in a static library
36+
// and it will be linked with user's host code by default. If those functions
37+
// are decorated with "weak" attribute, compiler will use PLT entry to call
38+
// all __device_imf_* functions, this will lead to crash.
39+
#define DEVICE_EXTERN_C EXTERN_C
3640
#define DEVICE_EXTERN_C_INLINE DEVICE_EXTERN_C __attribute__((always_inline))
3741
#endif // __LIBDEVICE_HOST_IMPL__
3842

0 commit comments

Comments
 (0)