@fugood/llama.node 1.4.1 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CMakeLists.txt +1 -1
- package/lib/binding.js +3 -0
- package/lib/binding.ts +2 -0
- package/package.json +16 -16
- package/scripts/llama.cpp.patch +25 -11
- package/src/LlamaContext.cpp +2 -2
- package/src/llama.cpp/CMakeLists.txt +21 -6
- package/src/llama.cpp/common/CMakeLists.txt +6 -0
- package/src/llama.cpp/common/arg.cpp +65 -16
- package/src/llama.cpp/common/chat-parser.cpp +40 -0
- package/src/llama.cpp/common/chat-peg-parser.cpp +110 -0
- package/src/llama.cpp/common/chat-peg-parser.h +105 -0
- package/src/llama.cpp/common/chat.cpp +40 -29
- package/src/llama.cpp/common/chat.h +10 -1
- package/src/llama.cpp/common/common.cpp +24 -5
- package/src/llama.cpp/common/common.h +16 -5
- package/src/llama.cpp/common/download.cpp +18 -8
- package/src/llama.cpp/common/download.h +3 -1
- package/src/llama.cpp/common/json-schema-to-grammar.cpp +1 -1
- package/src/llama.cpp/common/log.cpp +15 -1
- package/src/llama.cpp/common/log.h +19 -12
- package/src/llama.cpp/common/peg-parser.cpp +1712 -0
- package/src/llama.cpp/common/peg-parser.h +459 -0
- package/src/llama.cpp/common/unicode.cpp +64 -0
- package/src/llama.cpp/common/unicode.h +22 -0
- package/src/llama.cpp/ggml/CMakeLists.txt +48 -48
- package/src/llama.cpp/ggml/include/ggml.h +7 -2
- package/src/llama.cpp/ggml/src/CMakeLists.txt +0 -4
- package/src/llama.cpp/ggml/src/ggml-cpu/arch/arm/cpu-feats.cpp +4 -0
- package/src/llama.cpp/ggml/src/ggml-cpu/ggml-cpu.c +10 -13
- package/src/llama.cpp/ggml/src/ggml-cpu/ops.cpp +60 -1
- package/src/llama.cpp/src/CMakeLists.txt +1 -0
- package/src/llama.cpp/src/llama-arch.cpp +30 -1
- package/src/llama.cpp/src/llama-arch.h +3 -0
- package/src/llama.cpp/src/llama-graph.cpp +3 -6
- package/src/llama.cpp/src/llama-hparams.h +2 -2
- package/src/llama.cpp/src/llama-impl.h +1 -1
- package/src/llama.cpp/src/llama-mmap.cpp +1 -1
- package/src/llama.cpp/src/llama-model.cpp +50 -6
- package/src/llama.cpp/src/llama-vocab.cpp +1 -2
- package/src/llama.cpp/src/models/mistral3.cpp +160 -0
- package/src/llama.cpp/src/models/models.h +4 -0
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <nlohmann/json_fwd.hpp>
|
|
4
|
+
|
|
5
|
+
#include <memory>
|
|
6
|
+
#include <unordered_map>
|
|
7
|
+
#include <string>
|
|
8
|
+
#include <string_view>
|
|
9
|
+
#include <functional>
|
|
10
|
+
#include <vector>
|
|
11
|
+
#include <variant>
|
|
12
|
+
|
|
13
|
+
struct common_grammar_builder;
|
|
14
|
+
|
|
15
|
+
class common_peg_parser_builder;
|
|
16
|
+
|
|
17
|
+
using common_peg_parser_id = size_t;
|
|
18
|
+
constexpr common_peg_parser_id COMMON_PEG_INVALID_PARSER_ID = static_cast<common_peg_parser_id>(-1);
|
|
19
|
+
|
|
20
|
+
using common_peg_ast_id = size_t;
|
|
21
|
+
constexpr common_peg_ast_id COMMON_PEG_INVALID_AST_ID = static_cast<common_peg_ast_id>(-1);
|
|
22
|
+
|
|
23
|
+
// Lightweight wrapper around common_peg_parser_id for convenience
|
|
24
|
+
class common_peg_parser {
|
|
25
|
+
common_peg_parser_id id_;
|
|
26
|
+
common_peg_parser_builder & builder_;
|
|
27
|
+
|
|
28
|
+
public:
|
|
29
|
+
common_peg_parser(const common_peg_parser & other) : id_(other.id_), builder_(other.builder_) {}
|
|
30
|
+
common_peg_parser(common_peg_parser_id id, common_peg_parser_builder & builder) : id_(id), builder_(builder) {}
|
|
31
|
+
|
|
32
|
+
common_peg_parser & operator=(const common_peg_parser & other);
|
|
33
|
+
common_peg_parser & operator+=(const common_peg_parser & other);
|
|
34
|
+
common_peg_parser & operator|=(const common_peg_parser & other);
|
|
35
|
+
|
|
36
|
+
operator common_peg_parser_id() const { return id_; }
|
|
37
|
+
common_peg_parser_id id() const { return id_; }
|
|
38
|
+
|
|
39
|
+
common_peg_parser_builder & builder() const { return builder_; }
|
|
40
|
+
|
|
41
|
+
// Creates a sequence
|
|
42
|
+
common_peg_parser operator+(const common_peg_parser & other) const;
|
|
43
|
+
|
|
44
|
+
// Creates a sequence separated by spaces.
|
|
45
|
+
common_peg_parser operator<<(const common_peg_parser & other) const;
|
|
46
|
+
|
|
47
|
+
// Creates a choice
|
|
48
|
+
common_peg_parser operator|(const common_peg_parser & other) const;
|
|
49
|
+
|
|
50
|
+
common_peg_parser operator+(const char * str) const;
|
|
51
|
+
common_peg_parser operator+(const std::string & str) const;
|
|
52
|
+
common_peg_parser operator<<(const char * str) const;
|
|
53
|
+
common_peg_parser operator<<(const std::string & str) const;
|
|
54
|
+
common_peg_parser operator|(const char * str) const;
|
|
55
|
+
common_peg_parser operator|(const std::string & str) const;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
common_peg_parser operator+(const char * str, const common_peg_parser & p);
|
|
59
|
+
common_peg_parser operator+(const std::string & str, const common_peg_parser & p);
|
|
60
|
+
common_peg_parser operator<<(const char * str, const common_peg_parser & p);
|
|
61
|
+
common_peg_parser operator<<(const std::string & str, const common_peg_parser & p);
|
|
62
|
+
common_peg_parser operator|(const char * str, const common_peg_parser & p);
|
|
63
|
+
common_peg_parser operator|(const std::string & str, const common_peg_parser & p);
|
|
64
|
+
|
|
65
|
+
enum common_peg_parse_result_type {
|
|
66
|
+
COMMON_PEG_PARSE_RESULT_FAIL = 0,
|
|
67
|
+
COMMON_PEG_PARSE_RESULT_SUCCESS = 1,
|
|
68
|
+
COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT = 2,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const char * common_peg_parse_result_type_name(common_peg_parse_result_type type);
|
|
72
|
+
|
|
73
|
+
struct common_peg_ast_node {
|
|
74
|
+
common_peg_ast_id id;
|
|
75
|
+
std::string rule;
|
|
76
|
+
std::string tag;
|
|
77
|
+
size_t start;
|
|
78
|
+
size_t end;
|
|
79
|
+
std::string_view text;
|
|
80
|
+
std::vector<common_peg_ast_id> children;
|
|
81
|
+
|
|
82
|
+
bool is_partial = false;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
struct common_peg_parse_result;
|
|
86
|
+
|
|
87
|
+
using common_peg_ast_visitor = std::function<void(const common_peg_ast_node & node)>;
|
|
88
|
+
|
|
89
|
+
class common_peg_ast_arena {
|
|
90
|
+
std::vector<common_peg_ast_node> nodes_;
|
|
91
|
+
public:
|
|
92
|
+
common_peg_ast_id add_node(
|
|
93
|
+
const std::string & rule,
|
|
94
|
+
const std::string & tag,
|
|
95
|
+
size_t start,
|
|
96
|
+
size_t end,
|
|
97
|
+
std::string_view text,
|
|
98
|
+
std::vector<common_peg_ast_id> children,
|
|
99
|
+
bool is_partial = false
|
|
100
|
+
) {
|
|
101
|
+
common_peg_ast_id id = nodes_.size();
|
|
102
|
+
nodes_.push_back({id, rule, tag, start, end, text, std::move(children), is_partial});
|
|
103
|
+
return id;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const common_peg_ast_node & get(common_peg_ast_id id) const { return nodes_.at(id); }
|
|
107
|
+
|
|
108
|
+
size_t size() const { return nodes_.size(); }
|
|
109
|
+
|
|
110
|
+
void clear() { nodes_.clear(); }
|
|
111
|
+
|
|
112
|
+
void visit(common_peg_ast_id id, const common_peg_ast_visitor & visitor) const;
|
|
113
|
+
void visit(const common_peg_parse_result & result, const common_peg_ast_visitor & visitor) const;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
struct common_peg_parse_result {
|
|
117
|
+
common_peg_parse_result_type type = COMMON_PEG_PARSE_RESULT_FAIL;
|
|
118
|
+
size_t start = 0;
|
|
119
|
+
size_t end = 0;
|
|
120
|
+
|
|
121
|
+
std::vector<common_peg_ast_id> nodes;
|
|
122
|
+
|
|
123
|
+
common_peg_parse_result() = default;
|
|
124
|
+
|
|
125
|
+
common_peg_parse_result(common_peg_parse_result_type type, size_t start)
|
|
126
|
+
: type(type), start(start), end(start) {}
|
|
127
|
+
|
|
128
|
+
common_peg_parse_result(common_peg_parse_result_type type, size_t start, size_t end)
|
|
129
|
+
: type(type), start(start), end(end) {}
|
|
130
|
+
|
|
131
|
+
common_peg_parse_result(common_peg_parse_result_type type, size_t start, size_t end, std::vector<common_peg_ast_id> nodes)
|
|
132
|
+
: type(type), start(start), end(end), nodes(std::move(nodes)) {}
|
|
133
|
+
|
|
134
|
+
bool fail() const { return type == COMMON_PEG_PARSE_RESULT_FAIL; }
|
|
135
|
+
bool need_more_input() const { return type == COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT; }
|
|
136
|
+
bool success() const { return type == COMMON_PEG_PARSE_RESULT_SUCCESS; }
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
struct common_peg_parse_context {
|
|
140
|
+
std::string input;
|
|
141
|
+
bool is_partial;
|
|
142
|
+
common_peg_ast_arena ast;
|
|
143
|
+
|
|
144
|
+
int parse_depth;
|
|
145
|
+
|
|
146
|
+
common_peg_parse_context()
|
|
147
|
+
: is_partial(false), parse_depth(0) {}
|
|
148
|
+
|
|
149
|
+
common_peg_parse_context(const std::string & input)
|
|
150
|
+
: input(input), is_partial(false), parse_depth(0) {}
|
|
151
|
+
|
|
152
|
+
common_peg_parse_context(const std::string & input, bool is_partial)
|
|
153
|
+
: input(input), is_partial(is_partial), parse_depth(0) {}
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
class common_peg_arena;
|
|
157
|
+
|
|
158
|
+
// Parser variants
|
|
159
|
+
struct common_peg_epsilon_parser {};
|
|
160
|
+
|
|
161
|
+
struct common_peg_start_parser {};
|
|
162
|
+
|
|
163
|
+
struct common_peg_end_parser {};
|
|
164
|
+
|
|
165
|
+
struct common_peg_literal_parser {
|
|
166
|
+
std::string literal;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
struct common_peg_sequence_parser {
|
|
170
|
+
std::vector<common_peg_parser_id> children;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
struct common_peg_choice_parser {
|
|
174
|
+
std::vector<common_peg_parser_id> children;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
struct common_peg_repetition_parser {
|
|
178
|
+
common_peg_parser_id child;
|
|
179
|
+
int min_count;
|
|
180
|
+
int max_count; // -1 for unbounded
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
struct common_peg_and_parser {
|
|
184
|
+
common_peg_parser_id child;
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
struct common_peg_not_parser {
|
|
188
|
+
common_peg_parser_id child;
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
struct common_peg_any_parser {};
|
|
192
|
+
|
|
193
|
+
struct common_peg_space_parser {};
|
|
194
|
+
|
|
195
|
+
struct common_peg_chars_parser {
|
|
196
|
+
struct char_range {
|
|
197
|
+
uint32_t start;
|
|
198
|
+
uint32_t end;
|
|
199
|
+
bool contains(uint32_t codepoint) const { return codepoint >= start && codepoint <= end; }
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
std::string pattern;
|
|
203
|
+
std::vector<char_range> ranges;
|
|
204
|
+
bool negated;
|
|
205
|
+
int min_count;
|
|
206
|
+
int max_count; // -1 for unbounded
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
struct common_peg_json_string_parser {};
|
|
210
|
+
|
|
211
|
+
struct common_peg_until_parser {
|
|
212
|
+
std::vector<std::string> delimiters;
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
struct common_peg_schema_parser {
|
|
216
|
+
common_peg_parser_id child;
|
|
217
|
+
std::string name;
|
|
218
|
+
std::shared_ptr<nlohmann::ordered_json> schema;
|
|
219
|
+
|
|
220
|
+
// Indicates if the GBNF should accept a raw string that matches the schema.
|
|
221
|
+
bool raw;
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
struct common_peg_rule_parser {
|
|
225
|
+
std::string name;
|
|
226
|
+
common_peg_parser_id child;
|
|
227
|
+
bool trigger;
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
struct common_peg_ref_parser {
|
|
231
|
+
std::string name;
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
struct common_peg_atomic_parser {
|
|
235
|
+
common_peg_parser_id child;
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
struct common_peg_tag_parser {
|
|
239
|
+
common_peg_parser_id child;
|
|
240
|
+
std::string tag;
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
// Variant holding all parser types
|
|
244
|
+
using common_peg_parser_variant = std::variant<
|
|
245
|
+
common_peg_epsilon_parser,
|
|
246
|
+
common_peg_start_parser,
|
|
247
|
+
common_peg_end_parser,
|
|
248
|
+
common_peg_literal_parser,
|
|
249
|
+
common_peg_sequence_parser,
|
|
250
|
+
common_peg_choice_parser,
|
|
251
|
+
common_peg_repetition_parser,
|
|
252
|
+
common_peg_and_parser,
|
|
253
|
+
common_peg_not_parser,
|
|
254
|
+
common_peg_any_parser,
|
|
255
|
+
common_peg_space_parser,
|
|
256
|
+
common_peg_chars_parser,
|
|
257
|
+
common_peg_json_string_parser,
|
|
258
|
+
common_peg_until_parser,
|
|
259
|
+
common_peg_schema_parser,
|
|
260
|
+
common_peg_rule_parser,
|
|
261
|
+
common_peg_ref_parser,
|
|
262
|
+
common_peg_atomic_parser,
|
|
263
|
+
common_peg_tag_parser
|
|
264
|
+
>;
|
|
265
|
+
|
|
266
|
+
class common_peg_arena {
|
|
267
|
+
std::vector<common_peg_parser_variant> parsers_;
|
|
268
|
+
std::unordered_map<std::string, common_peg_parser_id> rules_;
|
|
269
|
+
common_peg_parser_id root_ = COMMON_PEG_INVALID_PARSER_ID;
|
|
270
|
+
|
|
271
|
+
public:
|
|
272
|
+
const common_peg_parser_variant & get(common_peg_parser_id id) const { return parsers_.at(id); }
|
|
273
|
+
common_peg_parser_variant & get(common_peg_parser_id id) { return parsers_.at(id); }
|
|
274
|
+
|
|
275
|
+
size_t size() const { return parsers_.size(); }
|
|
276
|
+
bool empty() const { return parsers_.empty(); }
|
|
277
|
+
|
|
278
|
+
common_peg_parser_id get_rule(const std::string & name) const;
|
|
279
|
+
bool has_rule(const std::string & name) const { return rules_.find(name) != rules_.end(); }
|
|
280
|
+
|
|
281
|
+
common_peg_parser_id root() const { return root_; }
|
|
282
|
+
void set_root(common_peg_parser_id id) { root_ = id; }
|
|
283
|
+
|
|
284
|
+
common_peg_parse_result parse(common_peg_parse_context & ctx, size_t start = 0) const;
|
|
285
|
+
common_peg_parse_result parse(common_peg_parser_id id, common_peg_parse_context & ctx, size_t start) const;
|
|
286
|
+
|
|
287
|
+
void resolve_refs();
|
|
288
|
+
|
|
289
|
+
void build_grammar(const common_grammar_builder & builder, bool lazy = false) const;
|
|
290
|
+
|
|
291
|
+
std::string dump(common_peg_parser_id id) const;
|
|
292
|
+
|
|
293
|
+
nlohmann::json to_json() const;
|
|
294
|
+
static common_peg_arena from_json(const nlohmann::json & j);
|
|
295
|
+
|
|
296
|
+
std::string save() const;
|
|
297
|
+
void load(const std::string & data);
|
|
298
|
+
|
|
299
|
+
friend class common_peg_parser_builder;
|
|
300
|
+
|
|
301
|
+
private:
|
|
302
|
+
common_peg_parser_id add_parser(common_peg_parser_variant parser);
|
|
303
|
+
void add_rule(const std::string & name, common_peg_parser_id id);
|
|
304
|
+
|
|
305
|
+
common_peg_parser_id resolve_ref(common_peg_parser_id id);
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
class common_peg_parser_builder {
|
|
309
|
+
common_peg_arena arena_;
|
|
310
|
+
|
|
311
|
+
common_peg_parser wrap(common_peg_parser_id id) { return common_peg_parser(id, *this); }
|
|
312
|
+
common_peg_parser add(const common_peg_parser_variant & p) { return wrap(arena_.add_parser(p)); }
|
|
313
|
+
|
|
314
|
+
public:
|
|
315
|
+
common_peg_parser_builder();
|
|
316
|
+
|
|
317
|
+
// Match nothing, always succeed.
|
|
318
|
+
// S -> ε
|
|
319
|
+
common_peg_parser eps() { return add(common_peg_epsilon_parser{}); }
|
|
320
|
+
|
|
321
|
+
// Matches the start of the input.
|
|
322
|
+
// S -> ^
|
|
323
|
+
common_peg_parser start() { return add(common_peg_start_parser{}); }
|
|
324
|
+
|
|
325
|
+
// Matches the end of the input.
|
|
326
|
+
// S -> $
|
|
327
|
+
common_peg_parser end() { return add(common_peg_end_parser{}); }
|
|
328
|
+
|
|
329
|
+
// Matches an exact literal string.
|
|
330
|
+
// S -> "hello"
|
|
331
|
+
common_peg_parser literal(const std::string & literal) { return add(common_peg_literal_parser{literal}); }
|
|
332
|
+
|
|
333
|
+
// Matches a sequence of parsers in order, all must succeed.
|
|
334
|
+
// S -> A B C
|
|
335
|
+
common_peg_parser sequence() { return add(common_peg_sequence_parser{}); }
|
|
336
|
+
common_peg_parser sequence(const std::vector<common_peg_parser_id> & parsers);
|
|
337
|
+
common_peg_parser sequence(const std::vector<common_peg_parser> & parsers);
|
|
338
|
+
common_peg_parser sequence(std::initializer_list<common_peg_parser> parsers);
|
|
339
|
+
|
|
340
|
+
// Matches the first parser that succeeds from a list of alternatives.
|
|
341
|
+
// S -> A | B | C
|
|
342
|
+
common_peg_parser choice() { return add(common_peg_choice_parser{}); }
|
|
343
|
+
common_peg_parser choice(const std::vector<common_peg_parser_id> & parsers);
|
|
344
|
+
common_peg_parser choice(const std::vector<common_peg_parser> & parsers);
|
|
345
|
+
common_peg_parser choice(std::initializer_list<common_peg_parser> parsers);
|
|
346
|
+
|
|
347
|
+
// Matches one or more repetitions of a parser.
|
|
348
|
+
// S -> A+
|
|
349
|
+
common_peg_parser one_or_more(const common_peg_parser & p) { return repeat(p, 1, -1); }
|
|
350
|
+
|
|
351
|
+
// Matches zero or more repetitions of a parser, always succeeds.
|
|
352
|
+
// S -> A*
|
|
353
|
+
common_peg_parser zero_or_more(const common_peg_parser & p) { return repeat(p, 0, -1); }
|
|
354
|
+
|
|
355
|
+
// Matches zero or one occurrence of a parser, always succeeds.
|
|
356
|
+
// S -> A?
|
|
357
|
+
common_peg_parser optional(const common_peg_parser & p) { return repeat(p, 0, 1); }
|
|
358
|
+
|
|
359
|
+
// Positive lookahead: succeeds if child parser succeeds, consumes no input.
|
|
360
|
+
// S -> &A
|
|
361
|
+
common_peg_parser peek(const common_peg_parser & p) { return add(common_peg_and_parser{p}); }
|
|
362
|
+
|
|
363
|
+
// Negative lookahead: succeeds if child parser fails, consumes no input.
|
|
364
|
+
// S -> !A
|
|
365
|
+
common_peg_parser negate(const common_peg_parser & p) { return add(common_peg_not_parser{p}); }
|
|
366
|
+
|
|
367
|
+
// Matches any single character.
|
|
368
|
+
// S -> .
|
|
369
|
+
common_peg_parser any() { return add(common_peg_any_parser{}); }
|
|
370
|
+
|
|
371
|
+
// Matches between min and max repetitions of characters from a character class.
|
|
372
|
+
// S -> [a-z]{m,n}
|
|
373
|
+
//
|
|
374
|
+
// Use -1 for max to represent unbounded repetition (equivalent to {m,})
|
|
375
|
+
common_peg_parser chars(const std::string & classes, int min = 1, int max = -1);
|
|
376
|
+
|
|
377
|
+
// Creates a lightweight reference to a named rule (resolved during build()).
|
|
378
|
+
// Use this for forward references in recursive grammars.
|
|
379
|
+
// expr_ref -> expr
|
|
380
|
+
common_peg_parser ref(const std::string & name) { return add(common_peg_ref_parser{name}); }
|
|
381
|
+
|
|
382
|
+
// Matches zero or more whitespace characters (space, tab, newline).
|
|
383
|
+
// S -> [ \t\n]*
|
|
384
|
+
common_peg_parser space() { return add(common_peg_space_parser{}); }
|
|
385
|
+
|
|
386
|
+
// Matches all characters until a delimiter is found (delimiter not consumed).
|
|
387
|
+
// S -> (!delim .)*
|
|
388
|
+
common_peg_parser until(const std::string & delimiter) { return add(common_peg_until_parser{{delimiter}}); }
|
|
389
|
+
|
|
390
|
+
// Matches all characters until one of the delimiters in the list is found (delimiter not consumed).
|
|
391
|
+
// S -> (!delim .)*
|
|
392
|
+
common_peg_parser until_one_of(const std::vector<std::string> & delimiters) { return add(common_peg_until_parser{delimiters}); }
|
|
393
|
+
|
|
394
|
+
// Matches everything
|
|
395
|
+
// S -> .*
|
|
396
|
+
common_peg_parser rest() { return until_one_of({}); }
|
|
397
|
+
|
|
398
|
+
// Matches between min and max repetitions of a parser (inclusive).
|
|
399
|
+
// S -> A{m,n}
|
|
400
|
+
// Use -1 for max to represent unbounded repetition (equivalent to {m,})
|
|
401
|
+
common_peg_parser repeat(const common_peg_parser & p, int min, int max) { return add(common_peg_repetition_parser{p, min,max}); }
|
|
402
|
+
|
|
403
|
+
// Matches exactly n repetitions of a parser.
|
|
404
|
+
// S -> A{n}
|
|
405
|
+
common_peg_parser repeat(const common_peg_parser & p, int n) { return repeat(p, n, n); }
|
|
406
|
+
|
|
407
|
+
// Creates a complete JSON parser supporting objects, arrays, strings, numbers, booleans, and null.
|
|
408
|
+
// value -> object | array | string | number | true | false | null
|
|
409
|
+
common_peg_parser json();
|
|
410
|
+
common_peg_parser json_object();
|
|
411
|
+
common_peg_parser json_string();
|
|
412
|
+
common_peg_parser json_array();
|
|
413
|
+
common_peg_parser json_number();
|
|
414
|
+
common_peg_parser json_bool();
|
|
415
|
+
common_peg_parser json_null();
|
|
416
|
+
|
|
417
|
+
// Matches JSON string content without the surrounding quotes.
|
|
418
|
+
// Useful for extracting content within a JSON string.
|
|
419
|
+
common_peg_parser json_string_content();
|
|
420
|
+
|
|
421
|
+
// Matches a JSON object member with a key and associated parser as the
|
|
422
|
+
// value.
|
|
423
|
+
common_peg_parser json_member(const std::string & key, const common_peg_parser & p);
|
|
424
|
+
|
|
425
|
+
// Wraps a parser with JSON schema metadata for grammar generation.
|
|
426
|
+
// Used internally to convert JSON schemas to GBNF grammar rules.
|
|
427
|
+
common_peg_parser schema(const common_peg_parser & p, const std::string & name, const nlohmann::ordered_json & schema, bool raw = false);
|
|
428
|
+
|
|
429
|
+
// Creates a named rule, stores it in the grammar, and returns a ref.
|
|
430
|
+
// If trigger=true, marks this rule as an entry point for lazy grammar generation.
|
|
431
|
+
// auto json = p.rule("json", json_obj | json_arr | ...)
|
|
432
|
+
common_peg_parser rule(const std::string & name, const common_peg_parser & p, bool trigger = false);
|
|
433
|
+
|
|
434
|
+
// Creates a named rule using a builder function, and returns a ref.
|
|
435
|
+
// If trigger=true, marks this rule as an entry point for lazy grammar generation.
|
|
436
|
+
// auto json = p.rule("json", [&]() { return json_object() | json_array() | ... })
|
|
437
|
+
common_peg_parser rule(const std::string & name, const std::function<common_peg_parser()> & builder, bool trigger = false);
|
|
438
|
+
|
|
439
|
+
// Creates a trigger rule. When generating a lazy grammar from the parser,
|
|
440
|
+
// only trigger rules and descendents are emitted.
|
|
441
|
+
common_peg_parser trigger_rule(const std::string & name, const common_peg_parser & p) { return rule(name, p, true); }
|
|
442
|
+
common_peg_parser trigger_rule(const std::string & name, const std::function<common_peg_parser()> & builder) { return rule(name, builder, true); }
|
|
443
|
+
|
|
444
|
+
// Creates an atomic parser. Atomic parsers do not create an AST node if
|
|
445
|
+
// the child results in a partial parse, i.e. NEEDS_MORE_INPUT. This is
|
|
446
|
+
// intended for situations where partial output is undesirable.
|
|
447
|
+
common_peg_parser atomic(const common_peg_parser & p) { return add(common_peg_atomic_parser{p}); }
|
|
448
|
+
|
|
449
|
+
// Tags create nodes in the generated AST for semantic purposes.
|
|
450
|
+
// Unlike rules, you can tag multiple nodes with the same tag.
|
|
451
|
+
common_peg_parser tag(const std::string & tag, const common_peg_parser & p) { return add(common_peg_tag_parser{p.id(), tag}); }
|
|
452
|
+
|
|
453
|
+
void set_root(const common_peg_parser & p);
|
|
454
|
+
|
|
455
|
+
common_peg_arena build();
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
// Helper function for building parsers
|
|
459
|
+
common_peg_arena build_peg_parser(const std::function<common_peg_parser(common_peg_parser_builder & builder)> & fn);
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#include "unicode.h"
|
|
2
|
+
|
|
3
|
+
// implementation adopted from src/unicode.cpp
|
|
4
|
+
|
|
5
|
+
size_t utf8_sequence_length(unsigned char first_byte) {
|
|
6
|
+
const size_t lookup[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 4 };
|
|
7
|
+
uint8_t highbits = static_cast<uint8_t>(first_byte) >> 4;
|
|
8
|
+
return lookup[highbits];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
utf8_parse_result parse_utf8_codepoint(std::string_view input, size_t offset) {
|
|
12
|
+
if (offset >= input.size()) {
|
|
13
|
+
return utf8_parse_result(utf8_parse_result::INCOMPLETE);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// ASCII fast path
|
|
17
|
+
if (!(input[offset] & 0x80)) {
|
|
18
|
+
return utf8_parse_result(utf8_parse_result::SUCCESS, input[offset], 1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Invalid: continuation byte as first byte
|
|
22
|
+
if (!(input[offset] & 0x40)) {
|
|
23
|
+
return utf8_parse_result(utf8_parse_result::INVALID);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// 2-byte sequence
|
|
27
|
+
if (!(input[offset] & 0x20)) {
|
|
28
|
+
if (offset + 1 >= input.size()) {
|
|
29
|
+
return utf8_parse_result(utf8_parse_result::INCOMPLETE);
|
|
30
|
+
}
|
|
31
|
+
if ((input[offset + 1] & 0xc0) != 0x80) {
|
|
32
|
+
return utf8_parse_result(utf8_parse_result::INVALID);
|
|
33
|
+
}
|
|
34
|
+
auto result = ((input[offset] & 0x1f) << 6) | (input[offset + 1] & 0x3f);
|
|
35
|
+
return utf8_parse_result(utf8_parse_result::SUCCESS, result, 2);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// 3-byte sequence
|
|
39
|
+
if (!(input[offset] & 0x10)) {
|
|
40
|
+
if (offset + 2 >= input.size()) {
|
|
41
|
+
return utf8_parse_result(utf8_parse_result::INCOMPLETE);
|
|
42
|
+
}
|
|
43
|
+
if ((input[offset + 1] & 0xc0) != 0x80 || (input[offset + 2] & 0xc0) != 0x80) {
|
|
44
|
+
return utf8_parse_result(utf8_parse_result::INVALID);
|
|
45
|
+
}
|
|
46
|
+
auto result = ((input[offset] & 0x0f) << 12) | ((input[offset + 1] & 0x3f) << 6) | (input[offset + 2] & 0x3f);
|
|
47
|
+
return utf8_parse_result(utf8_parse_result::SUCCESS, result, 3);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 4-byte sequence
|
|
51
|
+
if (!(input[offset] & 0x08)) {
|
|
52
|
+
if (offset + 3 >= input.size()) {
|
|
53
|
+
return utf8_parse_result(utf8_parse_result::INCOMPLETE);
|
|
54
|
+
}
|
|
55
|
+
if ((input[offset + 1] & 0xc0) != 0x80 || (input[offset + 2] & 0xc0) != 0x80 || (input[offset + 3] & 0xc0) != 0x80) {
|
|
56
|
+
return utf8_parse_result(utf8_parse_result::INVALID);
|
|
57
|
+
}
|
|
58
|
+
auto result = ((input[offset] & 0x07) << 18) | ((input[offset + 1] & 0x3f) << 12) | ((input[offset + 2] & 0x3f) << 6) | (input[offset + 3] & 0x3f);
|
|
59
|
+
return utf8_parse_result(utf8_parse_result::SUCCESS, result, 4);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Invalid first byte
|
|
63
|
+
return utf8_parse_result(utf8_parse_result::INVALID);
|
|
64
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <cstdint>
|
|
4
|
+
#include <string_view>
|
|
5
|
+
|
|
6
|
+
// UTF-8 parsing utilities for streaming-aware unicode support
|
|
7
|
+
|
|
8
|
+
struct utf8_parse_result {
|
|
9
|
+
uint32_t codepoint; // Decoded codepoint (only valid if status == SUCCESS)
|
|
10
|
+
size_t bytes_consumed; // How many bytes this codepoint uses (1-4)
|
|
11
|
+
enum status { SUCCESS, INCOMPLETE, INVALID } status;
|
|
12
|
+
|
|
13
|
+
utf8_parse_result(enum status s, uint32_t cp = 0, size_t bytes = 0)
|
|
14
|
+
: codepoint(cp), bytes_consumed(bytes), status(s) {}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// Determine the expected length of a UTF-8 sequence from its first byte
|
|
18
|
+
// Returns 0 for invalid first bytes
|
|
19
|
+
size_t utf8_sequence_length(unsigned char first_byte);
|
|
20
|
+
|
|
21
|
+
// Parse a single UTF-8 codepoint from input
|
|
22
|
+
utf8_parse_result parse_utf8_codepoint(std::string_view input, size_t offset);
|
|
@@ -175,11 +175,6 @@ option(GGML_CPU_ALL_VARIANTS "ggml: build all variants of the CPU backend (requi
|
|
|
175
175
|
set(GGML_CPU_ARM_ARCH "" CACHE STRING "ggml: CPU architecture for ARM")
|
|
176
176
|
set(GGML_CPU_POWERPC_CPUTYPE "" CACHE STRING "ggml: CPU type for PowerPC")
|
|
177
177
|
|
|
178
|
-
|
|
179
|
-
if (MINGW)
|
|
180
|
-
set(GGML_WIN_VER "0xA00" CACHE STRING "ggml: Windows version")
|
|
181
|
-
endif()
|
|
182
|
-
|
|
183
178
|
# ggml core
|
|
184
179
|
set(GGML_SCHED_MAX_COPIES "4" CACHE STRING "ggml: max input copies for pipeline parallelism")
|
|
185
180
|
option(GGML_CPU "ggml: enable CPU backend" ON)
|
|
@@ -226,7 +221,7 @@ option(GGML_WEBGPU "ggml: use WebGPU"
|
|
|
226
221
|
option(GGML_WEBGPU_DEBUG "ggml: enable WebGPU debug output" OFF)
|
|
227
222
|
option(GGML_WEBGPU_CPU_PROFILE "ggml: enable WebGPU profiling (CPU)" OFF)
|
|
228
223
|
option(GGML_WEBGPU_GPU_PROFILE "ggml: enable WebGPU profiling (GPU)" OFF)
|
|
229
|
-
|
|
224
|
+
option(GGML_WEBGPU_JSPI "ggml: use JSPI for WebGPU" ON)
|
|
230
225
|
option(GGML_ZDNN "ggml: use zDNN" OFF)
|
|
231
226
|
option(GGML_METAL "ggml: use Metal" ${GGML_METAL_DEFAULT})
|
|
232
227
|
option(GGML_METAL_NDEBUG "ggml: disable Metal debugging" OFF)
|
|
@@ -408,62 +403,67 @@ if (MSVC)
|
|
|
408
403
|
/wd4996 # Disable POSIX deprecation warnings
|
|
409
404
|
/wd4702 # Unreachable code warnings
|
|
410
405
|
)
|
|
411
|
-
|
|
406
|
+
set(MSVC_COMPILE_OPTIONS
|
|
407
|
+
"$<$<COMPILE_LANGUAGE:C>:/utf-8>"
|
|
408
|
+
"$<$<COMPILE_LANGUAGE:CXX>:/utf-8>"
|
|
409
|
+
)
|
|
410
|
+
function(configure_msvc_target target_name)
|
|
412
411
|
if(TARGET ${target_name})
|
|
413
412
|
target_compile_options(${target_name} PRIVATE ${MSVC_WARNING_FLAGS})
|
|
413
|
+
target_compile_options(${target_name} PRIVATE ${MSVC_COMPILE_OPTIONS})
|
|
414
414
|
endif()
|
|
415
415
|
endfunction()
|
|
416
416
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
417
|
+
configure_msvc_target(ggml-base)
|
|
418
|
+
configure_msvc_target(ggml)
|
|
419
|
+
configure_msvc_target(ggml-cpu)
|
|
420
|
+
configure_msvc_target(ggml-cpu-x64)
|
|
421
|
+
configure_msvc_target(ggml-cpu-sse42)
|
|
422
|
+
configure_msvc_target(ggml-cpu-sandybridge)
|
|
423
|
+
configure_msvc_target(ggml-cpu-haswell)
|
|
424
|
+
configure_msvc_target(ggml-cpu-skylakex)
|
|
425
|
+
configure_msvc_target(ggml-cpu-icelake)
|
|
426
|
+
configure_msvc_target(ggml-cpu-alderlake)
|
|
427
427
|
|
|
428
428
|
if (GGML_BUILD_EXAMPLES)
|
|
429
|
-
|
|
430
|
-
|
|
429
|
+
configure_msvc_target(common-ggml)
|
|
430
|
+
configure_msvc_target(common)
|
|
431
431
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
432
|
+
configure_msvc_target(mnist-common)
|
|
433
|
+
configure_msvc_target(mnist-eval)
|
|
434
|
+
configure_msvc_target(mnist-train)
|
|
435
435
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
436
|
+
configure_msvc_target(gpt-2-ctx)
|
|
437
|
+
configure_msvc_target(gpt-2-alloc)
|
|
438
|
+
configure_msvc_target(gpt-2-backend)
|
|
439
|
+
configure_msvc_target(gpt-2-sched)
|
|
440
|
+
configure_msvc_target(gpt-2-quantize)
|
|
441
|
+
configure_msvc_target(gpt-2-batched)
|
|
442
442
|
|
|
443
|
-
|
|
444
|
-
|
|
443
|
+
configure_msvc_target(gpt-j)
|
|
444
|
+
configure_msvc_target(gpt-j-quantize)
|
|
445
445
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
446
|
+
configure_msvc_target(magika)
|
|
447
|
+
configure_msvc_target(yolov3-tiny)
|
|
448
|
+
configure_msvc_target(sam)
|
|
449
449
|
|
|
450
|
-
|
|
451
|
-
|
|
450
|
+
configure_msvc_target(simple-ctx)
|
|
451
|
+
configure_msvc_target(simple-backend)
|
|
452
452
|
endif()
|
|
453
453
|
|
|
454
454
|
if (GGML_BUILD_TESTS)
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
455
|
+
configure_msvc_target(test-mul-mat)
|
|
456
|
+
configure_msvc_target(test-arange)
|
|
457
|
+
configure_msvc_target(test-backend-ops)
|
|
458
|
+
configure_msvc_target(test-cont)
|
|
459
|
+
configure_msvc_target(test-conv-transpose)
|
|
460
|
+
configure_msvc_target(test-conv-transpose-1d)
|
|
461
|
+
configure_msvc_target(test-conv1d)
|
|
462
|
+
configure_msvc_target(test-conv2d)
|
|
463
|
+
configure_msvc_target(test-conv2d-dw)
|
|
464
|
+
configure_msvc_target(test-customop)
|
|
465
|
+
configure_msvc_target(test-dup)
|
|
466
|
+
configure_msvc_target(test-opt)
|
|
467
|
+
configure_msvc_target(test-pool)
|
|
468
468
|
endif ()
|
|
469
469
|
endif()
|