Files
Jungfraujoch/common/CUDAWrapper.cpp
T

116 lines
2.6 KiB
C++

// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#include "CUDAWrapper.h"
#include <condition_variable>
#include <mutex>
// Build-independent: the CUDA build gets get_gpu_names() from CUDAWrapper.cu, the CPU-only build from
// the stub below, and this collapses whichever list came back. Four identical cards read better as
// "4x <name>" than as the same name four times, and a mixed machine keeps one group per model.
std::string get_gpu_description() {
const auto names = get_gpu_names();
std::string out;
for (size_t i = 0; i < names.size();) {
size_t n = 1;
while (i + n < names.size() && names[i + n] == names[i])
n++;
if (!out.empty())
out += ", ";
if (n > 1)
out += std::to_string(n) + "x ";
out += names[i];
i += n;
}
return out;
}
namespace {
// How many of one kind of GPU work are running, for a thread to wait until none is.
struct GPUWorkCount {
std::mutex m;
std::condition_variable none;
int n = 0;
void Add() {
std::lock_guard lock(m);
++n;
}
void Remove() {
{
std::lock_guard lock(m);
--n;
}
none.notify_all();
}
};
GPUWorkCount gpu_work_beside, gpu_image_passes;
}
GPUWorkBeside::GPUWorkBeside() {
gpu_work_beside.Add();
}
GPUWorkBeside::~GPUWorkBeside() {
gpu_work_beside.Remove();
}
bool wait_for_gpu_work_beside(std::chrono::seconds timeout) {
std::unique_lock lock(gpu_work_beside.m);
return gpu_work_beside.none.wait_for(lock, timeout, [] { return gpu_work_beside.n == 0; });
}
GPUImagePass::GPUImagePass() {
gpu_image_passes.Add();
}
GPUImagePass::~GPUImagePass() {
gpu_image_passes.Remove();
}
void wait_for_gpu_image_passes() {
std::unique_lock lock(gpu_image_passes.m);
gpu_image_passes.none.wait(lock, [] { return gpu_image_passes.n == 0; });
}
#ifndef JFJOCH_USE_CUDA
int32_t get_gpu_count() {
return 0;
}
std::vector<std::string> get_gpu_names() {
return {};
}
size_t get_gpu_total_memory(int32_t) {
return 0;
}
void set_gpu(int32_t dev_id) {}
void pin_gpu() {}
void pin_gpu(int32_t dev_id) {}
ScopedGpuPin::ScopedGpuPin(int32_t) {}
ScopedGpuPin::~ScopedGpuPin() {}
void enable_gpu_numa_binding() {}
std::vector<int> get_gpu_numa_nodes() { return {}; }
void set_gpu_blocking_sync() {}
void create_gpu_contexts(int32_t) {}
void release_gpu_contexts() {}
void cuda_clear_error() {}
void cuda_throw_if_context_lost() {}
#endif