Coverage Report

Created: 2026-07-16 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/llama.cpp/ggml/src/gguf.cpp
Line
Count
Source
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
18
213k
#define GGUF_MAX_STRING_LENGTH  (1024*1024*1024)
19
16.0k
#define GGUF_MAX_ARRAY_ELEMENTS (1024*1024*1024)
20
21
#ifdef _WIN32
22
#    define gguf_ftell _ftelli64
23
#    define gguf_fseek _fseeki64
24
#else
25
25.3k
#    define gguf_ftell ftello
26
16.9k
#    define gguf_fseek fseeko
27
#endif
28
29
template <typename T>
30
struct type_to_gguf_type;
31
32
template <>
33
struct type_to_gguf_type<uint8_t> {
34
    static constexpr enum gguf_type value = GGUF_TYPE_UINT8;
35
};
36
37
template <>
38
struct type_to_gguf_type<int8_t> {
39
    static constexpr enum gguf_type value = GGUF_TYPE_INT8;
40
};
41
42
template <>
43
struct type_to_gguf_type<uint16_t> {
44
    static constexpr enum gguf_type value = GGUF_TYPE_UINT16;
45
};
46
47
template <>
48
struct type_to_gguf_type<int16_t> {
49
    static constexpr enum gguf_type value = GGUF_TYPE_INT16;
50
};
51
52
template <>
53
struct type_to_gguf_type<uint32_t> {
54
    static constexpr enum gguf_type value = GGUF_TYPE_UINT32;
55
};
56
57
template <>
58
struct type_to_gguf_type<int32_t> {
59
    static constexpr enum gguf_type value = GGUF_TYPE_INT32;
60
};
61
62
template <>
63
struct type_to_gguf_type<float> {
64
    static constexpr enum gguf_type value = GGUF_TYPE_FLOAT32;
65
};
66
67
template <>
68
struct type_to_gguf_type<bool> {
69
    static constexpr enum gguf_type value = GGUF_TYPE_BOOL;
70
};
71
72
template <>
73
struct type_to_gguf_type<std::string> {
74
    static constexpr enum gguf_type value = GGUF_TYPE_STRING;
75
};
76
77
template <>
78
struct type_to_gguf_type<uint64_t> {
79
    static constexpr enum gguf_type value = GGUF_TYPE_UINT64;
80
};
81
82
template <>
83
struct type_to_gguf_type<int64_t> {
84
    static constexpr enum gguf_type value = GGUF_TYPE_INT64;
85
};
86
87
template <>
88
struct type_to_gguf_type<double> {
89
    static constexpr enum gguf_type value = GGUF_TYPE_FLOAT64;
90
};
91
92
static const std::map<gguf_type, size_t> GGUF_TYPE_SIZE = {
93
    {GGUF_TYPE_UINT8,   sizeof(uint8_t)},
94
    {GGUF_TYPE_INT8,    sizeof(int8_t)},
95
    {GGUF_TYPE_UINT16,  sizeof(uint16_t)},
96
    {GGUF_TYPE_INT16,   sizeof(int16_t)},
97
    {GGUF_TYPE_UINT32,  sizeof(uint32_t)},
98
    {GGUF_TYPE_INT32,   sizeof(int32_t)},
99
    {GGUF_TYPE_FLOAT32, sizeof(float)},
100
    {GGUF_TYPE_BOOL,    sizeof(int8_t)},
101
    {GGUF_TYPE_STRING,  0}, // undefined
102
    {GGUF_TYPE_ARRAY,   0}, // undefined
103
    {GGUF_TYPE_UINT64,  sizeof(uint64_t)},
104
    {GGUF_TYPE_INT64,   sizeof(int64_t)},
105
    {GGUF_TYPE_FLOAT64, sizeof(double)},
106
};
107
static_assert(GGUF_TYPE_COUNT == 13, "GGUF_TYPE_COUNT != 13");
108
109
static const std::map<gguf_type, const char *> GGUF_TYPE_NAME = {
110
    {GGUF_TYPE_UINT8,   "u8"},
111
    {GGUF_TYPE_INT8,    "i8"},
112
    {GGUF_TYPE_UINT16,  "u16"},
113
    {GGUF_TYPE_INT16,   "i16"},
114
    {GGUF_TYPE_UINT32,  "u32"},
115
    {GGUF_TYPE_INT32,   "i32"},
116
    {GGUF_TYPE_FLOAT32, "f32"},
117
    {GGUF_TYPE_BOOL,    "bool"},
118
    {GGUF_TYPE_STRING,  "str"},
119
    {GGUF_TYPE_ARRAY,   "arr"},
120
    {GGUF_TYPE_UINT64,  "u64"},
121
    {GGUF_TYPE_INT64,   "i64"},
122
    {GGUF_TYPE_FLOAT64, "f64"},
123
};
124
static_assert(GGUF_TYPE_COUNT == 13, "GGUF_TYPE_COUNT != 13");
125
126
12.4k
size_t gguf_type_size(enum gguf_type type) {
127
12.4k
    auto it = GGUF_TYPE_SIZE.find(type);
128
12.4k
    return it == GGUF_TYPE_SIZE.end() ? 0 : it->second;
129
12.4k
}
130
131
struct gguf_kv {
132
    std::string key;
133
134
    bool is_array;
135
    enum gguf_type type;
136
137
    std::vector<int8_t>      data;
138
    std::vector<std::string> data_string;
139
140
    template <typename T>
141
    gguf_kv(const std::string & key, const T value)
142
18.3k
            : key(key), is_array(false), type(type_to_gguf_type<T>::value) {
143
18.3k
        GGML_ASSERT(!key.empty());
144
18.3k
        data.resize(sizeof(T));
145
18.3k
        memcpy(data.data(), &value, sizeof(T));
146
18.3k
    }
gguf_kv::gguf_kv<unsigned char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned char)
Line
Count
Source
142
4.46k
            : key(key), is_array(false), type(type_to_gguf_type<T>::value) {
143
4.46k
        GGML_ASSERT(!key.empty());
144
4.46k
        data.resize(sizeof(T));
145
4.46k
        memcpy(data.data(), &value, sizeof(T));
146
4.46k
    }
gguf_kv::gguf_kv<signed char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, signed char)
Line
Count
Source
142
1.50k
            : key(key), is_array(false), type(type_to_gguf_type<T>::value) {
143
1.50k
        GGML_ASSERT(!key.empty());
144
1.50k
        data.resize(sizeof(T));
145
1.50k
        memcpy(data.data(), &value, sizeof(T));
146
1.50k
    }
gguf_kv::gguf_kv<unsigned short>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned short)
Line
Count
Source
142
2.26k
            : key(key), is_array(false), type(type_to_gguf_type<T>::value) {
143
2.26k
        GGML_ASSERT(!key.empty());
144
2.26k
        data.resize(sizeof(T));
145
2.26k
        memcpy(data.data(), &value, sizeof(T));
146
2.26k
    }
gguf_kv::gguf_kv<short>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, short)
Line
Count
Source
142
1.40k
            : key(key), is_array(false), type(type_to_gguf_type<T>::value) {
143
1.40k
        GGML_ASSERT(!key.empty());
144
1.40k
        data.resize(sizeof(T));
145
1.40k
        memcpy(data.data(), &value, sizeof(T));
146
1.40k
    }
gguf_kv::gguf_kv<unsigned int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned int)
Line
Count
Source
142
1.63k
            : key(key), is_array(false), type(type_to_gguf_type<T>::value) {
143
1.63k
        GGML_ASSERT(!key.empty());
144
1.63k
        data.resize(sizeof(T));
145
1.63k
        memcpy(data.data(), &value, sizeof(T));
146
1.63k
    }
gguf_kv::gguf_kv<int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)
Line
Count
Source
142
1.34k
            : key(key), is_array(false), type(type_to_gguf_type<T>::value) {
143
1.34k
        GGML_ASSERT(!key.empty());
144
1.34k
        data.resize(sizeof(T));
145
1.34k
        memcpy(data.data(), &value, sizeof(T));
146
1.34k
    }
gguf_kv::gguf_kv<float>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, float)
Line
Count
Source
142
1.17k
            : key(key), is_array(false), type(type_to_gguf_type<T>::value) {
143
1.17k
        GGML_ASSERT(!key.empty());
144
1.17k
        data.resize(sizeof(T));
145
1.17k
        memcpy(data.data(), &value, sizeof(T));
146
1.17k
    }
gguf_kv::gguf_kv<bool>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool)
Line
Count
Source
142
1.16k
            : key(key), is_array(false), type(type_to_gguf_type<T>::value) {
143
1.16k
        GGML_ASSERT(!key.empty());
144
1.16k
        data.resize(sizeof(T));
145
1.16k
        memcpy(data.data(), &value, sizeof(T));
146
1.16k
    }
gguf_kv::gguf_kv<unsigned long>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long)
Line
Count
Source
142
1.09k
            : key(key), is_array(false), type(type_to_gguf_type<T>::value) {
143
1.09k
        GGML_ASSERT(!key.empty());
144
1.09k
        data.resize(sizeof(T));
145
1.09k
        memcpy(data.data(), &value, sizeof(T));
146
1.09k
    }
gguf_kv::gguf_kv<long>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, long)
Line
Count
Source
142
1.06k
            : key(key), is_array(false), type(type_to_gguf_type<T>::value) {
143
1.06k
        GGML_ASSERT(!key.empty());
144
1.06k
        data.resize(sizeof(T));
145
1.06k
        memcpy(data.data(), &value, sizeof(T));
146
1.06k
    }
gguf_kv::gguf_kv<double>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, double)
Line
Count
Source
142
1.26k
            : key(key), is_array(false), type(type_to_gguf_type<T>::value) {
143
1.26k
        GGML_ASSERT(!key.empty());
144
1.26k
        data.resize(sizeof(T));
145
1.26k
        memcpy(data.data(), &value, sizeof(T));
146
1.26k
    }
147
148
    template <typename T>
149
    gguf_kv(const std::string & key, const std::vector<T> & value)
150
5.63k
            : key(key), is_array(true), type(type_to_gguf_type<T>::value) {
151
5.63k
        GGML_ASSERT(!key.empty());
152
5.63k
        data.resize(value.size()*sizeof(T));
153
6.40M
        for (size_t i = 0; i < value.size(); ++i) {
154
6.40M
            const T tmp = value[i];
155
6.40M
            memcpy(data.data() + i*sizeof(T), &tmp, sizeof(T));
156
6.40M
        }
157
5.63k
    }
gguf_kv::gguf_kv<unsigned char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Line
Count
Source
150
380
            : key(key), is_array(true), type(type_to_gguf_type<T>::value) {
151
380
        GGML_ASSERT(!key.empty());
152
380
        data.resize(value.size()*sizeof(T));
153
7.20k
        for (size_t i = 0; i < value.size(); ++i) {
154
6.82k
            const T tmp = value[i];
155
6.82k
            memcpy(data.data() + i*sizeof(T), &tmp, sizeof(T));
156
6.82k
        }
157
380
    }
gguf_kv::gguf_kv<signed char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<signed char, std::__1::allocator<signed char> > const&)
Line
Count
Source
150
419
            : key(key), is_array(true), type(type_to_gguf_type<T>::value) {
151
419
        GGML_ASSERT(!key.empty());
152
419
        data.resize(value.size()*sizeof(T));
153
40.0k
        for (size_t i = 0; i < value.size(); ++i) {
154
39.6k
            const T tmp = value[i];
155
39.6k
            memcpy(data.data() + i*sizeof(T), &tmp, sizeof(T));
156
39.6k
        }
157
419
    }
gguf_kv::gguf_kv<unsigned short>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<unsigned short, std::__1::allocator<unsigned short> > const&)
Line
Count
Source
150
587
            : key(key), is_array(true), type(type_to_gguf_type<T>::value) {
151
587
        GGML_ASSERT(!key.empty());
152
587
        data.resize(value.size()*sizeof(T));
153
9.85k
        for (size_t i = 0; i < value.size(); ++i) {
154
9.26k
            const T tmp = value[i];
155
9.26k
            memcpy(data.data() + i*sizeof(T), &tmp, sizeof(T));
156
9.26k
        }
157
587
    }
gguf_kv::gguf_kv<short>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<short, std::__1::allocator<short> > const&)
Line
Count
Source
150
918
            : key(key), is_array(true), type(type_to_gguf_type<T>::value) {
151
918
        GGML_ASSERT(!key.empty());
152
918
        data.resize(value.size()*sizeof(T));
153
6.80k
        for (size_t i = 0; i < value.size(); ++i) {
154
5.88k
            const T tmp = value[i];
155
5.88k
            memcpy(data.data() + i*sizeof(T), &tmp, sizeof(T));
156
5.88k
        }
157
918
    }
gguf_kv::gguf_kv<unsigned int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&)
Line
Count
Source
150
256
            : key(key), is_array(true), type(type_to_gguf_type<T>::value) {
151
256
        GGML_ASSERT(!key.empty());
152
256
        data.resize(value.size()*sizeof(T));
153
708k
        for (size_t i = 0; i < value.size(); ++i) {
154
708k
            const T tmp = value[i];
155
708k
            memcpy(data.data() + i*sizeof(T), &tmp, sizeof(T));
156
708k
        }
157
256
    }
gguf_kv::gguf_kv<int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> > const&)
Line
Count
Source
150
347
            : key(key), is_array(true), type(type_to_gguf_type<T>::value) {
151
347
        GGML_ASSERT(!key.empty());
152
347
        data.resize(value.size()*sizeof(T));
153
615k
        for (size_t i = 0; i < value.size(); ++i) {
154
615k
            const T tmp = value[i];
155
615k
            memcpy(data.data() + i*sizeof(T), &tmp, sizeof(T));
156
615k
        }
157
347
    }
gguf_kv::gguf_kv<float>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<float, std::__1::allocator<float> > const&)
Line
Count
Source
150
1.07k
            : key(key), is_array(true), type(type_to_gguf_type<T>::value) {
151
1.07k
        GGML_ASSERT(!key.empty());
152
1.07k
        data.resize(value.size()*sizeof(T));
153
1.55M
        for (size_t i = 0; i < value.size(); ++i) {
154
1.55M
            const T tmp = value[i];
155
1.55M
            memcpy(data.data() + i*sizeof(T), &tmp, sizeof(T));
156
1.55M
        }
157
1.07k
    }
gguf_kv::gguf_kv<bool>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<bool, std::__1::allocator<bool> > const&)
Line
Count
Source
150
413
            : key(key), is_array(true), type(type_to_gguf_type<T>::value) {
151
413
        GGML_ASSERT(!key.empty());
152
413
        data.resize(value.size()*sizeof(T));
153
1.50M
        for (size_t i = 0; i < value.size(); ++i) {
154
1.50M
            const T tmp = value[i];
155
1.50M
            memcpy(data.data() + i*sizeof(T), &tmp, sizeof(T));
156
1.50M
        }
157
413
    }
gguf_kv::gguf_kv<unsigned long>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<unsigned long, std::__1::allocator<unsigned long> > const&)
Line
Count
Source
150
452
            : key(key), is_array(true), type(type_to_gguf_type<T>::value) {
151
452
        GGML_ASSERT(!key.empty());
152
452
        data.resize(value.size()*sizeof(T));
153
782k
        for (size_t i = 0; i < value.size(); ++i) {
154
782k
            const T tmp = value[i];
155
782k
            memcpy(data.data() + i*sizeof(T), &tmp, sizeof(T));
156
782k
        }
157
452
    }
gguf_kv::gguf_kv<long>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<long, std::__1::allocator<long> > const&)
Line
Count
Source
150
322
            : key(key), is_array(true), type(type_to_gguf_type<T>::value) {
151
322
        GGML_ASSERT(!key.empty());
152
322
        data.resize(value.size()*sizeof(T));
153
544k
        for (size_t i = 0; i < value.size(); ++i) {
154
543k
            const T tmp = value[i];
155
543k
            memcpy(data.data() + i*sizeof(T), &tmp, sizeof(T));
156
543k
        }
157
322
    }
gguf_kv::gguf_kv<double>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<double, std::__1::allocator<double> > const&)
Line
Count
Source
150
463
            : key(key), is_array(true), type(type_to_gguf_type<T>::value) {
151
463
        GGML_ASSERT(!key.empty());
152
463
        data.resize(value.size()*sizeof(T));
153
625k
        for (size_t i = 0; i < value.size(); ++i) {
154
625k
            const T tmp = value[i];
155
625k
            memcpy(data.data() + i*sizeof(T), &tmp, sizeof(T));
156
625k
        }
157
463
    }
158
159
    gguf_kv(const std::string & key, const std::string & value)
160
1.53k
            : key(key), is_array(false), type(GGUF_TYPE_STRING) {
161
1.53k
        GGML_ASSERT(!key.empty());
162
1.53k
        data_string.push_back(value);
163
1.53k
    }
164
165
    gguf_kv(const std::string & key, const std::vector<std::string> & value)
166
851
            : key(key), is_array(true), type(GGUF_TYPE_STRING) {
167
851
        GGML_ASSERT(!key.empty());
168
851
        data_string = value;
169
851
    }
170
171
63.4k
    const std::string & get_key() const {
172
63.4k
        return key;
173
63.4k
    }
174
175
205k
    const enum gguf_type & get_type() const {
176
205k
        return type;
177
205k
    }
178
179
11.9k
    size_t get_ne() const {
180
11.9k
        if (type == GGUF_TYPE_STRING) {
181
1.67k
            const size_t ne = data_string.size();
182
1.67k
            GGML_ASSERT(is_array || ne == 1);
183
1.67k
            return ne;
184
1.67k
        }
185
10.2k
        const size_t type_size = gguf_type_size(type);
186
10.2k
        GGML_ASSERT(data.size() % type_size == 0);
187
10.2k
        const size_t ne = data.size() / type_size;
188
10.2k
        GGML_ASSERT(is_array || ne == 1);
189
10.2k
        return ne;
190
11.9k
    }
191
192
    template <typename T>
193
1.79k
    const T & get_val(const size_t i = 0) const {
194
1.79k
        GGML_ASSERT(type_to_gguf_type<T>::value == type);
195
1.79k
        if constexpr (std::is_same<T, std::string>::value) {
196
1.67k
            GGML_ASSERT(data_string.size() >= i+1);
197
1.67k
            return data_string[i];
198
1.67k
        }
199
0
        const size_t type_size = gguf_type_size(type);
200
1.79k
        GGML_ASSERT(data.size() % type_size == 0);
201
1.79k
        GGML_ASSERT(data.size() >= (i+1)*type_size);
202
1.79k
        return reinterpret_cast<const T *>(data.data())[i];
203
1.79k
    }
Unexecuted instantiation: unsigned char const& gguf_kv::get_val<unsigned char>(unsigned long) const
Unexecuted instantiation: signed char const& gguf_kv::get_val<signed char>(unsigned long) const
unsigned short const& gguf_kv::get_val<unsigned short>(unsigned long) const
Line
Count
Source
193
35
    const T & get_val(const size_t i = 0) const {
194
35
        GGML_ASSERT(type_to_gguf_type<T>::value == type);
195
        if constexpr (std::is_same<T, std::string>::value) {
196
            GGML_ASSERT(data_string.size() >= i+1);
197
            return data_string[i];
198
        }
199
35
        const size_t type_size = gguf_type_size(type);
200
35
        GGML_ASSERT(data.size() % type_size == 0);
201
35
        GGML_ASSERT(data.size() >= (i+1)*type_size);
202
35
        return reinterpret_cast<const T *>(data.data())[i];
203
35
    }
Unexecuted instantiation: short const& gguf_kv::get_val<short>(unsigned long) const
unsigned int const& gguf_kv::get_val<unsigned int>(unsigned long) const
Line
Count
Source
193
82
    const T & get_val(const size_t i = 0) const {
194
82
        GGML_ASSERT(type_to_gguf_type<T>::value == type);
195
        if constexpr (std::is_same<T, std::string>::value) {
196
            GGML_ASSERT(data_string.size() >= i+1);
197
            return data_string[i];
198
        }
199
82
        const size_t type_size = gguf_type_size(type);
200
82
        GGML_ASSERT(data.size() % type_size == 0);
201
82
        GGML_ASSERT(data.size() >= (i+1)*type_size);
202
82
        return reinterpret_cast<const T *>(data.data())[i];
203
82
    }
Unexecuted instantiation: int const& gguf_kv::get_val<int>(unsigned long) const
Unexecuted instantiation: float const& gguf_kv::get_val<float>(unsigned long) const
Unexecuted instantiation: unsigned long const& gguf_kv::get_val<unsigned long>(unsigned long) const
Unexecuted instantiation: long const& gguf_kv::get_val<long>(unsigned long) const
Unexecuted instantiation: double const& gguf_kv::get_val<double>(unsigned long) const
Unexecuted instantiation: bool const& gguf_kv::get_val<bool>(unsigned long) const
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const& gguf_kv::get_val<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(unsigned long) const
Line
Count
Source
193
1.67k
    const T & get_val(const size_t i = 0) const {
194
1.67k
        GGML_ASSERT(type_to_gguf_type<T>::value == type);
195
1.67k
        if constexpr (std::is_same<T, std::string>::value) {
196
1.67k
            GGML_ASSERT(data_string.size() >= i+1);
197
1.67k
            return data_string[i];
198
1.67k
        }
199
0
        const size_t type_size = gguf_type_size(type);
200
1.67k
        GGML_ASSERT(data.size() % type_size == 0);
201
1.67k
        GGML_ASSERT(data.size() >= (i+1)*type_size);
202
1.67k
        return reinterpret_cast<const T *>(data.data())[i];
203
1.67k
    }
204
205
0
    void cast(const enum gguf_type new_type) {
206
0
        const size_t new_type_size = gguf_type_size(new_type);
207
0
        GGML_ASSERT(data.size() % new_type_size == 0);
208
0
        type = new_type;
209
0
    }
210
};
211
212
struct gguf_tensor_info {
213
    struct ggml_tensor t; // for holding the equivalent info
214
    uint64_t offset;      // offset from start of `data`, must be a multiple of `ALIGNMENT`
215
};
216
217
struct gguf_context {
218
    uint32_t version = GGUF_VERSION;
219
220
    std::vector<struct gguf_kv> kv;
221
    std::vector<struct gguf_tensor_info> info;
222
223
    size_t alignment = GGUF_DEFAULT_ALIGNMENT;
224
    size_t offset    = 0; // offset of `data` from beginning of file
225
    size_t size      = 0; // size of `data` in bytes
226
227
    void * data = nullptr;
228
};
229
230
struct gguf_reader {
231
    gguf_reader(
232
            gguf_reader_callback_t callback,
233
            void * userdata,
234
            size_t max_chunk_read,
235
            uint64_t data_offset = 0,
236
            uint64_t nbytes_remain = 0)
237
8.45k
        : callback(callback),
238
8.45k
          userdata(userdata),
239
8.45k
          max_chunk_read(max_chunk_read),
240
8.45k
          data_offset(data_offset),
241
8.45k
          nbytes_remain(nbytes_remain) {
242
8.45k
        GGML_ASSERT(max_chunk_read > 0);
243
8.45k
    }
244
245
    // helper for remaining bytes in a file
246
8.45k
    static uint64_t file_remain(FILE * file) {
247
8.45k
        const int64_t cur = gguf_ftell(file);
248
8.45k
        if (cur < 0) {
249
0
            return 0;
250
0
        }
251
8.45k
        if (gguf_fseek(file, 0, SEEK_END) != 0) {
252
0
            gguf_fseek(file, cur, SEEK_SET);
253
254
0
            return 0;
255
0
        }
256
8.45k
        const int64_t end = gguf_ftell(file);
257
8.45k
        if (end < 0) {
258
0
            gguf_fseek(file, cur, SEEK_SET);
259
260
0
            return 0;
261
0
        }
262
8.45k
        gguf_fseek(file, cur, SEEK_SET);
263
8.45k
        return static_cast<uint64_t>(end - cur);
264
8.45k
    }
265
266
    template <typename T>
267
6.76M
    bool read(T & dst) const {
268
6.76M
        const size_t size = sizeof(dst);
269
6.76M
        if (size > nbytes_remain) {
270
1.24k
            return false;
271
1.24k
        }
272
6.76M
        return read_raw(&dst, size) == size;
273
6.76M
    }
bool gguf_reader::read<char>(char&) const
Line
Count
Source
267
33.8k
    bool read(T & dst) const {
268
33.8k
        const size_t size = sizeof(dst);
269
33.8k
        if (size > nbytes_remain) {
270
0
            return false;
271
0
        }
272
33.8k
        return read_raw(&dst, size) == size;
273
33.8k
    }
bool gguf_reader::read<unsigned int>(unsigned int&) const
Line
Count
Source
267
725k
    bool read(T & dst) const {
268
725k
        const size_t size = sizeof(dst);
269
725k
        if (size > nbytes_remain) {
270
63
            return false;
271
63
        }
272
725k
        return read_raw(&dst, size) == size;
273
725k
    }
bool gguf_reader::read<long>(long&) const
Line
Count
Source
267
573k
    bool read(T & dst) const {
268
573k
        const size_t size = sizeof(dst);
269
573k
        if (size > nbytes_remain) {
270
224
            return false;
271
224
        }
272
573k
        return read_raw(&dst, size) == size;
273
573k
    }
bool gguf_reader::read<int>(int&) const
Line
Count
Source
267
658k
    bool read(T & dst) const {
268
658k
        const size_t size = sizeof(dst);
269
658k
        if (size > nbytes_remain) {
270
141
            return false;
271
141
        }
272
658k
        return read_raw(&dst, size) == size;
273
658k
    }
bool gguf_reader::read<unsigned long>(unsigned long&) const
Line
Count
Source
267
1.01M
    bool read(T & dst) const {
268
1.01M
        const size_t size = sizeof(dst);
269
1.01M
        if (size > nbytes_remain) {
270
787
            return false;
271
787
        }
272
1.00M
        return read_raw(&dst, size) == size;
273
1.01M
    }
bool gguf_reader::read<unsigned char>(unsigned char&) const
Line
Count
Source
267
11.2k
    bool read(T & dst) const {
268
11.2k
        const size_t size = sizeof(dst);
269
11.2k
        if (size > nbytes_remain) {
270
5
            return false;
271
5
        }
272
11.2k
        return read_raw(&dst, size) == size;
273
11.2k
    }
bool gguf_reader::read<signed char>(signed char&) const
Line
Count
Source
267
1.55M
    bool read(T & dst) const {
268
1.55M
        const size_t size = sizeof(dst);
269
1.55M
        if (size > nbytes_remain) {
270
6
            return false;
271
6
        }
272
1.55M
        return read_raw(&dst, size) == size;
273
1.55M
    }
bool gguf_reader::read<unsigned short>(unsigned short&) const
Line
Count
Source
267
11.5k
    bool read(T & dst) const {
268
11.5k
        const size_t size = sizeof(dst);
269
11.5k
        if (size > nbytes_remain) {
270
3
            return false;
271
3
        }
272
11.5k
        return read_raw(&dst, size) == size;
273
11.5k
    }
bool gguf_reader::read<short>(short&) const
Line
Count
Source
267
7.29k
    bool read(T & dst) const {
268
7.29k
        const size_t size = sizeof(dst);
269
7.29k
        if (size > nbytes_remain) {
270
4
            return false;
271
4
        }
272
7.29k
        return read_raw(&dst, size) == size;
273
7.29k
    }
bool gguf_reader::read<float>(float&) const
Line
Count
Source
267
1.55M
    bool read(T & dst) const {
268
1.55M
        const size_t size = sizeof(dst);
269
1.55M
        if (size > nbytes_remain) {
270
3
            return false;
271
3
        }
272
1.55M
        return read_raw(&dst, size) == size;
273
1.55M
    }
bool gguf_reader::read<double>(double&) const
Line
Count
Source
267
626k
    bool read(T & dst) const {
268
626k
        const size_t size = sizeof(dst);
269
626k
        if (size > nbytes_remain) {
270
6
            return false;
271
6
        }
272
626k
        return read_raw(&dst, size) == size;
273
626k
    }
274
275
    template <typename T>
276
16.0k
    bool read(std::vector<T> & dst, const size_t n) const {
277
16.0k
        if (n > GGUF_MAX_ARRAY_ELEMENTS) {
278
709
            return false;
279
709
        }
280
15.3k
        if constexpr (std::is_same<T, std::string>::value) {
281
            // strings are prefixed with their length, so we need to account for that
282
914
            if (n > SIZE_MAX / sizeof(uint64_t)) {
283
0
                return false;
284
0
            }
285
914
            if (nbytes_remain < n * sizeof(uint64_t)) {
286
10
                return false;
287
10
            }
288
14.4k
        } else {
289
14.4k
            if (n > SIZE_MAX / sizeof(T)) {
290
0
                return false;
291
0
            }
292
14.4k
            if (nbytes_remain < n * sizeof(T)) {
293
322
                return false;
294
322
            }
295
14.4k
        }
296
14.9k
        dst.resize(n);
297
6.62M
        for (size_t i = 0; i < dst.size(); ++i) {
298
6.61M
            if constexpr (std::is_same<T, bool>::value) {
299
1.50M
                bool tmp;
300
1.50M
                if (!read(tmp)) {
301
0
                    return false;
302
0
                }
303
1.50M
                dst[i] = tmp;
304
5.10M
            } else {
305
5.10M
                if (!read(dst[i])) {
306
53
                    return false;
307
53
                }
308
5.10M
            }
309
6.61M
        }
310
15.3k
        return true;
311
16.0k
    }
bool gguf_reader::read<char>(std::__1::vector<char, std::__1::allocator<char> >&, unsigned long) const
Line
Count
Source
276
8.45k
    bool read(std::vector<T> & dst, const size_t n) const {
277
8.45k
        if (n > GGUF_MAX_ARRAY_ELEMENTS) {
278
0
            return false;
279
0
        }
280
        if constexpr (std::is_same<T, std::string>::value) {
281
            // strings are prefixed with their length, so we need to account for that
282
            if (n > SIZE_MAX / sizeof(uint64_t)) {
283
                return false;
284
            }
285
            if (nbytes_remain < n * sizeof(uint64_t)) {
286
                return false;
287
            }
288
8.45k
        } else {
289
8.45k
            if (n > SIZE_MAX / sizeof(T)) {
290
0
                return false;
291
0
            }
292
8.45k
            if (nbytes_remain < n * sizeof(T)) {
293
3
                return false;
294
3
            }
295
8.45k
        }
296
8.45k
        dst.resize(n);
297
42.2k
        for (size_t i = 0; i < dst.size(); ++i) {
298
            if constexpr (std::is_same<T, bool>::value) {
299
                bool tmp;
300
                if (!read(tmp)) {
301
                    return false;
302
                }
303
                dst[i] = tmp;
304
33.8k
            } else {
305
33.8k
                if (!read(dst[i])) {
306
0
                    return false;
307
0
                }
308
33.8k
            }
309
33.8k
        }
310
8.45k
        return true;
311
8.45k
    }
bool gguf_reader::read<unsigned char>(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, unsigned long) const
Line
Count
Source
276
471
    bool read(std::vector<T> & dst, const size_t n) const {
277
471
        if (n > GGUF_MAX_ARRAY_ELEMENTS) {
278
55
            return false;
279
55
        }
280
        if constexpr (std::is_same<T, std::string>::value) {
281
            // strings are prefixed with their length, so we need to account for that
282
            if (n > SIZE_MAX / sizeof(uint64_t)) {
283
                return false;
284
            }
285
            if (nbytes_remain < n * sizeof(uint64_t)) {
286
                return false;
287
            }
288
416
        } else {
289
416
            if (n > SIZE_MAX / sizeof(T)) {
290
0
                return false;
291
0
            }
292
416
            if (nbytes_remain < n * sizeof(T)) {
293
36
                return false;
294
36
            }
295
416
        }
296
380
        dst.resize(n);
297
7.24k
        for (size_t i = 0; i < dst.size(); ++i) {
298
            if constexpr (std::is_same<T, bool>::value) {
299
                bool tmp;
300
                if (!read(tmp)) {
301
                    return false;
302
                }
303
                dst[i] = tmp;
304
6.82k
            } else {
305
6.82k
                if (!read(dst[i])) {
306
0
                    return false;
307
0
                }
308
6.82k
            }
309
6.82k
        }
310
416
        return true;
311
471
    }
bool gguf_reader::read<signed char>(std::__1::vector<signed char, std::__1::allocator<signed char> >&, unsigned long) const
Line
Count
Source
276
487
    bool read(std::vector<T> & dst, const size_t n) const {
277
487
        if (n > GGUF_MAX_ARRAY_ELEMENTS) {
278
46
            return false;
279
46
        }
280
        if constexpr (std::is_same<T, std::string>::value) {
281
            // strings are prefixed with their length, so we need to account for that
282
            if (n > SIZE_MAX / sizeof(uint64_t)) {
283
                return false;
284
            }
285
            if (nbytes_remain < n * sizeof(uint64_t)) {
286
                return false;
287
            }
288
441
        } else {
289
441
            if (n > SIZE_MAX / sizeof(T)) {
290
0
                return false;
291
0
            }
292
441
            if (nbytes_remain < n * sizeof(T)) {
293
22
                return false;
294
22
            }
295
441
        }
296
419
        dst.resize(n);
297
40.1k
        for (size_t i = 0; i < dst.size(); ++i) {
298
            if constexpr (std::is_same<T, bool>::value) {
299
                bool tmp;
300
                if (!read(tmp)) {
301
                    return false;
302
                }
303
                dst[i] = tmp;
304
39.6k
            } else {
305
39.6k
                if (!read(dst[i])) {
306
0
                    return false;
307
0
                }
308
39.6k
            }
309
39.6k
        }
310
441
        return true;
311
487
    }
bool gguf_reader::read<unsigned short>(std::__1::vector<unsigned short, std::__1::allocator<unsigned short> >&, unsigned long) const
Line
Count
Source
276
666
    bool read(std::vector<T> & dst, const size_t n) const {
277
666
        if (n > GGUF_MAX_ARRAY_ELEMENTS) {
278
52
            return false;
279
52
        }
280
        if constexpr (std::is_same<T, std::string>::value) {
281
            // strings are prefixed with their length, so we need to account for that
282
            if (n > SIZE_MAX / sizeof(uint64_t)) {
283
                return false;
284
            }
285
            if (nbytes_remain < n * sizeof(uint64_t)) {
286
                return false;
287
            }
288
614
        } else {
289
614
            if (n > SIZE_MAX / sizeof(T)) {
290
0
                return false;
291
0
            }
292
614
            if (nbytes_remain < n * sizeof(T)) {
293
27
                return false;
294
27
            }
295
614
        }
296
587
        dst.resize(n);
297
9.88k
        for (size_t i = 0; i < dst.size(); ++i) {
298
            if constexpr (std::is_same<T, bool>::value) {
299
                bool tmp;
300
                if (!read(tmp)) {
301
                    return false;
302
                }
303
                dst[i] = tmp;
304
9.26k
            } else {
305
9.26k
                if (!read(dst[i])) {
306
0
                    return false;
307
0
                }
308
9.26k
            }
309
9.26k
        }
310
614
        return true;
311
666
    }
bool gguf_reader::read<short>(std::__1::vector<short, std::__1::allocator<short> >&, unsigned long) const
Line
Count
Source
276
1.01k
    bool read(std::vector<T> & dst, const size_t n) const {
277
1.01k
        if (n > GGUF_MAX_ARRAY_ELEMENTS) {
278
64
            return false;
279
64
        }
280
        if constexpr (std::is_same<T, std::string>::value) {
281
            // strings are prefixed with their length, so we need to account for that
282
            if (n > SIZE_MAX / sizeof(uint64_t)) {
283
                return false;
284
            }
285
            if (nbytes_remain < n * sizeof(uint64_t)) {
286
                return false;
287
            }
288
951
        } else {
289
951
            if (n > SIZE_MAX / sizeof(T)) {
290
0
                return false;
291
0
            }
292
951
            if (nbytes_remain < n * sizeof(T)) {
293
33
                return false;
294
33
            }
295
951
        }
296
918
        dst.resize(n);
297
6.83k
        for (size_t i = 0; i < dst.size(); ++i) {
298
            if constexpr (std::is_same<T, bool>::value) {
299
                bool tmp;
300
                if (!read(tmp)) {
301
                    return false;
302
                }
303
                dst[i] = tmp;
304
5.88k
            } else {
305
5.88k
                if (!read(dst[i])) {
306
0
                    return false;
307
0
                }
308
5.88k
            }
309
5.88k
        }
310
951
        return true;
311
1.01k
    }
bool gguf_reader::read<unsigned int>(std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&, unsigned long) const
Line
Count
Source
276
294
    bool read(std::vector<T> & dst, const size_t n) const {
277
294
        if (n > GGUF_MAX_ARRAY_ELEMENTS) {
278
32
            return false;
279
32
        }
280
        if constexpr (std::is_same<T, std::string>::value) {
281
            // strings are prefixed with their length, so we need to account for that
282
            if (n > SIZE_MAX / sizeof(uint64_t)) {
283
                return false;
284
            }
285
            if (nbytes_remain < n * sizeof(uint64_t)) {
286
                return false;
287
            }
288
262
        } else {
289
262
            if (n > SIZE_MAX / sizeof(T)) {
290
0
                return false;
291
0
            }
292
262
            if (nbytes_remain < n * sizeof(T)) {
293
6
                return false;
294
6
            }
295
262
        }
296
256
        dst.resize(n);
297
708k
        for (size_t i = 0; i < dst.size(); ++i) {
298
            if constexpr (std::is_same<T, bool>::value) {
299
                bool tmp;
300
                if (!read(tmp)) {
301
                    return false;
302
                }
303
                dst[i] = tmp;
304
708k
            } else {
305
708k
                if (!read(dst[i])) {
306
0
                    return false;
307
0
                }
308
708k
            }
309
708k
        }
310
262
        return true;
311
294
    }
bool gguf_reader::read<int>(std::__1::vector<int, std::__1::allocator<int> >&, unsigned long) const
Line
Count
Source
276
471
    bool read(std::vector<T> & dst, const size_t n) const {
277
471
        if (n > GGUF_MAX_ARRAY_ELEMENTS) {
278
83
            return false;
279
83
        }
280
        if constexpr (std::is_same<T, std::string>::value) {
281
            // strings are prefixed with their length, so we need to account for that
282
            if (n > SIZE_MAX / sizeof(uint64_t)) {
283
                return false;
284
            }
285
            if (nbytes_remain < n * sizeof(uint64_t)) {
286
                return false;
287
            }
288
388
        } else {
289
388
            if (n > SIZE_MAX / sizeof(T)) {
290
0
                return false;
291
0
            }
292
388
            if (nbytes_remain < n * sizeof(T)) {
293
41
                return false;
294
41
            }
295
388
        }
296
347
        dst.resize(n);
297
615k
        for (size_t i = 0; i < dst.size(); ++i) {
298
            if constexpr (std::is_same<T, bool>::value) {
299
                bool tmp;
300
                if (!read(tmp)) {
301
                    return false;
302
                }
303
                dst[i] = tmp;
304
615k
            } else {
305
615k
                if (!read(dst[i])) {
306
0
                    return false;
307
0
                }
308
615k
            }
309
615k
        }
310
388
        return true;
311
471
    }
bool gguf_reader::read<float>(std::__1::vector<float, std::__1::allocator<float> >&, unsigned long) const
Line
Count
Source
276
1.18k
    bool read(std::vector<T> & dst, const size_t n) const {
277
1.18k
        if (n > GGUF_MAX_ARRAY_ELEMENTS) {
278
78
            return false;
279
78
        }
280
        if constexpr (std::is_same<T, std::string>::value) {
281
            // strings are prefixed with their length, so we need to account for that
282
            if (n > SIZE_MAX / sizeof(uint64_t)) {
283
                return false;
284
            }
285
            if (nbytes_remain < n * sizeof(uint64_t)) {
286
                return false;
287
            }
288
1.11k
        } else {
289
1.11k
            if (n > SIZE_MAX / sizeof(T)) {
290
0
                return false;
291
0
            }
292
1.11k
            if (nbytes_remain < n * sizeof(T)) {
293
37
                return false;
294
37
            }
295
1.11k
        }
296
1.07k
        dst.resize(n);
297
1.55M
        for (size_t i = 0; i < dst.size(); ++i) {
298
            if constexpr (std::is_same<T, bool>::value) {
299
                bool tmp;
300
                if (!read(tmp)) {
301
                    return false;
302
                }
303
                dst[i] = tmp;
304
1.55M
            } else {
305
1.55M
                if (!read(dst[i])) {
306
0
                    return false;
307
0
                }
308
1.55M
            }
309
1.55M
        }
310
1.11k
        return true;
311
1.18k
    }
bool gguf_reader::read<bool>(std::__1::vector<bool, std::__1::allocator<bool> >&, unsigned long) const
Line
Count
Source
276
522
    bool read(std::vector<T> & dst, const size_t n) const {
277
522
        if (n > GGUF_MAX_ARRAY_ELEMENTS) {
278
79
            return false;
279
79
        }
280
        if constexpr (std::is_same<T, std::string>::value) {
281
            // strings are prefixed with their length, so we need to account for that
282
            if (n > SIZE_MAX / sizeof(uint64_t)) {
283
                return false;
284
            }
285
            if (nbytes_remain < n * sizeof(uint64_t)) {
286
                return false;
287
            }
288
443
        } else {
289
443
            if (n > SIZE_MAX / sizeof(T)) {
290
0
                return false;
291
0
            }
292
443
            if (nbytes_remain < n * sizeof(T)) {
293
30
                return false;
294
30
            }
295
443
        }
296
413
        dst.resize(n);
297
1.50M
        for (size_t i = 0; i < dst.size(); ++i) {
298
1.50M
            if constexpr (std::is_same<T, bool>::value) {
299
1.50M
                bool tmp;
300
1.50M
                if (!read(tmp)) {
301
0
                    return false;
302
0
                }
303
1.50M
                dst[i] = tmp;
304
            } else {
305
                if (!read(dst[i])) {
306
                    return false;
307
                }
308
            }
309
1.50M
        }
310
443
        return true;
311
522
    }
bool gguf_reader::read<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, unsigned long) const
Line
Count
Source
276
968
    bool read(std::vector<T> & dst, const size_t n) const {
277
968
        if (n > GGUF_MAX_ARRAY_ELEMENTS) {
278
54
            return false;
279
54
        }
280
914
        if constexpr (std::is_same<T, std::string>::value) {
281
            // strings are prefixed with their length, so we need to account for that
282
914
            if (n > SIZE_MAX / sizeof(uint64_t)) {
283
0
                return false;
284
0
            }
285
914
            if (nbytes_remain < n * sizeof(uint64_t)) {
286
10
                return false;
287
10
            }
288
        } else {
289
            if (n > SIZE_MAX / sizeof(T)) {
290
                return false;
291
            }
292
            if (nbytes_remain < n * sizeof(T)) {
293
                return false;
294
            }
295
        }
296
904
        dst.resize(n);
297
176k
        for (size_t i = 0; i < dst.size(); ++i) {
298
            if constexpr (std::is_same<T, bool>::value) {
299
                bool tmp;
300
                if (!read(tmp)) {
301
                    return false;
302
                }
303
                dst[i] = tmp;
304
175k
            } else {
305
175k
                if (!read(dst[i])) {
306
53
                    return false;
307
53
                }
308
175k
            }
309
175k
        }
310
914
        return true;
311
968
    }
bool gguf_reader::read<unsigned long>(std::__1::vector<unsigned long, std::__1::allocator<unsigned long> >&, unsigned long) const
Line
Count
Source
276
540
    bool read(std::vector<T> & dst, const size_t n) const {
277
540
        if (n > GGUF_MAX_ARRAY_ELEMENTS) {
278
54
            return false;
279
54
        }
280
        if constexpr (std::is_same<T, std::string>::value) {
281
            // strings are prefixed with their length, so we need to account for that
282
            if (n > SIZE_MAX / sizeof(uint64_t)) {
283
                return false;
284
            }
285
            if (nbytes_remain < n * sizeof(uint64_t)) {
286
                return false;
287
            }
288
486
        } else {
289
486
            if (n > SIZE_MAX / sizeof(T)) {
290
0
                return false;
291
0
            }
292
486
            if (nbytes_remain < n * sizeof(T)) {
293
34
                return false;
294
34
            }
295
486
        }
296
452
        dst.resize(n);
297
782k
        for (size_t i = 0; i < dst.size(); ++i) {
298
            if constexpr (std::is_same<T, bool>::value) {
299
                bool tmp;
300
                if (!read(tmp)) {
301
                    return false;
302
                }
303
                dst[i] = tmp;
304
782k
            } else {
305
782k
                if (!read(dst[i])) {
306
0
                    return false;
307
0
                }
308
782k
            }
309
782k
        }
310
486
        return true;
311
540
    }
bool gguf_reader::read<long>(std::__1::vector<long, std::__1::allocator<long> >&, unsigned long) const
Line
Count
Source
276
406
    bool read(std::vector<T> & dst, const size_t n) const {
277
406
        if (n > GGUF_MAX_ARRAY_ELEMENTS) {
278
57
            return false;
279
57
        }
280
        if constexpr (std::is_same<T, std::string>::value) {
281
            // strings are prefixed with their length, so we need to account for that
282
            if (n > SIZE_MAX / sizeof(uint64_t)) {
283
                return false;
284
            }
285
            if (nbytes_remain < n * sizeof(uint64_t)) {
286
                return false;
287
            }
288
349
        } else {
289
349
            if (n > SIZE_MAX / sizeof(T)) {
290
0
                return false;
291
0
            }
292
349
            if (nbytes_remain < n * sizeof(T)) {
293
27
                return false;
294
27
            }
295
349
        }
296
322
        dst.resize(n);
297
544k
        for (size_t i = 0; i < dst.size(); ++i) {
298
            if constexpr (std::is_same<T, bool>::value) {
299
                bool tmp;
300
                if (!read(tmp)) {
301
                    return false;
302
                }
303
                dst[i] = tmp;
304
543k
            } else {
305
543k
                if (!read(dst[i])) {
306
0
                    return false;
307
0
                }
308
543k
            }
309
543k
        }
310
349
        return true;
311
406
    }
bool gguf_reader::read<double>(std::__1::vector<double, std::__1::allocator<double> >&, unsigned long) const
Line
Count
Source
276
544
    bool read(std::vector<T> & dst, const size_t n) const {
277
544
        if (n > GGUF_MAX_ARRAY_ELEMENTS) {
278
55
            return false;
279
55
        }
280
        if constexpr (std::is_same<T, std::string>::value) {
281
            // strings are prefixed with their length, so we need to account for that
282
            if (n > SIZE_MAX / sizeof(uint64_t)) {
283
                return false;
284
            }
285
            if (nbytes_remain < n * sizeof(uint64_t)) {
286
                return false;
287
            }
288
489
        } else {
289
489
            if (n > SIZE_MAX / sizeof(T)) {
290
0
                return false;
291
0
            }
292
489
            if (nbytes_remain < n * sizeof(T)) {
293
26
                return false;
294
26
            }
295
489
        }
296
463
        dst.resize(n);
297
625k
        for (size_t i = 0; i < dst.size(); ++i) {
298
            if constexpr (std::is_same<T, bool>::value) {
299
                bool tmp;
300
                if (!read(tmp)) {
301
                    return false;
302
                }
303
                dst[i] = tmp;
304
625k
            } else {
305
625k
                if (!read(dst[i])) {
306
0
                    return false;
307
0
                }
308
625k
            }
309
625k
        }
310
489
        return true;
311
544
    }
312
313
1.51M
    bool read(bool & dst) const {
314
1.51M
        int8_t tmp = -1;
315
1.51M
        if (!read(tmp)) {
316
3
            return false;
317
3
        }
318
1.51M
        dst = tmp != 0;
319
1.51M
        return true;
320
1.51M
    }
321
322
5.78k
    bool read(enum ggml_type & dst) const {
323
5.78k
        int32_t tmp = -1;
324
5.78k
        if (!read(tmp)) {
325
58
            return false;
326
58
        }
327
5.72k
        dst = ggml_type(tmp);
328
5.72k
        return true;
329
5.78k
    }
330
331
35.7k
    bool read(enum gguf_type & dst) const {
332
35.7k
        int32_t tmp = -1;
333
35.7k
        if (!read(tmp)) {
334
80
            return false;
335
80
        }
336
35.6k
        dst = gguf_type(tmp);
337
35.6k
        return true;
338
35.7k
    }
339
340
214k
    bool read(std::string & dst) const {
341
214k
        uint64_t size = 0;
342
214k
        if (!read(size)) {
343
697
            return false;
344
697
        }
345
213k
        if (size > GGUF_MAX_STRING_LENGTH) {
346
780
            GGML_LOG_ERROR("%s: string length %" PRIu64 " exceeds maximum %" PRIu64 "\n", __func__, size, (uint64_t) GGUF_MAX_STRING_LENGTH);
347
780
            return false;
348
780
        }
349
212k
        if (size > nbytes_remain) {
350
461
            GGML_LOG_ERROR("%s: string length %" PRIu64 " exceeds remaining file size %" PRIu64 " bytes\n", __func__, size, nbytes_remain);
351
461
            return false;
352
461
        }
353
212k
        dst.resize(static_cast<size_t>(size));
354
212k
        return read_raw(dst.data(), static_cast<size_t>(size)) == size;
355
212k
    }
356
357
0
    bool read(void * dst, const size_t size) const {
358
0
        if (size > nbytes_remain) {
359
0
            return false;
360
0
        }
361
0
        return read_raw(dst, size) == size;
362
0
    }
363
364
3.50k
    uint64_t tell() const {
365
3.50k
        return data_offset;
366
3.50k
    }
367
368
1.10k
    bool seek(uint64_t absolute_offset) const {
369
1.10k
        const uint64_t end_offset = uint64_t(data_offset) + nbytes_remain;
370
1.10k
        if (absolute_offset > end_offset) {
371
36
            return false;
372
36
        }
373
374
1.07k
        data_offset = absolute_offset;
375
1.07k
        nbytes_remain = end_offset - absolute_offset;
376
377
1.07k
        return true;
378
1.10k
    }
379
380
private:
381
6.97M
    size_t read_raw(void * dst, size_t size) const {
382
6.97M
        if (callback == nullptr || size == 0) {
383
173k
            return 0;
384
173k
        }
385
386
6.80M
        uint8_t * data = static_cast<uint8_t *>(dst);
387
6.80M
        size_t total_nread = 0;
388
6.80M
        bool reached_eof = false;
389
390
13.6M
        while (total_nread < size) {
391
6.80M
            const size_t chunk_size = std::min(max_chunk_read, size - total_nread);
392
6.80M
            if (data_offset + total_nread < data_offset) {
393
0
                break;
394
0
            }
395
6.80M
            const size_t nread = callback(userdata, static_cast<void *>(data + total_nread), data_offset + total_nread, chunk_size);
396
6.80M
            total_nread += nread;
397
6.80M
            if (nread != chunk_size) {
398
0
                reached_eof = true;
399
0
                break;
400
0
            }
401
6.80M
        }
402
403
6.80M
        data_offset += total_nread;
404
6.80M
        GGML_ASSERT(total_nread <= nbytes_remain);
405
6.80M
        nbytes_remain -= total_nread;
406
407
6.80M
        if (reached_eof) {
408
0
            nbytes_remain = 0;
409
0
        }
410
411
6.80M
        return total_nread;
412
6.97M
    }
413
414
    gguf_reader_callback_t callback = nullptr;
415
    void * userdata = nullptr;
416
    size_t max_chunk_read = 0;
417
    mutable uint64_t data_offset = 0;
418
    mutable uint64_t nbytes_remain = 0;
419
};
420
421
0
struct gguf_context * gguf_init_empty(void) {
422
0
    return new gguf_context;
423
0
}
424
425
template<typename T>
426
27.5k
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) {
427
27.5k
    if (is_array) {
428
7.57k
        std::vector<T> value;
429
7.57k
        try {
430
7.57k
            if (!gr.read(value, n)) {
431
1.09k
                return false;
432
1.09k
            }
433
7.57k
        } catch (std::length_error &) {
434
0
            GGML_LOG_ERROR("%s: encountered length_error while reading value for key '%s'\n", __func__, key.c_str());
435
0
            return false;
436
0
        } catch (std::bad_alloc &) {
437
0
            GGML_LOG_ERROR("%s: encountered bad_alloc error while reading value for key '%s'\n", __func__, key.c_str());
438
0
            return false;
439
0
        }
440
6.48k
        kv.emplace_back(key, value);
441
19.9k
    } else {
442
19.9k
        T value;
443
19.9k
        if (!gr.read(value)) {
444
63
            return false;
445
63
        }
446
19.9k
        kv.emplace_back(key, value);
447
19.9k
    }
448
26.4k
    return true;
449
27.5k
}
bool gguf_read_emplace_helper<unsigned char>(gguf_reader const&, std::__1::vector<gguf_kv, std::__1::allocator<gguf_kv> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, unsigned long)
Line
Count
Source
426
4.94k
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) {
427
4.94k
    if (is_array) {
428
471
        std::vector<T> value;
429
471
        try {
430
471
            if (!gr.read(value, n)) {
431
91
                return false;
432
91
            }
433
471
        } catch (std::length_error &) {
434
0
            GGML_LOG_ERROR("%s: encountered length_error while reading value for key '%s'\n", __func__, key.c_str());
435
0
            return false;
436
0
        } catch (std::bad_alloc &) {
437
0
            GGML_LOG_ERROR("%s: encountered bad_alloc error while reading value for key '%s'\n", __func__, key.c_str());
438
0
            return false;
439
0
        }
440
380
        kv.emplace_back(key, value);
441
4.46k
    } else {
442
4.46k
        T value;
443
4.46k
        if (!gr.read(value)) {
444
5
            return false;
445
5
        }
446
4.46k
        kv.emplace_back(key, value);
447
4.46k
    }
448
4.84k
    return true;
449
4.94k
}
bool gguf_read_emplace_helper<signed char>(gguf_reader const&, std::__1::vector<gguf_kv, std::__1::allocator<gguf_kv> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, unsigned long)
Line
Count
Source
426
1.99k
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) {
427
1.99k
    if (is_array) {
428
487
        std::vector<T> value;
429
487
        try {
430
487
            if (!gr.read(value, n)) {
431
68
                return false;
432
68
            }
433
487
        } catch (std::length_error &) {
434
0
            GGML_LOG_ERROR("%s: encountered length_error while reading value for key '%s'\n", __func__, key.c_str());
435
0
            return false;
436
0
        } catch (std::bad_alloc &) {
437
0
            GGML_LOG_ERROR("%s: encountered bad_alloc error while reading value for key '%s'\n", __func__, key.c_str());
438
0
            return false;
439
0
        }
440
419
        kv.emplace_back(key, value);
441
1.50k
    } else {
442
1.50k
        T value;
443
1.50k
        if (!gr.read(value)) {
444
3
            return false;
445
3
        }
446
1.50k
        kv.emplace_back(key, value);
447
1.50k
    }
448
1.92k
    return true;
449
1.99k
}
bool gguf_read_emplace_helper<unsigned short>(gguf_reader const&, std::__1::vector<gguf_kv, std::__1::allocator<gguf_kv> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, unsigned long)
Line
Count
Source
426
2.93k
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) {
427
2.93k
    if (is_array) {
428
666
        std::vector<T> value;
429
666
        try {
430
666
            if (!gr.read(value, n)) {
431
79
                return false;
432
79
            }
433
666
        } catch (std::length_error &) {
434
0
            GGML_LOG_ERROR("%s: encountered length_error while reading value for key '%s'\n", __func__, key.c_str());
435
0
            return false;
436
0
        } catch (std::bad_alloc &) {
437
0
            GGML_LOG_ERROR("%s: encountered bad_alloc error while reading value for key '%s'\n", __func__, key.c_str());
438
0
            return false;
439
0
        }
440
587
        kv.emplace_back(key, value);
441
2.26k
    } else {
442
2.26k
        T value;
443
2.26k
        if (!gr.read(value)) {
444
3
            return false;
445
3
        }
446
2.26k
        kv.emplace_back(key, value);
447
2.26k
    }
448
2.85k
    return true;
449
2.93k
}
bool gguf_read_emplace_helper<short>(gguf_reader const&, std::__1::vector<gguf_kv, std::__1::allocator<gguf_kv> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, unsigned long)
Line
Count
Source
426
2.42k
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) {
427
2.42k
    if (is_array) {
428
1.01k
        std::vector<T> value;
429
1.01k
        try {
430
1.01k
            if (!gr.read(value, n)) {
431
97
                return false;
432
97
            }
433
1.01k
        } catch (std::length_error &) {
434
0
            GGML_LOG_ERROR("%s: encountered length_error while reading value for key '%s'\n", __func__, key.c_str());
435
0
            return false;
436
0
        } catch (std::bad_alloc &) {
437
0
            GGML_LOG_ERROR("%s: encountered bad_alloc error while reading value for key '%s'\n", __func__, key.c_str());
438
0
            return false;
439
0
        }
440
918
        kv.emplace_back(key, value);
441
1.41k
    } else {
442
1.41k
        T value;
443
1.41k
        if (!gr.read(value)) {
444
4
            return false;
445
4
        }
446
1.40k
        kv.emplace_back(key, value);
447
1.40k
    }
448
2.32k
    return true;
449
2.42k
}
bool gguf_read_emplace_helper<unsigned int>(gguf_reader const&, std::__1::vector<gguf_kv, std::__1::allocator<gguf_kv> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, unsigned long)
Line
Count
Source
426
1.93k
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) {
427
1.93k
    if (is_array) {
428
294
        std::vector<T> value;
429
294
        try {
430
294
            if (!gr.read(value, n)) {
431
38
                return false;
432
38
            }
433
294
        } catch (std::length_error &) {
434
0
            GGML_LOG_ERROR("%s: encountered length_error while reading value for key '%s'\n", __func__, key.c_str());
435
0
            return false;
436
0
        } catch (std::bad_alloc &) {
437
0
            GGML_LOG_ERROR("%s: encountered bad_alloc error while reading value for key '%s'\n", __func__, key.c_str());
438
0
            return false;
439
0
        }
440
256
        kv.emplace_back(key, value);
441
1.64k
    } else {
442
1.64k
        T value;
443
1.64k
        if (!gr.read(value)) {
444
10
            return false;
445
10
        }
446
1.63k
        kv.emplace_back(key, value);
447
1.63k
    }
448
1.88k
    return true;
449
1.93k
}
bool gguf_read_emplace_helper<int>(gguf_reader const&, std::__1::vector<gguf_kv, std::__1::allocator<gguf_kv> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, unsigned long)
Line
Count
Source
426
1.82k
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) {
427
1.82k
    if (is_array) {
428
471
        std::vector<T> value;
429
471
        try {
430
471
            if (!gr.read(value, n)) {
431
124
                return false;
432
124
            }
433
471
        } catch (std::length_error &) {
434
0
            GGML_LOG_ERROR("%s: encountered length_error while reading value for key '%s'\n", __func__, key.c_str());
435
0
            return false;
436
0
        } catch (std::bad_alloc &) {
437
0
            GGML_LOG_ERROR("%s: encountered bad_alloc error while reading value for key '%s'\n", __func__, key.c_str());
438
0
            return false;
439
0
        }
440
347
        kv.emplace_back(key, value);
441
1.34k
    } else {
442
1.34k
        T value;
443
1.34k
        if (!gr.read(value)) {
444
3
            return false;
445
3
        }
446
1.34k
        kv.emplace_back(key, value);
447
1.34k
    }
448
1.69k
    return true;
449
1.82k
}
bool gguf_read_emplace_helper<float>(gguf_reader const&, std::__1::vector<gguf_kv, std::__1::allocator<gguf_kv> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, unsigned long)
Line
Count
Source
426
2.36k
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) {
427
2.36k
    if (is_array) {
428
1.18k
        std::vector<T> value;
429
1.18k
        try {
430
1.18k
            if (!gr.read(value, n)) {
431
115
                return false;
432
115
            }
433
1.18k
        } catch (std::length_error &) {
434
0
            GGML_LOG_ERROR("%s: encountered length_error while reading value for key '%s'\n", __func__, key.c_str());
435
0
            return false;
436
0
        } catch (std::bad_alloc &) {
437
0
            GGML_LOG_ERROR("%s: encountered bad_alloc error while reading value for key '%s'\n", __func__, key.c_str());
438
0
            return false;
439
0
        }
440
1.07k
        kv.emplace_back(key, value);
441
1.17k
    } else {
442
1.17k
        T value;
443
1.17k
        if (!gr.read(value)) {
444
3
            return false;
445
3
        }
446
1.17k
        kv.emplace_back(key, value);
447
1.17k
    }
448
2.24k
    return true;
449
2.36k
}
bool gguf_read_emplace_helper<bool>(gguf_reader const&, std::__1::vector<gguf_kv, std::__1::allocator<gguf_kv> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, unsigned long)
Line
Count
Source
426
1.69k
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) {
427
1.69k
    if (is_array) {
428
522
        std::vector<T> value;
429
522
        try {
430
522
            if (!gr.read(value, n)) {
431
109
                return false;
432
109
            }
433
522
        } catch (std::length_error &) {
434
0
            GGML_LOG_ERROR("%s: encountered length_error while reading value for key '%s'\n", __func__, key.c_str());
435
0
            return false;
436
0
        } catch (std::bad_alloc &) {
437
0
            GGML_LOG_ERROR("%s: encountered bad_alloc error while reading value for key '%s'\n", __func__, key.c_str());
438
0
            return false;
439
0
        }
440
413
        kv.emplace_back(key, value);
441
1.16k
    } else {
442
1.16k
        T value;
443
1.16k
        if (!gr.read(value)) {
444
3
            return false;
445
3
        }
446
1.16k
        kv.emplace_back(key, value);
447
1.16k
    }
448
1.57k
    return true;
449
1.69k
}
bool gguf_read_emplace_helper<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(gguf_reader const&, std::__1::vector<gguf_kv, std::__1::allocator<gguf_kv> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, unsigned long)
Line
Count
Source
426
2.51k
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) {
427
2.51k
    if (is_array) {
428
968
        std::vector<T> value;
429
968
        try {
430
968
            if (!gr.read(value, n)) {
431
117
                return false;
432
117
            }
433
968
        } catch (std::length_error &) {
434
0
            GGML_LOG_ERROR("%s: encountered length_error while reading value for key '%s'\n", __func__, key.c_str());
435
0
            return false;
436
0
        } catch (std::bad_alloc &) {
437
0
            GGML_LOG_ERROR("%s: encountered bad_alloc error while reading value for key '%s'\n", __func__, key.c_str());
438
0
            return false;
439
0
        }
440
851
        kv.emplace_back(key, value);
441
1.54k
    } else {
442
1.54k
        T value;
443
1.54k
        if (!gr.read(value)) {
444
14
            return false;
445
14
        }
446
1.53k
        kv.emplace_back(key, value);
447
1.53k
    }
448
2.38k
    return true;
449
2.51k
}
bool gguf_read_emplace_helper<unsigned long>(gguf_reader const&, std::__1::vector<gguf_kv, std::__1::allocator<gguf_kv> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, unsigned long)
Line
Count
Source
426
1.64k
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) {
427
1.64k
    if (is_array) {
428
540
        std::vector<T> value;
429
540
        try {
430
540
            if (!gr.read(value, n)) {
431
88
                return false;
432
88
            }
433
540
        } catch (std::length_error &) {
434
0
            GGML_LOG_ERROR("%s: encountered length_error while reading value for key '%s'\n", __func__, key.c_str());
435
0
            return false;
436
0
        } catch (std::bad_alloc &) {
437
0
            GGML_LOG_ERROR("%s: encountered bad_alloc error while reading value for key '%s'\n", __func__, key.c_str());
438
0
            return false;
439
0
        }
440
452
        kv.emplace_back(key, value);
441
1.10k
    } else {
442
1.10k
        T value;
443
1.10k
        if (!gr.read(value)) {
444
4
            return false;
445
4
        }
446
1.09k
        kv.emplace_back(key, value);
447
1.09k
    }
448
1.55k
    return true;
449
1.64k
}
bool gguf_read_emplace_helper<long>(gguf_reader const&, std::__1::vector<gguf_kv, std::__1::allocator<gguf_kv> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, unsigned long)
Line
Count
Source
426
1.48k
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) {
427
1.48k
    if (is_array) {
428
406
        std::vector<T> value;
429
406
        try {
430
406
            if (!gr.read(value, n)) {
431
84
                return false;
432
84
            }
433
406
        } catch (std::length_error &) {
434
0
            GGML_LOG_ERROR("%s: encountered length_error while reading value for key '%s'\n", __func__, key.c_str());
435
0
            return false;
436
0
        } catch (std::bad_alloc &) {
437
0
            GGML_LOG_ERROR("%s: encountered bad_alloc error while reading value for key '%s'\n", __func__, key.c_str());
438
0
            return false;
439
0
        }
440
322
        kv.emplace_back(key, value);
441
1.07k
    } else {
442
1.07k
        T value;
443
1.07k
        if (!gr.read(value)) {
444
5
            return false;
445
5
        }
446
1.06k
        kv.emplace_back(key, value);
447
1.06k
    }
448
1.39k
    return true;
449
1.48k
}
bool gguf_read_emplace_helper<double>(gguf_reader const&, std::__1::vector<gguf_kv, std::__1::allocator<gguf_kv> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, unsigned long)
Line
Count
Source
426
1.81k
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) {
427
1.81k
    if (is_array) {
428
544
        std::vector<T> value;
429
544
        try {
430
544
            if (!gr.read(value, n)) {
431
81
                return false;
432
81
            }
433
544
        } catch (std::length_error &) {
434
0
            GGML_LOG_ERROR("%s: encountered length_error while reading value for key '%s'\n", __func__, key.c_str());
435
0
            return false;
436
0
        } catch (std::bad_alloc &) {
437
0
            GGML_LOG_ERROR("%s: encountered bad_alloc error while reading value for key '%s'\n", __func__, key.c_str());
438
0
            return false;
439
0
        }
440
463
        kv.emplace_back(key, value);
441
1.27k
    } else {
442
1.27k
        T value;
443
1.27k
        if (!gr.read(value)) {
444
6
            return false;
445
6
        }
446
1.26k
        kv.emplace_back(key, value);
447
1.26k
    }
448
1.72k
    return true;
449
1.81k
}
450
451
8.45k
static struct gguf_context * gguf_init_from_reader(const struct gguf_reader & gr, struct gguf_init_params params) {
452
8.45k
    struct gguf_context * ctx = new gguf_context;
453
454
8.45k
    bool ok = true;
455
456
    // file magic
457
8.45k
    {
458
8.45k
        std::vector<char> magic;
459
8.45k
        ok = ok && gr.read(magic, 4);
460
461
8.45k
        if (!ok) {
462
3
            GGML_LOG_ERROR("%s: failed to read magic\n", __func__);
463
3
            gguf_free(ctx);
464
3
            return nullptr;
465
3
        }
466
467
42.1k
        for (uint32_t i = 0; i < magic.size(); i++) {
468
33.7k
            if (magic[i] != GGUF_MAGIC[i]) {
469
24
                char c0 = isprint(magic[0]) ? magic[0] : '?';
470
24
                char c1 = isprint(magic[1]) ? magic[1] : '?';
471
24
                char c2 = isprint(magic[2]) ? magic[2] : '?';
472
24
                char c3 = isprint(magic[3]) ? magic[3] : '?';
473
24
                GGML_LOG_ERROR("%s: invalid magic characters: '%c%c%c%c', expected 'GGUF'\n", __func__, c0, c1, c2, c3);
474
24
                gguf_free(ctx);
475
24
                return nullptr;
476
24
            }
477
33.7k
        }
478
8.45k
    }
479
480
    // header
481
8.43k
    int64_t n_kv      = 0;
482
8.43k
    int64_t n_tensors = 0;
483
484
8.43k
    if (ok && gr.read(ctx->version)) {
485
8.42k
        if (ok && ctx->version == 0) {
486
16
            GGML_LOG_ERROR("%s: bad GGUF version: %" PRIu32 "\n", __func__, ctx->version);
487
16
            ok = false;
488
16
        }
489
490
        /*
491
         * bit layout is different when reading non-native endian models.
492
         * assuming that the GGUF version is 3, the non-native endian model
493
         * would read it as 0x30000000. we can use the AND operation against
494
         * the last 4 hexadecimal digits to check if the model is the same
495
         * endianness as the host system.
496
        */
497
8.42k
        if (ok && (ctx->version & 0x0000FFFF) == 0x00000000) {
498
13
            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);
499
13
            ok = false;
500
13
        }
501
502
8.42k
        if (ok && ctx->version == 1) {
503
2
            GGML_LOG_ERROR("%s: GGUFv1 is no longer supported, please use a more up-to-date version\n", __func__);
504
2
            ok = false;
505
2
        }
506
8.42k
        if (ok && ctx->version > GGUF_VERSION) {
507
215
            GGML_LOG_ERROR("%s: this GGUF file is version %" PRIu32 " but this software only supports up to version %d\n",
508
215
                __func__, ctx->version, GGUF_VERSION);
509
215
            ok = false;
510
215
        }
511
8.42k
    } else {
512
3
        ok = false;
513
3
    }
514
515
8.43k
    if (ok && gr.read(n_tensors)) {
516
8.16k
        static_assert(sizeof(size_t) <= 8 && sizeof(gguf_tensor_info) >= 2, "int64_t insufficient for indexing");
517
8.16k
        if (n_tensors < 0 || n_tensors > int64_t(SIZE_MAX/sizeof(gguf_tensor_info))) {
518
191
            GGML_LOG_ERROR("%s: number of tensors is %" PRIi64 " but must be in [0, %zu]\n",
519
191
                __func__, n_tensors, SIZE_MAX/sizeof(gguf_tensor_info));
520
191
            ok = false;
521
191
        }
522
8.16k
    } else {
523
263
        ok = false;
524
263
    }
525
526
8.43k
    if (ok && gr.read(n_kv)) {
527
7.88k
        static_assert(sizeof(size_t) <= 8 && sizeof(gguf_tensor_info) >= 2, "int64_t insufficient for indexing");
528
7.88k
        if (n_kv < 0 || n_kv > int64_t(SIZE_MAX/sizeof(gguf_kv))) {
529
201
            GGML_LOG_ERROR("%s: number of key value pairs is %" PRIi64 " but must be in [0, %zu]\n",
530
201
                    __func__, n_kv, SIZE_MAX/sizeof(gguf_kv));
531
201
            ok = false;
532
201
        }
533
7.88k
    } else {
534
551
        ok = false;
535
551
    }
536
537
8.43k
    if (!ok) {
538
752
        GGML_LOG_ERROR("%s: failed to read header\n", __func__);
539
752
        gguf_free(ctx);
540
752
        return nullptr;
541
752
    }
542
543
    // KV pairs
544
7.68k
    {
545
35.6k
        for (int64_t i = 0; ok && i < n_kv; ++i) {
546
30.0k
            std::string key;
547
30.0k
            gguf_type   type     = gguf_type(-1);
548
30.0k
            bool        is_array = false;
549
30.0k
            uint64_t    n        = 1;
550
551
30.0k
            try {
552
30.0k
                ok = ok && gr.read(key);
553
30.0k
            } catch (std::length_error &) {
554
0
                GGML_LOG_ERROR("%s: encountered length_error while reading key %" PRIi64 "\n", __func__, i);
555
0
                ok = false;
556
0
            } catch (std::bad_alloc &) {
557
0
                GGML_LOG_ERROR("%s: encountered bad_alloc error while reading key %" PRIi64 "\n", __func__, i);
558
0
                ok = false;
559
0
            }
560
30.0k
            if (ok && key.empty()) {
561
272
                GGML_LOG_ERROR("%s: key %" PRIi64 " is empty\n", __func__, i);
562
272
                ok = false;
563
272
            }
564
215k
            for (size_t j = 0; ok && j < ctx->kv.size(); ++j) {
565
185k
                if (key == ctx->kv[j].key) {
566
90
                    GGML_LOG_ERROR("%s: duplicate key '%s' for tensors %zu and %" PRIi64 " \n", __func__, key.c_str(), j, i);
567
90
                    ok = false;
568
90
                }
569
185k
            }
570
30.0k
            if (!ok) {
571
1.94k
                break;
572
1.94k
            }
573
574
28.0k
            ok = ok && gr.read(type);
575
28.0k
            if (type == GGUF_TYPE_ARRAY) {
576
7.62k
                is_array = true;
577
7.62k
                ok = ok && gr.read(type);
578
7.62k
                ok = ok && gr.read(n);
579
7.62k
            }
580
28.0k
            if (!ok) {
581
106
                break;
582
106
            }
583
584
27.9k
            switch (type) {
585
4.94k
                case GGUF_TYPE_UINT8:   ok = ok && gguf_read_emplace_helper<uint8_t>    (gr, ctx->kv, key, is_array, n); break;
586
1.99k
                case GGUF_TYPE_INT8:    ok = ok && gguf_read_emplace_helper<int8_t>     (gr, ctx->kv, key, is_array, n); break;
587
2.93k
                case GGUF_TYPE_UINT16:  ok = ok && gguf_read_emplace_helper<uint16_t>   (gr, ctx->kv, key, is_array, n); break;
588
2.42k
                case GGUF_TYPE_INT16:   ok = ok && gguf_read_emplace_helper<int16_t>    (gr, ctx->kv, key, is_array, n); break;
589
1.93k
                case GGUF_TYPE_UINT32:  ok = ok && gguf_read_emplace_helper<uint32_t>   (gr, ctx->kv, key, is_array, n); break;
590
1.82k
                case GGUF_TYPE_INT32:   ok = ok && gguf_read_emplace_helper<int32_t>    (gr, ctx->kv, key, is_array, n); break;
591
2.36k
                case GGUF_TYPE_FLOAT32: ok = ok && gguf_read_emplace_helper<float>      (gr, ctx->kv, key, is_array, n); break;
592
1.69k
                case GGUF_TYPE_BOOL:    ok = ok && gguf_read_emplace_helper<bool>       (gr, ctx->kv, key, is_array, n); break;
593
2.51k
                case GGUF_TYPE_STRING:  ok = ok && gguf_read_emplace_helper<std::string>(gr, ctx->kv, key, is_array, n); break;
594
1.64k
                case GGUF_TYPE_UINT64:  ok = ok && gguf_read_emplace_helper<uint64_t>   (gr, ctx->kv, key, is_array, n); break;
595
1.48k
                case GGUF_TYPE_INT64:   ok = ok && gguf_read_emplace_helper<int64_t>    (gr, ctx->kv, key, is_array, n); break;
596
1.81k
                case GGUF_TYPE_FLOAT64: ok = ok && gguf_read_emplace_helper<double>     (gr, ctx->kv, key, is_array, n); break;
597
0
                case GGUF_TYPE_ARRAY:
598
407
                default:
599
407
                    {
600
407
                        GGML_LOG_ERROR("%s: key '%s' has invalid GGUF type %d\n", __func__, key.c_str(), type);
601
407
                        ok = false;
602
407
                    } break;
603
27.9k
            }
604
27.9k
        }
605
606
7.68k
        if (!ok) {
607
3.60k
            GGML_LOG_ERROR("%s: failed to read key-value pairs\n", __func__);
608
3.60k
            gguf_free(ctx);
609
3.60k
            return nullptr;
610
3.60k
        }
611
4.07k
        GGML_ASSERT(int64_t(ctx->kv.size()) == n_kv);
612
613
4.07k
        const int alignment_idx = gguf_find_key(ctx, GGUF_KEY_GENERAL_ALIGNMENT);
614
4.07k
        ctx->alignment = alignment_idx == -1 ? GGUF_DEFAULT_ALIGNMENT : gguf_get_val_u32(ctx, alignment_idx);
615
616
4.07k
        if (ctx->alignment == 0 || (ctx->alignment & (ctx->alignment - 1)) != 0) {
617
14
            GGML_LOG_ERROR("%s: alignment %zu is not a power of 2\n", __func__, ctx->alignment);
618
14
            gguf_free(ctx);
619
14
            return nullptr;
620
14
        }
621
4.07k
    }
622
623
    // read the tensor info
624
9.51k
    for (int64_t i = 0; ok && i < n_tensors; ++i) {
625
7.00k
        struct gguf_tensor_info info;
626
627
        // tensor name
628
7.00k
        {
629
7.00k
            std::string name;
630
7.00k
            try {
631
7.00k
                ok = ok && gr.read(name);
632
7.00k
            } catch (std::length_error &) {
633
0
                GGML_LOG_ERROR("%s: encountered length_error while reading tensor name %" PRIi64 "\n", __func__, i);
634
0
                ok = false;
635
0
            } catch (std::bad_alloc &) {
636
0
                GGML_LOG_ERROR("%s: encountered bad_alloc error while reading tensor name %" PRIi64 "\n", __func__, i);
637
0
                ok = false;
638
0
            }
639
7.00k
            if (name.length() >= GGML_MAX_NAME) {
640
23
                GGML_LOG_ERROR("%s: tensor name %" PRIi64 " is too long: %zu >= %d\n", __func__, i, name.length(), GGML_MAX_NAME);
641
23
                ok = false;
642
23
                break;
643
23
            }
644
6.98k
            ggml_set_name(&info.t, name.c_str());
645
646
            // make sure there are no duplicate tensor names
647
23.4k
            for (int64_t j = 0; ok && j < i; ++j) {
648
16.4k
                if (strcmp(info.t.name, ctx->info[j].t.name) == 0) {
649
38
                    GGML_LOG_ERROR("%s: duplicate tensor name '%s' for tensors %" PRIi64 " and %" PRIi64 "\n", __func__, info.t.name, j, i);
650
38
                    ok = false;
651
38
                    break;
652
38
                }
653
16.4k
            }
654
6.98k
        }
655
6.98k
        if (!ok) {
656
330
            break;
657
330
        }
658
659
        // tensor shape
660
6.65k
        {
661
6.65k
            uint32_t n_dims = 0;
662
6.65k
            ok = ok && gr.read(n_dims);
663
6.65k
            if (n_dims > GGML_MAX_DIMS) {
664
228
                GGML_LOG_ERROR("%s: tensor '%s' has invalid number of dimensions: %" PRIu32 " > %" PRIu32 "\n",
665
228
                    __func__, info.t.name, n_dims, GGML_MAX_DIMS);
666
228
                ok = false;
667
228
                break;
668
228
            }
669
30.9k
            for (uint32_t j = 0; ok && j < GGML_MAX_DIMS; ++j) {
670
24.8k
                info.t.ne[j] = 1;
671
24.8k
                if (j < n_dims) {
672
12.7k
                    ok = ok && gr.read(info.t.ne[j]);
673
12.7k
                }
674
675
                // check that all ne are non-negative
676
24.8k
                if (info.t.ne[j] < 0) {
677
302
                    GGML_LOG_ERROR("%s: tensor '%s' dimension %" PRIu32 " has invalid number of elements: %" PRIi64 " < 0\n",
678
302
                        __func__, info.t.name, j, info.t.ne[j]);
679
302
                    ok = false;
680
302
                    break;
681
302
                }
682
24.8k
            }
683
684
            // check that the total number of elements is representable
685
6.42k
            if (ok && ((INT64_MAX/info.t.ne[1] <= info.t.ne[0]) ||
686
5.86k
                       (INT64_MAX/info.t.ne[2] <= info.t.ne[0]*info.t.ne[1]) ||
687
5.80k
                       (INT64_MAX/info.t.ne[3] <= info.t.ne[0]*info.t.ne[1]*info.t.ne[2]))) {
688
689
186
                GGML_LOG_ERROR("%s: total number of elements in tensor '%s' with shape "
690
186
                    "(%" PRIi64 ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 ") is >= %" PRIi64 "\n",
691
186
                    __func__, info.t.name, info.t.ne[0], info.t.ne[1], info.t.ne[2], info.t.ne[3], INT64_MAX);
692
186
                ok = false;
693
186
                break;
694
186
            }
695
6.42k
        }
696
6.24k
        if (!ok) {
697
460
            break;
698
460
        }
699
700
        // tensor type
701
5.78k
        {
702
5.78k
            ok = ok && gr.read(info.t.type);
703
704
            // check that tensor type is within defined range
705
5.78k
            if (info.t.type < 0 || info.t.type >= GGML_TYPE_COUNT) {
706
267
                GGML_LOG_ERROR("%s: tensor '%s' has invalid ggml type %d. should be in [0, %d)\n",
707
267
                    __func__, info.t.name, info.t.type, GGML_TYPE_COUNT);
708
267
                ok = false;
709
267
                break;
710
267
            }
711
5.51k
            const size_t  type_size = ggml_type_size(info.t.type);
712
5.51k
            const int64_t blck_size = ggml_blck_size(info.t.type);
713
714
            // check that row size is divisible by block size
715
5.51k
            if (blck_size == 0 || info.t.ne[0] % blck_size != 0) {
716
31
                GGML_LOG_ERROR("%s: tensor '%s' of type %d (%s) has %" PRId64 " elements per row, "
717
31
                    "not a multiple of block size (%" PRId64 ")\n",
718
31
                    __func__, info.t.name, (int) info.t.type, ggml_type_name(info.t.type), info.t.ne[0], blck_size);
719
31
                ok = false;
720
31
                break;
721
31
            }
722
723
            // check that the size of the tensor in bytes is representable
724
5.48k
            if (ok && uint64_t(ggml_nelements(&info.t)/ggml_blck_size(info.t.type)) > SIZE_MAX/ggml_type_size(info.t.type)) {
725
14
                GGML_LOG_ERROR("%s: tensor '%s' with shape (%" PRIi64 ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 ") has a size in bytes > %zu\n",
726
14
                    __func__, info.t.name, info.t.ne[0], info.t.ne[1], info.t.ne[2], info.t.ne[3], SIZE_MAX);
727
14
                ok = false;
728
14
                break;
729
14
            }
730
731
            // calculate byte offsets given the tensor shape and type
732
5.46k
            info.t.nb[0] = type_size;
733
5.46k
            info.t.nb[1] = info.t.nb[0]*(info.t.ne[0]/blck_size);
734
16.4k
            for (int j = 2; j < GGML_MAX_DIMS; ++j) {
735
10.9k
                info.t.nb[j] = info.t.nb[j - 1]*info.t.ne[j - 1];
736
10.9k
            }
737
5.46k
        }
738
5.46k
        if (!ok) {
739
7
            break;
740
7
        }
741
742
        // tensor data offset within buffer
743
5.46k
        ok = ok && gr.read(info.offset);
744
745
5.46k
        ctx->info.push_back(info);
746
5.46k
    }
747
748
4.05k
    if (!ok) {
749
1.60k
        GGML_LOG_ERROR("%s: failed to read tensor info\n", __func__);
750
1.60k
        gguf_free(ctx);
751
1.60k
        return nullptr;
752
1.60k
    }
753
2.45k
    GGML_ASSERT(int64_t(ctx->info.size()) == n_tensors);
754
755
    // we require the data section to be aligned, so take into account any padding
756
2.45k
    if (n_tensors > 0 && !gr.seek(GGML_PAD(gr.tell(), ctx->alignment))) {
757
36
        GGML_LOG_ERROR("%s: failed to seek to beginning of data section\n", __func__);
758
36
        gguf_free(ctx);
759
36
        return nullptr;
760
36
    }
761
762
    // store the current file offset - this is where the data section starts
763
2.41k
    ctx->offset = gr.tell();
764
765
    // compute the total size of the data section, taking into account the alignment
766
2.41k
    {
767
2.41k
        ctx->size = 0;
768
5.87k
        for (size_t i = 0; i < ctx->info.size(); ++i) {
769
3.74k
            const gguf_tensor_info & ti = ctx->info[i];
770
3.74k
            if (ti.offset != ctx->size) {
771
287
                GGML_LOG_ERROR("%s: tensor '%s' has offset %" PRIu64 ", expected %zu\n",
772
287
                    __func__, ti.t.name, ti.offset, ctx->size);
773
287
                GGML_LOG_ERROR("%s: failed to read tensor data\n", __func__);
774
287
                gguf_free(ctx);
775
287
                return nullptr;
776
287
            }
777
3.45k
            size_t padded_size = GGML_PAD(ggml_nbytes(&ti.t), ctx->alignment);
778
3.45k
            if (SIZE_MAX - ctx->size < padded_size) {
779
2
                GGML_LOG_ERROR("%s: tensor '%s' size overflow, cannot accumulate size %zu + %zu\n",
780
2
                    __func__, ti.t.name, ctx->size, padded_size);
781
2
                gguf_free(ctx);
782
2
                return nullptr;
783
2
            }
784
3.45k
            ctx->size += padded_size;
785
3.45k
        }
786
2.41k
    }
787
788
    // load the tensor data only if requested
789
2.12k
    if (params.ctx != nullptr) {
790
        // if the provided gguf_context is no_alloc, then we create "empty" tensors and do not read the binary blob
791
        // otherwise, we load the binary blob into the created ggml_context as well, and point the "data" members of
792
        //   the ggml_tensor structs to the appropriate locations in the binary blob
793
794
        // compute the exact size needed for the new ggml_context
795
2.11k
        size_t mem_size = 0;
796
2.11k
        if (params.no_alloc) {
797
2.11k
            if (n_tensors != 0 && SIZE_MAX / n_tensors < ggml_tensor_overhead()) {
798
0
                GGML_LOG_ERROR("%s: memory size overflow while allocating ggml context\n", __func__);
799
0
                gguf_free(ctx);
800
0
                return nullptr;
801
0
            }
802
803
2.11k
            const size_t overhead = n_tensors * ggml_tensor_overhead();
804
805
2.11k
            mem_size = overhead;
806
2.11k
        } else {
807
0
            if ((n_tensors + 1) != 0 && SIZE_MAX / (n_tensors + 1) < ggml_tensor_overhead()) {
808
0
                GGML_LOG_ERROR("%s: memory size overflow while allocating ggml context\n", __func__);
809
0
                gguf_free(ctx);
810
0
                return nullptr;
811
0
            }
812
813
0
            const size_t overhead = (n_tensors + 1) * ggml_tensor_overhead();
814
815
0
            if (SIZE_MAX - overhead < ctx->size) {
816
0
                GGML_LOG_ERROR("%s: memory size overflow while allocating ggml context\n", __func__);
817
0
                gguf_free(ctx);
818
0
                return nullptr;
819
0
            }
820
821
0
            mem_size = overhead + ctx->size;
822
0
        }
823
824
2.11k
        struct ggml_init_params pdata = {
825
2.11k
            /*mem_size   =*/ mem_size,
826
2.11k
            /*mem_buffer =*/ nullptr,
827
2.11k
            /*no_alloc   =*/ params.no_alloc,
828
2.11k
        };
829
830
2.11k
        *params.ctx = ggml_init(pdata);
831
2.11k
        if (*params.ctx == nullptr) {
832
0
            GGML_LOG_ERROR("%s: failed to initialize ggml context for storing tensors\n", __func__);
833
0
            gguf_free(ctx);
834
0
            return nullptr;
835
0
        }
836
837
2.11k
        struct ggml_context * ctx_data = *params.ctx;
838
839
2.11k
        struct ggml_tensor * data = nullptr;
840
841
2.11k
        if (!params.no_alloc) {
842
0
            data = ggml_new_tensor_1d(ctx_data, GGML_TYPE_I8, ctx->size);
843
844
0
            ok = ok && data != nullptr;
845
846
0
            if (ok) {
847
0
                ggml_set_name(data, "GGUF tensor data binary blob");
848
0
            }
849
850
            // read the binary blob with the tensor data
851
0
            ok = ok && gr.read(data->data, ctx->size);
852
853
0
            if (!ok) {
854
0
                GGML_LOG_ERROR("%s: failed to read tensor data binary blob\n", __func__);
855
0
                ggml_free(ctx_data);
856
0
                *params.ctx = nullptr;
857
0
                gguf_free(ctx);
858
0
                return nullptr;
859
0
            }
860
861
0
            ctx->data = data->data;
862
0
        }
863
864
2.11k
        ggml_set_no_alloc(ctx_data, true);
865
866
        // create the tensors
867
5.26k
        for (size_t i = 0; i < ctx->info.size(); ++i) {
868
3.14k
            const struct gguf_tensor_info & info = ctx->info[i];
869
870
3.14k
            struct ggml_tensor * cur = ggml_new_tensor(ctx_data, info.t.type, GGML_MAX_DIMS, info.t.ne);
871
872
3.14k
            ok = ok && cur != nullptr;
873
874
3.14k
            if (!ok) {
875
0
                break;
876
0
            }
877
878
3.14k
            ggml_set_name(cur, info.t.name);
879
880
            // point the data member to the appropriate location in the binary blob using the tensor info
881
3.14k
            if (!params.no_alloc) {
882
0
                cur->data = (char *) data->data + info.offset;
883
0
            }
884
3.14k
        }
885
886
2.11k
        if (!ok) {
887
0
            GGML_LOG_ERROR("%s: failed to create tensors\n", __func__);
888
0
            ggml_free(ctx_data);
889
0
            *params.ctx = nullptr;
890
0
            gguf_free(ctx);
891
0
            return nullptr;
892
0
        }
893
894
2.11k
        ggml_set_no_alloc(ctx_data, params.no_alloc);
895
2.11k
    }
896
897
2.12k
    return ctx;
898
2.12k
}
899
900
0
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) {
901
0
    if (callback == nullptr) {
902
0
        return nullptr;
903
0
    }
904
905
0
    const struct gguf_reader gr(callback, userdata, max_chunk_read == 0 ? SIZE_MAX : max_chunk_read, 0, max_expected_size);
906
0
    return gguf_init_from_reader(gr, params);
907
0
}
908
909
struct gguf_file_reader {
910
    FILE * file;
911
    uint64_t offset;
912
};
913
914
6.80M
static size_t gguf_file_reader_callback(void * userdata, void * output, uint64_t offset, size_t len) {
915
6.80M
    GGML_ASSERT(len > 0);
916
917
6.80M
    gguf_file_reader & reader = *static_cast<gguf_file_reader *>(userdata);
918
919
6.80M
    if (reader.offset != offset) {
920
0
        if (offset > INT64_MAX || gguf_fseek(reader.file, static_cast<int64_t>(offset), SEEK_SET) != 0) {
921
0
            return 0;
922
0
        }
923
924
0
        reader.offset = offset;
925
0
    }
926
927
6.80M
    const size_t nread = fread(static_cast<uint8_t *>(output), 1, len, reader.file);
928
6.80M
    reader.offset += nread;
929
6.80M
    return nread;
930
6.80M
}
931
932
8.45k
struct gguf_context * gguf_init_from_file_ptr(FILE * file, struct gguf_init_params params) {
933
8.45k
    if (!file) {
934
0
        return nullptr;
935
0
    }
936
937
8.45k
    const int64_t cur = gguf_ftell(file);
938
8.45k
    if (cur < 0) {
939
0
        return nullptr;
940
0
    }
941
942
8.45k
    gguf_file_reader reader = {
943
8.45k
        /*.file   = */ file,
944
8.45k
        /*.offset = */ static_cast<uint64_t>(cur),
945
8.45k
    };
946
8.45k
    const struct gguf_reader gr(gguf_file_reader_callback, &reader, SIZE_MAX, reader.offset, gguf_reader::file_remain(file));
947
8.45k
    return gguf_init_from_reader(gr, params);
948
8.45k
}
949
950
struct gguf_buffer_reader {
951
    const uint8_t * data;
952
    size_t          size;
953
};
954
955
0
static size_t gguf_buffer_reader_callback(void * userdata, void * output, uint64_t offset, size_t len) {
956
0
    GGML_ASSERT(len > 0);
957
958
0
    const gguf_buffer_reader & reader = *static_cast<gguf_buffer_reader *>(userdata);
959
960
0
    if (offset > reader.size || len > reader.size - offset) {
961
0
        return 0;
962
0
    }
963
964
0
    const size_t data_offset = static_cast<size_t>(offset);
965
0
    const size_t nread = std::min(len, reader.size - data_offset);
966
0
    memcpy(static_cast<uint8_t *>(output), reader.data + data_offset, nread);
967
0
    return nread;
968
0
}
969
970
0
struct gguf_context * gguf_init_from_buffer(const void * data, size_t size, struct gguf_init_params params) {
971
0
    if (data == nullptr || size == 0) {
972
0
        return nullptr;
973
0
    }
974
975
0
    gguf_buffer_reader reader = {
976
0
        /*.data = */ static_cast<const uint8_t *>(data),
977
0
        /*.size = */ size,
978
0
    };
979
0
    const struct gguf_reader gr(gguf_buffer_reader_callback, &reader, SIZE_MAX, 0, size);
980
0
    return gguf_init_from_reader(gr, params);
981
0
}
982
983
8.45k
struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_params params) {
984
8.45k
    FILE * file = ggml_fopen(fname, "rb");
985
986
8.45k
    if (!file) {
987
0
        GGML_LOG_ERROR("%s: failed to open GGUF file '%s' (%s)\n", __func__, fname, strerror(errno));
988
0
        return nullptr;
989
0
    }
990
991
8.45k
    struct gguf_context * result = gguf_init_from_file_ptr(file, params);
992
8.45k
    fclose(file);
993
8.45k
    return result;
994
8.45k
}
995
996
8.44k
void gguf_free(struct gguf_context * ctx) {
997
8.44k
    if (ctx == nullptr) {
998
0
        return;
999
0
    }
1000
8.44k
    delete ctx;
1001
8.44k
}
1002
1003
9.34k
const char * gguf_type_name(enum gguf_type type) {
1004
9.34k
    auto it = GGUF_TYPE_NAME.find(type);
1005
9.34k
    return it == GGUF_TYPE_NAME.end() ? nullptr : it->second;
1006
9.34k
}
1007
1008
1.65k
uint32_t gguf_get_version(const struct gguf_context * ctx) {
1009
1.65k
    return ctx->version;
1010
1.65k
}
1011
1012
0
size_t gguf_get_alignment(const struct gguf_context * ctx) {
1013
0
    return ctx->alignment;
1014
0
}
1015
1016
2.57k
size_t gguf_get_data_offset(const struct gguf_context * ctx) {
1017
2.57k
    return ctx->offset;
1018
2.57k
}
1019
1020
296k
int64_t gguf_get_n_kv(const struct gguf_context * ctx) {
1021
296k
    return ctx->kv.size();
1022
296k
}
1023
1024
11.6k
int64_t gguf_find_key(const struct gguf_context * ctx, const char * key) {
1025
    // return -1 if key not found
1026
11.6k
    int64_t keyfound = -1;
1027
1028
11.6k
    const int64_t n_kv = gguf_get_n_kv(ctx);
1029
1030
61.7k
    for (int64_t i = 0; i < n_kv; ++i) {
1031
50.6k
        if (strcmp(key, gguf_get_key(ctx, i)) == 0) {
1032
571
            keyfound = i;
1033
571
            break;
1034
571
        }
1035
50.6k
    }
1036
1037
11.6k
    return keyfound;
1038
11.6k
}
1039
1040
63.4k
const char * gguf_get_key(const struct gguf_context * ctx, int64_t key_id) {
1041
63.4k
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1042
63.4k
    return ctx->kv[key_id].get_key().c_str();
1043
63.4k
}
1044
1045
26.7k
enum gguf_type gguf_get_kv_type(const struct gguf_context * ctx, int64_t key_id) {
1046
26.7k
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1047
26.7k
    return ctx->kv[key_id].is_array ? GGUF_TYPE_ARRAY : ctx->kv[key_id].get_type();
1048
26.7k
}
1049
1050
2.61k
enum gguf_type gguf_get_arr_type(const struct gguf_context * ctx, int64_t key_id) {
1051
2.61k
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1052
2.61k
    GGML_ASSERT(ctx->kv[key_id].is_array);
1053
2.61k
    return ctx->kv[key_id].get_type();
1054
2.61k
}
1055
1056
1.04k
const void * gguf_get_arr_data(const struct gguf_context * ctx, int64_t key_id) {
1057
1.04k
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1058
1.04k
    GGML_ASSERT(ctx->kv[key_id].get_type() != GGUF_TYPE_STRING);
1059
1.04k
    return ctx->kv[key_id].data.data();
1060
1.04k
}
1061
1062
168k
const char * gguf_get_arr_str(const struct gguf_context * ctx, int64_t key_id, size_t i) {
1063
168k
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1064
168k
    GGML_ASSERT(ctx->kv[key_id].get_type() == GGUF_TYPE_STRING);
1065
168k
    return ctx->kv[key_id].data_string[i].c_str();
1066
168k
}
1067
1068
2.61k
size_t gguf_get_arr_n(const struct gguf_context * ctx, int64_t key_id) {
1069
2.61k
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1070
1071
2.61k
    if (ctx->kv[key_id].type == GGUF_TYPE_STRING) {
1072
526
        return ctx->kv[key_id].data_string.size();
1073
526
    }
1074
1075
2.08k
    const size_t type_size = gguf_type_size(ctx->kv[key_id].type);
1076
2.08k
    GGML_ASSERT(ctx->kv[key_id].data.size() % type_size == 0);
1077
2.08k
    return ctx->kv[key_id].data.size() / type_size;
1078
2.61k
}
1079
1080
0
uint8_t gguf_get_val_u8(const struct gguf_context * ctx, int64_t key_id) {
1081
0
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1082
0
    GGML_ASSERT(ctx->kv[key_id].get_ne() == 1);
1083
0
    return ctx->kv[key_id].get_val<uint8_t>();
1084
0
}
1085
1086
0
int8_t gguf_get_val_i8(const struct gguf_context * ctx, int64_t key_id) {
1087
0
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1088
0
    GGML_ASSERT(ctx->kv[key_id].get_ne() == 1);
1089
0
    return ctx->kv[key_id].get_val<int8_t>();
1090
0
}
1091
1092
35
uint16_t gguf_get_val_u16(const struct gguf_context * ctx, int64_t key_id) {
1093
35
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1094
35
    GGML_ASSERT(ctx->kv[key_id].get_ne() == 1);
1095
35
    return ctx->kv[key_id].get_val<uint16_t>();
1096
35
}
1097
1098
0
int16_t gguf_get_val_i16(const struct gguf_context * ctx, int64_t key_id) {
1099
0
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1100
0
    GGML_ASSERT(ctx->kv[key_id].get_ne() == 1);
1101
0
    return ctx->kv[key_id].get_val<int16_t>();
1102
0
}
1103
1104
89
uint32_t gguf_get_val_u32(const struct gguf_context * ctx, int64_t key_id) {
1105
89
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1106
89
    GGML_ASSERT(ctx->kv[key_id].get_ne() == 1);
1107
89
    return ctx->kv[key_id].get_val<uint32_t>();
1108
89
}
1109
1110
0
int32_t gguf_get_val_i32(const struct gguf_context * ctx, int64_t key_id) {
1111
0
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1112
0
    GGML_ASSERT(ctx->kv[key_id].get_ne() == 1);
1113
0
    return ctx->kv[key_id].get_val<int32_t>();
1114
0
}
1115
1116
0
float gguf_get_val_f32(const struct gguf_context * ctx, int64_t key_id) {
1117
0
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1118
0
    GGML_ASSERT(ctx->kv[key_id].get_ne() == 1);
1119
0
    return ctx->kv[key_id].get_val<float>();
1120
0
}
1121
1122
0
uint64_t gguf_get_val_u64(const struct gguf_context * ctx, int64_t key_id) {
1123
0
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1124
0
    GGML_ASSERT(ctx->kv[key_id].get_ne() == 1);
1125
0
    return ctx->kv[key_id].get_val<uint64_t>();
1126
0
}
1127
1128
0
int64_t gguf_get_val_i64(const struct gguf_context * ctx, int64_t key_id) {
1129
0
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1130
0
    GGML_ASSERT(ctx->kv[key_id].get_ne() == 1);
1131
0
    return ctx->kv[key_id].get_val<int64_t>();
1132
0
}
1133
1134
0
double gguf_get_val_f64(const struct gguf_context * ctx, int64_t key_id) {
1135
0
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1136
0
    GGML_ASSERT(ctx->kv[key_id].get_ne() == 1);
1137
0
    return ctx->kv[key_id].get_val<double>();
1138
0
}
1139
1140
0
bool gguf_get_val_bool(const struct gguf_context * ctx, int64_t key_id) {
1141
0
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1142
0
    GGML_ASSERT(ctx->kv[key_id].get_ne() == 1);
1143
0
    return ctx->kv[key_id].get_val<bool>();
1144
0
}
1145
1146
1.67k
const char * gguf_get_val_str(const struct gguf_context * ctx, int64_t key_id) {
1147
1.67k
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1148
1.67k
    GGML_ASSERT(ctx->kv[key_id].get_ne() == 1);
1149
1.67k
    return ctx->kv[key_id].get_val<std::string>().c_str();
1150
1.67k
}
1151
1152
10.1k
const void * gguf_get_val_data(const struct gguf_context * ctx, int64_t key_id) {
1153
10.1k
    GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
1154
10.1k
    GGML_ASSERT(ctx->kv[key_id].get_ne() == 1);
1155
10.1k
    GGML_ASSERT(ctx->kv[key_id].get_type() != GGUF_TYPE_STRING);
1156
10.1k
    return ctx->kv[key_id].data.data();
1157
10.1k
}
1158
1159
14.1k
int64_t gguf_get_n_tensors(const struct gguf_context * ctx) {
1160
14.1k
    return ctx->info.size();
1161
14.1k
}
1162
1163
2.57k
int64_t gguf_find_tensor(const struct gguf_context * ctx, const char * name) {
1164
    // return -1 if tensor not found
1165
2.57k
    int64_t tensor_id = -1;
1166
1167
2.57k
    const int64_t n_tensors = gguf_get_n_tensors(ctx);
1168
1169
8.99k
    for (int64_t i = 0; i < n_tensors; ++i) {
1170
8.99k
        if (strcmp(name, gguf_get_tensor_name(ctx, i)) == 0) {
1171
2.57k
            tensor_id = i;
1172
2.57k
            break;
1173
2.57k
        }
1174
8.99k
    }
1175
1176
2.57k
    return tensor_id;
1177
2.57k
}
1178
1179
2.57k
size_t gguf_get_tensor_offset(const struct gguf_context * ctx, int64_t tensor_id) {
1180
2.57k
    GGML_ASSERT(tensor_id >= 0 && tensor_id < gguf_get_n_tensors(ctx));
1181
2.57k
    return ctx->info[tensor_id].offset;
1182
2.57k
}
1183
1184
8.99k
const char * gguf_get_tensor_name(const struct gguf_context * ctx, int64_t tensor_id) {
1185
8.99k
    GGML_ASSERT(tensor_id >= 0 && tensor_id < gguf_get_n_tensors(ctx));
1186
8.99k
    return ctx->info[tensor_id].t.name;
1187
8.99k
}
1188
1189
0
const int64_t * gguf_get_tensor_ne(const struct gguf_context * ctx, int64_t tensor_id) {
1190
0
    GGML_ASSERT(tensor_id >= 0 && tensor_id < gguf_get_n_tensors(ctx));
1191
0
    return ctx->info[tensor_id].t.ne;
1192
0
}
1193
1194
0
enum ggml_type gguf_get_tensor_type(const struct gguf_context * ctx, int64_t tensor_id) {
1195
0
    GGML_ASSERT(tensor_id >= 0 && tensor_id < gguf_get_n_tensors(ctx));
1196
0
    return ctx->info[tensor_id].t.type;
1197
0
}
1198
1199
0
size_t gguf_get_tensor_size(const struct gguf_context * ctx, int64_t tensor_id) {
1200
0
    GGML_ASSERT(tensor_id >= 0 && tensor_id < gguf_get_n_tensors(ctx));
1201
0
    return ggml_nbytes(&ctx->info[tensor_id].t);
1202
0
}
1203
1204
0
int64_t gguf_remove_key(struct gguf_context * ctx, const char * key) {
1205
0
    const int64_t key_id = gguf_find_key(ctx, key);
1206
0
    if (key_id >= 0) {
1207
0
        ctx->kv.erase(ctx->kv.begin() + key_id);
1208
0
    }
1209
0
    return key_id;
1210
0
}
1211
1212
template<typename T>
1213
0
static void gguf_check_reserved_keys(const std::string & key, const T val) {
1214
0
    if (key == GGUF_KEY_GENERAL_ALIGNMENT) {
1215
0
        if constexpr (std::is_same<T, uint32_t>::value) {
1216
0
            GGML_ASSERT(val > 0 && (val & (val - 1)) == 0 && GGUF_KEY_GENERAL_ALIGNMENT " must be power of 2");
1217
0
        } else {
1218
0
            GGML_UNUSED(val);
1219
0
            GGML_ABORT(GGUF_KEY_GENERAL_ALIGNMENT " must be type u32");
1220
0
        }
1221
0
    }
1222
0
}
Unexecuted instantiation: gguf.cpp:void gguf_check_reserved_keys<unsigned char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned char)
Unexecuted instantiation: gguf.cpp:void gguf_check_reserved_keys<signed char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, signed char)
Unexecuted instantiation: gguf.cpp:void gguf_check_reserved_keys<unsigned short>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned short)
Unexecuted instantiation: gguf.cpp:void gguf_check_reserved_keys<short>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, short)
Unexecuted instantiation: gguf.cpp:void gguf_check_reserved_keys<unsigned int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned int)
Unexecuted instantiation: gguf.cpp:void gguf_check_reserved_keys<int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)
Unexecuted instantiation: gguf.cpp:void gguf_check_reserved_keys<float>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, float)
Unexecuted instantiation: gguf.cpp:void gguf_check_reserved_keys<unsigned long>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long)
Unexecuted instantiation: gguf.cpp:void gguf_check_reserved_keys<long>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, long)
Unexecuted instantiation: gguf.cpp:void gguf_check_reserved_keys<double>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, double)
Unexecuted instantiation: gguf.cpp:void gguf_check_reserved_keys<bool>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool)
Unexecuted instantiation: gguf.cpp:void gguf_check_reserved_keys<char const*>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const*)
Unexecuted instantiation: gguf.cpp:void gguf_check_reserved_keys<void const*>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, void const*)
Unexecuted instantiation: gguf.cpp:void gguf_check_reserved_keys<char const**>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const**)
1223
1224
0
void gguf_set_val_u8(struct gguf_context * ctx, const char * key, uint8_t val) {
1225
0
    gguf_check_reserved_keys(key, val);
1226
0
    gguf_remove_key(ctx, key);
1227
0
    ctx->kv.emplace_back(key, val);
1228
0
}
1229
1230
0
void gguf_set_val_i8(struct gguf_context * ctx, const char * key, int8_t val) {
1231
0
    gguf_check_reserved_keys(key, val);
1232
0
    gguf_remove_key(ctx, key);
1233
0
    ctx->kv.emplace_back(key, val);
1234
0
}
1235
1236
0
void gguf_set_val_u16(struct gguf_context * ctx, const char * key, uint16_t val) {
1237
0
    gguf_check_reserved_keys(key, val);
1238
0
    gguf_remove_key(ctx, key);
1239
0
    ctx->kv.emplace_back(key, val);
1240
0
}
1241
1242
0
void gguf_set_val_i16(struct gguf_context * ctx, const char * key, int16_t val) {
1243
0
    gguf_check_reserved_keys(key, val);
1244
0
    gguf_remove_key(ctx, key);
1245
0
    ctx->kv.emplace_back(key, val);
1246
0
}
1247
1248
0
void gguf_set_val_u32(struct gguf_context * ctx, const char * key, uint32_t val) {
1249
0
    gguf_check_reserved_keys(key, val);
1250
0
    gguf_remove_key(ctx, key);
1251
0
    ctx->kv.emplace_back(key, val);
1252
0
}
1253
1254
0
void gguf_set_val_i32(struct gguf_context * ctx, const char * key, int32_t val) {
1255
0
    gguf_check_reserved_keys(key, val);
1256
0
    gguf_remove_key(ctx, key);
1257
0
    ctx->kv.emplace_back(key, val);
1258
0
}
1259
1260
0
void gguf_set_val_f32(struct gguf_context * ctx, const char * key, float val) {
1261
0
    gguf_check_reserved_keys(key, val);
1262
0
    gguf_remove_key(ctx, key);
1263
0
    ctx->kv.emplace_back(key, val);
1264
0
}
1265
1266
0
void gguf_set_val_u64(struct gguf_context * ctx, const char * key, uint64_t val) {
1267
0
    gguf_check_reserved_keys(key, val);
1268
0
    gguf_remove_key(ctx, key);
1269
0
    ctx->kv.emplace_back(key, val);
1270
0
}
1271
1272
0
void gguf_set_val_i64(struct gguf_context * ctx, const char * key, int64_t val) {
1273
0
    gguf_check_reserved_keys(key, val);
1274
0
    gguf_remove_key(ctx, key);
1275
0
    ctx->kv.emplace_back(key, val);
1276
0
}
1277
1278
0
void gguf_set_val_f64(struct gguf_context * ctx, const char * key, double val) {
1279
0
    gguf_check_reserved_keys(key, val);
1280
0
    gguf_remove_key(ctx, key);
1281
0
    ctx->kv.emplace_back(key, val);
1282
0
}
1283
1284
0
void gguf_set_val_bool(struct gguf_context * ctx, const char * key, bool val) {
1285
0
    gguf_check_reserved_keys(key, val);
1286
0
    gguf_remove_key(ctx, key);
1287
0
    ctx->kv.emplace_back(key, val);
1288
0
}
1289
1290
0
void gguf_set_val_str(struct gguf_context * ctx, const char * key, const char * val) {
1291
0
    gguf_check_reserved_keys(key, val);
1292
0
    gguf_remove_key(ctx, key);
1293
0
    ctx->kv.emplace_back(key, std::string(val));
1294
0
}
1295
1296
0
void gguf_set_arr_data(struct gguf_context * ctx, const char * key, enum gguf_type type, const void * data, size_t n) {
1297
0
    gguf_check_reserved_keys(key, data);
1298
0
    gguf_remove_key(ctx, key);
1299
1300
0
    const size_t nbytes = n*gguf_type_size(type);
1301
0
    std::vector<int8_t> tmp(nbytes);
1302
0
    if (!tmp.empty()) {
1303
0
        memcpy(tmp.data(), data, nbytes);
1304
0
    }
1305
0
    ctx->kv.emplace_back(key, tmp);
1306
0
    ctx->kv.back().cast(type);
1307
0
}
1308
1309
0
void gguf_set_arr_str(struct gguf_context * ctx, const char * key, const char ** data, size_t n) {
1310
0
    gguf_check_reserved_keys(key, data);
1311
0
    gguf_remove_key(ctx, key);
1312
1313
0
    std::vector<std::string> tmp(n);
1314
0
    for (size_t i = 0; i < n; ++i) {
1315
0
        tmp[i] = data[i];
1316
0
    }
1317
0
    ctx->kv.emplace_back(key, tmp);
1318
0
}
1319
1320
// set or add KV pairs from another context
1321
0
void gguf_set_kv(struct gguf_context * ctx, const struct gguf_context * src) {
1322
0
    const int64_t n_kv = gguf_get_n_kv(src);
1323
0
    for (int64_t i = 0; i < n_kv; ++i) {
1324
0
        const struct gguf_kv & kv = src->kv[i];
1325
1326
0
        if (!kv.is_array) {
1327
0
            switch (kv.get_type()) {
1328
0
                case GGUF_TYPE_UINT8:   gguf_set_val_u8  (ctx, kv.get_key().c_str(), kv.get_val<uint8_t>());             break;
1329
0
                case GGUF_TYPE_INT8:    gguf_set_val_i8  (ctx, kv.get_key().c_str(), kv.get_val<int8_t>());              break;
1330
0
                case GGUF_TYPE_UINT16:  gguf_set_val_u16 (ctx, kv.get_key().c_str(), kv.get_val<uint16_t>());            break;
1331
0
                case GGUF_TYPE_INT16:   gguf_set_val_i16 (ctx, kv.get_key().c_str(), kv.get_val<int16_t>());             break;
1332
0
                case GGUF_TYPE_UINT32:  gguf_set_val_u32 (ctx, kv.get_key().c_str(), kv.get_val<uint32_t>());            break;
1333
0
                case GGUF_TYPE_INT32:   gguf_set_val_i32 (ctx, kv.get_key().c_str(), kv.get_val<int32_t>());             break;
1334
0
                case GGUF_TYPE_FLOAT32: gguf_set_val_f32 (ctx, kv.get_key().c_str(), kv.get_val<float>());               break;
1335
0
                case GGUF_TYPE_UINT64:  gguf_set_val_u64 (ctx, kv.get_key().c_str(), kv.get_val<uint64_t>());            break;
1336
0
                case GGUF_TYPE_INT64:   gguf_set_val_i64 (ctx, kv.get_key().c_str(), kv.get_val<int64_t>());             break;
1337
0
                case GGUF_TYPE_FLOAT64: gguf_set_val_f64 (ctx, kv.get_key().c_str(), kv.get_val<double>());              break;
1338
0
                case GGUF_TYPE_BOOL:    gguf_set_val_bool(ctx, kv.get_key().c_str(), kv.get_val<bool>());                break;
1339
0
                case GGUF_TYPE_STRING:  gguf_set_val_str (ctx, kv.get_key().c_str(), kv.get_val<std::string>().c_str()); break;
1340
0
                case GGUF_TYPE_ARRAY:
1341
0
                default: GGML_ABORT("invalid type");
1342
0
            }
1343
0
            continue;
1344
0
        }
1345
1346
0
        const size_t ne = kv.get_ne();
1347
1348
0
        switch (kv.get_type()) {
1349
0
            case GGUF_TYPE_UINT8:
1350
0
            case GGUF_TYPE_INT8:
1351
0
            case GGUF_TYPE_UINT16:
1352
0
            case GGUF_TYPE_INT16:
1353
0
            case GGUF_TYPE_UINT32:
1354
0
            case GGUF_TYPE_INT32:
1355
0
            case GGUF_TYPE_FLOAT32:
1356
0
            case GGUF_TYPE_UINT64:
1357
0
            case GGUF_TYPE_INT64:
1358
0
            case GGUF_TYPE_FLOAT64:
1359
0
            case GGUF_TYPE_BOOL: {
1360
0
                gguf_set_arr_data(ctx, kv.get_key().c_str(), kv.get_type(), kv.data.data(), ne);
1361
0
            } break;
1362
0
            case GGUF_TYPE_STRING: {
1363
0
                std::vector<const char *> tmp(ne);
1364
0
                for (size_t j = 0; j < ne; ++j) {
1365
0
                    tmp[j] = kv.data_string[j].c_str();
1366
0
                }
1367
0
                gguf_set_arr_str(ctx, kv.get_key().c_str(), tmp.data(), ne);
1368
0
            } break;
1369
0
            case GGUF_TYPE_ARRAY:
1370
0
            default: GGML_ABORT("invalid type");
1371
0
        }
1372
0
    }
1373
0
}
1374
1375
void gguf_add_tensor(
1376
             struct gguf_context * ctx,
1377
0
        const struct ggml_tensor * tensor) {
1378
0
    GGML_ASSERT(tensor);
1379
0
    if (gguf_find_tensor(ctx, tensor->name) != -1) {
1380
0
        GGML_ABORT("duplicate tensor name: %s", tensor->name);
1381
0
    }
1382
1383
0
    struct gguf_tensor_info ti;
1384
0
    ti.t = *tensor;
1385
0
    ti.offset = ctx->info.empty() ? 0 :
1386
0
        ctx->info.back().offset + GGML_PAD(ggml_nbytes(&ctx->info.back().t), ctx->alignment);
1387
0
    ctx->info.push_back(ti);
1388
0
}
1389
1390
0
void gguf_set_tensor_type(struct gguf_context * ctx, const char * name, enum ggml_type type) {
1391
0
    const int64_t tensor_id = gguf_find_tensor(ctx, name);
1392
0
    if (tensor_id < 0) {
1393
0
        GGML_ABORT("tensor not found: %s", name);
1394
0
    }
1395
0
    struct ggml_tensor * tensor = &ctx->info[tensor_id].t;
1396
0
    const size_t  type_size = ggml_type_size(type);
1397
0
    const int64_t blck_size = ggml_blck_size(type);
1398
1399
0
    tensor->type = type;
1400
0
    GGML_ASSERT(tensor->ne[0] % blck_size == 0 && "tensor row size not divisible by block size of new type");
1401
1402
0
    tensor->nb[0] = type_size;
1403
0
    tensor->nb[1] = tensor->nb[0]*(tensor->ne[0]/blck_size);
1404
0
    for (int i = 2; i < GGML_MAX_DIMS; i++) {
1405
0
        tensor->nb[i] = tensor->nb[i - 1]*tensor->ne[i - 1];
1406
0
    }
1407
1408
    // update offsets
1409
0
    const int64_t n_tensors = gguf_get_n_tensors(ctx);
1410
0
    for (int64_t i = tensor_id + 1; i < n_tensors; ++i) {
1411
0
        ctx->info[i].offset = ctx->info[i - 1].offset + GGML_PAD(ggml_nbytes(&ctx->info[i - 1].t), ctx->alignment);
1412
0
    }
1413
0
}
1414
1415
0
void gguf_set_tensor_data(struct gguf_context * ctx, const char * name, const void * data) {
1416
0
    const int64_t tensor_id = gguf_find_tensor(ctx, name);
1417
0
    if (tensor_id < 0) {
1418
0
        GGML_ABORT("tensor not found: %s", name);
1419
0
    }
1420
1421
0
    ctx->info[tensor_id].t.data = (void *)(uintptr_t)data; // double cast suppresses warning about casting away const
1422
0
}
1423
1424
struct gguf_writer_base {
1425
    size_t written_bytes {0u};
1426
1427
    ~gguf_writer_base(void) = default;
1428
1429
    // we bet on devirtualization
1430
    virtual void write(int8_t val) = 0;
1431
    virtual void write(const std::vector<int8_t> & val) = 0;
1432
    virtual void write_tensor_data(const struct gguf_tensor_info & info, size_t offset_data, size_t alignment) = 0;
1433
1434
    template <typename T>
1435
0
    void write(const T & val) {
1436
0
        for (size_t i = 0; i < sizeof(val); ++i) {
1437
0
            write(reinterpret_cast<const int8_t *>(&val)[i]);
1438
0
        }
1439
0
    }
Unexecuted instantiation: void gguf_writer_base::write<char>(char const&)
Unexecuted instantiation: void gguf_writer_base::write<unsigned int>(unsigned int const&)
Unexecuted instantiation: void gguf_writer_base::write<long>(long const&)
Unexecuted instantiation: void gguf_writer_base::write<int>(int const&)
Unexecuted instantiation: void gguf_writer_base::write<unsigned long>(unsigned long const&)
1440
1441
0
    void write(const bool & val) {
1442
0
        const int8_t val8 = val ? 1 : 0;
1443
0
        write(val8);
1444
0
    }
1445
1446
0
    void write(const std::string & val) {
1447
0
        {
1448
0
            const uint64_t n = val.length();
1449
0
            write(n);
1450
0
        }
1451
0
        for (size_t i = 0; i < val.length(); ++i) {
1452
0
            write((val.data())[i]);
1453
0
        }
1454
0
    }
1455
1456
0
    void write(const char * val) {
1457
0
        write(std::string(val));
1458
0
    }
1459
1460
0
    void write(const enum ggml_type & val) {
1461
0
        write(int32_t(val));
1462
0
    }
1463
1464
0
    void write(const enum gguf_type & val) {
1465
0
        write(int32_t(val));
1466
0
    }
1467
1468
0
    void write(const struct gguf_kv & kv) {
1469
0
        const uint64_t ne = kv.get_ne();
1470
1471
0
        write(kv.get_key());
1472
1473
0
        if (kv.is_array) {
1474
0
            write(GGUF_TYPE_ARRAY);
1475
0
            write(kv.get_type());
1476
0
            write(ne);
1477
0
        } else {
1478
0
            write(kv.get_type());
1479
0
        }
1480
1481
0
        switch (kv.get_type()) {
1482
0
            case GGUF_TYPE_UINT8:
1483
0
            case GGUF_TYPE_INT8:
1484
0
            case GGUF_TYPE_UINT16:
1485
0
            case GGUF_TYPE_INT16:
1486
0
            case GGUF_TYPE_UINT32:
1487
0
            case GGUF_TYPE_INT32:
1488
0
            case GGUF_TYPE_FLOAT32:
1489
0
            case GGUF_TYPE_UINT64:
1490
0
            case GGUF_TYPE_INT64:
1491
0
            case GGUF_TYPE_FLOAT64: {
1492
0
                write(kv.data);
1493
0
            } break;
1494
0
            case GGUF_TYPE_BOOL: {
1495
0
                for (size_t i = 0; i < ne; ++i) {
1496
0
                    write(kv.get_val<bool>(i));
1497
0
                }
1498
0
            } break;
1499
0
            case GGUF_TYPE_STRING: {
1500
0
                for (size_t i = 0; i < ne; ++i) {
1501
0
                    write(kv.get_val<std::string>(i));
1502
0
                }
1503
0
            } break;
1504
0
            case GGUF_TYPE_ARRAY:
1505
0
            default: GGML_ABORT("invalid type");
1506
0
        }
1507
0
    }
1508
1509
0
    void write_tensor_meta(const struct gguf_tensor_info & info) {
1510
0
        write(info.t.name);
1511
1512
0
        const uint32_t n_dims = ggml_n_dims(&info.t);
1513
0
        write(n_dims);
1514
1515
0
        for (uint32_t j = 0; j < n_dims; ++j) {
1516
0
            write(info.t.ne[j]);
1517
0
        }
1518
0
        write(info.t.type);
1519
0
        write(info.offset);
1520
0
    }
1521
1522
0
    void pad(const size_t alignment) {
1523
0
        while (written_bytes % alignment != 0) {
1524
0
            const int8_t zero = 0;
1525
0
            write(zero);
1526
0
        }
1527
0
    }
1528
};
1529
1530
// vector buffer based writer
1531
struct gguf_writer_buf final : public gguf_writer_base {
1532
    std::vector<int8_t> & buf;
1533
1534
0
    gguf_writer_buf(std::vector<int8_t> & buf) : buf(buf) {}
1535
1536
    using gguf_writer_base::write;
1537
1538
0
    void write(const int8_t val) override {
1539
0
        buf.push_back(val);
1540
0
        written_bytes++;
1541
0
    }
1542
1543
0
    void write(const std::vector<int8_t> & val) override {
1544
0
        buf.insert(buf.end(), val.begin(), val.end());
1545
0
        written_bytes += val.size();
1546
0
    }
1547
1548
0
    void write_tensor_data(const struct gguf_tensor_info & info, const size_t offset_data, const size_t alignment) override {
1549
0
        GGML_ASSERT(buf.size() - offset_data == info.offset);
1550
1551
0
        GGML_ASSERT(ggml_is_contiguous(&info.t));
1552
0
        const size_t offset = buf.size();
1553
0
        const size_t nbytes = ggml_nbytes(&info.t);
1554
1555
0
        buf.resize(offset + nbytes);
1556
0
        if (info.t.buffer) {
1557
0
            ggml_backend_tensor_get(&info.t, buf.data() + offset, 0, nbytes);
1558
0
        } else {
1559
0
            GGML_ASSERT(info.t.data);
1560
0
            memcpy(buf.data() + offset, info.t.data, nbytes);
1561
0
        }
1562
0
        written_bytes += nbytes;
1563
1564
0
        pad(alignment);
1565
0
    }
1566
};
1567
1568
// file based writer
1569
struct gguf_writer_file final : public gguf_writer_base {
1570
    FILE * file;
1571
1572
0
    gguf_writer_file(FILE* file) : file(file) {}
1573
1574
    using gguf_writer_base::write;
1575
1576
0
    void write(const int8_t val) override {
1577
0
        const auto real_val = static_cast<uint8_t>(val);
1578
0
        const auto ret = fputc(real_val, file);
1579
0
        written_bytes++;
1580
0
        if (ret != real_val) {
1581
0
            throw std::runtime_error("unexpected fputc result '" + std::to_string(ret) + "' instead of '" + std::to_string((int)real_val) + "'");
1582
0
        }
1583
0
    }
1584
1585
0
    void write(const std::vector<int8_t> & val) override {
1586
0
        const auto ret = fwrite(val.data(), 1, val.size(), file);
1587
0
        written_bytes += val.size();
1588
0
        if (ret != val.size()) {
1589
0
            throw std::runtime_error("unexpected fwrite number of bytes written, '" + std::to_string(ret) + "' instead of '" + std::to_string(val.size()) + "'");
1590
0
        }
1591
0
    }
1592
1593
0
    void write_tensor_data(const struct gguf_tensor_info & info, const size_t offset_data, const size_t alignment) override {
1594
0
        GGML_ASSERT(written_bytes - offset_data == info.offset);
1595
1596
0
        GGML_ASSERT(ggml_is_contiguous(&info.t));
1597
0
        const size_t nbytes = ggml_nbytes(&info.t);
1598
1599
0
        std::vector<int8_t> buf(nbytes);
1600
0
        if (info.t.buffer) {
1601
0
            ggml_backend_tensor_get(&info.t, buf.data(), 0, nbytes);
1602
0
        } else {
1603
0
            GGML_ASSERT(info.t.data);
1604
0
            memcpy(buf.data(), info.t.data, nbytes);
1605
0
        }
1606
0
        write(buf);
1607
1608
0
        pad(alignment);
1609
0
    }
1610
};
1611
1612
template <typename writer_t>
1613
0
static void gguf_write_out(const struct gguf_context * ctx, writer_t & gw, bool only_meta) {
1614
0
    const int64_t n_kv      = gguf_get_n_kv(ctx);
1615
0
    const int64_t n_tensors = gguf_get_n_tensors(ctx);
1616
1617
    // write header
1618
0
    gw.write(GGUF_MAGIC[0]);
1619
0
    gw.write(GGUF_MAGIC[1]);
1620
0
    gw.write(GGUF_MAGIC[2]);
1621
0
    gw.write(GGUF_MAGIC[3]);
1622
0
    gw.write(ctx->version);
1623
0
    gw.write(n_tensors);
1624
0
    gw.write(n_kv);
1625
1626
    // write key-value pairs
1627
0
    for (int64_t i = 0; i < n_kv; ++i) {
1628
0
        gw.write(ctx->kv[i]);
1629
0
    }
1630
1631
    // write tensor info
1632
0
    for (int64_t i = 0; i < n_tensors; ++i) {
1633
0
        gw.write_tensor_meta(ctx->info[i]);
1634
0
    }
1635
1636
    // we require the data section to be aligned
1637
0
    gw.pad(ctx->alignment);
1638
1639
0
    if (only_meta) {
1640
0
        return;
1641
0
    }
1642
1643
0
    const size_t offset_data = gw.written_bytes;
1644
1645
    // write tensor data
1646
0
    for (int64_t i = 0; i < n_tensors; ++i) {
1647
0
        gw.write_tensor_data(ctx->info[i], offset_data, ctx->alignment);
1648
0
    }
1649
0
}
Unexecuted instantiation: gguf.cpp:void gguf_write_out<gguf_writer_buf>(gguf_context const*, gguf_writer_buf&, bool)
Unexecuted instantiation: gguf.cpp:void gguf_write_out<gguf_writer_file>(gguf_context const*, gguf_writer_file&, bool)
1650
1651
0
void gguf_write_to_buf(const struct gguf_context * ctx, std::vector<int8_t> & buf, bool only_meta) {
1652
0
    gguf_writer_buf gw(buf);
1653
0
    gguf_write_out(ctx, gw, only_meta);
1654
0
}
1655
1656
0
bool gguf_write_to_file_ptr(const struct gguf_context * ctx, FILE * file, bool only_meta) {
1657
0
    GGML_ASSERT(file);
1658
1659
0
    try {
1660
0
        gguf_writer_file gw(file);
1661
0
        gguf_write_out(ctx, gw, only_meta);
1662
0
    } catch (const std::runtime_error& ex) {
1663
0
        GGML_LOG_ERROR("%s: failed to write GGUF data: %s\n", __func__, ex.what());
1664
0
        return false;
1665
0
    }
1666
0
    return true;
1667
0
}
1668
1669
0
bool gguf_write_to_file(const struct gguf_context * ctx, const char * fname, bool only_meta) {
1670
0
    FILE * file = ggml_fopen(fname, "wb");
1671
1672
0
    if (!file) {
1673
0
        GGML_LOG_ERROR("%s: failed to open file '%s' for writing GGUF data\n", __func__, fname);
1674
0
        return false;
1675
0
    }
1676
1677
0
    const bool success = gguf_write_to_file_ptr(ctx, file, only_meta);
1678
0
    if (!success) {
1679
0
        GGML_LOG_ERROR("%s: failed to write GGUF data into '%s'\n", __func__, fname);
1680
0
    }
1681
1682
0
    fclose(file);
1683
0
    return success;
1684
0
}
1685
1686
0
size_t gguf_get_meta_size(const struct gguf_context * ctx) {
1687
    // only return size
1688
0
    std::vector<int8_t> buf;
1689
0
    gguf_write_to_buf(ctx, buf, /*only_meta =*/ true);
1690
0
    return buf.size();
1691
0
}
1692
1693
0
void gguf_get_meta_data(const struct gguf_context * ctx, void * data) {
1694
0
    std::vector<int8_t> buf;
1695
0
    gguf_write_to_buf(ctx, buf, /*only_meta =*/ true);
1696
0
    memcpy(data, buf.data(), buf.size());
1697
0
}