@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.
Files changed (42) hide show
  1. package/CMakeLists.txt +1 -1
  2. package/lib/binding.js +3 -0
  3. package/lib/binding.ts +2 -0
  4. package/package.json +16 -16
  5. package/scripts/llama.cpp.patch +25 -11
  6. package/src/LlamaContext.cpp +2 -2
  7. package/src/llama.cpp/CMakeLists.txt +21 -6
  8. package/src/llama.cpp/common/CMakeLists.txt +6 -0
  9. package/src/llama.cpp/common/arg.cpp +65 -16
  10. package/src/llama.cpp/common/chat-parser.cpp +40 -0
  11. package/src/llama.cpp/common/chat-peg-parser.cpp +110 -0
  12. package/src/llama.cpp/common/chat-peg-parser.h +105 -0
  13. package/src/llama.cpp/common/chat.cpp +40 -29
  14. package/src/llama.cpp/common/chat.h +10 -1
  15. package/src/llama.cpp/common/common.cpp +24 -5
  16. package/src/llama.cpp/common/common.h +16 -5
  17. package/src/llama.cpp/common/download.cpp +18 -8
  18. package/src/llama.cpp/common/download.h +3 -1
  19. package/src/llama.cpp/common/json-schema-to-grammar.cpp +1 -1
  20. package/src/llama.cpp/common/log.cpp +15 -1
  21. package/src/llama.cpp/common/log.h +19 -12
  22. package/src/llama.cpp/common/peg-parser.cpp +1712 -0
  23. package/src/llama.cpp/common/peg-parser.h +459 -0
  24. package/src/llama.cpp/common/unicode.cpp +64 -0
  25. package/src/llama.cpp/common/unicode.h +22 -0
  26. package/src/llama.cpp/ggml/CMakeLists.txt +48 -48
  27. package/src/llama.cpp/ggml/include/ggml.h +7 -2
  28. package/src/llama.cpp/ggml/src/CMakeLists.txt +0 -4
  29. package/src/llama.cpp/ggml/src/ggml-cpu/arch/arm/cpu-feats.cpp +4 -0
  30. package/src/llama.cpp/ggml/src/ggml-cpu/ggml-cpu.c +10 -13
  31. package/src/llama.cpp/ggml/src/ggml-cpu/ops.cpp +60 -1
  32. package/src/llama.cpp/src/CMakeLists.txt +1 -0
  33. package/src/llama.cpp/src/llama-arch.cpp +30 -1
  34. package/src/llama.cpp/src/llama-arch.h +3 -0
  35. package/src/llama.cpp/src/llama-graph.cpp +3 -6
  36. package/src/llama.cpp/src/llama-hparams.h +2 -2
  37. package/src/llama.cpp/src/llama-impl.h +1 -1
  38. package/src/llama.cpp/src/llama-mmap.cpp +1 -1
  39. package/src/llama.cpp/src/llama-model.cpp +50 -6
  40. package/src/llama.cpp/src/llama-vocab.cpp +1 -2
  41. package/src/llama.cpp/src/models/mistral3.cpp +160 -0
  42. 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
- function(disable_msvc_warnings target_name)
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
- disable_msvc_warnings(ggml-base)
418
- disable_msvc_warnings(ggml)
419
- disable_msvc_warnings(ggml-cpu)
420
- disable_msvc_warnings(ggml-cpu-x64)
421
- disable_msvc_warnings(ggml-cpu-sse42)
422
- disable_msvc_warnings(ggml-cpu-sandybridge)
423
- disable_msvc_warnings(ggml-cpu-haswell)
424
- disable_msvc_warnings(ggml-cpu-skylakex)
425
- disable_msvc_warnings(ggml-cpu-icelake)
426
- disable_msvc_warnings(ggml-cpu-alderlake)
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
- disable_msvc_warnings(common-ggml)
430
- disable_msvc_warnings(common)
429
+ configure_msvc_target(common-ggml)
430
+ configure_msvc_target(common)
431
431
 
432
- disable_msvc_warnings(mnist-common)
433
- disable_msvc_warnings(mnist-eval)
434
- disable_msvc_warnings(mnist-train)
432
+ configure_msvc_target(mnist-common)
433
+ configure_msvc_target(mnist-eval)
434
+ configure_msvc_target(mnist-train)
435
435
 
436
- disable_msvc_warnings(gpt-2-ctx)
437
- disable_msvc_warnings(gpt-2-alloc)
438
- disable_msvc_warnings(gpt-2-backend)
439
- disable_msvc_warnings(gpt-2-sched)
440
- disable_msvc_warnings(gpt-2-quantize)
441
- disable_msvc_warnings(gpt-2-batched)
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
- disable_msvc_warnings(gpt-j)
444
- disable_msvc_warnings(gpt-j-quantize)
443
+ configure_msvc_target(gpt-j)
444
+ configure_msvc_target(gpt-j-quantize)
445
445
 
446
- disable_msvc_warnings(magika)
447
- disable_msvc_warnings(yolov3-tiny)
448
- disable_msvc_warnings(sam)
446
+ configure_msvc_target(magika)
447
+ configure_msvc_target(yolov3-tiny)
448
+ configure_msvc_target(sam)
449
449
 
450
- disable_msvc_warnings(simple-ctx)
451
- disable_msvc_warnings(simple-backend)
450
+ configure_msvc_target(simple-ctx)
451
+ configure_msvc_target(simple-backend)
452
452
  endif()
453
453
 
454
454
  if (GGML_BUILD_TESTS)
455
- disable_msvc_warnings(test-mul-mat)
456
- disable_msvc_warnings(test-arange)
457
- disable_msvc_warnings(test-backend-ops)
458
- disable_msvc_warnings(test-cont)
459
- disable_msvc_warnings(test-conv-transpose)
460
- disable_msvc_warnings(test-conv-transpose-1d)
461
- disable_msvc_warnings(test-conv1d)
462
- disable_msvc_warnings(test-conv2d)
463
- disable_msvc_warnings(test-conv2d-dw)
464
- disable_msvc_warnings(test-customop)
465
- disable_msvc_warnings(test-dup)
466
- disable_msvc_warnings(test-opt)
467
- disable_msvc_warnings(test-pool)
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()