载入中...
搜索中...
未找到
GpuBackend.cpp
浏览该文件的文档.
1#include "tensor/GpuBackend.h"
2#include "agent/Agent.h"
5#include "gpgpu/Gpgpu.h"
6#include "tensor/Optimizer.h"
7
8#include <cmath>
9#include <exception>
10#include <limits>
11
12namespace eve::agent {
13namespace {
14class GpuBackend final : public IGpuPolicyBackend {
15public:
16 std::string name() const override { return "tensor-gpu"; }
17 Result<void> available() const override {
18 try {
19 auto* device = gpgpu::Gpgpu::create();
20 if (device && device->isAvailable()) return Result<void>::success();
23 "GPU requires an initialized compute-capable Graphics device", {}, {}, "agent.gpu"));
24 } catch (const std::exception& e) {
25 return Result<void>::failure(Diagnostic::error(DiagnosticCode::Unsupported, e.what(), {}, {}, "agent.gpu"));
26 }
27 }
28 Result<std::vector<double>> evaluate(const Policy& p, const Observation& o) override {
29 return execute(p, o, 0, 0, false);
30 }
31 Result<Policy> train(const Policy& p, const Observation& o, std::uint32_t action, double rate) override {
32 auto result = execute(p, o, action, rate, true);
33 if (!result) return Result<Policy>::failure(result.status());
34 Policy next = p;
35 next.weights = std::move(result).takeValue();
36 auto validated = validatePolicy(next);
37 if (!validated) return Result<Policy>::failure(validated.status());
38 return Result<Policy>::success(std::move(next));
39 }
40
41private:
42 Result<std::vector<double>> execute(const Policy& p, const Observation& o, std::uint32_t action, double rate,
43 bool training) {
44 auto ready = available();
45 if (!ready) return Result<std::vector<double>>::failure(ready.status());
46 try {
47 // Cache only the two shapes, never caller-owned weights or observation pointers.
48 if (f_ != p.featureCount || h_ != p.hiddenWidth || a_ != p.actionCount) {
49 inference_.reset();
50 training_.reset();
51 f_ = p.featureCount;
52 h_ = p.hiddenWidth;
53 a_ = p.actionCount;
54 }
55 auto& program = training ? training_ : inference_;
56 if (!program) {
57 auto recipe = detail::makePolicyGraph(int(f_), int(h_), int(a_), training);
58 auto optimized = tensor::optimizeGraph(recipe.graph, recipe.output);
59 program.reset(tensor::GpuProgram::tryBuild(recipe.graph, optimized, recipe.output));
60 if (!program)
61 return Result<std::vector<double>>::failure(Diagnostic::error(
62 DiagnosticCode::Unsupported, "Policy graph cannot execute on this GPU; no CPU fallback", {}, {},
63 "agent.gpu"));
64 }
65 std::vector<float> weights;
66 weights.reserve(p.weights.size());
67 for (double weight : p.weights) weights.push_back(static_cast<float>(weight));
68 std::vector<float> mask(a_, -std::numeric_limits<float>::infinity()), target(a_, 0);
69 for (auto legal : o.legalActions) mask[legal] = 0;
70 std::vector<const float*> feeds{weights.data(), o.features.data(), mask.data()};
71 float learningRate = float(rate);
72 if (training) {
73 target[action] = 1;
74 feeds.push_back(target.data());
75 feeds.push_back(&learningRate);
76 }
77 auto output = program->run(feeds);
78 if (output.size() != (training ? p.weights.size() : p.actionCount))
79 return Result<std::vector<double>>::failure(Diagnostic::error(
80 DiagnosticCode::Unsupported, "GPU returned an invalid output shape", {}, {}, "agent.gpu"));
81 for (auto value : output)
82 if (!std::isfinite(value))
83 return Result<std::vector<double>>::failure(Diagnostic::error(
84 DiagnosticCode::Unsupported, "GPU returned non-finite values", {}, {}, "agent.gpu"));
85 return Result<std::vector<double>>::success({output.begin(), output.end()});
86 } catch (const std::exception& e) {
87 inference_.reset();
88 training_.reset();
89 return Result<std::vector<double>>::failure(
90 Diagnostic::error(DiagnosticCode::Unsupported, e.what(), {}, {}, "agent.gpu"));
91 }
92 }
93 std::uint32_t f_ = 0, h_ = 0, a_ = 0;
94 std::unique_ptr<tensor::GpuProgram> inference_, training_;
95};
96} // namespace
100} // namespace eve::agent
LogicalId target
double value
std::string output
int mask
glm::vec4 p[6]
vkb::Device & device
std::string name
std::string error
Definition Package.cpp:60
std::string action
Definition PlayHost.cpp:117
std::shared_ptr< const ExpressionProgram > program
float weights[3]
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
static GpuProgram * tryBuild(const Graph &graph, const OptimizedGraph &opt, int outputNode)
Try build.
void train(Policy &p, const Observation &o, std::uint32_t action, double rate)
Train.
Definition Learning.h:90
PolicyGraph makePolicyGraph(int f, int h, int a, bool training)
Make policy graph.
Definition GpuGraph.cpp:65
Result< std::unique_ptr< IGpuPolicyBackend > > makeGpuBackend()
Create an owning GPU provider; compile lazily on the device owner thread.
Result< void > validatePolicy(const Policy &policy)
Validate the complete owning policy before inference/import, with no mutation or callbacks.
Definition Agent.cpp:79
eve::Diagnostic Diagnostic
eve::Result< T > Result
constexpr HexDirection next(HexDirection d) noexcept
The next direction clockwise (NW wraps to NE).
Definition HexMetrics.h:76
std::vector< OnnxNamedTensor > evaluate(const ModelData &, std::span< const OnnxNamedTensor >, const std::vector< std::string > &, OnnxCompute *, OnnxRunOptions options)
Evaluate.
std::vector< RuntimeTensor > execute(const Node &n, const std::vector< const RuntimeTensor * > &in, OnnxCompute *compute)
Execute.
OptimizedGraph optimizeGraph(const Graph &graph, int outputNode)
Optimize graph.
DiagnosticCode
Stable machine-readable diagnostic codes.
Definition Diagnostic.h:47