21#ifdef GPUCA_CPUDEVICE_RTC
24#include "GPUReconstructionKernelIncludes.h"
26#include "GPUReconstructionRTCHelpers.inc"
36namespace rtc = o2::gpu::internal::rtc;
38static constexpr const char* RTC_SRC_EXTENSION =
".cxx";
39static constexpr const char* RTC_BIN_EXTENSION =
".so";
40static constexpr const char* RTC_MAP_EXTENSION =
".map";
42static bool kernelWithoutRTC(
const std::string&
name) {
return name ==
"GPUTPCCFCheckPadBaseline"; }
44int32_t GPUReconstructionCPUDevice::genRTC(std::string&
filename, uint32_t& nCompile)
47 const std::string_view rtcSource(_binary_GPUReconstructionCPUDevicertc_src_start, _binary_GPUReconstructionCPUDevicertc_src_len);
48 const std::string rtcparam = rtc::paramCode(proc,
param());
49 rtc::tmpFilename(
filename,
"/tmp/o2cagpu_rtc_cpudevice_");
51 std::vector<std::string> kernels;
52 getRTCKernelCalls(kernels);
53 for (uint32_t
i = 0;
i < kernels.size();
i++) {
58 const std::string kernelsall = rtc::joinKernels(kernels);
60 const std::string baseCommand = rtc::baseCommand(proc, std::string_view(_binary_GPUReconstructionCPUDevicertc_command_start, _binary_GPUReconstructionCPUDevicertc_command_len)) +
" " + proc.rtctech.overrideArchitecture;
61 const std::string noFastMath(_binary_GPUReconstructionCPUDevicertc_command_no_fast_math_start, _binary_GPUReconstructionCPUDevicertc_command_no_fast_math_len);
65 if (proc.rtctech.printLaunchBounds >= 2) {
69 nCompile = proc.rtc.compilePerKernel ? kernels.size() : 1;
71 rtc::Cache cache(proc,
"cpudevice", {rtcSource, rtcparam, baseCommand, kernelsall, launchBounds, compilerVersions});
72 if (!cache.load(
filename, RTC_BIN_EXTENSION, nCompile)) {
73 rtc::compile(proc, nCompile,
"CPUDevice", [&](uint32_t
i) {
75 if (proc.debugLevel >= 3) {
76 printf(
"Compiling %s\n", (fileBase + RTC_SRC_EXTENSION).c_str());
78 const bool deterministic = rtc::deterministic(proc,
GetKernelName(
i));
79 rtc::writeSource(fileBase + RTC_SRC_EXTENSION, deterministic, rtcparam, launchBounds, rtcSource, proc.rtc.compilePerKernel ? kernels[
i] : kernelsall);
82 FILE* fp = fopen((fileBase + RTC_MAP_EXTENSION).c_str(),
"w+b");
83 if (fp ==
nullptr || fprintf(fp,
"{ global: krnl_*; local: *; };\n") < 0) {
84 throw std::runtime_error(
"Error writing version script");
88 const std::string command = baseCommand + (deterministic ?
" " + noFastMath :
"") +
" -Wl,--version-script=" + fileBase + RTC_MAP_EXTENSION +
" -x c++ " + fileBase + RTC_SRC_EXTENSION +
" -o " + fileBase + RTC_BIN_EXTENSION;
89 rtc::runCommand(proc, command, fileBase + RTC_SRC_EXTENSION,
"Error during CPUDevice RTC compilation");
91 cache.store(
filename, RTC_BIN_EXTENSION, nCompile);
96void GPUReconstructionCPUDevice::genAndLoadRTC()
99 uint32_t nCompile = 0;
101 throw std::runtime_error(
"Runtime compilation failed");
103 for (uint32_t
i = 0;
i < nCompile;
i++) {
106 void* lib = dlopen((fileBase + RTC_BIN_EXTENSION).c_str(), RTLD_NOW | RTLD_LOCAL);
107 if (lib ==
nullptr) {
108 throw std::runtime_error(std::string(
"Error loading CPUDevice RTC library: ") + dlerror());
113 remove((fileBase + RTC_SRC_EXTENSION).c_str());
114 remove((fileBase + RTC_BIN_EXTENSION).c_str());
115 remove((fileBase + RTC_MAP_EXTENSION).c_str());
125#define GPUCA_KRNL(x_class, ...) \
126 if (GetKernelNum<GPUCA_M_KRNL_TEMPLATE(x_class)>() != j) { \
127 GPUFatal("kernel numbers out of sync"); \
129 mInternals->rtcKernels[j] = dlsym(mInternals->rtcLibraries[perKernel ? j : 0], GPUCA_M_STR(GPUCA_M_CAT(krnl_, GPUCA_M_KRNL_NAME(x_class)))); \
130 if (mInternals->rtcKernels[j] == nullptr && !kernelWithoutRTC(GetKernelName(j))) { \
131 GPUFatal("Error loading RTC kernel %s", GPUCA_M_STR(GPUCA_M_CAT(krnl_, GPUCA_M_KRNL_NAME(x_class)))); \
134#include "GPUReconstructionKernelList.h"
145int32_t GPUReconstructionCPUDevice::genRTC(std::string&
filename, uint32_t& nCompile)
147 throw std::runtime_error(
"CPUDevice backend compiled without RTC support (requires Linux)");
150void GPUReconstructionCPUDevice::genAndLoadRTC()
152 throw std::runtime_error(
"CPUDevice backend compiled without RTC support (requires Linux)");
GPUReconstructionCPUDeviceInternals * mInternals
static const char * GetKernelName()
static uint32_t GetNKernels()
GPUDefParameters * mParDevice
static std::string getBackendVersions()
const GPUSettingsProcessing & GetProcessingSettings() const
GLuint const GLchar * name
std::string to_string(gsl::span< T, Size > span)
#define QGET_LD_BINARY_SYMBOLS(filename)
std::vector< void * > rtcLibraries
std::vector< void * > rtcKernels