Skip to content

Commit 081b29b

Browse files
tests: add tests for GGUF (#10830)
1 parent 5437d4a commit 081b29b

File tree

4 files changed

+1344
-41
lines changed

4 files changed

+1344
-41
lines changed

ggml/src/ggml-impl.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,22 @@ static inline ggml_bf16_t ggml_compute_fp32_to_bf16(float s) {
551551
#define GGML_FP32_TO_BF16(x) ggml_compute_fp32_to_bf16(x)
552552
#define GGML_BF16_TO_FP32(x) ggml_compute_bf16_to_fp32(x)
553553

554+
// expose GGUF internals for test code
555+
556+
GGML_API size_t gguf_type_size(enum gguf_type type);
557+
558+
GGML_API struct gguf_context * gguf_init_from_file_impl(FILE * file, struct gguf_init_params params);
559+
560+
struct gguf_buf {
561+
void * data;
562+
size_t size;
563+
size_t offset;
564+
};
565+
GGML_API struct gguf_buf gguf_buf_init(size_t size);
566+
GGML_API void gguf_buf_free(struct gguf_buf buf);
567+
568+
GGML_API void gguf_write_to_buf(const struct gguf_context * ctx, struct gguf_buf * buf, bool only_meta);
569+
554570
#ifdef __cplusplus
555571
}
556572
#endif

ggml/src/ggml.c

Lines changed: 24 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -6489,7 +6489,7 @@ struct gguf_context {
64896489
void * data;
64906490
};
64916491

6492-
static size_t gguf_type_size(enum gguf_type type) {
6492+
size_t gguf_type_size(enum gguf_type type) {
64936493
GGML_ASSERT(0 <= type && type < GGUF_TYPE_COUNT);
64946494
return GGUF_TYPE_SIZE[type];
64956495
}
@@ -6617,13 +6617,7 @@ struct gguf_context * gguf_init_empty(void) {
66176617
return ctx;
66186618
}
66196619

6620-
struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_params params) {
6621-
FILE * file = ggml_fopen(fname, "rb");
6622-
if (!file) {
6623-
fprintf(stderr, "%s: failed to open '%s': '%s'\n", __func__, fname, strerror(errno));
6624-
return NULL;
6625-
}
6626-
6620+
struct gguf_context * gguf_init_from_file_impl(FILE * file, struct gguf_init_params params) {
66276621
// offset from start of file
66286622
size_t offset = 0;
66296623

@@ -6636,7 +6630,6 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
66366630
for (uint32_t i = 0; i < sizeof(magic); i++) {
66376631
if (magic[i] != GGUF_MAGIC[i]) {
66386632
fprintf(stderr, "%s: invalid magic characters '%c%c%c%c'\n", __func__, magic[0], magic[1], magic[2], magic[3]);
6639-
fclose(file);
66406633
return NULL;
66416634
}
66426635
}
@@ -6647,7 +6640,6 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
66476640
struct gguf_context * ctx = calloc(1, sizeof(struct gguf_context));
66486641
if (!ctx) {
66496642
fprintf(stderr, "%s: failed to allocate memory for context\n", __func__);
6650-
fclose(file);
66516643
return NULL;
66526644
}
66536645

@@ -6665,7 +6657,6 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
66656657

66666658
if (ctx->header.version == 1) {
66676659
fprintf(stderr, "%s: GGUFv1 is no longer supported. please use a more up-to-date version\n", __func__);
6668-
fclose(file);
66696660
gguf_free(ctx);
66706661
return NULL;
66716662
}
@@ -6678,7 +6669,6 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
66786669

66796670
if (!ok) {
66806671
fprintf(stderr, "%s: failed to read header\n", __func__);
6681-
fclose(file);
66826672
gguf_free(ctx);
66836673
return NULL;
66846674
}
@@ -6688,12 +6678,13 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
66886678
{
66896679
const uint64_t n_kv = ctx->header.n_kv;
66906680

6691-
ctx->kv = calloc(n_kv, sizeof(struct gguf_kv));
6692-
if (!ctx->kv) {
6693-
fprintf(stderr, "%s: failed to allocate memory for kv pairs\n", __func__);
6694-
fclose(file);
6695-
gguf_free(ctx);
6696-
return NULL;
6681+
if (n_kv > 0) {
6682+
ctx->kv = calloc(n_kv, sizeof(struct gguf_kv));
6683+
if (!ctx->kv) {
6684+
fprintf(stderr, "%s: failed to allocate memory for kv pairs\n", __func__);
6685+
gguf_free(ctx);
6686+
return NULL;
6687+
}
66976688
}
66986689

66996690
for (uint64_t i = 0; i < n_kv; ++i) {
@@ -6740,15 +6731,13 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
67406731
// prevent from integer overflow in the malloc below
67416732
if (kv->value.arr.n >= SIZE_MAX/gguf_type_size(kv->value.arr.type)) {
67426733
fprintf(stderr, "%s: array size is too large (%" PRIu64 ")\n", __func__, kv->value.arr.n);
6743-
fclose(file);
67446734
gguf_free(ctx);
67456735
return NULL;
67466736
}
67476737

67486738
kv->value.arr.data = calloc(kv->value.arr.n, gguf_type_size(kv->value.arr.type));
67496739
if (!kv->value.arr.data) {
67506740
fprintf(stderr, "%s: failed to allocate memory for array\n", __func__);
6751-
fclose(file);
67526741
gguf_free(ctx);
67536742
return NULL;
67546743
}
@@ -6760,15 +6749,13 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
67606749
// prevent from integer overflow in the malloc below
67616750
if (kv->value.arr.n >= SIZE_MAX/sizeof(struct gguf_str)) {
67626751
fprintf(stderr, "%s: array size is too large (%" PRIu64 ")\n", __func__, kv->value.arr.n);
6763-
fclose(file);
67646752
gguf_free(ctx);
67656753
return NULL;
67666754
}
67676755

67686756
kv->value.arr.data = calloc(kv->value.arr.n, sizeof(struct gguf_str));
67696757
if (!kv->value.arr.data) {
67706758
fprintf(stderr, "%s: failed to allocate memory for array\n", __func__);
6771-
fclose(file);
67726759
gguf_free(ctx);
67736760
return NULL;
67746761
}
@@ -6799,7 +6786,6 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
67996786

68006787
if (!ok) {
68016788
fprintf(stderr, "%s: failed to read key-value pairs\n", __func__);
6802-
fclose(file);
68036789
gguf_free(ctx);
68046790
return NULL;
68056791
}
@@ -6810,7 +6796,6 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
68106796
ctx->infos = calloc(ctx->header.n_tensors, sizeof(struct gguf_tensor_info));
68116797
if (!ctx->infos) {
68126798
fprintf(stderr, "%s: failed to allocate memory for tensor infos\n", __func__);
6813-
fclose(file);
68146799
gguf_free(ctx);
68156800
return NULL;
68166801
}
@@ -6846,7 +6831,6 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
68466831

68476832
if (!ok) {
68486833
fprintf(stderr, "%s: failed to read tensor info\n", __func__);
6849-
fclose(file);
68506834
gguf_free(ctx);
68516835
return NULL;
68526836
}
@@ -6889,15 +6873,13 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
68896873
// this tensor type support have been removed:
68906874
fprintf(stderr, "%s: tensor '%s' of type %d: %s\n",
68916875
__func__, info->name.data, (int) info->type, ggml_type_name(info->type));
6892-
fclose(file);
68936876
gguf_free(ctx);
68946877
return NULL;
68956878
}
68966879

68976880
if (ne % ggml_blck_size(info->type) != 0) {
68986881
fprintf(stderr, "%s: tensor '%s' of type %d (%s) number of elements (%" PRId64 ") is not a multiple of block size (%" PRId64 ")\n",
68996882
__func__, info->name.data, (int) info->type, ggml_type_name(info->type), ne, ggml_blck_size(info->type));
6900-
fclose(file);
69016883
gguf_free(ctx);
69026884
return NULL;
69036885
}
@@ -6929,7 +6911,6 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
69296911
*params.ctx = ggml_init(pdata);
69306912
if (*params.ctx == NULL) {
69316913
fprintf(stderr, "%s: failed to initialize context\n", __func__);
6932-
fclose(file);
69336914
gguf_free(ctx);
69346915
return NULL;
69356916
}
@@ -6948,7 +6929,6 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
69486929

69496930
if (!ok) {
69506931
fprintf(stderr, "%s: failed to read tensor data\n", __func__);
6951-
fclose(file);
69526932
ggml_free(ctx_data);
69536933
gguf_free(ctx);
69546934
return NULL;
@@ -6987,7 +6967,6 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
69876967

69886968
if (!ok) {
69896969
fprintf(stderr, "%s: failed to read the tensor data\n", __func__);
6990-
fclose(file);
69916970
ggml_free(ctx_data);
69926971
gguf_free(ctx);
69936972
return NULL;
@@ -6996,11 +6975,21 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
69966975
ggml_set_no_alloc(ctx_data, params.no_alloc);
69976976
}
69986977

6999-
fclose(file);
7000-
70016978
return ctx;
70026979
}
70036980

6981+
struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_params params) {
6982+
FILE * file = ggml_fopen(fname, "rb");
6983+
if (!file) {
6984+
fprintf(stderr, "%s: failed to open '%s': '%s'\n", __func__, fname, strerror(errno));
6985+
return NULL;
6986+
}
6987+
6988+
struct gguf_context * result = gguf_init_from_file_impl(file, params);
6989+
fclose(file);
6990+
return result;
6991+
}
6992+
70046993
void gguf_free(struct gguf_context * ctx) {
70056994
if (ctx == NULL) {
70066995
return;
@@ -7460,13 +7449,7 @@ void gguf_set_tensor_data(struct gguf_context * ctx, const char * name, const vo
74607449
// fwrite(val, sizeof(char), size, file);
74617450
//}
74627451

7463-
struct gguf_buf {
7464-
void * data;
7465-
size_t size;
7466-
size_t offset;
7467-
};
7468-
7469-
static struct gguf_buf gguf_buf_init(size_t size) {
7452+
struct gguf_buf gguf_buf_init(size_t size) {
74707453
struct gguf_buf buf = {
74717454
/*buf.data =*/ size == 0 ? NULL : GGML_CALLOC(1, size),
74727455
/*buf.size =*/ size,
@@ -7476,7 +7459,7 @@ static struct gguf_buf gguf_buf_init(size_t size) {
74767459
return buf;
74777460
}
74787461

7479-
static void gguf_buf_free(struct gguf_buf buf) {
7462+
void gguf_buf_free(struct gguf_buf buf) {
74807463
if (buf.data) {
74817464
GGML_FREE(buf.data);
74827465
}
@@ -7514,7 +7497,7 @@ static void gguf_bwrite_el(struct gguf_buf * buf, const void * val, size_t el_si
75147497
buf->offset += el_size;
75157498
}
75167499

7517-
static void gguf_write_to_buf(const struct gguf_context * ctx, struct gguf_buf * buf, bool only_meta) {
7500+
void gguf_write_to_buf(const struct gguf_context * ctx, struct gguf_buf * buf, bool only_meta) {
75187501
// write header
75197502
gguf_bwrite_el(buf, &ctx->header.magic, sizeof(ctx->header.magic));
75207503
gguf_bwrite_el(buf, &ctx->header.version, sizeof(ctx->header.version));

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ llama_target_and_test(test-arg-parser.cpp)
129129
llama_target_and_test(test-chat-template.cpp)
130130

131131
# llama_target_and_test(test-opt.cpp) # SLOW
132+
llama_target_and_test(test-gguf.cpp)
132133
llama_target_and_test(test-backend-ops.cpp)
133134

134135
llama_target_and_test(test-model-load-cancel.cpp LABEL "model")

0 commit comments

Comments
 (0)