Bicameral Engine
GPU-resident engine for a magic-research open-world game
Loading...
Searching...
No Matches
lab_session.h
Go to the documentation of this file.
1// lab_session.h — 実験室(14 §2・T-0142)の 1 回の実験: 同じ箱を GPU(sim/gpu_lab_box)と CPU リファレンス(sim/lab_box の StepLabBox)で
2// 並べて刻み、刻みごとに状態の全部を比べる。食い違ったら最初の刻みとセルを残して止まる。エディタのパネル(editor/lab_panel)とテストが使う。
3//
4// データの流れ:
5// パネルの「置く」「温度」→ Place・SetTemperature(次の刻みのコマンドにする。CPU は箱に触れない)
6// → Step(n): 刻みごとに 1 本のリスト(コマンドを当てる → 刻む → 読み戻す)を自分のキューに投げて待つ → CPU も同じ刻み → 比べる
7// → Recording()(コマンドの列 + ハッシュの列)を保存 → Replay で初めの箱から流し直し、ハッシュの列が記録と同じかも確かめる。
8// 箱は小さい(512 セル)ので、1 刻みずつ待つ(エディタの道具。ゲームの世界のフレームの歩調〔ADR-0011〕とは別のキュー)。
9#pragma once
10
11#include <cstdint>
12#include <expected>
13#include <optional>
14#include <span>
15#include <string>
16#include <vector>
17
18#include "gpu/debug_ring.h"
19#include "gpu/immediate_queue.h"
20#include "sim/gpu_lab_box.h"
21#include "sim/lab_box.h"
22
23namespace bicameral::sim {
24
25 class LabSession {
26 public:
27 // table は写して持つ(呼ぶ側の表が消えてもよい)
28 [[nodiscard]] static std::expected<LabSession, std::string> Create(ID3D12Device5* device,
29 D3D12_COMMAND_LIST_TYPE queueType,
30 const BakedReactionTable& table);
31
32 // --- 置く(次の刻み NextTick() のコマンドにする。1 刻みに LAB_MAX_COMMANDS_PER_TICK まで)---
33 bool Place(LabCellPosition cell, std::span<const SpeciesAmount> contents, uint32_t temperatureMilliKelvin);
34 bool SetTemperature(LabCellPosition cell, uint32_t temperatureMilliKelvin);
35
36 // tickCount 刻み進める。食い違ったらその刻みで止まり(Mismatch())、以後は Reset まで進めない。GPU の失敗はエラー
37 [[nodiscard]] std::expected<void, std::string> Step(uint32_t tickCount);
38
39 // 初めの箱(300 K の空気)に戻し、記録を空にする
40 [[nodiscard]] std::expected<void, std::string> Reset();
41
42 // 初めの箱から記録のコマンドを流し直す(記録の刻みの数まで)。記録のハッシュと違った最初の刻みは ReplayDivergence()
43 [[nodiscard]] std::expected<void, std::string> Replay(const LabRecording& recording);
44
45 // --- 見る ---
46 [[nodiscard]] uint64_t NextTick() const { return m_tick; }
47 [[nodiscard]] const MultiresNest& Cpu() const { return m_cpu; }
48 [[nodiscard]] const MultiresNest& Gpu() const { return m_read; }
49 [[nodiscard]] const BakedReactionTable& Table() const { return m_table; }
50 [[nodiscard]] const std::optional<LabMismatch>& Mismatch() const { return m_mismatch; }
51 [[nodiscard]] std::optional<uint64_t> ReplayDivergence() const { return m_replayDivergence; }
52 [[nodiscard]] bool Replaying() const { return m_replayEnd > m_tick; }
53 [[nodiscard]] size_t PendingCommands() const { return m_pending.size(); }
54 [[nodiscard]] LabRecording Recording() const;
55
56 private:
58
59 bool Queue(const Command& command);
60 [[nodiscard]] std::vector<Command> TakeCommands(uint64_t tick);
61 [[nodiscard]] std::expected<void, std::string> StepOne();
62
67
68 // --- 箱 ---
69 MultiresNest m_cpu; // CPU リファレンス
70 MultiresNest m_read; // GPU から読み戻した箱
71 bool m_uploaded = false;
72 uint64_t m_tick = 0; // 次に刻む刻み
73 uint32_t m_sequence = 0;
74
75 // --- コマンド ---
76 std::vector<Command> m_pending; // 置いたが、まだ刻んでいない
77 std::vector<Command> m_scheduled; // 再生中の記録のうち、まだ刻んでいない
78 std::vector<Command> m_history; // 刻んだ(記録に入る)
79
80 // --- 比べた結果 ---
81 std::vector<uint64_t> m_hashes; // 刻みごとの CPU の HashWholeNest
82 std::optional<LabMismatch> m_mismatch;
83 std::vector<uint64_t> m_replayHashes;
84 uint64_t m_replayEnd = 0;
85 std::optional<uint64_t> m_replayDivergence;
86 };
87
88} // namespace bicameral::sim
const MultiresNest & Cpu() const
Definition lab_session.h:47
std::optional< LabMismatch > m_mismatch
Definition lab_session.h:82
std::vector< uint64_t > m_hashes
Definition lab_session.h:81
bool Queue(const Command &command)
std::expected< void, std::string > Step(uint32_t tickCount)
const BakedReactionTable & Table() const
Definition lab_session.h:49
std::vector< Command > m_history
Definition lab_session.h:78
bool SetTemperature(LabCellPosition cell, uint32_t temperatureMilliKelvin)
BakedReactionTable m_table
Definition lab_session.h:63
std::optional< uint64_t > m_replayDivergence
Definition lab_session.h:85
std::expected< void, std::string > Replay(const LabRecording &recording)
std::optional< uint64_t > ReplayDivergence() const
Definition lab_session.h:51
std::expected< void, std::string > StepOne()
LabRecording Recording() const
std::expected< void, std::string > Reset()
std::vector< Command > m_scheduled
Definition lab_session.h:77
uint64_t NextTick() const
Definition lab_session.h:46
std::vector< uint64_t > m_replayHashes
Definition lab_session.h:83
static std::expected< LabSession, std::string > Create(ID3D12Device5 *device, D3D12_COMMAND_LIST_TYPE queueType, const BakedReactionTable &table)
std::vector< Command > m_pending
Definition lab_session.h:76
bool Place(LabCellPosition cell, std::span< const SpeciesAmount > contents, uint32_t temperatureMilliKelvin)
const std::optional< LabMismatch > & Mismatch() const
Definition lab_session.h:50
size_t PendingCommands() const
Definition lab_session.h:53
gpu::ImmediateQueue m_queue
Definition lab_session.h:64
const MultiresNest & Gpu() const
Definition lab_session.h:48
std::vector< Command > TakeCommands(uint64_t tick)
LabSession(BakedReactionTable table, gpu::ImmediateQueue queue, gpu::DebugRing ring, GpuLabBox box)