Project
Loading...
Searching...
No Matches
GPUReconstructionLibrary.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 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
14
15#ifdef _WIN32
16#include <windows.h>
17#include <winbase.h>
18#include <conio.h>
19#else
20#include <dlfcn.h>
21#include <pthread.h>
22#include <unistd.h>
23#endif
24#include <mutex>
25
26#include "GPUReconstruction.h"
27#include "GPUReconstructionAvailableBackends.h"
28#include "GPUSettings.h"
29
30#include "utils/qlibload.h"
31
32#include "GPULogging.h"
33
34using namespace o2::gpu;
35
37{
39 cfg.deviceType = type;
40 cfg.forceDeviceType = forceType;
41 cfg.master = master;
42 return CreateInstance(cfg);
43}
44
46{
47 GPUReconstruction* retVal = nullptr;
49#ifdef DEBUG_STREAMER
50 if (type != DeviceType::CPU) {
51 GPUError("Cannot create GPUReconstruction for a non-CPU device if DEBUG_STREAMER are enabled");
52 return nullptr;
53 }
54#endif
55 if (type == DeviceType::CPU) {
57 } else {
58 auto* loader = GetLibraryInstance(type, true);
59 if (loader && (retVal = (*loader)->GetPtr(cfg))) {
60 retVal->mMyLib = *loader;
61 }
62 }
63
64 if (retVal == nullptr) {
65 if (cfg.forceDeviceType) {
66 GPUError("Error: Could not load GPUReconstruction for specified device: %s (%u)", gpudatatypes::DEVICE_TYPE_NAMES[type], cfg.deviceType);
67 } else if (type != DeviceType::CPU) {
68 GPUError("Could not load GPUReconstruction for device type %s (%u), falling back to CPU version", gpudatatypes::DEVICE_TYPE_NAMES[type], cfg.deviceType);
69 GPUSettingsDeviceBackend cfg2 = cfg;
70 cfg2.deviceType = DeviceType::CPU;
71 retVal = CreateInstance(cfg2);
72 }
73 } else {
74 GPUInfo("Created GPUReconstruction instance for device type %s (%u)%s", gpudatatypes::DEVICE_TYPE_NAMES[type], cfg.deviceType, cfg.master ? " (slave)" : "");
75 }
76
77 return retVal;
78}
79
81{
82 if (type == DeviceType::CPU) {
83 return true;
84 } else {
85 auto* loader = GetLibraryInstance(type, verbose);
86 return loader != nullptr && (*loader)->LoadLibrary() == 0;
87 }
88}
89
90std::shared_ptr<GPUReconstruction::LibraryLoader>* GPUReconstruction::GetLibraryInstance(DeviceType type, bool verbose)
91{
92 if (type == DeviceType::CPU) {
93 return nullptr;
94 } else if (type == DeviceType::CUDA) {
95#ifdef CUDA_ENABLED
96 return &sLibCUDA;
97#endif
98 } else if (type == DeviceType::HIP) {
99#ifdef HIP_ENABLED
100 return &sLibHIP;
101#endif
102 } else if (type == DeviceType::OCL) {
103#ifdef OPENCL_ENABLED
104 return &sLibOCL;
105#endif
106 } else if (type == DeviceType::METAL) {
107#ifdef METAL_ENABLED
108 return &sLibMETAL;
109#endif
110 } else {
111 GPUError("Error: Invalid device type %u", (uint32_t)type);
112 return nullptr;
113 }
114 if (verbose) {
115 GPUInfo("%s Support not compiled in for device type %u (%s)", gpudatatypes::DEVICE_TYPE_NAMES[type], (uint32_t)type, gpudatatypes::DEVICE_TYPE_NAMES[type]);
116 }
117 return nullptr;
118}
119
121{
123 if (t == DeviceType::INVALID_DEVICE) {
124 GPUError("Invalid device type: %s", type);
125 return nullptr;
126 }
127 return CreateInstance(t, forceType, master);
128}
129
130std::shared_ptr<GPUReconstruction::LibraryLoader> GPUReconstruction::sLibCUDA(new GPUReconstruction::LibraryLoader("lib" LIBRARY_PREFIX "GPUTrackingCUDA" LIBRARY_EXTENSION, "GPUReconstruction_Create_CUDA"));
131std::shared_ptr<GPUReconstruction::LibraryLoader> GPUReconstruction::sLibHIP(new GPUReconstruction::LibraryLoader("lib" LIBRARY_PREFIX "GPUTrackingHIP" LIBRARY_EXTENSION, "GPUReconstruction_Create_HIP"));
132std::shared_ptr<GPUReconstruction::LibraryLoader> GPUReconstruction::sLibOCL(new GPUReconstruction::LibraryLoader("lib" LIBRARY_PREFIX "GPUTrackingOCL" LIBRARY_EXTENSION, "GPUReconstruction_Create_OCL"));
133std::shared_ptr<GPUReconstruction::LibraryLoader> GPUReconstruction::sLibMETAL(new GPUReconstruction::LibraryLoader("lib" LIBRARY_PREFIX "GPUTrackingMETAL" LIBRARY_EXTENSION, "GPUReconstruction_Create_METAL"));
134
135GPUReconstruction::LibraryLoader::LibraryLoader(const char* lib, const char* func) : mLibName(lib), mFuncName(func), mGPULib(nullptr), mGPUEntry(nullptr) {}
136
138
139int32_t GPUReconstruction::LibraryLoader::LoadLibrary()
140{
141 static std::mutex mut;
142 std::lock_guard<std::mutex> lock(mut);
143
144 if (mGPUEntry) {
145 return 0;
146 }
147
148 LIBRARY_TYPE hGPULib;
149 hGPULib = LIBRARY_LOAD(mLibName);
150 if (hGPULib == nullptr) {
151#ifndef _WIN32
152 GPUImportant("The following error occured during dlopen: %s", dlerror());
153#endif
154 GPUError("Error Opening cagpu library for GPU Tracker (%s)", mLibName);
155 return 1;
156 } else {
157 void* createFunc = LIBRARY_FUNCTION(hGPULib, mFuncName);
158 if (createFunc == nullptr) {
159 GPUError("Error fetching entry function in GPU library\n");
160 LIBRARY_CLOSE(hGPULib);
161 return 1;
162 } else {
163 mGPULib = (void*)(size_t)hGPULib;
164 mGPUEntry = createFunc;
165 GPUInfo("GPU Tracker library loaded and GPU tracker object created sucessfully");
166 }
167 }
168 return 0;
169}
170
171GPUReconstruction* GPUReconstruction::LibraryLoader::GetPtr(const GPUSettingsDeviceBackend& cfg)
172{
173 if (LoadLibrary()) {
174 return nullptr;
175 }
176 if (mGPUEntry == nullptr) {
177 return nullptr;
178 }
179 GPUReconstruction* (*tmp)(const GPUSettingsDeviceBackend& cfg) = (GPUReconstruction * (*)(const GPUSettingsDeviceBackend& cfg)) mGPUEntry;
180 return tmp(cfg);
181}
182
183int32_t GPUReconstruction::LibraryLoader::CloseLibrary()
184{
185 if (mGPUEntry == nullptr) {
186 return 1;
187 }
188 LIBRARY_CLOSE((LIBRARY_TYPE)(size_t)mGPULib);
189 mGPULib = nullptr;
190 mGPUEntry = nullptr;
191 return 0;
192}
193
#define GPUCA_M_STR(a)
int32_t retVal
LibraryLoader(const LibraryLoader &)=delete
static std::shared_ptr< LibraryLoader > sLibHIP
static std::shared_ptr< LibraryLoader > sLibMETAL
static std::shared_ptr< LibraryLoader > * GetLibraryInstance(DeviceType type, bool verbose)
static bool CheckInstanceAvailable(DeviceType type, bool verbose)
static std::shared_ptr< LibraryLoader > sLibOCL
static GPUReconstruction * CreateInstance(const GPUSettingsDeviceBackend &cfg)
static GPUReconstruction * GPUReconstruction_Create_CPU(const GPUSettingsDeviceBackend &cfg)
static std::shared_ptr< LibraryLoader > sLibCUDA
gpudatatypes::DeviceType DeviceType
GLenum func
Definition glcorearb.h:778
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
DeviceType GetDeviceType(const char *type)
#define LIBRARY_EXTENSION
Definition qlibload.h:31
#define LIBRARY_CLOSE
Definition qlibload.h:34
#define LIBRARY_TYPE
Definition qlibload.h:32
#define LIBRARY_PREFIX
Definition qlibload.h:39
#define LIBRARY_LOAD(name)
Definition qlibload.h:33
#define LIBRARY_FUNCTION
Definition qlibload.h:35