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