Skip to content

Commit f6f942e

Browse files
committed
ggml: Allow for gguf_reader implementation to be overridden
1 parent faced1d commit f6f942e

File tree

10 files changed

+162
-122
lines changed

10 files changed

+162
-122
lines changed

ggml/include/gguf-reader-file.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#pragma once
2+
3+
#include "ggml.h"
4+
5+
#include "gguf-reader.h"
6+
7+
#include <cstddef>
8+
#include <cstdio>
9+
10+
struct GGML_API_CLASS gguf_reader_file final : public gguf_reader_impl {
11+
gguf_reader_file() = default;
12+
13+
~gguf_reader_file() override {
14+
close();
15+
}
16+
17+
bool close() override;
18+
bool open(const std::filesystem::path & path) override;
19+
position_t position() override;
20+
bool position_set(position_t position) override;
21+
size_t read(void * dst, size_t size) override;
22+
23+
private:
24+
FILE * file = nullptr;
25+
};

ggml/include/gguf-reader.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
#include "gguf.h"
55

66
#include <cstddef>
7-
#include <ios>
7+
#include <cstdint>
8+
#include <filesystem>
89
#include <string>
10+
#include <type_traits>
911
#include <vector>
10-
#include <filesystem>
1112

1213
#ifdef GGML_SHARED
1314
# if defined(_WIN32) && !defined(__MINGW32__)

ggml/include/gguf.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ extern "C" {
6868
};
6969

7070
struct gguf_context;
71+
struct gguf_reader_impl_factory;
7172

7273
struct gguf_init_params {
7374
bool no_alloc;
@@ -78,6 +79,9 @@ extern "C" {
7879

7980
GGML_API struct gguf_context * gguf_init_empty(void);
8081
GGML_API struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_params params);
82+
83+
GGML_API void gguf_set_default_reader_impl(struct gguf_reader_impl_factory * factory);
84+
8185
//GGML_API struct gguf_context * gguf_init_from_buffer(..);
8286

8387
GGML_API void gguf_free(struct gguf_context * ctx);

ggml/src/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ add_library(ggml-base
194194
../include/ggml-cpp.h
195195
../include/ggml-opt.h
196196
../include/gguf-reader.h
197+
../include/gguf-reader-file.h
197198
../include/gguf.h
198199
ggml.c
199200
ggml.cpp
@@ -205,9 +206,11 @@ add_library(ggml-base
205206
ggml-quants.c
206207
ggml-quants.h
207208
gguf.cpp
208-
gguf-reader.cpp)
209+
gguf-reader.cpp
210+
gguf-reader-file.cpp)
209211

210212
target_include_directories(ggml-base PRIVATE .)
213+
211214
if (GGML_BACKEND_DL)
212215
target_compile_definitions(ggml-base PUBLIC GGML_BACKEND_DL)
213216
endif()

ggml/src/ggml-impl.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,5 @@ inline bool ggml_can_fuse(const struct ggml_cgraph * cgraph, int node_idx, std::
617617

618618
// expose GGUF internals for test code
619619
GGML_API size_t gguf_type_size(enum gguf_type type);
620-
GGML_API struct gguf_context * gguf_init_from_file_impl(FILE * file, struct gguf_init_params params);
621620
GGML_API void gguf_write_to_buf(const struct gguf_context * ctx, std::vector<int8_t> & buf, bool only_meta);
622621
#endif // __cplusplus

ggml/src/gguf-reader-file.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include "gguf-reader-file.h"
2+
3+
#include "ggml.h"
4+
#include "ggml-impl.h"
5+
6+
#include <algorithm>
7+
#include <cstddef>
8+
#include <cstdio>
9+
#include <string>
10+
#include <type_traits>
11+
12+
bool gguf_reader_file::close() {
13+
if (file) {
14+
fclose(file);
15+
16+
file = nullptr;
17+
}
18+
19+
return true;
20+
}
21+
22+
bool gguf_reader_file::open(const std::filesystem::path & path) {
23+
close();
24+
25+
file = ggml_fopen(path.generic_string().c_str(), "rb");
26+
27+
if (!file) {
28+
GGML_LOG_ERROR("%s: failed to open GGUF file '%s'\n", __func__, path.c_str());
29+
30+
return false;
31+
}
32+
33+
return true;
34+
}
35+
36+
gguf_reader_file::position_t gguf_reader_file::position() {
37+
if (!file) {
38+
return -1;
39+
}
40+
41+
return ftell(file);
42+
}
43+
44+
bool gguf_reader_file::position_set(position_t position) {
45+
if (!file || position < 0) {
46+
return false;
47+
}
48+
49+
return fseek(file, position, SEEK_SET) == 0;
50+
}
51+
52+
size_t gguf_reader_file::read(void * dst, const size_t size) {
53+
if (!file) {
54+
return 0U;
55+
}
56+
57+
return fread(reinterpret_cast<char *>(dst), 1U, size, file);
58+
}

ggml/src/gguf-reader.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
#include "gguf-reader.h"
22

33
#include "gguf.h"
4+
#include "gguf-reader-file.h"
45

56
#include <cstddef>
67
#include <memory>
78

89
struct default_impl_factory : public gguf_reader_impl_factory {
910
std::unique_ptr<gguf_reader_impl> build_for(const std::filesystem::path &) override {
10-
return nullptr;
11+
return std::make_unique<gguf_reader_file>();
1112
}
1213
};
1314

ggml/src/gguf.cpp

Lines changed: 14 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "ggml-backend.h"
33
#include "ggml-impl.h"
44
#include "gguf.h"
5+
#include "gguf-reader.h"
56

67
#include <cinttypes>
78
#include <cstddef>
@@ -216,82 +217,12 @@ struct gguf_context {
216217
void * data = nullptr;
217218
};
218219

219-
struct gguf_reader {
220-
FILE * file;
221-
222-
gguf_reader(FILE * file) : file(file) {}
223-
224-
template <typename T>
225-
bool read(T & dst) const {
226-
return fread(&dst, 1, sizeof(dst), file) == sizeof(dst);
227-
}
228-
229-
template <typename T>
230-
bool read(std::vector<T> & dst, const size_t n) const {
231-
dst.resize(n);
232-
for (size_t i = 0; i < dst.size(); ++i) {
233-
if constexpr (std::is_same<T, bool>::value) {
234-
bool tmp;
235-
if (!read(tmp)) {
236-
return false;
237-
}
238-
dst[i] = tmp;
239-
} else {
240-
if (!read(dst[i])) {
241-
return false;
242-
}
243-
}
244-
}
245-
return true;
246-
}
247-
248-
bool read(bool & dst) const {
249-
int8_t tmp = -1;
250-
if (!read(tmp)) {
251-
return false;
252-
}
253-
dst = tmp != 0;
254-
return true;
255-
}
256-
257-
bool read(enum ggml_type & dst) const {
258-
int32_t tmp = -1;
259-
if (!read(tmp)) {
260-
return false;
261-
}
262-
dst = ggml_type(tmp);
263-
return true;
264-
}
265-
266-
bool read(enum gguf_type & dst) const {
267-
int32_t tmp = -1;
268-
if (!read(tmp)) {
269-
return false;
270-
}
271-
dst = gguf_type(tmp);
272-
return true;
273-
}
274-
275-
bool read(std::string & dst) const {
276-
uint64_t size = -1;
277-
if (!read(size)) {
278-
return false;
279-
}
280-
dst.resize(size);
281-
return fread(dst.data(), 1, dst.length(), file) == dst.length();
282-
}
283-
284-
bool read(void * dst, const size_t size) const {
285-
return fread(dst, 1, size, file) == size;
286-
}
287-
};
288-
289220
struct gguf_context * gguf_init_empty(void) {
290221
return new gguf_context;
291222
}
292223

293224
template<typename T>
294-
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) {
225+
bool gguf_read_emplace_helper(struct gguf_reader & gr, std::vector<struct gguf_kv> & kv, const std::string & key, const bool is_array, const size_t n) {
295226
if (is_array) {
296227
std::vector<T> value;
297228
try {
@@ -316,8 +247,15 @@ bool gguf_read_emplace_helper(const struct gguf_reader & gr, std::vector<struct
316247
return true;
317248
}
318249

319-
struct gguf_context * gguf_init_from_file_impl(FILE * file, struct gguf_init_params params) {
320-
const struct gguf_reader gr(file);
250+
struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_params params)
251+
{
252+
gguf_reader gr(fname);
253+
254+
if (!gr.open()) {
255+
GGML_LOG_ERROR("%s: failed to open reader\n", __func__);
256+
return nullptr;
257+
}
258+
321259
struct gguf_context * ctx = new gguf_context;
322260

323261
bool ok = true;
@@ -610,14 +548,14 @@ struct gguf_context * gguf_init_from_file_impl(FILE * file, struct gguf_init_par
610548
GGML_ASSERT(int64_t(ctx->info.size()) == n_tensors);
611549

612550
// we require the data section to be aligned, so take into account any padding
613-
if (fseek(file, GGML_PAD(ftell(file), ctx->alignment), SEEK_SET) != 0) {
551+
if (!gr.position_set(GGML_PAD(gr.position(), ctx->alignment))) {
614552
GGML_LOG_ERROR("%s: failed to seek to beginning of data section\n", __func__);
615553
gguf_free(ctx);
616554
return nullptr;
617555
}
618556

619557
// store the current file offset - this is where the data section starts
620-
ctx->offset = ftell(file);
558+
ctx->offset = gr.position();
621559

622560
// compute the total size of the data section, taking into account the alignment
623561
{
@@ -681,7 +619,7 @@ struct gguf_context * gguf_init_from_file_impl(FILE * file, struct gguf_init_par
681619
}
682620

683621
// read the binary blob with the tensor data
684-
ok = ok && gr.read(data->data, ctx->size);
622+
ok = ok && gr.read(data->data, ctx->size) == ctx->size;
685623

686624
if (!ok) {
687625
GGML_LOG_ERROR("%s: failed to read tensor data binary blob\n", __func__);
@@ -730,19 +668,6 @@ struct gguf_context * gguf_init_from_file_impl(FILE * file, struct gguf_init_par
730668
return ctx;
731669
}
732670

733-
struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_params params) {
734-
FILE * file = ggml_fopen(fname, "rb");
735-
736-
if (!file) {
737-
GGML_LOG_ERROR("%s: failed to open GGUF file '%s'\n", __func__, fname);
738-
return nullptr;
739-
}
740-
741-
struct gguf_context * result = gguf_init_from_file_impl(file, params);
742-
fclose(file);
743-
return result;
744-
}
745-
746671
void gguf_free(struct gguf_context * ctx) {
747672
if (ctx == nullptr) {
748673
return;

0 commit comments

Comments
 (0)