-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstance_meta_loader.hpp
More file actions
103 lines (94 loc) · 3.14 KB
/
Copy pathinstance_meta_loader.hpp
File metadata and controls
103 lines (94 loc) · 3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// instance_meta_loader.hpp
//
// Self-contained loader for InstanceMeta files produced by main_real.cu's
// --save-metas option.
//
// File format (binary, little-endian):
//
// uint32_t num_metas
// for each meta:
// uint32_t inst_id
// uint8_t type (0=ROM, 1=INPUT, 2=RAM)
// uint8_t pad[3]
// uint32_t first_addr
// uint32_t last_addr
// uint32_t first_addr_chunk
// uint32_t first_addr_skip
// uint32_t last_addr_chunk
// uint32_t last_addr_include
// uint32_t count_per_chunk_size
// uint32_t addr_offsets_size
// uint32_t count_per_chunk[count_per_chunk_size]
// uint32_t addr_offsets[addr_offsets_size]
//
// Usage:
// #include "instance_meta_loader.hpp"
// std::vector<InstanceMeta> metas = load_instance_metas("metas.bin");
// for (const InstanceMeta& m : metas) {
// // m.inst_id, m.type, m.first_addr, m.last_addr,
// // m.count_per_chunk[chunk], m.addr_offsets[addr_index],
// // m.first_addr_chunk, m.first_addr_skip,
// // m.last_addr_chunk, m.last_addr_include
// }
//
// Each InstanceMeta owns its own arrays; no external storage to manage.
// Header-only, no external dependencies, requires C++17.
#ifndef INSTANCE_META_LOADER_HPP
#define INSTANCE_META_LOADER_HPP
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <stdexcept>
#include <string>
#include <vector>
struct InstanceMeta {
uint32_t inst_id;
uint8_t type; // 0=ROM, 1=INPUT, 2=RAM
uint32_t first_addr;
uint32_t last_addr;
uint32_t first_addr_chunk;
uint32_t first_addr_skip;
uint32_t last_addr_chunk;
uint32_t last_addr_include;
std::vector<uint32_t> count_per_chunk;
std::vector<uint32_t> addr_offsets;
};
inline std::vector<InstanceMeta> load_instance_metas(const std::string& path) {
std::FILE* f = std::fopen(path.c_str(), "rb");
if (!f) throw std::runtime_error("cannot open " + path);
auto rd = [&](void* p, std::size_t bytes) {
if (std::fread(p, 1, bytes, f) != bytes) {
std::fclose(f);
throw std::runtime_error("short read on " + path);
}
};
uint32_t n;
rd(&n, sizeof(uint32_t));
std::vector<InstanceMeta> out;
out.reserve(n);
for (uint32_t i = 0; i < n; i++) {
InstanceMeta m;
uint8_t type, pad[3];
rd(&m.inst_id, sizeof(uint32_t));
rd(&type, 1);
rd(pad, 3);
m.type = type;
rd(&m.first_addr, sizeof(uint32_t));
rd(&m.last_addr, sizeof(uint32_t));
rd(&m.first_addr_chunk, sizeof(uint32_t));
rd(&m.first_addr_skip, sizeof(uint32_t));
rd(&m.last_addr_chunk, sizeof(uint32_t));
rd(&m.last_addr_include, sizeof(uint32_t));
uint32_t cps, aos;
rd(&cps, sizeof(uint32_t));
rd(&aos, sizeof(uint32_t));
m.count_per_chunk.resize(cps);
m.addr_offsets.resize(aos);
rd(m.count_per_chunk.data(), cps * sizeof(uint32_t));
rd(m.addr_offsets.data(), aos * sizeof(uint32_t));
out.push_back(std::move(m));
}
std::fclose(f);
return out;
}
#endif // INSTANCE_META_LOADER_HPP