18#include "GPUReconstructionKernelIncludes.h"
21#include "GPUDefParametersRuntime.h"
63 GPUError(
"CPUDevice Error: %ld (%s:%d)", (int64_t)retval, file, line);
83 GPUInfo(
"Disabling device timers for CPUDevice");
121 GPUInfo(
"CPUDevice Initialisation successfull (from master)");
124 mEventStorage.reserve(
mEvents.size());
125 for (uint32_t
i = 0;
i <
mEvents.size();
i++) {
138 mEventStorage.clear();
153 GPUInfo(
"CPUDevice Uninitialized");
172 std::lock_guard lock(q.mutex);
173 q.tasks.emplace_back(std::move(task));
175 q.active =
start =
true;
194 std::lock_guard lock(q.mutex);
195 if (q.tasks.empty()) {
200 task = &q.tasks.front();
204 std::lock_guard lock(e->mutex);
205 if (e->nCompleted <
value) {
214 }
catch (
const std::exception& ex) {
215 GPUError(
"CPUDevice: Error in command queue %d: %s",
stream, ex.what());
222 std::lock_guard lock(q.mutex);
229 std::vector<GPUReconstructionCPUDeviceEvent::waitingQueue> resume;
231 std::lock_guard lock(e->
mutex);
235 resume.emplace_back(*it);
243 for (
auto&
w : resume) {
244 w.internals->startQueue(
w.stream);
248void GPUReconstructionCPUDevice::EnqueueTask(int32_t
stream, deviceEvent* evList, int32_t
nEvents, deviceEvent* ev, std::function<
void()>&& work)
255 for (int32_t k = 0; k <
nEvents; k++) {
256 auto* e = getEvent(evList[k]);
257 std::lock_guard lock(e->mutex);
258 task.
waits.emplace_back(e, e->nRecorded);
262 task.
record = getEvent(*ev);
266 task.
work = std::move(work);
273 std::unique_lock lock(q.mutex);
274 q.cv.wait(lock, [&q]() {
return !q.active; });
287 auto* e = getEvent(evList[
i]);
288 std::unique_lock lock(e->mutex);
289 const uint64_t
value = e->nRecorded;
290 e->cv.wait(lock, [e,
value]() {
return e->nCompleted >=
value; });
304 auto* e = getEvent(evList[
i]);
305 std::lock_guard lock(e->mutex);
306 if (e->nCompleted < e->nRecorded) {
315 EnqueueTask(
stream,
nullptr, 0, ev, []() {});
321 GPUError(
"CPUDevice Error while running (%s) (Stream %d)",
state,
stream);
333 GPUError(
"CPUDevice Error while synchronizing (%s) (Stream %d)",
state,
stream);
337 GPUInfo(
"GPU Sync Done");
353 auto* e = getEvent(*ev);
356 std::lock_guard lock(e->mutex);
357 value = ++e->nRecorded;
382 auto buffer = std::make_shared<std::vector<char>>((
const char*)
src, (
const char*)
src +
size);
391template <
class T, int32_t I,
typename... Args>
397 if (
x.nThreads != 1) {
398 throw std::runtime_error(
"CPUDevice backend supports only kernels with nThreads = 1");
400 const uint32_t nBlocks =
x.nBlocks;
403 using rtcKernel =
void (*)(
GPUConstantMem*, int32_t, uint32_t, uint32_t, uint32_t, Args...);
407 EnqueueTask(
x.stream,
z.evList,
z.evList ?
z.nEvents : 0,
z.ev, [nBlocks,
iSector, constantMem, rtc, ... args = args]() {
408 tbb::this_task_arena::isolate([&] {
409 tbb::parallel_for(tbb::blocked_range<uint32_t>(0, nBlocks, 1), [&](
const tbb::blocked_range<uint32_t>&
r) {
411 rtc(constantMem,
iSector, nBlocks,
r.begin(),
r.end(), args...);
413 for (uint32_t iBlock =
r.begin(); iBlock <
r.end(); iBlock++) {
414 typename T::GPUSharedMemory smem;
415 T::template Thread<I>(nBlocks, 1, iBlock, 0, smem, T::Processor(*constantMem)[
iSector], args...);
424inline void GPUReconstructionCPUDevice::runKernelBackend<GPUMemClean16, 0>(
const krnlSetupTime& _xyz,
void*
const&
ptr, uint64_t
const&
size)
429#include "GPUReconstructionProcessingKernels.inc"
433#define GPUCA_CPUDEVICE_KRNL_RTC(x_class, x_attributes, x_arguments, x_forward, x_types, ...) \
434 extern "C" __attribute__((visibility("default"))) void GPUCA_M_CAT(krnl_, GPUCA_M_KRNL_NAME(x_class))(GPUConstantMem * pConstant, int32_t _iSector_internal, uint32_t nBlocks, uint32_t iBlockStart, uint32_t iBlockEnd GPUCA_M_STRIP(x_arguments)) \
436 for (uint32_t iBlock = iBlockStart; iBlock < iBlockEnd; iBlock++) { \
437 typename GPUCA_M_STRIP_FIRST(x_class)::GPUSharedMemory smem; \
438 GPUCA_M_STRIP_FIRST(x_class)::template Thread<GPUCA_M_KRNL_NUM(x_class)>(nBlocks, 1, iBlock, 0, smem, GPUCA_M_STRIP_FIRST(x_class)::Processor(*pConstant)[_iSector_internal] GPUCA_M_STRIP(x_forward)); \
442void GPUReconstructionCPUDevice::getRTCKernelCalls(std::vector<std::string>& kernels)
444#define GPUCA_KRNL(...) kernels.emplace_back(GPUCA_M_STR(GPUCA_CPUDEVICE_KRNL_RTC(__VA_ARGS__)));
445#include "GPUReconstructionKernelList.h"
GPUReconstruction * GPUReconstruction_Create_CPUDEVICE(const GPUSettingsDeviceBackend &cfg)
GPUReconstructionCPUDevice(const GPUSettingsDeviceBackend &cfg)
int32_t GPUChkErrInternal(const int64_t retval, const char *file, int32_t line) const override
void StreamWaitForEvents(int32_t stream, deviceEvent *evList, int32_t nEvents=1) override
int32_t GPUDebug(const char *state="UNKNOWN", int32_t stream=-1, bool force=false) override
int32_t InitDevice_Runtime() override
void SynchronizeStream(int32_t stream) override
size_t WriteToConstantMemory(size_t offset, const void *src, size_t size, int32_t stream=-1, deviceEvent *ev=nullptr) override
void runKernelBackend(const krnlSetupTime &_xyz, const Args &... args)
void RecordMarker(deviceEvent *ev, int32_t stream) override
size_t GPUMemCpy(void *dst, const void *src, size_t size, int32_t stream, int32_t toGPU, deviceEvent *ev=nullptr, deviceEvent *evList=nullptr, int32_t nEvents=1) override
GPUReconstructionCPUDeviceInternals * mInternals
~GPUReconstructionCPUDevice() override
void SynchronizeGPU() override
void SynchronizeEvents(deviceEvent *evList, int32_t nEvents=1) override
int32_t ExitDevice_Runtime() override
bool IsEventDone(deviceEvent *evList, int32_t nEvents=1) override
uint32_t mMultiprocessorCount
virtual void runKernelVirtual(const int num, const void *args)
std::vector< std::vector< deviceEvent > > mEvents
GPUDefParameters * mParCPU
GPUDefParameters * mParDevice
GPUReconstruction * mMaster
GPUConstantMem * mDeviceConstantMem
alignedDeleter< char, constants::GPU_BUFFER_ALIGNMENT > alignedDefaultBufferDeleter
std::unique_ptr< GPUSettingsDeviceBackend > mDeviceBackendSettings
int32_t mMaxBackendThreads
std::unique_ptr< GPUSettingsProcessing > mProcessingSettings
const GPUSettingsProcessing & GetProcessingSettings() const
GLsizei const GLfloat * value
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLubyte GLubyte GLubyte GLubyte w
GLdouble GLdouble GLdouble z
std::string to_string(gsl::span< T, Size > span)
int32_t par_LB_maxThreads[$< LIST:LENGTH, $< TARGET_PROPERTY:O2_GPU_KERNELS, O2_GPU_KERNEL_NAMES > >]
std::vector< waitingQueue > waiting
std::condition_variable cv
void enqueue(int32_t stream, GPUReconstructionCPUDeviceTask &&task)
void processQueue(int32_t stream)
std::atomic< int32_t > error
std::unique_ptr< tbb::task_arena > arena
std::vector< void * > rtcLibraries
void completeEvent(GPUReconstructionCPUDeviceEvent *e, uint64_t value)
std::vector< void * > rtcKernels
std::array< GPUReconstructionCPUDeviceQueue, constants::GPU_MAX_STREAMS > queues
void startQueue(int32_t stream)
std::function< void()> work
GPUReconstructionCPUDeviceEvent * record
std::vector< std::pair< GPUReconstructionCPUDeviceEvent *, uint64_t > > waits