Deepity
Ultra-fast, SIMD-accelerated Predictive Coding
Loading...
Searching...
No Matches
ModelIO.h
Go to the documentation of this file.
1#pragma once
2#include <string>
3#include <fstream>
4#include <cstdint>
5#include <nlohmann/json.hpp>
6
12
13namespace Deep
14{
18 class ModelIO
19 {
20 public:
26 template <typename NetworkType>
27 static bool Save(const NetworkType &net, const std::string &filepath)
28 {
29 nlohmann::json header;
30 size_t current_offset = 0;
31 int layer_idx = 0;
32
33 for (const auto &layerPtr : net.GetLayers())
34 {
35 auto state_dict = layerPtr->GetStateDict();
36
37 for (const auto &[name, tensor] : state_dict)
38 {
39 std::string key = "layer_" + std::to_string(layer_idx) + "." + name;
40
41 size_t num_elements = 1;
42 for (size_t dim : tensor.shape)
43 {
44 num_elements *= dim;
45 }
46 size_t byte_size = num_elements * sizeof(float);
47
48 header[key] = {
49 {"dtype", "F32"},
50 {"shape", tensor.shape},
51 {"data_offsets", {current_offset, current_offset + byte_size}}};
52 current_offset += byte_size;
53 }
54 layer_idx++;
55 }
56
57 header["__metadata__"] = {{"format", "deepity_safetensors"}};
58
59 std::string header_str = header.dump();
60 uint64_t header_size = header_str.size();
61
62 std::ofstream out(filepath, std::ios::binary);
63 if (!out.is_open())
64 return false;
65
66 out.write(reinterpret_cast<const char *>(&header_size), sizeof(uint64_t));
67 out.write(header_str.data(), header_size);
68
69 for (const auto &layerPtr : net.GetLayers())
70 {
71 for (const auto &[name, tensor] : layerPtr->GetStateDict())
72 {
73 size_t num_elements = 1;
74 for (size_t dim : tensor.shape)
75 {
76 num_elements *= dim;
77 }
78 out.write(reinterpret_cast<const char *>(tensor.data), num_elements * sizeof(float));
79 }
80 }
81 return true;
82 }
83
89 template <typename NetworkType>
90 static bool Load(NetworkType &net, const std::string &filepath)
91 {
92 std::ifstream in(filepath, std::ios::binary);
93 if (!in.is_open())
94 return false;
95
96 uint64_t header_size;
97 in.read(reinterpret_cast<char *>(&header_size), sizeof(uint64_t));
98
99 std::string header_str(header_size, '\0');
100 in.read(&header_str[0], header_size);
101
102 auto header = nlohmann::json::parse(header_str);
103 size_t base_offset = sizeof(uint64_t) + header_size;
104
105 int layer_idx = 0;
106 for (auto &layerPtr : net.GetLayers())
107 {
108 auto state_dict = layerPtr->GetStateDict();
109 for (auto &[name, tensor] : state_dict)
110 {
111 std::string key = "layer_" + std::to_string(layer_idx) + "." + name;
112
113 if (header.contains(key))
114 {
115 size_t start_offset = header[key]["data_offsets"][0];
116 size_t end_offset = header[key]["data_offsets"][1];
117 size_t byte_size = end_offset - start_offset;
118
119 in.seekg(base_offset + start_offset, std::ios::beg);
120 in.read(reinterpret_cast<char *>(tensor.data), byte_size);
121 }
122 }
123 layer_idx++;
124 }
125 return true;
126 }
127 };
128}
Static save/load helpers for any network type exposing GetLayers() – templated so it works across eve...
Definition ModelIO.h:19
static bool Save(const NetworkType &net, const std::string &filepath)
Writes net's weights to a single file at filepath: a JSON header (per-layer tensor shapes/offsets) fo...
Definition ModelIO.h:27
static bool Load(NetworkType &net, const std::string &filepath)
Reads a file written by Save() back into net's already-compiled weight arena, matching each tensor by...
Definition ModelIO.h:90
This file exists to provide both Tensor.h and IComputeBackend.h with device types without introducing...
Definition Backend.cpp:10