Bug Summary

File:root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp
Warning:line 210, column 9
Division by zero

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name gguf.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +avx -target-feature +avx2 -target-feature +bmi2 -target-feature +f16c -target-feature +fma -target-feature +sse4.2 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/third_party/llama.cpp -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/third_party/llama.cpp -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D _GNU_SOURCE=1 -D GGML_USE_CPU=1 -D GGML_VERSION="GGML_VERSION" -D GGML_COMMIT="GGML_COMMIT" -D GGML_SHARED=1 -D LLAMA_SHARED=1 -D GGML_BUILD=1 -D LLAMA_BUILD=1 -D GGML_BACKEND_SHARED=1 -D GGML_BACKEND_BUILD=1 -D MOZ_HAS_MOZGLUE -I /root/firefox-clang/third_party/llama.cpp -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/third_party/llama.cpp -I /root/firefox-clang/third_party/llama.cpp/ggml -I /root/firefox-clang/third_party/llama.cpp/ggml/include -I /root/firefox-clang/third_party/llama.cpp/ggml/src -I /root/firefox-clang/third_party/llama.cpp/ggml/src/ggml-cpu -I /root/firefox-clang/third_party/llama.cpp/include -I /root/firefox-clang/third_party/llama.cpp/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -Wno-sign-compare -Wno-unused-function -Wno-tautological-unsigned-enum-zero-compare -Wno-implicit-fallthrough -Wno-unreachable-code -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c++ /root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp
1#include "ggml.h"
2#include "ggml-backend.h"
3#include "ggml-impl.h"
4#include "gguf.h"
5
6#include <cinttypes>
7#include <cstddef>
8#include <cstdint>
9#include <cstdio>
10#include <cstdlib>
11#include <cstring>
12#include <map>
13#include <new>
14#include <stdexcept>
15#include <string>
16#include <vector>
17#include <cerrno>
18
19#include "moz-overrides.h"
20
21#define GGUF_MAX_STRING_LENGTH(1024*1024*1024) (1024*1024*1024)
22#define GGUF_MAX_ARRAY_ELEMENTS(1024*1024*1024) (1024*1024*1024)
23
24#ifdef _WIN32
25# define gguf_ftellftello _ftelli64
26# define gguf_fseekfseeko _fseeki64
27#else
28# define gguf_ftellftello ftello
29# define gguf_fseekfseeko fseeko
30#endif
31
32template <typename T>
33struct type_to_gguf_type;
34
35template <>
36struct type_to_gguf_type<uint8_t> {
37 static constexpr enum gguf_type value = GGUF_TYPE_UINT8;
38};
39
40template <>
41struct type_to_gguf_type<int8_t> {
42 static constexpr enum gguf_type value = GGUF_TYPE_INT8;
43};
44
45template <>
46struct type_to_gguf_type<uint16_t> {
47 static constexpr enum gguf_type value = GGUF_TYPE_UINT16;
48};
49
50template <>
51struct type_to_gguf_type<int16_t> {
52 static constexpr enum gguf_type value = GGUF_TYPE_INT16;
53};
54
55template <>
56struct type_to_gguf_type<uint32_t> {
57 static constexpr enum gguf_type value = GGUF_TYPE_UINT32;
58};
59
60template <>
61struct type_to_gguf_type<int32_t> {
62 static constexpr enum gguf_type value = GGUF_TYPE_INT32;
63};
64
65template <>
66struct type_to_gguf_type<float> {
67 static constexpr enum gguf_type value = GGUF_TYPE_FLOAT32;
68};
69
70template <>
71struct type_to_gguf_type<bool> {
72 static constexpr enum gguf_type value = GGUF_TYPE_BOOL;
73};
74
75template <>
76struct type_to_gguf_type<std::string> {
77 static constexpr enum gguf_type value = GGUF_TYPE_STRING;
78};
79
80template <>
81struct type_to_gguf_type<uint64_t> {
82 static constexpr enum gguf_type value = GGUF_TYPE_UINT64;
83};
84
85template <>
86struct type_to_gguf_type<int64_t> {
87 static constexpr enum gguf_type value = GGUF_TYPE_INT64;
88};
89
90template <>
91struct type_to_gguf_type<double> {
92 static constexpr enum gguf_type value = GGUF_TYPE_FLOAT64;
93};
94
95static const std::map<gguf_type, size_t> & get_gguf_type_size_map() {
96 static const std::map<gguf_type, size_t> GGUF_TYPE_SIZE = {
97 {GGUF_TYPE_UINT8, sizeof(uint8_t)},
98 {GGUF_TYPE_INT8, sizeof(int8_t)},
99 {GGUF_TYPE_UINT16, sizeof(uint16_t)},
100 {GGUF_TYPE_INT16, sizeof(int16_t)},
101 {GGUF_TYPE_UINT32, sizeof(uint32_t)},
102 {GGUF_TYPE_INT32, sizeof(int32_t)},
103 {GGUF_TYPE_FLOAT32, sizeof(float)},
104 {GGUF_TYPE_BOOL, sizeof(int8_t)},
105 {GGUF_TYPE_STRING, 0}, // undefined
106 {GGUF_TYPE_ARRAY, 0}, // undefined
107 {GGUF_TYPE_UINT64, sizeof(uint64_t)},
108 {GGUF_TYPE_INT64, sizeof(int64_t)},
109 {GGUF_TYPE_FLOAT64, sizeof(double)},
110 };
111 static_assert(GGUF_TYPE_COUNT == 13, "GGUF_TYPE_COUNT != 13");
112 return GGUF_TYPE_SIZE;
113}
114
115static const std::map<gguf_type, const char *> & get_gguf_type_name_map() {
116 static const std::map<gguf_type, const char *> GGUF_TYPE_NAME = {
117 {GGUF_TYPE_UINT8, "u8"},
118 {GGUF_TYPE_INT8, "i8"},
119 {GGUF_TYPE_UINT16, "u16"},
120 {GGUF_TYPE_INT16, "i16"},
121 {GGUF_TYPE_UINT32, "u32"},
122 {GGUF_TYPE_INT32, "i32"},
123 {GGUF_TYPE_FLOAT32, "f32"},
124 {GGUF_TYPE_BOOL, "bool"},
125 {GGUF_TYPE_STRING, "str"},
126 {GGUF_TYPE_ARRAY, "arr"},
127 {GGUF_TYPE_UINT64, "u64"},
128 {GGUF_TYPE_INT64, "i64"},
129 {GGUF_TYPE_FLOAT64, "f64"},
130 };
131 static_assert(GGUF_TYPE_COUNT == 13, "GGUF_TYPE_COUNT != 13");
132 return GGUF_TYPE_NAME;
133}
134
135size_t gguf_type_size(enum gguf_type type) {
136 const auto & GGUF_TYPE_SIZE = get_gguf_type_size_map();
137 auto it = GGUF_TYPE_SIZE.find(type);
138 return it == GGUF_TYPE_SIZE.end() ? 0 : it->second;
10
'?' condition is true
11
Returning zero
139}
140
141struct gguf_kv {
142 std::string key;
143
144 bool is_array;
145 enum gguf_type type;
146
147 std::vector<int8_t> data;
148 std::vector<std::string> data_string;
149
150 template <typename T>
151 gguf_kv(const std::string & key, const T value)
152 : key(key), is_array(false), type(type_to_gguf_type<T>::value) {
153 GGML_ASSERT(!key.empty())if (!(!key.empty())) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 153, "GGML_ASSERT(%s) failed", "!key.empty()")
;
154 data.resize(sizeof(T));
155 memcpy(data.data(), &value, sizeof(T));
156 }
157
158 template <typename T>
159 gguf_kv(const std::string & key, const std::vector<T> & value)
160 : key(key), is_array(true), type(type_to_gguf_type<T>::value) {
161 GGML_ASSERT(!key.empty())if (!(!key.empty())) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 161, "GGML_ASSERT(%s) failed", "!key.empty()")
;
162 data.resize(value.size()*sizeof(T));
163 for (size_t i = 0; i < value.size(); ++i) {
164 const T tmp = value[i];
165 memcpy(data.data() + i*sizeof(T), &tmp, sizeof(T));
166 }
167 }
168
169 gguf_kv(const std::string & key, const std::string & value)
170 : key(key), is_array(false), type(GGUF_TYPE_STRING) {
171 GGML_ASSERT(!key.empty())if (!(!key.empty())) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 171, "GGML_ASSERT(%s) failed", "!key.empty()")
;
172 data_string.push_back(value);
173 }
174
175 gguf_kv(const std::string & key, const std::vector<std::string> & value)
176 : key(key), is_array(true), type(GGUF_TYPE_STRING) {
177 GGML_ASSERT(!key.empty())if (!(!key.empty())) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 177, "GGML_ASSERT(%s) failed", "!key.empty()")
;
178 data_string = value;
179 }
180
181 const std::string & get_key() const {
182 return key;
183 }
184
185 const enum gguf_type & get_type() const {
186 return type;
187 }
188
189 size_t get_ne() const {
190 if (type == GGUF_TYPE_STRING) {
191 const size_t ne = data_string.size();
192 GGML_ASSERT(is_array || ne == 1)if (!(is_array || ne == 1)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 192, "GGML_ASSERT(%s) failed", "is_array || ne == 1")
;
193 return ne;
194 }
195 const size_t type_size = gguf_type_size(type);
196 GGML_ASSERT(data.size() % type_size == 0)if (!(data.size() % type_size == 0)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 196, "GGML_ASSERT(%s) failed", "data.size() % type_size == 0"
)
;
197 const size_t ne = data.size() / type_size;
198 GGML_ASSERT(is_array || ne == 1)if (!(is_array || ne == 1)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 198, "GGML_ASSERT(%s) failed", "is_array || ne == 1")
;
199 return ne;
200 }
201
202 template <typename T>
203 const T & get_val(const size_t i = 0) const {
204 GGML_ASSERT(type_to_gguf_type<T>::value == type)if (!(type_to_gguf_type<T>::value == type)) ggml_abort(
"/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 204, "GGML_ASSERT(%s) failed", "type_to_gguf_type<T>::value == type"
)
;
7
Taking false branch
205 if constexpr (std::is_same<T, std::string>::value
7.1
'value' is false
) {
8
Taking false branch
206 GGML_ASSERT(data_string.size() >= i+1)if (!(data_string.size() >= i+1)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 206, "GGML_ASSERT(%s) failed", "data_string.size() >= i+1"
)
;
207 return data_string[i];
208 }
209 const size_t type_size = gguf_type_size(type);
9
Calling 'gguf_type_size'
12
Returning from 'gguf_type_size'
13
'type_size' initialized to 0
210 GGML_ASSERT(data.size() % type_size == 0)if (!(data.size() % type_size == 0)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 210, "GGML_ASSERT(%s) failed", "data.size() % type_size == 0"
)
;
14
Division by zero
211 GGML_ASSERT(data.size() >= (i+1)*type_size)if (!(data.size() >= (i+1)*type_size)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 211, "GGML_ASSERT(%s) failed", "data.size() >= (i+1)*type_size"
)
;
212 return reinterpret_cast<const T *>(data.data())[i];
213 }
214
215 void cast(const enum gguf_type new_type) {
216 const size_t new_type_size = gguf_type_size(new_type);
217 GGML_ASSERT(data.size() % new_type_size == 0)if (!(data.size() % new_type_size == 0)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 217, "GGML_ASSERT(%s) failed", "data.size() % new_type_size == 0"
)
;
218 type = new_type;
219 }
220};
221
222struct gguf_tensor_info {
223 struct ggml_tensor t; // for holding the equivalent info
224 uint64_t offset; // offset from start of `data`, must be a multiple of `ALIGNMENT`
225};
226
227struct gguf_context {
228 uint32_t version = GGUF_VERSION3;
229
230 std::vector<struct gguf_kv> kv;
231 std::vector<struct gguf_tensor_info> info;
232
233 size_t alignment = GGUF_DEFAULT_ALIGNMENT32;
234 size_t offset = 0; // offset of `data` from beginning of file
235 size_t size = 0; // size of `data` in bytes
236
237 void * data = nullptr;
238};
239
240struct gguf_reader {
241 gguf_reader(
242 gguf_reader_callback_t callback,
243 void * userdata,
244 size_t max_chunk_read,
245 uint64_t data_offset = 0,
246 uint64_t nbytes_remain = 0)
247 : callback(callback),
248 userdata(userdata),
249 max_chunk_read(max_chunk_read),
250 data_offset(data_offset),
251 nbytes_remain(nbytes_remain) {
252 GGML_ASSERT(max_chunk_read > 0)if (!(max_chunk_read > 0)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 252, "GGML_ASSERT(%s) failed", "max_chunk_read > 0")
;
253 }
254
255 // helper for remaining bytes in a file
256 static uint64_t file_remain(FILE * file) {
257 const int64_t cur = gguf_ftellftello(file);
258 if (cur < 0) {
259 return 0;
260 }
261 if (gguf_fseekfseeko(file, 0, SEEK_END2) != 0) {
262 gguf_fseekfseeko(file, cur, SEEK_SET0);
263
264 return 0;
265 }
266 const int64_t end = gguf_ftellftello(file);
267 if (end < 0) {
268 gguf_fseekfseeko(file, cur, SEEK_SET0);
269
270 return 0;
271 }
272 gguf_fseekfseeko(file, cur, SEEK_SET0);
273 return static_cast<uint64_t>(end - cur);
274 }
275
276 template <typename T>
277 bool read(T & dst) const {
278 const size_t size = sizeof(dst);
279 if (size > nbytes_remain) {
280 return false;
281 }
282 return read_raw(&dst, size) == size;
283 }
284
285 template <typename T>
286 bool read(std::vector<T> & dst, const size_t n) const {
287 if (n > GGUF_MAX_ARRAY_ELEMENTS(1024*1024*1024)) {
288 return false;
289 }
290 if constexpr (std::is_same<T, std::string>::value) {
291 // strings are prefixed with their length, so we need to account for that
292 if (n > SIZE_MAX(18446744073709551615UL) / sizeof(uint64_t)) {
293 return false;
294 }
295 if (nbytes_remain < n * sizeof(uint64_t)) {
296 return false;
297 }
298 } else {
299 if (n > SIZE_MAX(18446744073709551615UL) / sizeof(T)) {
300 return false;
301 }
302 if (nbytes_remain < n * sizeof(T)) {
303 return false;
304 }
305 }
306 dst.resize(n);
307 for (size_t i = 0; i < dst.size(); ++i) {
308 if constexpr (std::is_same<T, bool>::value) {
309 bool tmp;
310 if (!read(tmp)) {
311 return false;
312 }
313 dst[i] = tmp;
314 } else {
315 if (!read(dst[i])) {
316 return false;
317 }
318 }
319 }
320 return true;
321 }
322
323 bool read(bool & dst) const {
324 int8_t tmp = -1;
325 if (!read(tmp)) {
326 return false;
327 }
328 dst = tmp != 0;
329 return true;
330 }
331
332 bool read(enum ggml_type & dst) const {
333 int32_t tmp = -1;
334 if (!read(tmp)) {
335 return false;
336 }
337 dst = ggml_type(tmp);
338 return true;
339 }
340
341 bool read(enum gguf_type & dst) const {
342 int32_t tmp = -1;
343 if (!read(tmp)) {
344 return false;
345 }
346 dst = gguf_type(tmp);
347 return true;
348 }
349
350 bool read(std::string & dst) const {
351 uint64_t size = 0;
352 if (!read(size)) {
353 return false;
354 }
355 if (size > GGUF_MAX_STRING_LENGTH(1024*1024*1024)) {
356 GGML_LOG_ERROR("%s: string length %" PRIu64 " exceeds maximum %" PRIu64 "\n", __func__, size, (uint64_t) GGUF_MAX_STRING_LENGTH)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: string length %"
"l" "u" " exceeds maximum %" "l" "u" "\n", __func__, size, (
uint64_t) (1024*1024*1024))
;
357 return false;
358 }
359 if (size > nbytes_remain) {
360 GGML_LOG_ERROR("%s: string length %" PRIu64 " exceeds remaining file size %" PRIu64 " bytes\n", __func__, size, nbytes_remain)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: string length %"
"l" "u" " exceeds remaining file size %" "l" "u" " bytes\n",
__func__, size, nbytes_remain)
;
361 return false;
362 }
363 dst.resize(static_cast<size_t>(size));
364 return read_raw(dst.data(), static_cast<size_t>(size)) == size;
365 }
366
367 bool read(void * dst, const size_t size) const {
368 if (size > nbytes_remain) {
369 return false;
370 }
371 return read_raw(dst, size) == size;
372 }
373
374 uint64_t tell() const {
375 return data_offset;
376 }
377
378 bool seek(uint64_t absolute_offset) const {
379 const uint64_t end_offset = uint64_t(data_offset) + nbytes_remain;
380 if (absolute_offset > end_offset) {
381 return false;
382 }
383
384 data_offset = absolute_offset;
385 nbytes_remain = end_offset - absolute_offset;
386
387 return true;
388 }
389
390private:
391 size_t read_raw(void * dst, size_t size) const {
392 if (callback == nullptr || size == 0) {
393 return 0;
394 }
395
396 uint8_t * data = static_cast<uint8_t *>(dst);
397 size_t total_nread = 0;
398 bool reached_eof = false;
399
400 while (total_nread < size) {
401 const size_t chunk_size = std::min(max_chunk_read, size - total_nread);
402 if (data_offset + total_nread < data_offset) {
403 break;
404 }
405 const size_t nread = callback(userdata, static_cast<void *>(data + total_nread), data_offset + total_nread, chunk_size);
406 total_nread += nread;
407 if (nread != chunk_size) {
408 reached_eof = true;
409 break;
410 }
411 }
412
413 data_offset += total_nread;
414 GGML_ASSERT(total_nread <= nbytes_remain)if (!(total_nread <= nbytes_remain)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 414, "GGML_ASSERT(%s) failed", "total_nread <= nbytes_remain"
)
;
415 nbytes_remain -= total_nread;
416
417 if (reached_eof) {
418 nbytes_remain = 0;
419 }
420
421 return total_nread;
422 }
423
424 gguf_reader_callback_t callback = nullptr;
425 void * userdata = nullptr;
426 size_t max_chunk_read = 0;
427 mutable uint64_t data_offset = 0;
428 mutable uint64_t nbytes_remain = 0;
429};
430
431struct gguf_context * gguf_init_empty(void) {
432 return new gguf_context;
433}
434
435template<typename T>
436bool gguf_read_emplace_helper(const struct gguf_reader & gr, std::vector<struct gguf_kv> & kv, const std::string & key, const bool is_array, const size_t n) {
437 if (is_array) {
438 std::vector<T> value;
439 tryif (true) {
440 if (!gr.read(value, n)) {
441 return false;
442 }
443 } catch (std::length_error &)if (static const std::exception e, err, error, ex; false) {
444 GGML_LOG_ERROR("%s: encountered length_error while reading value for key '%s'\n", __func__, key.c_str())ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: encountered length_error while reading value for key '%s'\n"
, __func__, key.c_str())
;
445 return false;
446 } catch (std::bad_alloc &)if (static const std::exception e, err, error, ex; false) {
447 GGML_LOG_ERROR("%s: encountered bad_alloc error while reading value for key '%s'\n", __func__, key.c_str())ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: encountered bad_alloc error while reading value for key '%s'\n"
, __func__, key.c_str())
;
448 return false;
449 }
450 kv.emplace_back(key, value);
451 } else {
452 T value;
453 if (!gr.read(value)) {
454 return false;
455 }
456 kv.emplace_back(key, value);
457 }
458 return true;
459}
460
461static struct gguf_context * gguf_init_from_reader(const struct gguf_reader & gr, struct gguf_init_params params) {
462 struct gguf_context * ctx = new gguf_context;
463
464 bool ok = true;
465
466 // file magic
467 {
468 std::vector<char> magic;
469 ok = ok && gr.read(magic, 4);
470
471 if (!ok) {
472 GGML_LOG_ERROR("%s: failed to read magic\n", __func__)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: failed to read magic\n"
, __func__)
;
473 gguf_free(ctx);
474 return nullptr;
475 }
476
477 for (uint32_t i = 0; i < magic.size(); i++) {
478 if (magic[i] != GGUF_MAGIC"GGUF"[i]) {
479 char c0 = isprint(magic[0]) ? magic[0] : '?';
480 char c1 = isprint(magic[1]) ? magic[1] : '?';
481 char c2 = isprint(magic[2]) ? magic[2] : '?';
482 char c3 = isprint(magic[3]) ? magic[3] : '?';
483 GGML_LOG_ERROR("%s: invalid magic characters: '%c%c%c%c', expected 'GGUF'\n", __func__, c0, c1, c2, c3)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: invalid magic characters: '%c%c%c%c', expected 'GGUF'\n"
, __func__, c0, c1, c2, c3)
;
484 gguf_free(ctx);
485 return nullptr;
486 }
487 }
488 }
489
490 // header
491 int64_t n_kv = 0;
492 int64_t n_tensors = 0;
493
494 if (ok && gr.read(ctx->version)) {
495 if (ok && ctx->version == 0) {
496 GGML_LOG_ERROR("%s: bad GGUF version: %" PRIu32 "\n", __func__, ctx->version)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: bad GGUF version: %"
"u" "\n", __func__, ctx->version)
;
497 ok = false;
498 }
499
500 /*
501 * bit layout is different when reading non-native endian models.
502 * assuming that the GGUF version is 3, the non-native endian model
503 * would read it as 0x30000000. we can use the AND operation against
504 * the last 4 hexadecimal digits to check if the model is the same
505 * endianness as the host system.
506 */
507 if (ok && (ctx->version & 0x0000FFFF) == 0x00000000) {
508 GGML_LOG_ERROR("%s: failed to load model: this GGUF file version %" PRIu32 " is extremely large, is there a mismatch between the host and model endianness?\n", __func__, ctx->version)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: failed to load model: this GGUF file version %"
"u" " is extremely large, is there a mismatch between the host and model endianness?\n"
, __func__, ctx->version)
;
509 ok = false;
510 }
511
512 if (ok && ctx->version == 1) {
513 GGML_LOG_ERROR("%s: GGUFv1 is no longer supported, please use a more up-to-date version\n", __func__)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: GGUFv1 is no longer supported, please use a more up-to-date version\n"
, __func__)
;
514 ok = false;
515 }
516 if (ok && ctx->version > GGUF_VERSION3) {
517 GGML_LOG_ERROR("%s: this GGUF file is version %" PRIu32 " but this software only supports up to version %d\n",ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: this GGUF file is version %"
"u" " but this software only supports up to version %d\n", __func__
, ctx->version, 3)
518 __func__, ctx->version, GGUF_VERSION)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: this GGUF file is version %"
"u" " but this software only supports up to version %d\n", __func__
, ctx->version, 3)
;
519 ok = false;
520 }
521 } else {
522 ok = false;
523 }
524
525 if (ok && gr.read(n_tensors)) {
526 static_assert(sizeof(size_t) <= 8 && sizeof(gguf_tensor_info) >= 2, "int64_t insufficient for indexing");
527 if (n_tensors < 0 || n_tensors > int64_t(SIZE_MAX(18446744073709551615UL)/sizeof(gguf_tensor_info))) {
528 GGML_LOG_ERROR("%s: number of tensors is %" PRIi64 " but must be in [0, %zu]\n",ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: number of tensors is %"
"l" "i" " but must be in [0, %zu]\n", __func__, n_tensors, (
18446744073709551615UL)/sizeof(gguf_tensor_info))
529 __func__, n_tensors, SIZE_MAX/sizeof(gguf_tensor_info))ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: number of tensors is %"
"l" "i" " but must be in [0, %zu]\n", __func__, n_tensors, (
18446744073709551615UL)/sizeof(gguf_tensor_info))
;
530 ok = false;
531 }
532 } else {
533 ok = false;
534 }
535
536 if (ok && gr.read(n_kv)) {
537 static_assert(sizeof(size_t) <= 8 && sizeof(gguf_tensor_info) >= 2, "int64_t insufficient for indexing");
538 if (n_kv < 0 || n_kv > int64_t(SIZE_MAX(18446744073709551615UL)/sizeof(gguf_kv))) {
539 GGML_LOG_ERROR("%s: number of key value pairs is %" PRIi64 " but must be in [0, %zu]\n",ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: number of key value pairs is %"
"l" "i" " but must be in [0, %zu]\n", __func__, n_kv, (18446744073709551615UL
)/sizeof(gguf_kv))
540 __func__, n_kv, SIZE_MAX/sizeof(gguf_kv))ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: number of key value pairs is %"
"l" "i" " but must be in [0, %zu]\n", __func__, n_kv, (18446744073709551615UL
)/sizeof(gguf_kv))
;
541 ok = false;
542 }
543 } else {
544 ok = false;
545 }
546
547 if (!ok) {
548 GGML_LOG_ERROR("%s: failed to read header\n", __func__)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: failed to read header\n"
, __func__)
;
549 gguf_free(ctx);
550 return nullptr;
551 }
552
553 // KV pairs
554 {
555 for (int64_t i = 0; ok && i < n_kv; ++i) {
556 std::string key;
557 gguf_type type = gguf_type(-1);
558 bool is_array = false;
559 uint64_t n = 1;
560
561 tryif (true) {
562 ok = ok && gr.read(key);
563 } catch (std::length_error &)if (static const std::exception e, err, error, ex; false) {
564 GGML_LOG_ERROR("%s: encountered length_error while reading key %" PRIi64 "\n", __func__, i)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: encountered length_error while reading key %"
"l" "i" "\n", __func__, i)
;
565 ok = false;
566 } catch (std::bad_alloc &)if (static const std::exception e, err, error, ex; false) {
567 GGML_LOG_ERROR("%s: encountered bad_alloc error while reading key %" PRIi64 "\n", __func__, i)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: encountered bad_alloc error while reading key %"
"l" "i" "\n", __func__, i)
;
568 ok = false;
569 }
570 for (size_t j = 0; ok && j < ctx->kv.size(); ++j) {
571 if (key == ctx->kv[j].key) {
572 GGML_LOG_ERROR("%s: duplicate key '%s' for tensors %zu and %" PRIi64 " \n", __func__, key.c_str(), j, i)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: duplicate key '%s' for tensors %zu and %"
"l" "i" " \n", __func__, key.c_str(), j, i)
;
573 ok = false;
574 }
575 }
576 if (!ok) {
577 break;
578 }
579
580 ok = ok && gr.read(type);
581 if (type == GGUF_TYPE_ARRAY) {
582 is_array = true;
583 ok = ok && gr.read(type);
584 ok = ok && gr.read(n);
585 }
586 if (!ok) {
587 break;
588 }
589
590 switch (type) {
591 case GGUF_TYPE_UINT8: ok = ok && gguf_read_emplace_helper<uint8_t> (gr, ctx->kv, key, is_array, n); break;
592 case GGUF_TYPE_INT8: ok = ok && gguf_read_emplace_helper<int8_t> (gr, ctx->kv, key, is_array, n); break;
593 case GGUF_TYPE_UINT16: ok = ok && gguf_read_emplace_helper<uint16_t> (gr, ctx->kv, key, is_array, n); break;
594 case GGUF_TYPE_INT16: ok = ok && gguf_read_emplace_helper<int16_t> (gr, ctx->kv, key, is_array, n); break;
595 case GGUF_TYPE_UINT32: ok = ok && gguf_read_emplace_helper<uint32_t> (gr, ctx->kv, key, is_array, n); break;
596 case GGUF_TYPE_INT32: ok = ok && gguf_read_emplace_helper<int32_t> (gr, ctx->kv, key, is_array, n); break;
597 case GGUF_TYPE_FLOAT32: ok = ok && gguf_read_emplace_helper<float> (gr, ctx->kv, key, is_array, n); break;
598 case GGUF_TYPE_BOOL: ok = ok && gguf_read_emplace_helper<bool> (gr, ctx->kv, key, is_array, n); break;
599 case GGUF_TYPE_STRING: ok = ok && gguf_read_emplace_helper<std::string>(gr, ctx->kv, key, is_array, n); break;
600 case GGUF_TYPE_UINT64: ok = ok && gguf_read_emplace_helper<uint64_t> (gr, ctx->kv, key, is_array, n); break;
601 case GGUF_TYPE_INT64: ok = ok && gguf_read_emplace_helper<int64_t> (gr, ctx->kv, key, is_array, n); break;
602 case GGUF_TYPE_FLOAT64: ok = ok && gguf_read_emplace_helper<double> (gr, ctx->kv, key, is_array, n); break;
603 case GGUF_TYPE_ARRAY:
604 default:
605 {
606 GGML_LOG_ERROR("%s: key '%s' has invalid GGUF type %d\n", __func__, key.c_str(), type)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: key '%s' has invalid GGUF type %d\n"
, __func__, key.c_str(), type)
;
607 ok = false;
608 } break;
609 }
610 }
611
612 if (!ok) {
613 GGML_LOG_ERROR("%s: failed to read key-value pairs\n", __func__)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: failed to read key-value pairs\n"
, __func__)
;
614 gguf_free(ctx);
615 return nullptr;
616 }
617 GGML_ASSERT(int64_t(ctx->kv.size()) == n_kv)if (!(int64_t(ctx->kv.size()) == n_kv)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 617, "GGML_ASSERT(%s) failed", "int64_t(ctx->kv.size()) == n_kv"
)
;
618
619 const int alignment_idx = gguf_find_key(ctx, GGUF_KEY_GENERAL_ALIGNMENT"general.alignment");
620 ctx->alignment = alignment_idx == -1 ? GGUF_DEFAULT_ALIGNMENT32 : gguf_get_val_u32(ctx, alignment_idx);
621
622 if (ctx->alignment == 0 || (ctx->alignment & (ctx->alignment - 1)) != 0) {
623 GGML_LOG_ERROR("%s: alignment %zu is not a power of 2\n", __func__, ctx->alignment)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: alignment %zu is not a power of 2\n"
, __func__, ctx->alignment)
;
624 gguf_free(ctx);
625 return nullptr;
626 }
627 }
628
629 // read the tensor info
630 for (int64_t i = 0; ok && i < n_tensors; ++i) {
631 struct gguf_tensor_info info;
632
633 // tensor name
634 {
635 std::string name;
636 tryif (true) {
637 ok = ok && gr.read(name);
638 } catch (std::length_error &)if (static const std::exception e, err, error, ex; false) {
639 GGML_LOG_ERROR("%s: encountered length_error while reading tensor name %" PRIi64 "\n", __func__, i)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: encountered length_error while reading tensor name %"
"l" "i" "\n", __func__, i)
;
640 ok = false;
641 } catch (std::bad_alloc &)if (static const std::exception e, err, error, ex; false) {
642 GGML_LOG_ERROR("%s: encountered bad_alloc error while reading tensor name %" PRIi64 "\n", __func__, i)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: encountered bad_alloc error while reading tensor name %"
"l" "i" "\n", __func__, i)
;
643 ok = false;
644 }
645 if (name.length() >= GGML_MAX_NAME64) {
646 GGML_LOG_ERROR("%s: tensor name %" PRIi64 " is too long: %zu >= %d\n", __func__, i, name.length(), GGML_MAX_NAME)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: tensor name %" "l"
"i" " is too long: %zu >= %d\n", __func__, i, name.length
(), 64)
;
647 ok = false;
648 break;
649 }
650 ggml_set_name(&info.t, name.c_str());
651
652 // make sure there are no duplicate tensor names
653 for (int64_t j = 0; ok && j < i; ++j) {
654 if (strcmp(info.t.name, ctx->info[j].t.name) == 0) {
655 GGML_LOG_ERROR("%s: duplicate tensor name '%s' for tensors %" PRIi64 " and %" PRIi64 "\n", __func__, info.t.name, j, i)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: duplicate tensor name '%s' for tensors %"
"l" "i" " and %" "l" "i" "\n", __func__, info.t.name, j, i)
;
656 ok = false;
657 break;
658 }
659 }
660 }
661 if (!ok) {
662 break;
663 }
664
665 // tensor shape
666 {
667 uint32_t n_dims = 0;
668 ok = ok && gr.read(n_dims);
669 if (n_dims > GGML_MAX_DIMS4) {
670 GGML_LOG_ERROR("%s: tensor '%s' has invalid number of dimensions: %" PRIu32 " > %" PRIu32 "\n",ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: tensor '%s' has invalid number of dimensions: %"
"u" " > %" "u" "\n", __func__, info.t.name, n_dims, 4)
671 __func__, info.t.name, n_dims, GGML_MAX_DIMS)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: tensor '%s' has invalid number of dimensions: %"
"u" " > %" "u" "\n", __func__, info.t.name, n_dims, 4)
;
672 ok = false;
673 break;
674 }
675 for (uint32_t j = 0; ok && j < GGML_MAX_DIMS4; ++j) {
676 info.t.ne[j] = 1;
677 if (j < n_dims) {
678 ok = ok && gr.read(info.t.ne[j]);
679 }
680
681 // check that all ne are non-negative
682 if (info.t.ne[j] < 0) {
683 GGML_LOG_ERROR("%s: tensor '%s' dimension %" PRIu32 " has invalid number of elements: %" PRIi64 " < 0\n",ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: tensor '%s' dimension %"
"u" " has invalid number of elements: %" "l" "i" " < 0\n"
, __func__, info.t.name, j, info.t.ne[j])
684 __func__, info.t.name, j, info.t.ne[j])ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: tensor '%s' dimension %"
"u" " has invalid number of elements: %" "l" "i" " < 0\n"
, __func__, info.t.name, j, info.t.ne[j])
;
685 ok = false;
686 break;
687 }
688 }
689
690 // check that the total number of elements is representable
691 if (ok && ((INT64_MAX(9223372036854775807L)/info.t.ne[1] <= info.t.ne[0]) ||
692 (INT64_MAX(9223372036854775807L)/info.t.ne[2] <= info.t.ne[0]*info.t.ne[1]) ||
693 (INT64_MAX(9223372036854775807L)/info.t.ne[3] <= info.t.ne[0]*info.t.ne[1]*info.t.ne[2]))) {
694
695 GGML_LOG_ERROR("%s: total number of elements in tensor '%s' with shape "ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: total number of elements in tensor '%s' with shape "
"(%" "l" "i" ", %" "l" "i" ", %" "l" "i" ", %" "l" "i" ") is >= %"
"l" "i" "\n", __func__, info.t.name, info.t.ne[0], info.t.ne
[1], info.t.ne[2], info.t.ne[3], (9223372036854775807L))
696 "(%" PRIi64 ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 ") is >= %" PRIi64 "\n",ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: total number of elements in tensor '%s' with shape "
"(%" "l" "i" ", %" "l" "i" ", %" "l" "i" ", %" "l" "i" ") is >= %"
"l" "i" "\n", __func__, info.t.name, info.t.ne[0], info.t.ne
[1], info.t.ne[2], info.t.ne[3], (9223372036854775807L))
697 __func__, info.t.name, info.t.ne[0], info.t.ne[1], info.t.ne[2], info.t.ne[3], INT64_MAX)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: total number of elements in tensor '%s' with shape "
"(%" "l" "i" ", %" "l" "i" ", %" "l" "i" ", %" "l" "i" ") is >= %"
"l" "i" "\n", __func__, info.t.name, info.t.ne[0], info.t.ne
[1], info.t.ne[2], info.t.ne[3], (9223372036854775807L))
;
698 ok = false;
699 break;
700 }
701 }
702 if (!ok) {
703 break;
704 }
705
706 // tensor type
707 {
708 ok = ok && gr.read(info.t.type);
709
710 // check that tensor type is within defined range
711 if (info.t.type < 0 || info.t.type >= GGML_TYPE_COUNT) {
712 GGML_LOG_ERROR("%s: tensor '%s' has invalid ggml type %d. should be in [0, %d)\n",ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: tensor '%s' has invalid ggml type %d. should be in [0, %d)\n"
, __func__, info.t.name, info.t.type, GGML_TYPE_COUNT)
713 __func__, info.t.name, info.t.type, GGML_TYPE_COUNT)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: tensor '%s' has invalid ggml type %d. should be in [0, %d)\n"
, __func__, info.t.name, info.t.type, GGML_TYPE_COUNT)
;
714 ok = false;
715 break;
716 }
717 const size_t type_size = ggml_type_size(info.t.type);
718 const int64_t blck_size = ggml_blck_size(info.t.type);
719
720 // check that row size is divisible by block size
721 if (blck_size == 0 || info.t.ne[0] % blck_size != 0) {
722 GGML_LOG_ERROR("%s: tensor '%s' of type %d (%s) has %" PRId64 " elements per row, "ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: tensor '%s' of type %d (%s) has %"
"l" "d" " elements per row, " "not a multiple of block size (%"
"l" "d" ")\n", __func__, info.t.name, (int) info.t.type, ggml_type_name
(info.t.type), info.t.ne[0], blck_size)
723 "not a multiple of block size (%" PRId64 ")\n",ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: tensor '%s' of type %d (%s) has %"
"l" "d" " elements per row, " "not a multiple of block size (%"
"l" "d" ")\n", __func__, info.t.name, (int) info.t.type, ggml_type_name
(info.t.type), info.t.ne[0], blck_size)
724 __func__, info.t.name, (int) info.t.type, ggml_type_name(info.t.type), info.t.ne[0], blck_size)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: tensor '%s' of type %d (%s) has %"
"l" "d" " elements per row, " "not a multiple of block size (%"
"l" "d" ")\n", __func__, info.t.name, (int) info.t.type, ggml_type_name
(info.t.type), info.t.ne[0], blck_size)
;
725 ok = false;
726 break;
727 }
728
729 // check that the size of the tensor in bytes is representable
730 if (ok && uint64_t(ggml_nelements(&info.t)/ggml_blck_size(info.t.type)) > SIZE_MAX(18446744073709551615UL)/ggml_type_size(info.t.type)) {
731 GGML_LOG_ERROR("%s: tensor '%s' with shape (%" PRIi64 ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 ") has a size in bytes > %zu\n",ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: tensor '%s' with shape (%"
"l" "i" ", %" "l" "i" ", %" "l" "i" ", %" "l" "i" ") has a size in bytes > %zu\n"
, __func__, info.t.name, info.t.ne[0], info.t.ne[1], info.t.ne
[2], info.t.ne[3], (18446744073709551615UL))
732 __func__, info.t.name, info.t.ne[0], info.t.ne[1], info.t.ne[2], info.t.ne[3], SIZE_MAX)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: tensor '%s' with shape (%"
"l" "i" ", %" "l" "i" ", %" "l" "i" ", %" "l" "i" ") has a size in bytes > %zu\n"
, __func__, info.t.name, info.t.ne[0], info.t.ne[1], info.t.ne
[2], info.t.ne[3], (18446744073709551615UL))
;
733 ok = false;
734 break;
735 }
736
737 // calculate byte offsets given the tensor shape and type
738 info.t.nb[0] = type_size;
739 info.t.nb[1] = info.t.nb[0]*(info.t.ne[0]/blck_size);
740 for (int j = 2; j < GGML_MAX_DIMS4; ++j) {
741 info.t.nb[j] = info.t.nb[j - 1]*info.t.ne[j - 1];
742 }
743 }
744 if (!ok) {
745 break;
746 }
747
748 // tensor data offset within buffer
749 ok = ok && gr.read(info.offset);
750
751 ctx->info.push_back(info);
752 }
753
754 if (!ok) {
755 GGML_LOG_ERROR("%s: failed to read tensor info\n", __func__)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: failed to read tensor info\n"
, __func__)
;
756 gguf_free(ctx);
757 return nullptr;
758 }
759 GGML_ASSERT(int64_t(ctx->info.size()) == n_tensors)if (!(int64_t(ctx->info.size()) == n_tensors)) ggml_abort(
"/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 759, "GGML_ASSERT(%s) failed", "int64_t(ctx->info.size()) == n_tensors"
)
;
760
761 // we require the data section to be aligned, so take into account any padding
762 if (n_tensors > 0 && !gr.seek(GGML_PAD(gr.tell(), ctx->alignment)(((gr.tell()) + (ctx->alignment) - 1) & ~((ctx->alignment
) - 1))
)) {
763 GGML_LOG_ERROR("%s: failed to seek to beginning of data section\n", __func__)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: failed to seek to beginning of data section\n"
, __func__)
;
764 gguf_free(ctx);
765 return nullptr;
766 }
767
768 // store the current file offset - this is where the data section starts
769 ctx->offset = gr.tell();
770
771 // compute the total size of the data section, taking into account the alignment
772 {
773 ctx->size = 0;
774 for (size_t i = 0; i < ctx->info.size(); ++i) {
775 const gguf_tensor_info & ti = ctx->info[i];
776 if (ti.offset != ctx->size) {
777 GGML_LOG_ERROR("%s: tensor '%s' has offset %" PRIu64 ", expected %zu\n",ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: tensor '%s' has offset %"
"l" "u" ", expected %zu\n", __func__, ti.t.name, ti.offset, ctx
->size)
778 __func__, ti.t.name, ti.offset, ctx->size)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: tensor '%s' has offset %"
"l" "u" ", expected %zu\n", __func__, ti.t.name, ti.offset, ctx
->size)
;
779 GGML_LOG_ERROR("%s: failed to read tensor data\n", __func__)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: failed to read tensor data\n"
, __func__)
;
780 gguf_free(ctx);
781 return nullptr;
782 }
783 size_t padded_size = GGML_PAD(ggml_nbytes(&ti.t), ctx->alignment)(((ggml_nbytes(&ti.t)) + (ctx->alignment) - 1) & ~
((ctx->alignment) - 1))
;
784 if (SIZE_MAX(18446744073709551615UL) - ctx->size < padded_size) {
785 GGML_LOG_ERROR("%s: tensor '%s' size overflow, cannot accumulate size %zu + %zu\n",ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: tensor '%s' size overflow, cannot accumulate size %zu + %zu\n"
, __func__, ti.t.name, ctx->size, padded_size)
786 __func__, ti.t.name, ctx->size, padded_size)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: tensor '%s' size overflow, cannot accumulate size %zu + %zu\n"
, __func__, ti.t.name, ctx->size, padded_size)
;
787 gguf_free(ctx);
788 return nullptr;
789 }
790 ctx->size += padded_size;
791 }
792 }
793
794 // load the tensor data only if requested
795 if (params.ctx != nullptr) {
796 // if the provided gguf_context is no_alloc, then we create "empty" tensors and do not read the binary blob
797 // otherwise, we load the binary blob into the created ggml_context as well, and point the "data" members of
798 // the ggml_tensor structs to the appropriate locations in the binary blob
799
800 // compute the exact size needed for the new ggml_context
801 size_t mem_size = 0;
802 if (params.no_alloc) {
803 if (n_tensors != 0 && SIZE_MAX(18446744073709551615UL) / n_tensors < ggml_tensor_overhead()) {
804 GGML_LOG_ERROR("%s: memory size overflow while allocating ggml context\n", __func__)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: memory size overflow while allocating ggml context\n"
, __func__)
;
805 gguf_free(ctx);
806 return nullptr;
807 }
808
809 const size_t overhead = n_tensors * ggml_tensor_overhead();
810
811 mem_size = overhead;
812 } else {
813 if ((n_tensors + 1) != 0 && SIZE_MAX(18446744073709551615UL) / (n_tensors + 1) < ggml_tensor_overhead()) {
814 GGML_LOG_ERROR("%s: memory size overflow while allocating ggml context\n", __func__)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: memory size overflow while allocating ggml context\n"
, __func__)
;
815 gguf_free(ctx);
816 return nullptr;
817 }
818
819 const size_t overhead = (n_tensors + 1) * ggml_tensor_overhead();
820
821 if (SIZE_MAX(18446744073709551615UL) - overhead < ctx->size) {
822 GGML_LOG_ERROR("%s: memory size overflow while allocating ggml context\n", __func__)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: memory size overflow while allocating ggml context\n"
, __func__)
;
823 gguf_free(ctx);
824 return nullptr;
825 }
826
827 mem_size = overhead + ctx->size;
828 }
829
830 struct ggml_init_params pdata = {
831 /*mem_size =*/ mem_size,
832 /*mem_buffer =*/ nullptr,
833 /*no_alloc =*/ params.no_alloc,
834 };
835
836 *params.ctx = ggml_init(pdata);
837 if (*params.ctx == nullptr) {
838 GGML_LOG_ERROR("%s: failed to initialize ggml context for storing tensors\n", __func__)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: failed to initialize ggml context for storing tensors\n"
, __func__)
;
839 gguf_free(ctx);
840 return nullptr;
841 }
842
843 struct ggml_context * ctx_data = *params.ctx;
844
845 struct ggml_tensor * data = nullptr;
846
847 if (!params.no_alloc) {
848 data = ggml_new_tensor_1d(ctx_data, GGML_TYPE_I8, ctx->size);
849
850 ok = ok && data != nullptr;
851
852 if (ok) {
853 ggml_set_name(data, "GGUF tensor data binary blob");
854 }
855
856 // read the binary blob with the tensor data
857 ok = ok && gr.read(data->data, ctx->size);
858
859 if (!ok) {
860 GGML_LOG_ERROR("%s: failed to read tensor data binary blob\n", __func__)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: failed to read tensor data binary blob\n"
, __func__)
;
861 ggml_free(ctx_data);
862 *params.ctx = nullptr;
863 gguf_free(ctx);
864 return nullptr;
865 }
866
867 ctx->data = data->data;
868 }
869
870 ggml_set_no_alloc(ctx_data, true);
871
872 // create the tensors
873 for (size_t i = 0; i < ctx->info.size(); ++i) {
874 const struct gguf_tensor_info & info = ctx->info[i];
875
876 struct ggml_tensor * cur = ggml_new_tensor(ctx_data, info.t.type, GGML_MAX_DIMS4, info.t.ne);
877
878 ok = ok && cur != nullptr;
879
880 if (!ok) {
881 break;
882 }
883
884 ggml_set_name(cur, info.t.name);
885
886 // point the data member to the appropriate location in the binary blob using the tensor info
887 if (!params.no_alloc) {
888 cur->data = (char *) data->data + info.offset;
889 }
890 }
891
892 if (!ok) {
893 GGML_LOG_ERROR("%s: failed to create tensors\n", __func__)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: failed to create tensors\n"
, __func__)
;
894 ggml_free(ctx_data);
895 *params.ctx = nullptr;
896 gguf_free(ctx);
897 return nullptr;
898 }
899
900 ggml_set_no_alloc(ctx_data, params.no_alloc);
901 }
902
903 return ctx;
904}
905
906struct gguf_context * gguf_init_from_callback(gguf_reader_callback_t callback, void * userdata, size_t max_chunk_read, uint64_t max_expected_size, struct gguf_init_params params) {
907 if (callback == nullptr) {
908 return nullptr;
909 }
910
911 const struct gguf_reader gr(callback, userdata, max_chunk_read == 0 ? SIZE_MAX(18446744073709551615UL) : max_chunk_read, 0, max_expected_size);
912 return gguf_init_from_reader(gr, params);
913}
914
915struct gguf_file_reader {
916 FILE * file;
917 uint64_t offset;
918};
919
920static size_t gguf_file_reader_callback(void * userdata, void * output, uint64_t offset, size_t len) {
921 GGML_ASSERT(len > 0)if (!(len > 0)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 921, "GGML_ASSERT(%s) failed", "len > 0")
;
922
923 gguf_file_reader & reader = *static_cast<gguf_file_reader *>(userdata);
924
925 if (reader.offset != offset) {
926 if (offset > INT64_MAX(9223372036854775807L) || gguf_fseekfseeko(reader.file, static_cast<int64_t>(offset), SEEK_SET0) != 0) {
927 return 0;
928 }
929
930 reader.offset = offset;
931 }
932
933 const size_t nread = fread(static_cast<uint8_t *>(output), 1, len, reader.file);
934 reader.offset += nread;
935 return nread;
936}
937
938struct gguf_context * gguf_init_from_file_ptr(FILE * file, struct gguf_init_params params) {
939 if (!file) {
940 return nullptr;
941 }
942
943 const int64_t cur = gguf_ftellftello(file);
944 if (cur < 0) {
945 return nullptr;
946 }
947
948 gguf_file_reader reader = {
949 /*.file = */ file,
950 /*.offset = */ static_cast<uint64_t>(cur),
951 };
952 const struct gguf_reader gr(gguf_file_reader_callback, &reader, SIZE_MAX(18446744073709551615UL), reader.offset, gguf_reader::file_remain(file));
953 return gguf_init_from_reader(gr, params);
954}
955
956struct gguf_buffer_reader {
957 const uint8_t * data;
958 size_t size;
959};
960
961static size_t gguf_buffer_reader_callback(void * userdata, void * output, uint64_t offset, size_t len) {
962 GGML_ASSERT(len > 0)if (!(len > 0)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 962, "GGML_ASSERT(%s) failed", "len > 0")
;
963
964 const gguf_buffer_reader & reader = *static_cast<gguf_buffer_reader *>(userdata);
965
966 if (offset > reader.size || len > reader.size - offset) {
967 return 0;
968 }
969
970 const size_t data_offset = static_cast<size_t>(offset);
971 const size_t nread = std::min(len, reader.size - data_offset);
972 memcpy(static_cast<uint8_t *>(output), reader.data + data_offset, nread);
973 return nread;
974}
975
976struct gguf_context * gguf_init_from_buffer(const void * data, size_t size, struct gguf_init_params params) {
977 if (data == nullptr || size == 0) {
978 return nullptr;
979 }
980
981 gguf_buffer_reader reader = {
982 /*.data = */ static_cast<const uint8_t *>(data),
983 /*.size = */ size,
984 };
985 const struct gguf_reader gr(gguf_buffer_reader_callback, &reader, SIZE_MAX(18446744073709551615UL), 0, size);
986 return gguf_init_from_reader(gr, params);
987}
988
989struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_params params) {
990 FILE * file = ggml_fopen(fname, "rb");
991
992 if (!file) {
993 GGML_LOG_ERROR("%s: failed to open GGUF file '%s' (%s)\n", __func__, fname, strerror(errno))ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: failed to open GGUF file '%s' (%s)\n"
, __func__, fname, strerror((*__errno_location ())))
;
994 return nullptr;
995 }
996
997 struct gguf_context * result = gguf_init_from_file_ptr(file, params);
998 fclose(file);
999 return result;
1000}
1001
1002void gguf_free(struct gguf_context * ctx) {
1003 if (ctx == nullptr) {
1004 return;
1005 }
1006 delete ctx;
1007}
1008
1009const char * gguf_type_name(enum gguf_type type) {
1010 const auto & GGUF_TYPE_NAME = get_gguf_type_name_map();
1011 auto it = GGUF_TYPE_NAME.find(type);
1012 return it == GGUF_TYPE_NAME.end() ? nullptr : it->second;
1013}
1014
1015uint32_t gguf_get_version(const struct gguf_context * ctx) {
1016 return ctx->version;
1017}
1018
1019size_t gguf_get_alignment(const struct gguf_context * ctx) {
1020 return ctx->alignment;
1021}
1022
1023size_t gguf_get_data_offset(const struct gguf_context * ctx) {
1024 return ctx->offset;
1025}
1026
1027int64_t gguf_get_n_kv(const struct gguf_context * ctx) {
1028 return ctx->kv.size();
1029}
1030
1031int64_t gguf_find_key(const struct gguf_context * ctx, const char * key) {
1032 // return -1 if key not found
1033 int64_t keyfound = -1;
1034
1035 const int64_t n_kv = gguf_get_n_kv(ctx);
1036
1037 for (int64_t i = 0; i < n_kv; ++i) {
1038 if (strcmp(key, gguf_get_key(ctx, i)) == 0) {
1039 keyfound = i;
1040 break;
1041 }
1042 }
1043
1044 return keyfound;
1045}
1046
1047const char * gguf_get_key(const struct gguf_context * ctx, int64_t key_id) {
1048 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1048, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1049 return ctx->kv[key_id].get_key().c_str();
1050}
1051
1052enum gguf_type gguf_get_kv_type(const struct gguf_context * ctx, int64_t key_id) {
1053 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1053, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1054 return ctx->kv[key_id].is_array ? GGUF_TYPE_ARRAY : ctx->kv[key_id].get_type();
1055}
1056
1057enum gguf_type gguf_get_arr_type(const struct gguf_context * ctx, int64_t key_id) {
1058 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1058, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1059 GGML_ASSERT(ctx->kv[key_id].is_array)if (!(ctx->kv[key_id].is_array)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1059, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].is_array"
)
;
1060 return ctx->kv[key_id].get_type();
1061}
1062
1063const void * gguf_get_arr_data(const struct gguf_context * ctx, int64_t key_id) {
1064 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1064, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1065 GGML_ASSERT(ctx->kv[key_id].get_type() != GGUF_TYPE_STRING)if (!(ctx->kv[key_id].get_type() != GGUF_TYPE_STRING)) ggml_abort
("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1065, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].get_type() != GGUF_TYPE_STRING"
)
;
1066 return ctx->kv[key_id].data.data();
1067}
1068
1069const char * gguf_get_arr_str(const struct gguf_context * ctx, int64_t key_id, size_t i) {
1070 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1070, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1071 GGML_ASSERT(ctx->kv[key_id].get_type() == GGUF_TYPE_STRING)if (!(ctx->kv[key_id].get_type() == GGUF_TYPE_STRING)) ggml_abort
("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1071, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].get_type() == GGUF_TYPE_STRING"
)
;
1072 return ctx->kv[key_id].data_string[i].c_str();
1073}
1074
1075size_t gguf_get_arr_n(const struct gguf_context * ctx, int64_t key_id) {
1076 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1076, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1077
1078 if (ctx->kv[key_id].type == GGUF_TYPE_STRING) {
1079 return ctx->kv[key_id].data_string.size();
1080 }
1081
1082 const size_t type_size = gguf_type_size(ctx->kv[key_id].type);
1083 GGML_ASSERT(ctx->kv[key_id].data.size() % type_size == 0)if (!(ctx->kv[key_id].data.size() % type_size == 0)) ggml_abort
("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1083, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].data.size() % type_size == 0"
)
;
1084 return ctx->kv[key_id].data.size() / type_size;
1085}
1086
1087uint8_t gguf_get_val_u8(const struct gguf_context * ctx, int64_t key_id) {
1088 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1088, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1089 GGML_ASSERT(ctx->kv[key_id].get_ne() == 1)if (!(ctx->kv[key_id].get_ne() == 1)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1089, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].get_ne() == 1"
)
;
1090 return ctx->kv[key_id].get_val<uint8_t>();
1091}
1092
1093int8_t gguf_get_val_i8(const struct gguf_context * ctx, int64_t key_id) {
1094 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1094, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1095 GGML_ASSERT(ctx->kv[key_id].get_ne() == 1)if (!(ctx->kv[key_id].get_ne() == 1)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1095, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].get_ne() == 1"
)
;
1096 return ctx->kv[key_id].get_val<int8_t>();
1097}
1098
1099uint16_t gguf_get_val_u16(const struct gguf_context * ctx, int64_t key_id) {
1100 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1100, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1101 GGML_ASSERT(ctx->kv[key_id].get_ne() == 1)if (!(ctx->kv[key_id].get_ne() == 1)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1101, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].get_ne() == 1"
)
;
1102 return ctx->kv[key_id].get_val<uint16_t>();
1103}
1104
1105int16_t gguf_get_val_i16(const struct gguf_context * ctx, int64_t key_id) {
1106 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1106, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1107 GGML_ASSERT(ctx->kv[key_id].get_ne() == 1)if (!(ctx->kv[key_id].get_ne() == 1)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1107, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].get_ne() == 1"
)
;
1108 return ctx->kv[key_id].get_val<int16_t>();
1109}
1110
1111uint32_t gguf_get_val_u32(const struct gguf_context * ctx, int64_t key_id) {
1112 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1112, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1113 GGML_ASSERT(ctx->kv[key_id].get_ne() == 1)if (!(ctx->kv[key_id].get_ne() == 1)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1113, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].get_ne() == 1"
)
;
1114 return ctx->kv[key_id].get_val<uint32_t>();
1115}
1116
1117int32_t gguf_get_val_i32(const struct gguf_context * ctx, int64_t key_id) {
1118 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1118, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1119 GGML_ASSERT(ctx->kv[key_id].get_ne() == 1)if (!(ctx->kv[key_id].get_ne() == 1)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1119, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].get_ne() == 1"
)
;
1120 return ctx->kv[key_id].get_val<int32_t>();
1121}
1122
1123float gguf_get_val_f32(const struct gguf_context * ctx, int64_t key_id) {
1124 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1124, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1125 GGML_ASSERT(ctx->kv[key_id].get_ne() == 1)if (!(ctx->kv[key_id].get_ne() == 1)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1125, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].get_ne() == 1"
)
;
1126 return ctx->kv[key_id].get_val<float>();
1127}
1128
1129uint64_t gguf_get_val_u64(const struct gguf_context * ctx, int64_t key_id) {
1130 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1130, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1131 GGML_ASSERT(ctx->kv[key_id].get_ne() == 1)if (!(ctx->kv[key_id].get_ne() == 1)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1131, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].get_ne() == 1"
)
;
1132 return ctx->kv[key_id].get_val<uint64_t>();
1133}
1134
1135int64_t gguf_get_val_i64(const struct gguf_context * ctx, int64_t key_id) {
1136 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1136, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1137 GGML_ASSERT(ctx->kv[key_id].get_ne() == 1)if (!(ctx->kv[key_id].get_ne() == 1)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1137, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].get_ne() == 1"
)
;
1138 return ctx->kv[key_id].get_val<int64_t>();
1139}
1140
1141double gguf_get_val_f64(const struct gguf_context * ctx, int64_t key_id) {
1142 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1142, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1143 GGML_ASSERT(ctx->kv[key_id].get_ne() == 1)if (!(ctx->kv[key_id].get_ne() == 1)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1143, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].get_ne() == 1"
)
;
1144 return ctx->kv[key_id].get_val<double>();
1145}
1146
1147bool gguf_get_val_bool(const struct gguf_context * ctx, int64_t key_id) {
1148 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1148, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1149 GGML_ASSERT(ctx->kv[key_id].get_ne() == 1)if (!(ctx->kv[key_id].get_ne() == 1)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1149, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].get_ne() == 1"
)
;
1150 return ctx->kv[key_id].get_val<bool>();
1151}
1152
1153const char * gguf_get_val_str(const struct gguf_context * ctx, int64_t key_id) {
1154 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1154, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1155 GGML_ASSERT(ctx->kv[key_id].get_ne() == 1)if (!(ctx->kv[key_id].get_ne() == 1)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1155, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].get_ne() == 1"
)
;
1156 return ctx->kv[key_id].get_val<std::string>().c_str();
1157}
1158
1159const void * gguf_get_val_data(const struct gguf_context * ctx, int64_t key_id) {
1160 GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx))if (!(key_id >= 0 && key_id < gguf_get_n_kv(ctx
))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1160, "GGML_ASSERT(%s) failed", "key_id >= 0 && key_id < gguf_get_n_kv(ctx)"
)
;
1161 GGML_ASSERT(ctx->kv[key_id].get_ne() == 1)if (!(ctx->kv[key_id].get_ne() == 1)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1161, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].get_ne() == 1"
)
;
1162 GGML_ASSERT(ctx->kv[key_id].get_type() != GGUF_TYPE_STRING)if (!(ctx->kv[key_id].get_type() != GGUF_TYPE_STRING)) ggml_abort
("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1162, "GGML_ASSERT(%s) failed", "ctx->kv[key_id].get_type() != GGUF_TYPE_STRING"
)
;
1163 return ctx->kv[key_id].data.data();
1164}
1165
1166int64_t gguf_get_n_tensors(const struct gguf_context * ctx) {
1167 return ctx->info.size();
1168}
1169
1170int64_t gguf_find_tensor(const struct gguf_context * ctx, const char * name) {
1171 // return -1 if tensor not found
1172 int64_t tensor_id = -1;
1173
1174 const int64_t n_tensors = gguf_get_n_tensors(ctx);
1175
1176 for (int64_t i = 0; i < n_tensors; ++i) {
1177 if (strcmp(name, gguf_get_tensor_name(ctx, i)) == 0) {
1178 tensor_id = i;
1179 break;
1180 }
1181 }
1182
1183 return tensor_id;
1184}
1185
1186size_t gguf_get_tensor_offset(const struct gguf_context * ctx, int64_t tensor_id) {
1187 GGML_ASSERT(tensor_id >= 0 && tensor_id < gguf_get_n_tensors(ctx))if (!(tensor_id >= 0 && tensor_id < gguf_get_n_tensors
(ctx))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1187, "GGML_ASSERT(%s) failed", "tensor_id >= 0 && tensor_id < gguf_get_n_tensors(ctx)"
)
;
1188 return ctx->info[tensor_id].offset;
1189}
1190
1191const char * gguf_get_tensor_name(const struct gguf_context * ctx, int64_t tensor_id) {
1192 GGML_ASSERT(tensor_id >= 0 && tensor_id < gguf_get_n_tensors(ctx))if (!(tensor_id >= 0 && tensor_id < gguf_get_n_tensors
(ctx))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1192, "GGML_ASSERT(%s) failed", "tensor_id >= 0 && tensor_id < gguf_get_n_tensors(ctx)"
)
;
1193 return ctx->info[tensor_id].t.name;
1194}
1195
1196enum ggml_type gguf_get_tensor_type(const struct gguf_context * ctx, int64_t tensor_id) {
1197 GGML_ASSERT(tensor_id >= 0 && tensor_id < gguf_get_n_tensors(ctx))if (!(tensor_id >= 0 && tensor_id < gguf_get_n_tensors
(ctx))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1197, "GGML_ASSERT(%s) failed", "tensor_id >= 0 && tensor_id < gguf_get_n_tensors(ctx)"
)
;
1198 return ctx->info[tensor_id].t.type;
1199}
1200
1201size_t gguf_get_tensor_size(const struct gguf_context * ctx, int64_t tensor_id) {
1202 GGML_ASSERT(tensor_id >= 0 && tensor_id < gguf_get_n_tensors(ctx))if (!(tensor_id >= 0 && tensor_id < gguf_get_n_tensors
(ctx))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1202, "GGML_ASSERT(%s) failed", "tensor_id >= 0 && tensor_id < gguf_get_n_tensors(ctx)"
)
;
1203 return ggml_nbytes(&ctx->info[tensor_id].t);
1204}
1205
1206int64_t gguf_remove_key(struct gguf_context * ctx, const char * key) {
1207 const int64_t key_id = gguf_find_key(ctx, key);
1208 if (key_id >= 0) {
1209 ctx->kv.erase(ctx->kv.begin() + key_id);
1210 }
1211 return key_id;
1212}
1213
1214template<typename T>
1215static void gguf_check_reserved_keys(const std::string & key, const T val) {
1216 if (key == GGUF_KEY_GENERAL_ALIGNMENT"general.alignment") {
1217 if constexpr (std::is_same<T, uint32_t>::value) {
1218 GGML_ASSERT(val > 0 && (val & (val - 1)) == 0 && GGUF_KEY_GENERAL_ALIGNMENT " must be power of 2")if (!(val > 0 && (val & (val - 1)) == 0 &&
"general.alignment" " must be power of 2")) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1218, "GGML_ASSERT(%s) failed", "val > 0 && (val & (val - 1)) == 0 && GGUF_KEY_GENERAL_ALIGNMENT \" must be power of 2\""
)
;
1219 } else {
1220 GGML_UNUSED(val)(void)(val);
1221 GGML_ABORT(GGUF_KEY_GENERAL_ALIGNMENT " must be type u32")ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1221, "general.alignment" " must be type u32")
;
1222 }
1223 }
1224}
1225
1226void gguf_set_val_u8(struct gguf_context * ctx, const char * key, uint8_t val) {
1227 gguf_check_reserved_keys(key, val);
1228 gguf_remove_key(ctx, key);
1229 ctx->kv.emplace_back(key, val);
1230}
1231
1232void gguf_set_val_i8(struct gguf_context * ctx, const char * key, int8_t val) {
1233 gguf_check_reserved_keys(key, val);
1234 gguf_remove_key(ctx, key);
1235 ctx->kv.emplace_back(key, val);
1236}
1237
1238void gguf_set_val_u16(struct gguf_context * ctx, const char * key, uint16_t val) {
1239 gguf_check_reserved_keys(key, val);
1240 gguf_remove_key(ctx, key);
1241 ctx->kv.emplace_back(key, val);
1242}
1243
1244void gguf_set_val_i16(struct gguf_context * ctx, const char * key, int16_t val) {
1245 gguf_check_reserved_keys(key, val);
1246 gguf_remove_key(ctx, key);
1247 ctx->kv.emplace_back(key, val);
1248}
1249
1250void gguf_set_val_u32(struct gguf_context * ctx, const char * key, uint32_t val) {
1251 gguf_check_reserved_keys(key, val);
1252 gguf_remove_key(ctx, key);
1253 ctx->kv.emplace_back(key, val);
1254}
1255
1256void gguf_set_val_i32(struct gguf_context * ctx, const char * key, int32_t val) {
1257 gguf_check_reserved_keys(key, val);
1258 gguf_remove_key(ctx, key);
1259 ctx->kv.emplace_back(key, val);
1260}
1261
1262void gguf_set_val_f32(struct gguf_context * ctx, const char * key, float val) {
1263 gguf_check_reserved_keys(key, val);
1264 gguf_remove_key(ctx, key);
1265 ctx->kv.emplace_back(key, val);
1266}
1267
1268void gguf_set_val_u64(struct gguf_context * ctx, const char * key, uint64_t val) {
1269 gguf_check_reserved_keys(key, val);
1270 gguf_remove_key(ctx, key);
1271 ctx->kv.emplace_back(key, val);
1272}
1273
1274void gguf_set_val_i64(struct gguf_context * ctx, const char * key, int64_t val) {
1275 gguf_check_reserved_keys(key, val);
1276 gguf_remove_key(ctx, key);
1277 ctx->kv.emplace_back(key, val);
1278}
1279
1280void gguf_set_val_f64(struct gguf_context * ctx, const char * key, double val) {
1281 gguf_check_reserved_keys(key, val);
1282 gguf_remove_key(ctx, key);
1283 ctx->kv.emplace_back(key, val);
1284}
1285
1286void gguf_set_val_bool(struct gguf_context * ctx, const char * key, bool val) {
1287 gguf_check_reserved_keys(key, val);
1288 gguf_remove_key(ctx, key);
1289 ctx->kv.emplace_back(key, val);
1290}
1291
1292void gguf_set_val_str(struct gguf_context * ctx, const char * key, const char * val) {
1293 gguf_check_reserved_keys(key, val);
1294 gguf_remove_key(ctx, key);
1295 ctx->kv.emplace_back(key, std::string(val));
1296}
1297
1298void gguf_set_arr_data(struct gguf_context * ctx, const char * key, enum gguf_type type, const void * data, size_t n) {
1299 gguf_check_reserved_keys(key, data);
1300 gguf_remove_key(ctx, key);
1301
1302 const size_t nbytes = n*gguf_type_size(type);
1303 std::vector<int8_t> tmp(nbytes);
1304 if (!tmp.empty()) {
1305 memcpy(tmp.data(), data, nbytes);
1306 }
1307 ctx->kv.emplace_back(key, tmp);
1308 ctx->kv.back().cast(type);
1309}
1310
1311void gguf_set_arr_str(struct gguf_context * ctx, const char * key, const char ** data, size_t n) {
1312 gguf_check_reserved_keys(key, data);
1313 gguf_remove_key(ctx, key);
1314
1315 std::vector<std::string> tmp(n);
1316 for (size_t i = 0; i < n; ++i) {
1317 tmp[i] = data[i];
1318 }
1319 ctx->kv.emplace_back(key, tmp);
1320}
1321
1322// set or add KV pairs from another context
1323void gguf_set_kv(struct gguf_context * ctx, const struct gguf_context * src) {
1324 const int64_t n_kv = gguf_get_n_kv(src);
1325 for (int64_t i = 0; i < n_kv; ++i) {
1
Assuming 'i' is < 'n_kv'
2
Loop condition is true. Entering loop body
1326 const struct gguf_kv & kv = src->kv[i];
1327
1328 if (!kv.is_array) {
3
Assuming field 'is_array' is false
4
Taking true branch
1329 switch (kv.get_type()) {
5
Control jumps to 'case GGUF_TYPE_UINT8:' at line 1330
1330 case GGUF_TYPE_UINT8: gguf_set_val_u8 (ctx, kv.get_key().c_str(), kv.get_val<uint8_t>()); break;
6
Calling 'gguf_kv::get_val'
1331 case GGUF_TYPE_INT8: gguf_set_val_i8 (ctx, kv.get_key().c_str(), kv.get_val<int8_t>()); break;
1332 case GGUF_TYPE_UINT16: gguf_set_val_u16 (ctx, kv.get_key().c_str(), kv.get_val<uint16_t>()); break;
1333 case GGUF_TYPE_INT16: gguf_set_val_i16 (ctx, kv.get_key().c_str(), kv.get_val<int16_t>()); break;
1334 case GGUF_TYPE_UINT32: gguf_set_val_u32 (ctx, kv.get_key().c_str(), kv.get_val<uint32_t>()); break;
1335 case GGUF_TYPE_INT32: gguf_set_val_i32 (ctx, kv.get_key().c_str(), kv.get_val<int32_t>()); break;
1336 case GGUF_TYPE_FLOAT32: gguf_set_val_f32 (ctx, kv.get_key().c_str(), kv.get_val<float>()); break;
1337 case GGUF_TYPE_UINT64: gguf_set_val_u64 (ctx, kv.get_key().c_str(), kv.get_val<uint64_t>()); break;
1338 case GGUF_TYPE_INT64: gguf_set_val_i64 (ctx, kv.get_key().c_str(), kv.get_val<int64_t>()); break;
1339 case GGUF_TYPE_FLOAT64: gguf_set_val_f64 (ctx, kv.get_key().c_str(), kv.get_val<double>()); break;
1340 case GGUF_TYPE_BOOL: gguf_set_val_bool(ctx, kv.get_key().c_str(), kv.get_val<bool>()); break;
1341 case GGUF_TYPE_STRING: gguf_set_val_str (ctx, kv.get_key().c_str(), kv.get_val<std::string>().c_str()); break;
1342 case GGUF_TYPE_ARRAY:
1343 default: GGML_ABORT("invalid type")ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1343, "invalid type")
;
1344 }
1345 continue;
1346 }
1347
1348 const size_t ne = kv.get_ne();
1349
1350 switch (kv.get_type()) {
1351 case GGUF_TYPE_UINT8:
1352 case GGUF_TYPE_INT8:
1353 case GGUF_TYPE_UINT16:
1354 case GGUF_TYPE_INT16:
1355 case GGUF_TYPE_UINT32:
1356 case GGUF_TYPE_INT32:
1357 case GGUF_TYPE_FLOAT32:
1358 case GGUF_TYPE_UINT64:
1359 case GGUF_TYPE_INT64:
1360 case GGUF_TYPE_FLOAT64:
1361 case GGUF_TYPE_BOOL: {
1362 gguf_set_arr_data(ctx, kv.get_key().c_str(), kv.get_type(), kv.data.data(), ne);
1363 } break;
1364 case GGUF_TYPE_STRING: {
1365 std::vector<const char *> tmp(ne);
1366 for (size_t j = 0; j < ne; ++j) {
1367 tmp[j] = kv.data_string[j].c_str();
1368 }
1369 gguf_set_arr_str(ctx, kv.get_key().c_str(), tmp.data(), ne);
1370 } break;
1371 case GGUF_TYPE_ARRAY:
1372 default: GGML_ABORT("invalid type")ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1372, "invalid type")
;
1373 }
1374 }
1375}
1376
1377void gguf_add_tensor(
1378 struct gguf_context * ctx,
1379 const struct ggml_tensor * tensor) {
1380 GGML_ASSERT(tensor)if (!(tensor)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1380, "GGML_ASSERT(%s) failed", "tensor")
;
1381 if (gguf_find_tensor(ctx, tensor->name) != -1) {
1382 GGML_ABORT("duplicate tensor name: %s", tensor->name)ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1382, "duplicate tensor name: %s", tensor->name)
;
1383 }
1384
1385 struct gguf_tensor_info ti;
1386 ti.t = *tensor;
1387 ti.offset = ctx->info.empty() ? 0 :
1388 ctx->info.back().offset + GGML_PAD(ggml_nbytes(&ctx->info.back().t), ctx->alignment)(((ggml_nbytes(&ctx->info.back().t)) + (ctx->alignment
) - 1) & ~((ctx->alignment) - 1))
;
1389 ctx->info.push_back(ti);
1390}
1391
1392void gguf_set_tensor_type(struct gguf_context * ctx, const char * name, enum ggml_type type) {
1393 const int64_t tensor_id = gguf_find_tensor(ctx, name);
1394 if (tensor_id < 0) {
1395 GGML_ABORT("tensor not found: %s", name)ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1395, "tensor not found: %s", name)
;
1396 }
1397 struct ggml_tensor * tensor = &ctx->info[tensor_id].t;
1398 const size_t type_size = ggml_type_size(type);
1399 const int64_t blck_size = ggml_blck_size(type);
1400
1401 tensor->type = type;
1402 GGML_ASSERT(tensor->ne[0] % blck_size == 0 && "tensor row size not divisible by block size of new type")if (!(tensor->ne[0] % blck_size == 0 && "tensor row size not divisible by block size of new type"
)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1402, "GGML_ASSERT(%s) failed", "tensor->ne[0] % blck_size == 0 && \"tensor row size not divisible by block size of new type\""
)
;
1403
1404 tensor->nb[0] = type_size;
1405 tensor->nb[1] = tensor->nb[0]*(tensor->ne[0]/blck_size);
1406 for (int i = 2; i < GGML_MAX_DIMS4; i++) {
1407 tensor->nb[i] = tensor->nb[i - 1]*tensor->ne[i - 1];
1408 }
1409
1410 // update offsets
1411 const int64_t n_tensors = gguf_get_n_tensors(ctx);
1412 for (int64_t i = tensor_id + 1; i < n_tensors; ++i) {
1413 ctx->info[i].offset = ctx->info[i - 1].offset + GGML_PAD(ggml_nbytes(&ctx->info[i - 1].t), ctx->alignment)(((ggml_nbytes(&ctx->info[i - 1].t)) + (ctx->alignment
) - 1) & ~((ctx->alignment) - 1))
;
1414 }
1415}
1416
1417void gguf_set_tensor_data(struct gguf_context * ctx, const char * name, const void * data) {
1418 const int64_t tensor_id = gguf_find_tensor(ctx, name);
1419 if (tensor_id < 0) {
1420 GGML_ABORT("tensor not found: %s", name)ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1420, "tensor not found: %s", name)
;
1421 }
1422
1423 ctx->info[tensor_id].t.data = (void *)(uintptr_t)data; // double cast suppresses warning about casting away const
1424}
1425
1426struct gguf_writer_base {
1427 size_t written_bytes {0u};
1428
1429 ~gguf_writer_base(void) = default;
1430
1431 // we bet on devirtualization
1432 virtual void write(int8_t val) = 0;
1433 virtual void write(const std::vector<int8_t> & val) = 0;
1434 virtual void write_tensor_data(const struct gguf_tensor_info & info, size_t offset_data, size_t alignment) = 0;
1435
1436 template <typename T>
1437 void write(const T & val) {
1438 for (size_t i = 0; i < sizeof(val); ++i) {
1439 write(reinterpret_cast<const int8_t *>(&val)[i]);
1440 }
1441 }
1442
1443 void write(const bool & val) {
1444 const int8_t val8 = val ? 1 : 0;
1445 write(val8);
1446 }
1447
1448 void write(const std::string & val) {
1449 {
1450 const uint64_t n = val.length();
1451 write(n);
1452 }
1453 for (size_t i = 0; i < val.length(); ++i) {
1454 write((val.data())[i]);
1455 }
1456 }
1457
1458 void write(const char * val) {
1459 write(std::string(val));
1460 }
1461
1462 void write(const enum ggml_type & val) {
1463 write(int32_t(val));
1464 }
1465
1466 void write(const enum gguf_type & val) {
1467 write(int32_t(val));
1468 }
1469
1470 void write(const struct gguf_kv & kv) {
1471 const uint64_t ne = kv.get_ne();
1472
1473 write(kv.get_key());
1474
1475 if (kv.is_array) {
1476 write(GGUF_TYPE_ARRAY);
1477 write(kv.get_type());
1478 write(ne);
1479 } else {
1480 write(kv.get_type());
1481 }
1482
1483 switch (kv.get_type()) {
1484 case GGUF_TYPE_UINT8:
1485 case GGUF_TYPE_INT8:
1486 case GGUF_TYPE_UINT16:
1487 case GGUF_TYPE_INT16:
1488 case GGUF_TYPE_UINT32:
1489 case GGUF_TYPE_INT32:
1490 case GGUF_TYPE_FLOAT32:
1491 case GGUF_TYPE_UINT64:
1492 case GGUF_TYPE_INT64:
1493 case GGUF_TYPE_FLOAT64: {
1494 write(kv.data);
1495 } break;
1496 case GGUF_TYPE_BOOL: {
1497 for (size_t i = 0; i < ne; ++i) {
1498 write(kv.get_val<bool>(i));
1499 }
1500 } break;
1501 case GGUF_TYPE_STRING: {
1502 for (size_t i = 0; i < ne; ++i) {
1503 write(kv.get_val<std::string>(i));
1504 }
1505 } break;
1506 case GGUF_TYPE_ARRAY:
1507 default: GGML_ABORT("invalid type")ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1507, "invalid type")
;
1508 }
1509 }
1510
1511 void write_tensor_meta(const struct gguf_tensor_info & info) {
1512 write(info.t.name);
1513
1514 const uint32_t n_dims = ggml_n_dims(&info.t);
1515 write(n_dims);
1516
1517 for (uint32_t j = 0; j < n_dims; ++j) {
1518 write(info.t.ne[j]);
1519 }
1520 write(info.t.type);
1521 write(info.offset);
1522 }
1523
1524 void pad(const size_t alignment) {
1525 while (written_bytes % alignment != 0) {
1526 const int8_t zero = 0;
1527 write(zero);
1528 }
1529 }
1530};
1531
1532// vector buffer based writer
1533struct gguf_writer_buf final : public gguf_writer_base {
1534 std::vector<int8_t> & buf;
1535
1536 gguf_writer_buf(std::vector<int8_t> & buf) : buf(buf) {}
1537
1538 using gguf_writer_base::write;
1539
1540 void write(const int8_t val) override {
1541 buf.push_back(val);
1542 written_bytes++;
1543 }
1544
1545 void write(const std::vector<int8_t> & val) override {
1546 buf.insert(buf.end(), val.begin(), val.end());
1547 written_bytes += val.size();
1548 }
1549
1550 void write_tensor_data(const struct gguf_tensor_info & info, const size_t offset_data, const size_t alignment) override {
1551 GGML_ASSERT(buf.size() - offset_data == info.offset)if (!(buf.size() - offset_data == info.offset)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1551, "GGML_ASSERT(%s) failed", "buf.size() - offset_data == info.offset"
)
;
1552
1553 GGML_ASSERT(ggml_is_contiguous(&info.t))if (!(ggml_is_contiguous(&info.t))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1553, "GGML_ASSERT(%s) failed", "ggml_is_contiguous(&info.t)"
)
;
1554 const size_t offset = buf.size();
1555 const size_t nbytes = ggml_nbytes(&info.t);
1556
1557 buf.resize(offset + nbytes);
1558 if (info.t.buffer) {
1559 ggml_backend_tensor_get(&info.t, buf.data() + offset, 0, nbytes);
1560 } else {
1561 GGML_ASSERT(info.t.data)if (!(info.t.data)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1561, "GGML_ASSERT(%s) failed", "info.t.data")
;
1562 memcpy(buf.data() + offset, info.t.data, nbytes);
1563 }
1564 written_bytes += nbytes;
1565
1566 pad(alignment);
1567 }
1568};
1569
1570// file based writer
1571struct gguf_writer_file final : public gguf_writer_base {
1572 FILE * file;
1573
1574 gguf_writer_file(FILE* file) : file(file) {}
1575
1576 using gguf_writer_base::write;
1577
1578 void write(const int8_t val) override {
1579 const auto real_val = static_cast<uint8_t>(val);
1580 const auto ret = fputc(real_val, file);
1581 written_bytes++;
1582 if (ret != real_val) {
1583 throwabort_with_suppression(); if (false) std::runtime_error("unexpected fputc result '" + std::to_string(ret) + "' instead of '" + std::to_string((int)real_val) + "'");
1584 }
1585 }
1586
1587 void write(const std::vector<int8_t> & val) override {
1588 const auto ret = fwrite(val.data(), 1, val.size(), file);
1589 written_bytes += val.size();
1590 if (ret != val.size()) {
1591 throwabort_with_suppression(); if (false) std::runtime_error("unexpected fwrite number of bytes written, '" + std::to_string(ret) + "' instead of '" + std::to_string(val.size()) + "'");
1592 }
1593 }
1594
1595 void write_tensor_data(const struct gguf_tensor_info & info, const size_t offset_data, const size_t alignment) override {
1596 GGML_ASSERT(written_bytes - offset_data == info.offset)if (!(written_bytes - offset_data == info.offset)) ggml_abort
("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1596, "GGML_ASSERT(%s) failed", "written_bytes - offset_data == info.offset"
)
;
1597
1598 GGML_ASSERT(ggml_is_contiguous(&info.t))if (!(ggml_is_contiguous(&info.t))) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1598, "GGML_ASSERT(%s) failed", "ggml_is_contiguous(&info.t)"
)
;
1599 const size_t nbytes = ggml_nbytes(&info.t);
1600
1601 std::vector<int8_t> buf(nbytes);
1602 if (info.t.buffer) {
1603 ggml_backend_tensor_get(&info.t, buf.data(), 0, nbytes);
1604 } else {
1605 GGML_ASSERT(info.t.data)if (!(info.t.data)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1605, "GGML_ASSERT(%s) failed", "info.t.data")
;
1606 memcpy(buf.data(), info.t.data, nbytes);
1607 }
1608 write(buf);
1609
1610 pad(alignment);
1611 }
1612};
1613
1614template <typename writer_t>
1615static void gguf_write_out(const struct gguf_context * ctx, writer_t & gw, bool only_meta) {
1616 const int64_t n_kv = gguf_get_n_kv(ctx);
1617 const int64_t n_tensors = gguf_get_n_tensors(ctx);
1618
1619 // write header
1620 gw.write(GGUF_MAGIC"GGUF"[0]);
1621 gw.write(GGUF_MAGIC"GGUF"[1]);
1622 gw.write(GGUF_MAGIC"GGUF"[2]);
1623 gw.write(GGUF_MAGIC"GGUF"[3]);
1624 gw.write(ctx->version);
1625 gw.write(n_tensors);
1626 gw.write(n_kv);
1627
1628 // write key-value pairs
1629 for (int64_t i = 0; i < n_kv; ++i) {
1630 gw.write(ctx->kv[i]);
1631 }
1632
1633 // write tensor info
1634 for (int64_t i = 0; i < n_tensors; ++i) {
1635 gw.write_tensor_meta(ctx->info[i]);
1636 }
1637
1638 // we require the data section to be aligned
1639 gw.pad(ctx->alignment);
1640
1641 if (only_meta) {
1642 return;
1643 }
1644
1645 const size_t offset_data = gw.written_bytes;
1646
1647 // write tensor data
1648 for (int64_t i = 0; i < n_tensors; ++i) {
1649 gw.write_tensor_data(ctx->info[i], offset_data, ctx->alignment);
1650 }
1651}
1652
1653void gguf_write_to_buf(const struct gguf_context * ctx, std::vector<int8_t> & buf, bool only_meta) {
1654 gguf_writer_buf gw(buf);
1655 gguf_write_out(ctx, gw, only_meta);
1656}
1657
1658bool gguf_write_to_file_ptr(const struct gguf_context * ctx, FILE * file, bool only_meta) {
1659 GGML_ASSERT(file)if (!(file)) ggml_abort("/root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp"
, 1659, "GGML_ASSERT(%s) failed", "file")
;
1660
1661 tryif (true) {
1662 gguf_writer_file gw(file);
1663 gguf_write_out(ctx, gw, only_meta);
1664 } catch (const std::runtime_error& ex)if (static const std::exception e, err, error, ex; false) {
1665 GGML_LOG_ERROR("%s: failed to write GGUF data: %s\n", __func__, ex.what())ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: failed to write GGUF data: %s\n"
, __func__, ex.what())
;
1666 return false;
1667 }
1668 return true;
1669}
1670
1671bool gguf_write_to_file(const struct gguf_context * ctx, const char * fname, bool only_meta) {
1672 FILE * file = ggml_fopen(fname, "wb");
1673
1674 if (!file) {
1675 GGML_LOG_ERROR("%s: failed to open file '%s' for writing GGUF data\n", __func__, fname)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: failed to open file '%s' for writing GGUF data\n"
, __func__, fname)
;
1676 return false;
1677 }
1678
1679 const bool success = gguf_write_to_file_ptr(ctx, file, only_meta);
1680 if (!success) {
1681 GGML_LOG_ERROR("%s: failed to write GGUF data into '%s'\n", __func__, fname)ggml_log_internal(GGML_LOG_LEVEL_ERROR, "%s: failed to write GGUF data into '%s'\n"
, __func__, fname)
;
1682 }
1683
1684 fclose(file);
1685 return success;
1686}
1687
1688size_t gguf_get_meta_size(const struct gguf_context * ctx) {
1689 // only return size
1690 std::vector<int8_t> buf;
1691 gguf_write_to_buf(ctx, buf, /*only_meta =*/ true);
1692 return buf.size();
1693}
1694
1695void gguf_get_meta_data(const struct gguf_context * ctx, void * data) {
1696 std::vector<int8_t> buf;
1697 gguf_write_to_buf(ctx, buf, /*only_meta =*/ true);
1698 memcpy(data, buf.data(), buf.size());
1699}