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
|
##===----------------------------------------------------------------------===##
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
##===----------------------------------------------------------------------===##
#
# Build the DeviceRTL for all toolchains that are available
#
##===----------------------------------------------------------------------===##
set(LIBOMPTARGET_BUILD_DEVICERTL_BCLIB TRUE CACHE BOOL
"Can be set to false to disable building this library.")
if (NOT LIBOMPTARGET_BUILD_DEVICERTL_BCLIB)
libomptarget_say("Not building DeviceRTL: Disabled by LIBOMPTARGET_BUILD_DEVICERTL_BCLIB")
return()
endif()
# Check to ensure the host system is a supported host architecture.
if(NOT ${CMAKE_SIZEOF_VOID_P} EQUAL "8")
libomptarget_say("Not building DeviceRTL: Runtime does not support 32-bit hosts")
return()
endif()
if (LLVM_DIR)
# Builds that use pre-installed LLVM have LLVM_DIR set.
# A standalone or LLVM_ENABLE_RUNTIMES=openmp build takes this route
find_program(CLANG_TOOL clang PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH)
find_program(LINK_TOOL llvm-link PATHS ${LLVM_TOOLS_BINARY_DIR}
NO_DEFAULT_PATH)
find_program(OPT_TOOL opt PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH)
if ((NOT CLANG_TOOL) OR (NOT LINK_TOOL) OR (NOT OPT_TOOL))
libomptarget_say("Not building DeviceRTL. Missing clang: ${CLANG_TOOL}, llvm-link: ${LINK_TOOL} or opt: ${OPT_TOOL}")
return()
else()
libomptarget_say("Building DeviceRTL. Using clang: ${CLANG_TOOL}, llvm-link: ${LINK_TOOL} and opt: ${OPT_TOOL}")
endif()
elseif (LLVM_TOOL_CLANG_BUILD AND NOT CMAKE_CROSSCOMPILING AND NOT OPENMP_STANDALONE_BUILD)
# LLVM in-tree builds may use CMake target names to discover the tools.
# A LLVM_ENABLE_PROJECTS=openmp build takes this route
set(CLANG_TOOL $<TARGET_FILE:clang>)
set(LINK_TOOL $<TARGET_FILE:llvm-link>)
set(OPT_TOOL $<TARGET_FILE:opt>)
libomptarget_say("Building DeviceRTL. Using clang from in-tree build")
else()
libomptarget_say("Not building DeviceRTL. No appropriate clang found")
return()
endif()
set(devicertl_base_directory ${CMAKE_CURRENT_SOURCE_DIR})
set(include_directory ${devicertl_base_directory}/include)
set(source_directory ${devicertl_base_directory}/src)
set(all_capabilities 35 37 50 52 53 60 61 62 70 72 75 80 86)
set(LIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES ${all_capabilities} CACHE STRING
"List of CUDA Compute Capabilities to be used to compile the NVPTX DeviceRTL.")
string(TOLOWER ${LIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES} LIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES)
if (LIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES STREQUAL "all")
set(nvptx_sm_list ${all_capabilities})
elseif(LIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES STREQUAL "auto")
if (NOT LIBOMPTARGET_DEP_CUDA_FOUND)
libomptarget_error_say("[NVPTX] Cannot auto detect compute capability as CUDA not found.")
endif()
set(nvptx_sm_list ${LIBOMPTARGET_DEP_CUDA_ARCH})
else()
string(REPLACE "," ";" nvptx_sm_list "${LIBOMPTARGET_NVPTX_COMPUTE_CAPABILITIES}")
endif()
# Check all SM values
foreach(sm ${nvptx_sm_list})
if (NOT ${sm} IN_LIST all_capabilities)
libomptarget_warning_say("[NVPTX] Compute capability ${sm} is not supported. Make sure clang can work with it.")
endif()
endforeach()
set(amdgpu_mcpus gfx700 gfx701 gfx801 gfx803 gfx900 gfx902 gfx906 gfx908 gfx90a gfx90c gfx940 gfx1010 gfx1030 gfx1031 gfx1032 gfx1033 gfx1034 gfx1035 gfx1036)
if (DEFINED LIBOMPTARGET_AMDGCN_GFXLIST)
set(amdgpu_mcpus ${LIBOMPTARGET_AMDGCN_GFXLIST})
endif()
# Activate RTL message dumps if requested by the user.
set(LIBOMPTARGET_DEVICE_DEBUG FALSE CACHE BOOL
"Activate DeviceRTL debug messages.")
set(include_files
${include_directory}/Configuration.h
${include_directory}/Debug.h
${include_directory}/Interface.h
${include_directory}/Mapping.h
${include_directory}/State.h
${include_directory}/Synchronization.h
${include_directory}/Types.h
${include_directory}/Utils.h
)
set(src_files
${source_directory}/Configuration.cpp
${source_directory}/Debug.cpp
${source_directory}/Kernel.cpp
${source_directory}/Mapping.cpp
${source_directory}/Misc.cpp
${source_directory}/Parallelism.cpp
${source_directory}/Reduction.cpp
${source_directory}/State.cpp
${source_directory}/Synchronization.cpp
${source_directory}/Tasking.cpp
${source_directory}/Utils.cpp
${source_directory}/Workshare.cpp
)
set(clang_opt_flags -O3 -mllvm -openmp-opt-disable -DSHARED_SCRATCHPAD_SIZE=512)
set(link_opt_flags -O3 -openmp-opt-disable)
set(link_export_flag -passes=internalize -internalize-public-api-file=${source_directory}/exports)
# Prepend -I to each list element
set (LIBOMPTARGET_LLVM_INCLUDE_DIRS_DEVICERTL "${LIBOMPTARGET_LLVM_INCLUDE_DIRS}")
list(TRANSFORM LIBOMPTARGET_LLVM_INCLUDE_DIRS_DEVICERTL PREPEND "-I")
# Set flags for LLVM Bitcode compilation.
set(bc_flags -c -emit-llvm -std=c++17 -fvisibility=hidden
${clang_opt_flags} --offload-device-only
-nocudalib -nogpulib -nostdinc
-fopenmp -fopenmp-cuda-mode
-I${include_directory}
-I${devicertl_base_directory}/../include
${LIBOMPTARGET_LLVM_INCLUDE_DIRS_DEVICERTL}
)
if(${LIBOMPTARGET_DEVICE_DEBUG})
list(APPEND bc_flags -DOMPTARGET_DEBUG=-1)
else()
list(APPEND bc_flags -DOMPTARGET_DEBUG=0)
endif()
function(compileDeviceRTLLibrary target_cpu target_name)
set(target_bc_flags ${ARGN})
set(bc_files "")
foreach(src ${src_files})
get_filename_component(infile ${src} ABSOLUTE)
get_filename_component(outfile ${src} NAME)
set(outfile "${outfile}-${target_cpu}.bc")
add_custom_command(OUTPUT ${outfile}
COMMAND ${CLANG_TOOL}
${bc_flags}
--offload-arch=${target_cpu}
${target_bc_flags}
${infile} -o ${outfile}
DEPENDS ${infile} ${include_files}
IMPLICIT_DEPENDS CXX ${infile}
COMMENT "Building LLVM bitcode ${outfile}"
VERBATIM
)
if("${CLANG_TOOL}" STREQUAL "$<TARGET_FILE:clang>")
# Add a file-level dependency to ensure that clang is up-to-date.
# By default, add_custom_command only builds clang if the
# executable is missing.
add_custom_command(OUTPUT ${outfile}
DEPENDS clang
APPEND
)
endif()
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${outfile})
list(APPEND bc_files ${outfile})
endforeach()
set(bclib_name "libomptarget-${target_name}-${target_cpu}.bc")
# Link to a bitcode library.
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/linked_${bclib_name}
COMMAND ${LINK_TOOL}
-o ${CMAKE_CURRENT_BINARY_DIR}/linked_${bclib_name} ${bc_files}
DEPENDS ${bc_files}
COMMENT "Linking LLVM bitcode ${bclib_name}"
)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/internalized_${bclib_name}
COMMAND ${OPT_TOOL} ${link_export_flag} ${CMAKE_CURRENT_BINARY_DIR}/linked_${bclib_name}
-o ${CMAKE_CURRENT_BINARY_DIR}/internalized_${bclib_name}
DEPENDS ${source_directory}/exports ${CMAKE_CURRENT_BINARY_DIR}/linked_${bclib_name}
COMMENT "Internalizing LLVM bitcode ${bclib_name}"
)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${bclib_name}
COMMAND ${OPT_TOOL} ${link_opt_flags} ${CMAKE_CURRENT_BINARY_DIR}/internalized_${bclib_name}
-o ${CMAKE_CURRENT_BINARY_DIR}/${bclib_name}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/internalized_${bclib_name}
COMMENT "Optimizing LLVM bitcode ${bclib_name}"
)
# Add a file-level dependency to ensure that llvm-link and opt are up-to-date.
# By default, add_custom_command only builds the tool if the executable is missing
if("${LINK_TOOL}" STREQUAL "$<TARGET_FILE:llvm-link>")
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/linked_${bclib_name}
DEPENDS llvm-link
APPEND)
endif()
if("${OPT_TOOL}" STREQUAL "$<TARGET_FILE:opt>")
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${bclib_name}
DEPENDS opt
APPEND)
endif()
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${bclib_name})
set(bclib_target_name "omptarget-${target_name}-${target_cpu}-bc")
add_custom_target(${bclib_target_name} ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${bclib_name})
# Copy library to destination.
add_custom_command(TARGET ${bclib_target_name} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${bclib_name}
${LIBOMPTARGET_LIBRARY_DIR})
add_dependencies("omptarget.devicertl.${target_name}" "${bclib_target_name}")
# Install bitcode library under the lib destination folder.
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${bclib_name} DESTINATION "${OPENMP_INSTALL_LIBDIR}")
endfunction()
# Generate a Bitcode library for all the compute capabilities the user requested
add_custom_target(omptarget.devicertl.nvptx)
foreach(sm ${nvptx_sm_list})
compileDeviceRTLLibrary(sm_${sm} nvptx -fopenmp-targets=nvptx64-nvidia-cuda -DLIBOMPTARGET_BC_TARGET --cuda-feature=+ptx61)
endforeach()
add_custom_target(omptarget.devicertl.amdgpu)
foreach(mcpu ${amdgpu_mcpus})
compileDeviceRTLLibrary(${mcpu} amdgpu -fopenmp-targets=amdgcn-amd-amdhsa -DLIBOMPTARGET_BC_TARGET -D__AMDGCN__ -nogpulib)
endforeach()
# Set the flags to build the device runtime from clang.
set(clang_lib_flags -fopenmp -fopenmp-cuda-mode -foffload-lto -fvisibility=hidden -Xopenmp-target=nvptx64-nvidia-cuda --cuda-feature=+ptx61 -nocudalib -nogpulib -nostdinc ${clang_opt_flags})
foreach(arch ${nvptx_sm_list})
set(clang_lib_flags ${clang_lib_flags} --offload-arch=sm_${arch})
endforeach()
foreach(arch ${amdgpu_mcpus})
set(clang_lib_flags ${clang_lib_flags} --offload-arch=${arch})
endforeach()
# Build the static library version of the device runtime.
# first create an object target
add_library(omptarget.devicertl.all_objs OBJECT IMPORTED)
foreach(src ${src_files})
get_filename_component(infile ${src} ABSOLUTE)
get_filename_component(outfile ${src} NAME)
set(outfile "${outfile}.o")
set(outfile_full_path "${CMAKE_CURRENT_BINARY_DIR}/${outfile}")
add_custom_command(OUTPUT ${outfile_full_path}
COMMAND ${CLANG_TOOL} ${clang_lib_flags} --std=c++17 -c
-o ${outfile_full_path}
-I${include_directory}
-I${devicertl_base_directory}/../include
${LIBOMPTARGET_LLVM_INCLUDE_DIRS_DEVICERTL}
${infile}
DEPENDS ${infile} ${include_files}
IMPLICIT_DEPENDS CXX ${infile}
COMMENT "Building device code ${outfile}"
VERBATIM
)
if("${CLANG_TOOL}" STREQUAL "$<TARGET_FILE:clang>")
# Add a file-level dependency to ensure that clang is up-to-date.
# By default, add_custom_command only builds clang if the
# executable is missing.
add_custom_command(OUTPUT ${outfile_full_path}
DEPENDS clang
APPEND
)
endif()
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${outfile_full_path})
set_property(TARGET omptarget.devicertl.all_objs APPEND PROPERTY IMPORTED_OBJECTS ${outfile_full_path})
endforeach()
# second archive all the object files into a static library
add_library(omptarget.devicertl STATIC)
set_target_properties(omptarget.devicertl PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(omptarget.devicertl PRIVATE omptarget.devicertl.all_objs)
install(TARGETS omptarget.devicertl ARCHIVE DESTINATION ${OPENMP_INSTALL_LIBDIR})
|