Files
supercomputers/src/gpu_loader.cpp
2025-12-16 15:19:50 +00:00

134 lines
3.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "gpu_loader.hpp"
#include <dlfcn.h>
#include <iostream>
#include <cstdint>
// Структура результата GPU (должна совпадать с gpu_plugin.cu)
struct GpuPeriodStats {
int64_t period;
double avg;
double open_min;
double open_max;
double close_min;
double close_max;
int64_t count;
};
// Типы функций из GPU плагина
using gpu_is_available_fn = int (*)();
using gpu_aggregate_periods_fn = int (*)(
const double* h_timestamps,
const double* h_open,
const double* h_high,
const double* h_low,
const double* h_close,
int num_ticks,
int64_t interval,
GpuPeriodStats** h_out_stats,
int* out_num_periods
);
using gpu_free_results_fn = void (*)(GpuPeriodStats*);
static void* get_gpu_lib_handle() {
static void* h = dlopen("./libgpu_compute.so", RTLD_NOW | RTLD_LOCAL);
return h;
}
bool gpu_is_available() {
void* h = get_gpu_lib_handle();
if (!h) return false;
auto fn = reinterpret_cast<gpu_is_available_fn>(dlsym(h, "gpu_is_available"));
if (!fn) return false;
return fn() != 0;
}
bool aggregate_periods_gpu(
const std::vector<Record>& records,
int64_t aggregation_interval,
std::vector<PeriodStats>& out_stats)
{
if (records.empty()) {
out_stats.clear();
return true;
}
void* h = get_gpu_lib_handle();
if (!h) {
std::cerr << "GPU: Failed to load libgpu_compute.so" << std::endl;
return false;
}
auto aggregate_fn = reinterpret_cast<gpu_aggregate_periods_fn>(
dlsym(h, "gpu_aggregate_periods"));
auto free_fn = reinterpret_cast<gpu_free_results_fn>(
dlsym(h, "gpu_free_results"));
if (!aggregate_fn || !free_fn) {
std::cerr << "GPU: Failed to load functions from plugin" << std::endl;
return false;
}
int num_ticks = static_cast<int>(records.size());
// Конвертируем AoS в SoA
std::vector<double> timestamps(num_ticks);
std::vector<double> open(num_ticks);
std::vector<double> high(num_ticks);
std::vector<double> low(num_ticks);
std::vector<double> close(num_ticks);
for (int i = 0; i < num_ticks; i++) {
timestamps[i] = records[i].timestamp;
open[i] = records[i].open;
high[i] = records[i].high;
low[i] = records[i].low;
close[i] = records[i].close;
}
// Вызываем GPU функцию
GpuPeriodStats* gpu_stats = nullptr;
int num_periods = 0;
int result = aggregate_fn(
timestamps.data(),
open.data(),
high.data(),
low.data(),
close.data(),
num_ticks,
aggregation_interval,
&gpu_stats,
&num_periods
);
if (result != 0) {
std::cerr << "GPU: Aggregation failed with code " << result << std::endl;
return false;
}
// Конвертируем результат в PeriodStats
out_stats.clear();
out_stats.reserve(num_periods);
for (int i = 0; i < num_periods; i++) {
PeriodStats ps;
ps.period = gpu_stats[i].period;
ps.avg = gpu_stats[i].avg;
ps.open_min = gpu_stats[i].open_min;
ps.open_max = gpu_stats[i].open_max;
ps.close_min = gpu_stats[i].close_min;
ps.close_max = gpu_stats[i].close_max;
ps.count = gpu_stats[i].count;
out_stats.push_back(ps);
}
// Освобождаем память
free_fn(gpu_stats);
return true;
}