The Sparta Modeling Framework
Loading...
Searching...
No Matches
CherryPickFastCheckpointer.hpp
1// <CherryPickFastCheckpointer> -*- C++ -*-
2
3#pragma once
4
5#include "sparta/serialization/checkpoint/FastCheckpointer.hpp"
7#include "simdb/apps/App.hpp"
8#include "simdb/utils/ConcurrentQueue.hpp"
9#include "simdb/sqlite/Iterator.hpp"
10#include <map>
11
12namespace sparta
13{
14 class TreeNode;
15 class Scheduler;
16}
17
18namespace simdb::pipeline
19{
20 class Flusher;
21}
22
23namespace sparta::serialization::checkpoint
24{
25
26class CherryPickFastCheckpointer final : public simdb::App
27{
28public:
29 using checkpoint_type = typename FastCheckpointer::checkpoint_type;
30 using checkpoint_ptr = typename FastCheckpointer::checkpoint_ptr;
31 using checkpoint_ptrs = typename FastCheckpointer::checkpoint_ptrs;
32 using chkpt_id_t = typename Checkpointer::chkpt_id_t;
33 using arch_id_t = uint64_t;
34 using tick_t = typename Checkpointer::tick_t;
35
36 static constexpr auto NAME = "cherry-pick-fast-checkpointer";
37
54 CherryPickFastCheckpointer(simdb::DatabaseManager* db_mgr, const std::vector<TreeNode*> & roots,
55 Scheduler* sched = nullptr);
56
62 class AppFactory : public simdb::AppFactoryBase
63 {
64 public:
66
71 void parameterize(const std::vector<TreeNode*>& roots, Scheduler* sched = nullptr)
72 {
73 roots_ = roots;
74 scheduler_ = sched;
75 }
76
77 AppT* createApp(simdb::DatabaseManager* db_mgr) override
78 {
79 // Make the ctor call that the default AppFactory cannot make.
80 return new AppT(db_mgr, roots_, scheduler_);
81 }
82
83 void defineSchema(simdb::Schema& schema) const override
84 {
85 AppT::defineSchema(schema);
86 }
87
88 private:
89 std::vector<TreeNode*> roots_;
90 Scheduler* scheduler_ = nullptr;
91 };
92
96 static void defineSchema(simdb::Schema& schema);
97
101 void createPipeline(simdb::pipeline::PipelineManager* pipeline_mgr) override;
102
107 return checkpointer_;
108 }
109
127 void commitCurrentBranch(bool force_new_head_chkpt = false,
128 std::vector<chkpt_id_t>* committed_checkpoints = nullptr);
129
133 void saveCheckpoints(checkpoint_ptrs&& checkpoints);
134
138 void preTeardown() override;
139
141 struct ChkptWindow;
142
145 arch_id_t start_arch_id = UINT64_MAX;
146 arch_id_t end_arch_id = UINT64_MAX;
147 tick_t tick = UINT64_MAX;
148 };
149
156 {
157 public:
159 DatabaseCheckpointLoader(simdb::DatabaseManager* db_mgr, TreeNode* root) :
160 DatabaseCheckpointLoader(db_mgr, std::vector<TreeNode*>({root}))
161 {}
162
164 DatabaseCheckpointLoader(simdb::DatabaseManager* db_mgr, const std::vector<TreeNode*>& roots);
165
169 uint64_t getNumCheckpoints() const { return num_checkpoints_; }
170
173 void loadCheckpoint(uint64_t checkpoint_idx) {
174 if (checkpoint_idx >= num_checkpoints_) {
175 throw SpartaException("Checkpoint index out of range");
176 }
177 loadCheckpoint_(checkpoint_idx);
178 }
179
180 private:
182 static std::vector<ArchData*> enumerateArchDatas_(const std::vector<TreeNode*>& roots);
183
185 static checkpoint_type* getChkptFromWindow_(arch_id_t arch_id, tick_t tick, ChkptWindow& window);
186
188 checkpoint_type* getChkptFromCache_(arch_id_t arch_id, tick_t tick);
189
193 checkpoint_type* getChkptFromDisk_(arch_id_t arch_id, tick_t tick);
194
196 void loadCheckpoint_(uint64_t checkpoint_idx);
197
199 simdb::DatabaseManager *const db_mgr_;
200
202 const std::vector<ArchData*> adatas_;
203
205 std::unique_ptr<ChkptWindow> cached_window_;
206
208 std::vector<ArchIdsForTick> tick_runs_;
209
212 uint64_t num_checkpoints_ = 0;
213 };
214
221 {
222 public:
224 DatabaseCheckpointReplayer(simdb::DatabaseManager* db_mgr, TreeNode* root) :
225 DatabaseCheckpointReplayer(db_mgr, std::vector<TreeNode*>({root}))
226 {}
227
229 DatabaseCheckpointReplayer(simdb::DatabaseManager* db_mgr, const std::vector<TreeNode*>& roots) :
230 chkpt_loader_(db_mgr, roots)
231 {
232 // Load the initial simulation state
233 constexpr size_t first_head_chkpt_id = 0;
234 chkpt_loader_.loadCheckpoint(first_head_chkpt_id);
235 }
236
238 uint64_t getNumCheckpoints() const { return chkpt_loader_.getNumCheckpoints(); }
239
242 bool step();
243
244 private:
246 DatabaseCheckpointLoader chkpt_loader_;
247
252 uint64_t next_checkpoint_idx_ = 1;
253 };
254
260 size_t getNumCheckpoints() const;
261
265 std::string stringize() const;
266
267 struct ChkptWindow {
268 arch_id_t start_arch_id = UINT64_MAX;
269 arch_id_t end_arch_id = UINT64_MAX;
270 tick_t start_tick = UINT64_MAX;
271 tick_t end_tick = UINT64_MAX;
272 checkpoint_ptrs checkpoints;
273
274 template <typename Archive>
275 void serialize(Archive & ar, const unsigned int /*version*/) {
276 ar & start_arch_id;
277 ar & end_arch_id;
278 ar & start_tick;
279 ar & end_tick;
280
281 if (checkpoints.empty()) {
282 // We are loading a checkpoint window from disk
283 const auto num_chkpts = end_arch_id - start_arch_id + 1;
284 for (size_t i = 0; i < num_chkpts; ++i) {
285 checkpoints.emplace_back(new checkpoint_type);
286 ar & *checkpoints.back();
287 }
288 } else {
289 // We are saving a checkpoint window to disk
290 for (auto& chkpt : checkpoints) {
291 ar & *chkpt;
292 }
293 }
294 }
295 };
296
298 arch_id_t start_arch_id = UINT64_MAX;
299 arch_id_t end_arch_id = UINT64_MAX;
300 tick_t start_tick = UINT64_MAX;
301 tick_t end_tick = UINT64_MAX;
302 std::vector<char> chkpt_bytes;
303 };
304
305private:
306 FastCheckpointer checkpointer_;
307 simdb::DatabaseManager* db_mgr_ = nullptr;
308 simdb::ConcurrentQueue<ChkptWindow>* chkpt_window_head_ = nullptr;
309 simdb::ConcurrentQueue<ArchIdsForTick>* tick_runs_head_ = nullptr;
310 std::queue<ArchIdsForTick> tick_runs_;
311 uint64_t committed_arch_id_ = 0;
312 std::unique_ptr<simdb::pipeline::Flusher> pipeline_flusher_;
313 std::vector<chkpt_id_t> committed_checkpoints_;
314};
315
316} // namespace sparta::serialization::checkpoint
Exception class for all of Sparta.
A class that lets you schedule events now and in the future.
Used to construct and throw a standard C++ exception. Inherits from std::exception.
Node in a composite tree representing a sparta Tree item.
Definition TreeNode.hpp:204
Checkpoint::chkpt_id_t chkpt_id_t
tick_t Tick type to which checkpoints will refer
Checkpoint::tick_t tick_t
tick_t Tick type to which checkpoints will refer
This AppFactory specialization is provided since we have to initialize the FastCheckpointer which tak...
void parameterize(const std::vector< TreeNode * > &roots, Scheduler *sched=nullptr)
Sets the ArchData root(s) and Scheduler for a given instance of the checkpointer.
This class retrieves checkpoints from disk for post-simulation use cases.
void loadCheckpoint(uint64_t checkpoint_idx)
Load a checkpoint with an index between [0,getNumCheckpoints())
DatabaseCheckpointLoader(simdb::DatabaseManager *db_mgr, TreeNode *root)
Construct with one root from which we'll find the ArchData's.
DatabaseCheckpointLoader(simdb::DatabaseManager *db_mgr, const std::vector< TreeNode * > &roots)
Construct with multiple roots from which we'll find the ArchData's.
To assist with post-simulation replay, this class implements a step() method.
bool step()
Go to the next checkpoint and fill in the ArchData's from the roots.
DatabaseCheckpointReplayer(simdb::DatabaseManager *db_mgr, TreeNode *root)
Construct with one root from which we'll find the ArchData's.
DatabaseCheckpointReplayer(simdb::DatabaseManager *db_mgr, const std::vector< TreeNode * > &roots)
Construct with multiple roots from which we'll find the ArchData's.
static void defineSchema(simdb::Schema &schema)
Define the SimDB schema for this checkpointer.
std::string stringize() const
Returns a string describing this object.
void saveCheckpoints(checkpoint_ptrs &&checkpoints)
Send the committed checkpoints down the pipeline to the database.
void createPipeline(simdb::pipeline::PipelineManager *pipeline_mgr) override
Instantiate the async processing pipeline to save checkpoints to the DB.
CherryPickFastCheckpointer(simdb::DatabaseManager *db_mgr, const std::vector< TreeNode * > &roots, Scheduler *sched=nullptr)
CherryPickFastCheckpointer constructor.
void commitCurrentBranch(bool force_new_head_chkpt=false, std::vector< chkpt_id_t > *committed_checkpoints=nullptr)
When satisfied with the outstanding/uncommitted checkpoints, call this method to commit them to the d...
FastCheckpointer & getFastCheckpointer() noexcept
Use the FastCheckpointer to create checkpoints / checkpoint branches.
size_t getNumCheckpoints() const
Get the total number of checkpoints sent to the database thus far.
void preTeardown() override
Called at the end of simulation just prior to shutting down threads.
Single delta checkpoint object containing all simulator state which changed since some previous Delta...
Implements quick checkpointing through delta-checkpoint trees which store state-deltas in a compact f...
Macros for handling exponential backoff.