| File: | root/firefox-clang/third_party/llama.cpp/ggml/src/gguf.cpp |
| Warning: | line 1083, column 5 Division by zero |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 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 | ||||
| 32 | template <typename T> | |||
| 33 | struct type_to_gguf_type; | |||
| 34 | ||||
| 35 | template <> | |||
| 36 | struct type_to_gguf_type<uint8_t> { | |||
| 37 | static constexpr enum gguf_type value = GGUF_TYPE_UINT8; | |||
| 38 | }; | |||
| 39 | ||||
| 40 | template <> | |||
| 41 | struct type_to_gguf_type<int8_t> { | |||
| 42 | static constexpr enum gguf_type value = GGUF_TYPE_INT8; | |||
| 43 | }; | |||
| 44 | ||||
| 45 | template <> | |||
| 46 | struct type_to_gguf_type<uint16_t> { | |||
| 47 | static constexpr enum gguf_type value = GGUF_TYPE_UINT16; | |||
| 48 | }; | |||
| 49 | ||||
| 50 | template <> | |||
| 51 | struct type_to_gguf_type<int16_t> { | |||
| 52 | static constexpr enum gguf_type value = GGUF_TYPE_INT16; | |||
| 53 | }; | |||
| 54 | ||||
| 55 | template <> | |||
| 56 | struct type_to_gguf_type<uint32_t> { | |||
| 57 | static constexpr enum gguf_type value = GGUF_TYPE_UINT32; | |||
| 58 | }; | |||
| 59 | ||||
| 60 | template <> | |||
| 61 | struct type_to_gguf_type<int32_t> { | |||
| 62 | static constexpr enum gguf_type value = GGUF_TYPE_INT32; | |||
| 63 | }; | |||
| 64 | ||||
| 65 | template <> | |||
| 66 | struct type_to_gguf_type<float> { | |||
| 67 | static constexpr enum gguf_type value = GGUF_TYPE_FLOAT32; | |||
| 68 | }; | |||
| 69 | ||||
| 70 | template <> | |||
| 71 | struct type_to_gguf_type<bool> { | |||
| 72 | static constexpr enum gguf_type value = GGUF_TYPE_BOOL; | |||
| 73 | }; | |||
| 74 | ||||
| 75 | template <> | |||
| 76 | struct type_to_gguf_type<std::string> { | |||
| 77 | static constexpr enum gguf_type value = GGUF_TYPE_STRING; | |||
| 78 | }; | |||
| 79 | ||||
| 80 | template <> | |||
| 81 | struct type_to_gguf_type<uint64_t> { | |||
| 82 | static constexpr enum gguf_type value = GGUF_TYPE_UINT64; | |||
| 83 | }; | |||
| 84 | ||||
| 85 | template <> | |||
| 86 | struct type_to_gguf_type<int64_t> { | |||
| 87 | static constexpr enum gguf_type value = GGUF_TYPE_INT64; | |||
| 88 | }; | |||
| 89 | ||||
| 90 | template <> | |||
| 91 | struct type_to_gguf_type<double> { | |||
| 92 | static constexpr enum gguf_type value = GGUF_TYPE_FLOAT64; | |||
| 93 | }; | |||
| 94 | ||||
| 95 | static 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 | ||||
| 115 | static 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 | ||||
| 135 | size_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; | |||
| 139 | } | |||
| 140 | ||||
| 141 | struct 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" ); | |||
| 205 | if constexpr (std::is_same<T, std::string>::value) { | |||
| 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); | |||
| 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" ); | |||
| 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 | ||||
| 222 | struct 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 | ||||
| 227 | struct 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 | ||||
| 240 | struct 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 | ||||
| 390 | private: | |||
| 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 | ||||
| 431 | struct gguf_context * gguf_init_empty(void) { | |||
| 432 | return new gguf_context; | |||
| 433 | } | |||
| 434 | ||||
| 435 | template<typename T> | |||
| 436 | bool 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 | ||||
| 461 | static 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 | ||||
| 906 | struct 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 | ||||
| 915 | struct gguf_file_reader { | |||
| 916 | FILE * file; | |||
| 917 | uint64_t offset; | |||
| 918 | }; | |||
| 919 | ||||
| 920 | static 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 | ||||
| 938 | struct 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 | ||||
| 956 | struct gguf_buffer_reader { | |||
| 957 | const uint8_t * data; | |||
| 958 | size_t size; | |||
| 959 | }; | |||
| 960 | ||||
| 961 | static 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 | ||||
| 976 | struct 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 | ||||
| 989 | struct 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 | ||||
| 1002 | void gguf_free(struct gguf_context * ctx) { | |||
| 1003 | if (ctx == nullptr) { | |||
| 1004 | return; | |||
| 1005 | } | |||
| 1006 | delete ctx; | |||
| 1007 | } | |||
| 1008 | ||||
| 1009 | const 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 | ||||
| 1015 | uint32_t gguf_get_version(const struct gguf_context * ctx) { | |||
| 1016 | return ctx->version; | |||
| 1017 | } | |||
| 1018 | ||||
| 1019 | size_t gguf_get_alignment(const struct gguf_context * ctx) { | |||
| 1020 | return ctx->alignment; | |||
| 1021 | } | |||
| 1022 | ||||
| 1023 | size_t gguf_get_data_offset(const struct gguf_context * ctx) { | |||
| 1024 | return ctx->offset; | |||
| 1025 | } | |||
| 1026 | ||||
| 1027 | int64_t gguf_get_n_kv(const struct gguf_context * ctx) { | |||
| 1028 | return ctx->kv.size(); | |||
| 1029 | } | |||
| 1030 | ||||
| 1031 | int64_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 | ||||
| 1047 | const 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 | ||||
| 1052 | enum 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 | ||||
| 1057 | enum 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 | ||||
| 1063 | const 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 | ||||
| 1069 | const 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 | ||||
| 1075 | size_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 | ||||
| 1087 | uint8_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 | ||||
| 1093 | int8_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 | ||||
| 1099 | uint16_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 | ||||
| 1105 | int16_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 | ||||
| 1111 | uint32_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 | ||||
| 1117 | int32_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 | ||||
| 1123 | float 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 | ||||
| 1129 | uint64_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 | ||||
| 1135 | int64_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 | ||||
| 1141 | double 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 | ||||
| 1147 | bool 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 | ||||
| 1153 | const 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 | ||||
| 1159 | const 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 | ||||
| 1166 | int64_t gguf_get_n_tensors(const struct gguf_context * ctx) { | |||
| 1167 | return ctx->info.size(); | |||
| 1168 | } | |||
| 1169 | ||||
| 1170 | int64_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 | ||||
| 1186 | size_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 | ||||
| 1191 | const 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 | ||||
| 1196 | enum 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 | ||||
| 1201 | size_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 | ||||
| 1206 | int64_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 | ||||
| 1214 | template<typename T> | |||
| 1215 | static 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 | ||||
| 1226 | void 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 | ||||
| 1232 | void 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 | ||||
| 1238 | void 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 | ||||
| 1244 | void 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 | ||||
| 1250 | void 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 | ||||
| 1256 | void 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 | ||||
| 1262 | void 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 | ||||
| 1268 | void 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 | ||||
| 1274 | void 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 | ||||
| 1280 | void 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 | ||||
| 1286 | void 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 | ||||
| 1292 | void 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 | ||||
| 1298 | void 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 | ||||
| 1311 | void 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 | |||
| 1323 | void 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) { | |||
| 1326 | const struct gguf_kv & kv = src->kv[i]; | |||
| 1327 | ||||
| 1328 | if (!kv.is_array) { | |||
| 1329 | switch (kv.get_type()) { | |||
| 1330 | case GGUF_TYPE_UINT8: gguf_set_val_u8 (ctx, kv.get_key().c_str(), kv.get_val<uint8_t>()); break; | |||
| 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 | ||||
| 1377 | void 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 | ||||
| 1392 | void 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 | ||||
| 1417 | void 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 | ||||
| 1426 | struct 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 | |||
| 1533 | struct 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 | |||
| 1571 | struct 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 | ||||
| 1614 | template <typename writer_t> | |||
| 1615 | static 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 | ||||
| 1653 | void 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 | ||||
| 1658 | bool 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 | ||||
| 1671 | bool 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 | ||||
| 1688 | size_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 | ||||
| 1695 | void 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 | } |