Skip to content

Commit adc80c2

Browse files
committed
GPU: Add CPUDevice backend to emulate device-like processing on host
1 parent 50d355e commit adc80c2

16 files changed

Lines changed: 1229 additions & 12 deletions

‎GPU/GPUTracking/Base/GPUProcessor.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class GPUProcessor
5151
GPUd() GPUconstantref() const GPUConstantMem* GetConstantMem() const; // Body in GPUConstantMem.h to avoid circular headers
5252
GPUd() GPUconstantref() const GPUParam& Param() const; // ...
5353
GPUd() void raiseError(uint32_t code, uint32_t param1 = 0, uint32_t param2 = 0, uint32_t param3 = 0) const;
54+
GPUd() bool IsDeviceProcessor() const { return mGPUProcessorType == PROCESSOR_TYPE_DEVICE; }
5455
const GPUReconstruction& GetRec() const { return *mRec; }
5556

5657
#ifndef __OPENCL__

‎GPU/GPUTracking/Base/GPUReconstruction.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ class GPUReconstruction
427427
void* mGPULib;
428428
void* mGPUEntry;
429429
};
430-
static std::shared_ptr<LibraryLoader> sLibCUDA, sLibHIP, sLibOCL, sLibMETAL;
430+
static std::shared_ptr<LibraryLoader> sLibCUDA, sLibHIP, sLibOCL, sLibMETAL, sLibCPUDEVICE;
431431

432432
// Debugging
433433
struct debugInternal;

‎GPU/GPUTracking/Base/GPUReconstructionAvailableBackends.template.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@
1717
#cmakedefine HIP_ENABLED
1818
#cmakedefine OPENCL_ENABLED
1919
#cmakedefine METAL_ENABLED
20+
#cmakedefine CPUDEVICE_ENABLED
2021
#cmakedefine GPUCA_COMPILER_VERSIONS @GPUCA_COMPILER_VERSIONS@
2122
// clang-format on

‎GPU/GPUTracking/Base/GPUReconstructionLibrary.cxx‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ std::shared_ptr<GPUReconstruction::LibraryLoader>* GPUReconstruction::GetLibrary
106106
} else if (type == DeviceType::METAL) {
107107
#ifdef METAL_ENABLED
108108
return &sLibMETAL;
109+
#endif
110+
} else if (type == DeviceType::CPUDEVICE) {
111+
#ifdef CPUDEVICE_ENABLED
112+
return &sLibCPUDEVICE;
109113
#endif
110114
} else {
111115
GPUError("Error: Invalid device type %u", (uint32_t)type);
@@ -131,6 +135,7 @@ std::shared_ptr<GPUReconstruction::LibraryLoader> GPUReconstruction::sLibCUDA(ne
131135
std::shared_ptr<GPUReconstruction::LibraryLoader> GPUReconstruction::sLibHIP(new GPUReconstruction::LibraryLoader("lib" LIBRARY_PREFIX "GPUTrackingHIP" LIBRARY_EXTENSION, "GPUReconstruction_Create_HIP"));
132136
std::shared_ptr<GPUReconstruction::LibraryLoader> GPUReconstruction::sLibOCL(new GPUReconstruction::LibraryLoader("lib" LIBRARY_PREFIX "GPUTrackingOCL" LIBRARY_EXTENSION, "GPUReconstruction_Create_OCL"));
133137
std::shared_ptr<GPUReconstruction::LibraryLoader> GPUReconstruction::sLibMETAL(new GPUReconstruction::LibraryLoader("lib" LIBRARY_PREFIX "GPUTrackingMETAL" LIBRARY_EXTENSION, "GPUReconstruction_Create_METAL"));
138+
std::shared_ptr<GPUReconstruction::LibraryLoader> GPUReconstruction::sLibCPUDEVICE(new GPUReconstruction::LibraryLoader("lib" LIBRARY_PREFIX "GPUTrackingCPUDevice" LIBRARY_EXTENSION, "GPUReconstruction_Create_CPUDEVICE"));
134139

135140
GPUReconstruction::LibraryLoader::LibraryLoader(const char* lib, const char* func) : mLibName(lib), mFuncName(func), mGPULib(nullptr), mGPUEntry(nullptr) {}
136141

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Copyright 2019-2026 CERN and copyright holders of ALICE O2.
2+
# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
# All rights not expressly granted are reserved.
4+
#
5+
# This software is distributed under the terms of the GNU General Public
6+
# License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
#
8+
# In applying this license CERN does not waive the privileges and immunities
9+
# granted to it by virtue of its status as an Intergovernmental Organization
10+
# or submit itself to any jurisdiction.
11+
12+
set(MODULE GPUTrackingCPUDevice)
13+
14+
set(SRCS GPUReconstructionCPUDevice.cxx GPUReconstructionCPUDeviceGenRTC.cxx GPUReconstructionCPUDeviceRTCCalls.cxx)
15+
set(HDRS GPUReconstructionCPUDevice.h GPUReconstructionCPUDeviceInternals.h)
16+
17+
# -------------------------------- RTC: compile the host kernels with clang at runtime (Linux only) -------------------------------------------------------
18+
if(NOT LLVM_CLANG) # Normally detected in FindO2GPU.cmake for OpenCL, repeat the detection if OpenCL is disabled
19+
find_package(LLVM QUIET)
20+
if(LLVM_FOUND)
21+
find_package(Clang QUIET)
22+
endif()
23+
if(Clang_FOUND)
24+
find_program(LLVM_CLANG clang HINTS "${Clang_DIR}/../../../bin-safe")
25+
endif()
26+
endif()
27+
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND LLVM_CLANG)
28+
set(GPUCA_CPUDEVICE_RTC ON)
29+
message(STATUS "Building GPUTracking with CPUDevice support (RTC with ${LLVM_CLANG})")
30+
else()
31+
set(GPUCA_CPUDEVICE_RTC OFF)
32+
message(STATUS "Building GPUTracking with CPUDevice support (no RTC, requires Linux and clang)")
33+
endif()
34+
35+
if(ALIGPU_BUILD_TYPE STREQUAL "O2")
36+
set(defineIncludeSrc "O2::${MODULE}")
37+
else()
38+
set(defineIncludeSrc "${MODULE}")
39+
endif()
40+
41+
if(GPUCA_CPUDEVICE_RTC)
42+
enable_language(ASM)
43+
if(ALIGPU_BUILD_TYPE STREQUAL "Standalone")
44+
get_filename_component(GPUDIR ${CMAKE_SOURCE_DIR}/../ ABSOLUTE)
45+
else()
46+
set(GPUDIR ${CMAKE_SOURCE_DIR}/GPU/GPUTracking)
47+
endif()
48+
49+
# Use the same C++ standard library as the host compiler, since the RTC code is loaded into the same process
50+
set(GPU_RTC_GCC_TOOLCHAIN "")
51+
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
52+
get_filename_component(TMP_GCC_BIN_DIR "${CMAKE_CXX_COMPILER}" DIRECTORY)
53+
get_filename_component(TMP_GCC_ROOT "${TMP_GCC_BIN_DIR}" DIRECTORY)
54+
set(GPU_RTC_GCC_TOOLCHAIN "--gcc-toolchain=${TMP_GCC_ROOT}")
55+
endif()
56+
string(TOUPPER "${CMAKE_BUILD_TYPE}" TMP_BUILD_TYPE_UPPER)
57+
if(DEFINED CMAKE_CXX_STANDARD)
58+
set(GPU_RTC_CXX_STANDARD ${CMAKE_CXX_STANDARD})
59+
else()
60+
set(GPU_RTC_CXX_STANDARD 20)
61+
endif()
62+
63+
set(GPU_RTC_DEFINES "-D$<JOIN:$<TARGET_PROPERTY:${defineIncludeSrc},COMPILE_DEFINITIONS>,$<SEMICOLON>-D>")
64+
set(GPU_RTC_INCLUDES "-I$<JOIN:$<FILTER:$<TARGET_PROPERTY:${defineIncludeSrc},INCLUDE_DIRECTORIES>,EXCLUDE,^/usr/include/?>,$<SEMICOLON>-I>"
65+
-I${CMAKE_SOURCE_DIR}/Detectors/Base/src
66+
-I${CMAKE_SOURCE_DIR}/Detectors/TRD/base/src
67+
)
68+
set(GPU_RTC_FLAGS "${GPU_RTC_GCC_TOOLCHAIN} -std=c++${GPU_RTC_CXX_STANDARD} ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${TMP_BUILD_TYPE_UPPER}} -w")
69+
separate_arguments(GPU_RTC_FLAGS_SEPARATED NATIVE_COMMAND "${GPU_RTC_FLAGS}")
70+
# Self-contained shared library: static C++ runtime, all symbols hidden and bound locally, only the kernels are exported (via version script at runtime)
71+
set(GPU_RTC_LINK_FLAGS -fPIC -shared -fvisibility=hidden -fvisibility-inlines-hidden -static-libstdc++ -static-libgcc -Wl,--exclude-libs,ALL -Wl,-Bsymbolic)
72+
73+
set(GPU_RTC_SRC ${GPUDIR}/Base/cpudevice/GPUReconstructionCPUDevicertc.cxx)
74+
set(GPU_RTC_BIN ${CMAKE_CURRENT_BINARY_DIR}/GPUReconstructionCPUDevicertc)
75+
76+
# Preprocess the RTC source with the flags used for the RTC compilation, since they affect system headers
77+
add_custom_command(
78+
OUTPUT ${GPU_RTC_BIN}.src
79+
COMMAND ${LLVM_CLANG} --driver-mode=g++ ${GPU_RTC_DEFINES} ${GPU_RTC_INCLUDES} ${GPU_RTC_FLAGS_SEPARATED} -x c++ -E -MD -MT ${GPU_RTC_BIN}.src -MF ${GPU_RTC_BIN}.src.d ${GPU_RTC_SRC} -o ${GPU_RTC_BIN}.src
80+
DEPENDS ${GPU_RTC_SRC}
81+
DEPFILE ${GPU_RTC_BIN}.src.d
82+
COMMAND_EXPAND_LISTS
83+
COMMENT "Preparing CPUDevice RTC source file ${GPU_RTC_BIN}.src"
84+
)
85+
create_binary_resource(${GPU_RTC_BIN}.src ${GPU_RTC_BIN}.src.o)
86+
87+
add_custom_command(
88+
OUTPUT ${GPU_RTC_BIN}.command
89+
COMMAND echo -n "${LLVM_CLANG} --driver-mode=g++ ${GPU_RTC_FLAGS_SEPARATED} ${GPU_RTC_LINK_FLAGS}" > ${GPU_RTC_BIN}.command
90+
COMMAND_EXPAND_LISTS VERBATIM
91+
COMMENT "Preparing CPUDevice RTC command file ${GPU_RTC_BIN}.command"
92+
)
93+
create_binary_resource(${GPU_RTC_BIN}.command ${GPU_RTC_BIN}.command.o)
94+
95+
add_custom_command(
96+
OUTPUT ${GPU_RTC_BIN}.command.no_fast_math
97+
COMMAND echo -n "${GPUCA_CXX_NO_FAST_MATH_FLAGS}" > ${GPU_RTC_BIN}.command.no_fast_math
98+
COMMAND_EXPAND_LISTS VERBATIM
99+
COMMENT "Preparing CPUDevice RTC NO_FAST_MATH command file ${GPU_RTC_BIN}.command.no_fast_math"
100+
)
101+
create_binary_resource(${GPU_RTC_BIN}.command.no_fast_math ${GPU_RTC_BIN}.command.no_fast_math.o)
102+
103+
set(SRCS ${SRCS} ${GPU_RTC_BIN}.src.o ${GPU_RTC_BIN}.command.o ${GPU_RTC_BIN}.command.no_fast_math.o)
104+
endif()
105+
106+
if(ALIGPU_BUILD_TYPE STREQUAL "O2")
107+
o2_add_library(
108+
${MODULE}
109+
SOURCES ${SRCS}
110+
PUBLIC_LINK_LIBRARIES O2::GPUTracking
111+
PRIVATE_INCLUDE_DIRECTORIES
112+
${CMAKE_SOURCE_DIR}/Detectors/Base/src
113+
${CMAKE_SOURCE_DIR}/Detectors/TRD/base/src
114+
${CMAKE_SOURCE_DIR}/DataFormats/Reconstruction/src
115+
${CMAKE_CURRENT_SOURCE_DIR}
116+
TARGETVARNAME targetName)
117+
endif()
118+
119+
if(ALIGPU_BUILD_TYPE STREQUAL "Standalone")
120+
set(targetName "${MODULE}")
121+
add_library(${MODULE} SHARED ${SRCS})
122+
add_library(O2::${MODULE} ALIAS ${MODULE})
123+
target_link_libraries(${MODULE} PUBLIC O2::GPUTracking)
124+
install(TARGETS ${MODULE})
125+
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
126+
endif()
127+
128+
install(FILES ${HDRS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/GPU)
129+
130+
target_compile_definitions(${targetName} PRIVATE $<TARGET_PROPERTY:O2::GPUTracking,COMPILE_DEFINITIONS>)
131+
target_link_libraries(${targetName} PRIVATE TBB::tbb)
132+
if(GPUCA_CPUDEVICE_RTC)
133+
target_compile_definitions(${targetName} PRIVATE GPUCA_CPUDEVICE_RTC)
134+
target_link_libraries(${targetName} PRIVATE ${CMAKE_DL_LIBS})
135+
endif()

0 commit comments

Comments
 (0)