| 395 | } |
| 396 | |
| 397 | struct gguf_context * gguf_init_from_file_ptr(FILE * file, struct gguf_init_params params) { |
| 398 | if (!file) { |
| 399 | return nullptr; |
| 400 | } |
| 401 | |
| 402 | const struct gguf_reader gr(file); |
| 403 | struct gguf_context * ctx = new gguf_context; |
| 404 | |
| 405 | bool ok = true; |
| 406 | |
| 407 | // file magic |
| 408 | { |
| 409 | std::vector<char> magic; |
| 410 | ok = ok && gr.read(magic, 4); |
| 411 | |
| 412 | if (!ok) { |
| 413 | GGML_LOG_ERROR("%s: failed to read magic\n", __func__); |
| 414 | gguf_free(ctx); |
| 415 | return nullptr; |
| 416 | } |
| 417 | |
| 418 | for (uint32_t i = 0; i < magic.size(); i++) { |
| 419 | if (magic[i] != GGUF_MAGIC[i]) { |
| 420 | char c0 = isprint(magic[0]) ? magic[0] : '?'; |
| 421 | char c1 = isprint(magic[1]) ? magic[1] : '?'; |
| 422 | char c2 = isprint(magic[2]) ? magic[2] : '?'; |
| 423 | char c3 = isprint(magic[3]) ? magic[3] : '?'; |
| 424 | GGML_LOG_ERROR("%s: invalid magic characters: '%c%c%c%c', expected 'GGUF'\n", __func__, c0, c1, c2, c3); |
| 425 | gguf_free(ctx); |
| 426 | return nullptr; |
| 427 | } |
| 428 | } |
| 429 | } |
| 430 | |
| 431 | // header |
| 432 | int64_t n_kv = 0; |
| 433 | int64_t n_tensors = 0; |
| 434 | |
| 435 | if (ok && gr.read(ctx->version)) { |
| 436 | if (ok && ctx->version == 0) { |
| 437 | GGML_LOG_ERROR("%s: bad GGUF version: %" PRIu32 "\n", __func__, ctx->version); |
| 438 | ok = false; |
| 439 | } |
| 440 | |
| 441 | /* |
| 442 | * bit layout is different when reading non-native endian models. |
| 443 | * assuming that the GGUF version is 3, the non-native endian model |
| 444 | * would read it as 0x30000000. we can use the AND operation against |
| 445 | * the last 4 hexadecimal digits to check if the model is the same |
| 446 | * endianness as the host system. |
| 447 | */ |
| 448 | if (ok && (ctx->version & 0x0000FFFF) == 0x00000000) { |
| 449 | 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); |
| 450 | ok = false; |
| 451 | } |
| 452 | |
| 453 | if (ok && ctx->version == 1) { |
| 454 | GGML_LOG_ERROR("%s: GGUFv1 is no longer supported, please use a more up-to-date version\n", __func__); |
no test coverage detected