Skip to content

Commit faced1d

Browse files
committed
ggml: Add public gguf_reader interface
1 parent 17aefff commit faced1d

File tree

4 files changed

+191
-2
lines changed

4 files changed

+191
-2
lines changed

ggml/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,8 @@ set(GGML_PUBLIC_HEADERS
278278
include/ggml-sycl.h
279279
include/ggml-vulkan.h
280280
include/ggml-webgpu.h
281-
include/gguf.h)
281+
include/gguf.h
282+
include/gguf-reader.h)
282283

283284
set_target_properties(ggml PROPERTIES PUBLIC_HEADER "${GGML_PUBLIC_HEADERS}")
284285
#if (GGML_METAL)

ggml/include/gguf-reader.h

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#pragma once
2+
3+
#include "ggml.h"
4+
#include "gguf.h"
5+
6+
#include <cstddef>
7+
#include <ios>
8+
#include <string>
9+
#include <vector>
10+
#include <filesystem>
11+
12+
#ifdef GGML_SHARED
13+
# if defined(_WIN32) && !defined(__MINGW32__)
14+
# ifdef GGML_BUILD
15+
# define GGML_API_CLASS __declspec(dllexport)
16+
# else
17+
# define GGML_API_CLASS __declspec(dllimport)
18+
# endif
19+
# else
20+
# ifdef GGML_BUILD
21+
# define GGML_API_CLASS __attribute__ ((visibility ("default")))
22+
# else
23+
# define GGML_API_CLASS
24+
# endif
25+
# endif
26+
#else
27+
# define GGML_API_CLASS
28+
#endif
29+
30+
struct GGML_API_CLASS gguf_reader_impl {
31+
using position_t = int64_t;
32+
33+
virtual ~gguf_reader_impl() = default;
34+
35+
virtual bool close() = 0;
36+
virtual bool open(const std::filesystem::path & file) = 0;
37+
virtual position_t position() = 0;
38+
virtual bool position_set(position_t position) = 0;
39+
virtual size_t read(void * buf, size_t len) = 0;
40+
};
41+
42+
struct GGML_API_CLASS gguf_reader_impl_factory {
43+
virtual ~gguf_reader_impl_factory() = default;
44+
45+
virtual std::unique_ptr<gguf_reader_impl> build_for(const std::filesystem::path & file) = 0;
46+
};
47+
48+
struct GGML_API_CLASS gguf_reader {
49+
using position_t = gguf_reader_impl::position_t;
50+
51+
// Create a reader using the currently-configured default implementation (see
52+
// gguf_set_default_reader_impl())
53+
gguf_reader(const std::filesystem::path & path);
54+
55+
// Create a reader using the implementation given by impl
56+
gguf_reader(const std::filesystem::path & path, std::unique_ptr<gguf_reader_impl> && impl)
57+
: m_path(path), m_impl(std::move(impl)) {
58+
}
59+
60+
~gguf_reader() {
61+
m_impl->close();
62+
}
63+
64+
bool open() {
65+
return m_impl->open(m_path);
66+
}
67+
68+
position_t position() {
69+
return m_impl->position();
70+
}
71+
72+
bool position_set(position_t position) {
73+
return m_impl->position_set(position);
74+
}
75+
76+
bool read(bool & dst);
77+
bool read(enum ggml_type & dst);
78+
bool read(enum gguf_type & dst);
79+
bool read(std::string & dst);
80+
81+
size_t read(void * dst, size_t size) {
82+
return m_impl->read(dst, size);
83+
}
84+
85+
template <typename T>
86+
bool read(T & dst) {
87+
return m_impl->read(&dst, sizeof(dst)) == sizeof(dst);
88+
}
89+
90+
template <typename T>
91+
bool read(std::vector<T> & dst, const size_t n) {
92+
dst.resize(n);
93+
94+
for (size_t i = 0U; i < dst.size(); ++i) {
95+
if constexpr (std::is_same<T, bool>::value) {
96+
bool tmp;
97+
98+
if (!read(tmp)) {
99+
return false;
100+
}
101+
102+
dst[i] = tmp;
103+
} else if (!read(dst[i])) {
104+
return false;
105+
}
106+
}
107+
108+
return true;
109+
}
110+
111+
private:
112+
std::filesystem::path m_path;
113+
std::unique_ptr<gguf_reader_impl> m_impl;
114+
};

ggml/src/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ add_library(ggml-base
193193
../include/ggml-backend.h
194194
../include/ggml-cpp.h
195195
../include/ggml-opt.h
196+
../include/gguf-reader.h
196197
../include/gguf.h
197198
ggml.c
198199
ggml.cpp
@@ -203,7 +204,8 @@ add_library(ggml-base
203204
ggml-threading.h
204205
ggml-quants.c
205206
ggml-quants.h
206-
gguf.cpp)
207+
gguf.cpp
208+
gguf-reader.cpp)
207209

208210
target_include_directories(ggml-base PRIVATE .)
209211
if (GGML_BACKEND_DL)

ggml/src/gguf-reader.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#include "gguf-reader.h"
2+
3+
#include "gguf.h"
4+
5+
#include <cstddef>
6+
#include <memory>
7+
8+
struct default_impl_factory : public gguf_reader_impl_factory {
9+
std::unique_ptr<gguf_reader_impl> build_for(const std::filesystem::path &) override {
10+
return nullptr;
11+
}
12+
};
13+
14+
static default_impl_factory default_factory;
15+
16+
static gguf_reader_impl_factory * impl_factory = &default_factory;
17+
18+
gguf_reader::gguf_reader(const std::filesystem::path & path)
19+
: m_path(path), m_impl(impl_factory->build_for(path)) {
20+
}
21+
22+
bool gguf_reader::read(std::string & dst) {
23+
uint64_t size;
24+
25+
if (!read(size)) {
26+
return false;
27+
}
28+
29+
dst.resize(size);
30+
31+
return m_impl->read(dst.data(), dst.length()) == dst.length();
32+
}
33+
34+
bool gguf_reader::read(bool & dst) {
35+
int8_t tmp;
36+
37+
if (!read(tmp)) {
38+
return false;
39+
}
40+
41+
dst = tmp != 0;
42+
43+
return true;
44+
}
45+
46+
bool gguf_reader::read(enum ggml_type & dst) {
47+
int32_t tmp;
48+
49+
if (!read(tmp)) {
50+
return false;
51+
}
52+
53+
dst = ggml_type(tmp);
54+
55+
return true;
56+
}
57+
58+
bool gguf_reader::read(enum gguf_type & dst) {
59+
int32_t tmp;
60+
61+
if (!read(tmp)) {
62+
return false;
63+
}
64+
65+
dst = gguf_type(tmp);
66+
67+
return true;
68+
}
69+
70+
void gguf_set_default_reader_impl(struct gguf_reader_impl_factory * factory) {
71+
impl_factory = factory ? factory : &default_factory;
72+
}

0 commit comments

Comments
 (0)