@fugood/llama.node 0.3.6 → 0.3.8

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 (186) hide show
  1. package/README.md +17 -2
  2. package/bin/darwin/arm64/llama-node.node +0 -0
  3. package/bin/darwin/x64/llama-node.node +0 -0
  4. package/bin/linux/arm64/llama-node.node +0 -0
  5. package/bin/linux/x64/llama-node.node +0 -0
  6. package/bin/linux-cuda/arm64/llama-node.node +0 -0
  7. package/bin/linux-cuda/x64/llama-node.node +0 -0
  8. package/bin/linux-vulkan/arm64/llama-node.node +0 -0
  9. package/bin/linux-vulkan/x64/llama-node.node +0 -0
  10. package/bin/win32/arm64/llama-node.node +0 -0
  11. package/bin/win32/arm64/node.lib +0 -0
  12. package/bin/win32/x64/llama-node.node +0 -0
  13. package/bin/win32/x64/node.lib +0 -0
  14. package/bin/win32-vulkan/arm64/llama-node.node +0 -0
  15. package/bin/win32-vulkan/arm64/node.lib +0 -0
  16. package/bin/win32-vulkan/x64/llama-node.node +0 -0
  17. package/bin/win32-vulkan/x64/node.lib +0 -0
  18. package/lib/binding.ts +3 -1
  19. package/lib/index.js +16 -1
  20. package/lib/index.ts +16 -0
  21. package/package.json +1 -1
  22. package/src/EmbeddingWorker.cpp +4 -3
  23. package/src/LlamaCompletionWorker.cpp +4 -2
  24. package/src/LlamaContext.cpp +61 -6
  25. package/src/LlamaContext.h +1 -0
  26. package/src/common.hpp +6 -11
  27. package/src/llama.cpp/.github/workflows/build.yml +19 -17
  28. package/src/llama.cpp/.github/workflows/docker.yml +77 -30
  29. package/src/llama.cpp/.github/workflows/editorconfig.yml +3 -1
  30. package/src/llama.cpp/.github/workflows/server.yml +22 -3
  31. package/src/llama.cpp/CMakeLists.txt +49 -24
  32. package/src/llama.cpp/common/arg.cpp +82 -26
  33. package/src/llama.cpp/common/arg.h +3 -0
  34. package/src/llama.cpp/common/common.cpp +192 -72
  35. package/src/llama.cpp/common/common.h +51 -18
  36. package/src/llama.cpp/common/ngram-cache.cpp +12 -12
  37. package/src/llama.cpp/common/ngram-cache.h +2 -2
  38. package/src/llama.cpp/common/sampling.cpp +11 -6
  39. package/src/llama.cpp/common/speculative.cpp +18 -15
  40. package/src/llama.cpp/docs/build.md +2 -0
  41. package/src/llama.cpp/examples/batched/batched.cpp +9 -7
  42. package/src/llama.cpp/examples/batched-bench/batched-bench.cpp +3 -3
  43. package/src/llama.cpp/examples/convert-llama2c-to-ggml/convert-llama2c-to-ggml.cpp +10 -8
  44. package/src/llama.cpp/examples/cvector-generator/cvector-generator.cpp +11 -8
  45. package/src/llama.cpp/examples/cvector-generator/mean.hpp +1 -1
  46. package/src/llama.cpp/examples/cvector-generator/pca.hpp +1 -1
  47. package/src/llama.cpp/examples/embedding/embedding.cpp +8 -7
  48. package/src/llama.cpp/examples/eval-callback/eval-callback.cpp +7 -6
  49. package/src/llama.cpp/examples/export-lora/export-lora.cpp +8 -7
  50. package/src/llama.cpp/examples/gguf/gguf.cpp +10 -6
  51. package/src/llama.cpp/examples/gguf-hash/gguf-hash.cpp +1 -0
  52. package/src/llama.cpp/examples/gguf-split/gguf-split.cpp +8 -7
  53. package/src/llama.cpp/examples/gritlm/gritlm.cpp +13 -10
  54. package/src/llama.cpp/examples/imatrix/imatrix.cpp +13 -12
  55. package/src/llama.cpp/examples/infill/infill.cpp +23 -24
  56. package/src/llama.cpp/examples/llama-bench/llama-bench.cpp +44 -13
  57. package/src/llama.cpp/examples/llama.android/llama/src/main/cpp/llama-android.cpp +11 -6
  58. package/src/llama.cpp/examples/llava/clip.cpp +4 -2
  59. package/src/llama.cpp/examples/llava/llava-cli.cpp +9 -6
  60. package/src/llama.cpp/examples/llava/llava.cpp +2 -2
  61. package/src/llama.cpp/examples/llava/minicpmv-cli.cpp +8 -4
  62. package/src/llama.cpp/examples/llava/qwen2vl-cli.cpp +11 -8
  63. package/src/llama.cpp/examples/lookahead/lookahead.cpp +6 -7
  64. package/src/llama.cpp/examples/lookup/lookup-create.cpp +4 -9
  65. package/src/llama.cpp/examples/lookup/lookup-stats.cpp +3 -7
  66. package/src/llama.cpp/examples/lookup/lookup.cpp +5 -6
  67. package/src/llama.cpp/examples/main/main.cpp +51 -29
  68. package/src/llama.cpp/examples/parallel/parallel.cpp +5 -6
  69. package/src/llama.cpp/examples/passkey/passkey.cpp +7 -5
  70. package/src/llama.cpp/examples/perplexity/perplexity.cpp +37 -23
  71. package/src/llama.cpp/examples/quantize-stats/quantize-stats.cpp +12 -14
  72. package/src/llama.cpp/examples/retrieval/retrieval.cpp +8 -8
  73. package/src/llama.cpp/examples/rpc/rpc-server.cpp +12 -0
  74. package/src/llama.cpp/examples/run/CMakeLists.txt +1 -1
  75. package/src/llama.cpp/examples/run/linenoise.cpp/linenoise.cpp +1351 -0
  76. package/src/llama.cpp/examples/run/linenoise.cpp/linenoise.h +114 -0
  77. package/src/llama.cpp/examples/run/run.cpp +175 -61
  78. package/src/llama.cpp/examples/save-load-state/save-load-state.cpp +4 -25
  79. package/src/llama.cpp/examples/server/CMakeLists.txt +1 -0
  80. package/src/llama.cpp/examples/server/httplib.h +1295 -409
  81. package/src/llama.cpp/examples/server/server.cpp +387 -181
  82. package/src/llama.cpp/examples/server/tests/requirements.txt +1 -0
  83. package/src/llama.cpp/examples/server/utils.hpp +170 -58
  84. package/src/llama.cpp/examples/simple/simple.cpp +9 -8
  85. package/src/llama.cpp/examples/simple-chat/simple-chat.cpp +16 -12
  86. package/src/llama.cpp/examples/speculative/speculative.cpp +22 -23
  87. package/src/llama.cpp/examples/speculative-simple/speculative-simple.cpp +8 -12
  88. package/src/llama.cpp/examples/tokenize/tokenize.cpp +17 -5
  89. package/src/llama.cpp/examples/tts/tts.cpp +64 -23
  90. package/src/llama.cpp/ggml/CMakeLists.txt +5 -21
  91. package/src/llama.cpp/ggml/include/ggml-backend.h +2 -0
  92. package/src/llama.cpp/ggml/include/ggml-cpp.h +1 -0
  93. package/src/llama.cpp/ggml/include/ggml.h +36 -145
  94. package/src/llama.cpp/ggml/include/gguf.h +202 -0
  95. package/src/llama.cpp/ggml/src/CMakeLists.txt +6 -3
  96. package/src/llama.cpp/ggml/src/ggml-alloc.c +5 -0
  97. package/src/llama.cpp/ggml/src/ggml-backend-impl.h +0 -1
  98. package/src/llama.cpp/ggml/src/ggml-backend-reg.cpp +79 -49
  99. package/src/llama.cpp/ggml/src/ggml-backend.cpp +5 -2
  100. package/src/llama.cpp/ggml/src/ggml-cpu/CMakeLists.txt +33 -23
  101. package/src/llama.cpp/ggml/src/ggml-cpu/ggml-cpu-aarch64.cpp +57 -72
  102. package/src/llama.cpp/ggml/src/ggml-cpu/ggml-cpu-quants.c +87 -2
  103. package/src/llama.cpp/ggml/src/ggml-cpu/ggml-cpu.c +335 -66
  104. package/src/llama.cpp/ggml/src/ggml-cpu/ggml-cpu.cpp +10 -2
  105. package/src/llama.cpp/ggml/src/ggml-cpu/llamafile/sgemm.cpp +1090 -378
  106. package/src/llama.cpp/ggml/src/ggml-cpu/llamafile/sgemm.h +2 -2
  107. package/src/llama.cpp/ggml/src/ggml-cuda/vendors/cuda.h +1 -0
  108. package/src/llama.cpp/ggml/src/ggml-cuda/vendors/hip.h +3 -0
  109. package/src/llama.cpp/ggml/src/ggml-cuda/vendors/musa.h +3 -0
  110. package/src/llama.cpp/ggml/src/ggml-hip/CMakeLists.txt +3 -1
  111. package/src/llama.cpp/ggml/src/ggml-impl.h +11 -16
  112. package/src/llama.cpp/ggml/src/ggml-metal/CMakeLists.txt +16 -0
  113. package/src/llama.cpp/ggml/src/ggml-opencl/ggml-opencl.cpp +6 -6
  114. package/src/llama.cpp/ggml/src/ggml-rpc/ggml-rpc.cpp +154 -35
  115. package/src/llama.cpp/ggml/src/ggml-sycl/backend.hpp +1 -0
  116. package/src/llama.cpp/ggml/src/ggml-sycl/common.cpp +9 -3
  117. package/src/llama.cpp/ggml/src/ggml-sycl/common.hpp +18 -0
  118. package/src/llama.cpp/ggml/src/ggml-sycl/concat.cpp +3 -2
  119. package/src/llama.cpp/ggml/src/ggml-sycl/concat.hpp +1 -2
  120. package/src/llama.cpp/ggml/src/ggml-sycl/conv.cpp +3 -2
  121. package/src/llama.cpp/ggml/src/ggml-sycl/conv.hpp +1 -2
  122. package/src/llama.cpp/ggml/src/ggml-sycl/dpct/helper.hpp +40 -95
  123. package/src/llama.cpp/ggml/src/ggml-sycl/element_wise.cpp +48 -48
  124. package/src/llama.cpp/ggml/src/ggml-sycl/element_wise.hpp +24 -24
  125. package/src/llama.cpp/ggml/src/ggml-sycl/ggml-sycl.cpp +238 -164
  126. package/src/llama.cpp/ggml/src/ggml-sycl/gla.cpp +105 -0
  127. package/src/llama.cpp/ggml/src/ggml-sycl/gla.hpp +8 -0
  128. package/src/llama.cpp/ggml/src/ggml-sycl/outprod.cpp +3 -3
  129. package/src/llama.cpp/ggml/src/ggml-sycl/outprod.hpp +1 -2
  130. package/src/llama.cpp/ggml/src/ggml-sycl/tsembd.cpp +3 -2
  131. package/src/llama.cpp/ggml/src/ggml-sycl/tsembd.hpp +1 -2
  132. package/src/llama.cpp/ggml/src/ggml-sycl/wkv6.cpp +7 -5
  133. package/src/llama.cpp/ggml/src/ggml-sycl/wkv6.hpp +1 -2
  134. package/src/llama.cpp/ggml/src/ggml-vulkan/CMakeLists.txt +74 -4
  135. package/src/llama.cpp/ggml/src/ggml-vulkan/ggml-vulkan.cpp +314 -116
  136. package/src/llama.cpp/ggml/src/ggml-vulkan/vulkan-shaders/CMakeLists.txt +4 -2
  137. package/src/llama.cpp/ggml/src/ggml-vulkan/vulkan-shaders/vulkan-shaders-gen.cpp +9 -3
  138. package/src/llama.cpp/ggml/src/ggml.c +117 -1327
  139. package/src/llama.cpp/ggml/src/gguf.cpp +1329 -0
  140. package/src/llama.cpp/include/llama-cpp.h +6 -1
  141. package/src/llama.cpp/include/llama.h +138 -75
  142. package/src/llama.cpp/src/CMakeLists.txt +13 -1
  143. package/src/llama.cpp/src/llama-adapter.cpp +347 -0
  144. package/src/llama.cpp/src/llama-adapter.h +74 -0
  145. package/src/llama.cpp/src/llama-arch.cpp +1487 -0
  146. package/src/llama.cpp/src/llama-arch.h +400 -0
  147. package/src/llama.cpp/src/llama-batch.cpp +368 -0
  148. package/src/llama.cpp/src/llama-batch.h +88 -0
  149. package/src/llama.cpp/src/llama-chat.cpp +578 -0
  150. package/src/llama.cpp/src/llama-chat.h +52 -0
  151. package/src/llama.cpp/src/llama-context.cpp +1775 -0
  152. package/src/llama.cpp/src/llama-context.h +128 -0
  153. package/src/llama.cpp/src/llama-cparams.cpp +1 -0
  154. package/src/llama.cpp/src/llama-cparams.h +37 -0
  155. package/src/llama.cpp/src/llama-grammar.cpp +5 -4
  156. package/src/llama.cpp/src/llama-grammar.h +3 -1
  157. package/src/llama.cpp/src/llama-hparams.cpp +71 -0
  158. package/src/llama.cpp/src/llama-hparams.h +139 -0
  159. package/src/llama.cpp/src/llama-impl.cpp +167 -0
  160. package/src/llama.cpp/src/llama-impl.h +16 -136
  161. package/src/llama.cpp/src/llama-kv-cache.cpp +718 -0
  162. package/src/llama.cpp/src/llama-kv-cache.h +218 -0
  163. package/src/llama.cpp/src/llama-mmap.cpp +589 -0
  164. package/src/llama.cpp/src/llama-mmap.h +67 -0
  165. package/src/llama.cpp/src/llama-model-loader.cpp +1124 -0
  166. package/src/llama.cpp/src/llama-model-loader.h +167 -0
  167. package/src/llama.cpp/src/llama-model.cpp +3953 -0
  168. package/src/llama.cpp/src/llama-model.h +370 -0
  169. package/src/llama.cpp/src/llama-quant.cpp +934 -0
  170. package/src/llama.cpp/src/llama-quant.h +1 -0
  171. package/src/llama.cpp/src/llama-sampling.cpp +147 -32
  172. package/src/llama.cpp/src/llama-sampling.h +3 -19
  173. package/src/llama.cpp/src/llama-vocab.cpp +1832 -575
  174. package/src/llama.cpp/src/llama-vocab.h +97 -142
  175. package/src/llama.cpp/src/llama.cpp +7160 -20314
  176. package/src/llama.cpp/src/unicode.cpp +8 -3
  177. package/src/llama.cpp/tests/CMakeLists.txt +2 -0
  178. package/src/llama.cpp/tests/test-autorelease.cpp +3 -3
  179. package/src/llama.cpp/tests/test-backend-ops.cpp +370 -59
  180. package/src/llama.cpp/tests/test-chat-template.cpp +162 -125
  181. package/src/llama.cpp/tests/test-gguf.cpp +222 -187
  182. package/src/llama.cpp/tests/test-model-load-cancel.cpp +1 -1
  183. package/src/llama.cpp/tests/test-sampling.cpp +0 -1
  184. package/src/llama.cpp/tests/test-tokenizer-0.cpp +4 -4
  185. package/src/llama.cpp/tests/test-tokenizer-1-bpe.cpp +9 -7
  186. package/src/llama.cpp/tests/test-tokenizer-1-spm.cpp +8 -6
@@ -15,66 +15,71 @@ constexpr int offset_has_tensors = 2000;
15
15
  constexpr int offset_has_data = 3000;
16
16
 
17
17
  enum handcrafted_file_type {
18
- HANDCRAFTED_HEADER_BAD_MAGIC = 10,
19
- HANDCRAFTED_HEADER_BAD_VERSION_1 = 20,
20
- HANDCRAFTED_HEADER_BAD_VERSION_FUTURE = 30,
21
- HANDCRAFTED_HEADER_BAD_N_TENSORS = 40,
22
- HANDCRAFTED_HEADER_BAD_N_KV = 50,
23
- HANDCRAFTED_HEADER_EMPTY = 800,
24
-
25
- HANDCRAFTED_KV_BAD_KEY_SIZE = 10 + offset_has_kv,
26
- HANDCRAFTED_KV_BAD_TYPE = 20 + offset_has_kv,
27
- HANDCRAFTED_KV_BAD_VALUE_SIZE = 30 + offset_has_kv,
28
- HANDCRAFTED_KV_DUPLICATE_KEY = 40 + offset_has_kv,
29
- HANDCRAFTED_KV_SUCCESS = 800 + offset_has_kv,
30
-
31
- HANDCRAFTED_TENSORS_BAD_NAME_SIZE = 10 + offset_has_tensors,
32
- HANDCRAFTED_TENSORS_BAD_N_DIMS = 20 + offset_has_tensors,
33
- HANDCRAFTED_TENSORS_BAD_SHAPE = 30 + offset_has_tensors,
34
- HANDCRAFTED_TENSORS_NE_TOO_BIG = 40 + offset_has_tensors,
35
- HANDCRAFTED_TENSORS_BAD_TYPE = 50 + offset_has_tensors,
36
- HANDCRAFTED_TENSORS_BAD_OFFSET = 60 + offset_has_tensors,
37
- HANDCRAFTED_TENSORS_DUPLICATE_NAME = 70 + offset_has_tensors,
38
- HANDCRAFTED_TENSORS_BAD_ALIGNMENT = 80 + offset_has_tensors,
39
- HANDCRAFTED_TENSORS_SUCCESS = 800 + offset_has_tensors,
40
- HANDCRAFTED_TENSORS_CUSTOM_ALIGN = 810 + offset_has_tensors,
41
-
42
- HANDCRAFTED_DATA_NOT_ENOUGH_DATA = 10 + offset_has_data,
43
- HANDCRAFTED_DATA_BAD_ALIGNMENT = 20 + offset_has_data,
44
- HANDCRAFTED_DATA_SUCCESS = 800 + offset_has_data,
45
- HANDCRAFTED_DATA_CUSTOM_ALIGN = 810 + offset_has_data,
18
+ HANDCRAFTED_HEADER_BAD_MAGIC = 10,
19
+ HANDCRAFTED_HEADER_BAD_VERSION_1 = 20,
20
+ HANDCRAFTED_HEADER_BAD_VERSION_FUTURE = 30,
21
+ HANDCRAFTED_HEADER_BAD_N_TENSORS = 40,
22
+ HANDCRAFTED_HEADER_BAD_N_KV = 50,
23
+ HANDCRAFTED_HEADER_EMPTY = 800,
24
+
25
+ HANDCRAFTED_KV_BAD_KEY_SIZE = 10 + offset_has_kv,
26
+ HANDCRAFTED_KV_BAD_TYPE = 20 + offset_has_kv,
27
+ // HANDCRAFTED_KV_BAD_VALUE_SIZE = 30 + offset_has_kv, // removed because it can result in allocations > 1 TB (default sanitizer limit)
28
+ HANDCRAFTED_KV_DUPLICATE_KEY = 40 + offset_has_kv,
29
+ HANDCRAFTED_KV_BAD_ALIGN = 50 + offset_has_kv,
30
+ HANDCRAFTED_KV_SUCCESS = 800 + offset_has_kv,
31
+
32
+ HANDCRAFTED_TENSORS_BAD_NAME_SIZE = 10 + offset_has_tensors,
33
+ HANDCRAFTED_TENSORS_BAD_N_DIMS = 20 + offset_has_tensors,
34
+ HANDCRAFTED_TENSORS_BAD_SHAPE = 30 + offset_has_tensors,
35
+ HANDCRAFTED_TENSORS_NE_TOO_BIG = 40 + offset_has_tensors,
36
+ HANDCRAFTED_TENSORS_BAD_TYPE = 50 + offset_has_tensors,
37
+ HANDCRAFTED_TENSORS_BAD_OFFSET = 60 + offset_has_tensors,
38
+ HANDCRAFTED_TENSORS_DUPLICATE_NAME = 70 + offset_has_tensors,
39
+ HANDCRAFTED_TENSORS_BAD_ALIGN = 75 + offset_has_tensors,
40
+ HANDCRAFTED_TENSORS_INCONSISTENT_ALIGN = 80 + offset_has_tensors,
41
+ HANDCRAFTED_TENSORS_SUCCESS = 800 + offset_has_tensors,
42
+ HANDCRAFTED_TENSORS_CUSTOM_ALIGN = 810 + offset_has_tensors,
43
+
44
+ HANDCRAFTED_DATA_NOT_ENOUGH_DATA = 10 + offset_has_data,
45
+ HANDCRAFTED_DATA_BAD_ALIGN = 15 + offset_has_data,
46
+ HANDCRAFTED_DATA_INCONSISTENT_ALIGN = 20 + offset_has_data,
47
+ HANDCRAFTED_DATA_SUCCESS = 800 + offset_has_data,
48
+ HANDCRAFTED_DATA_CUSTOM_ALIGN = 810 + offset_has_data,
46
49
  };
47
50
 
48
- std::string handcrafted_file_type_name(const enum handcrafted_file_type hft) {
51
+ static std::string handcrafted_file_type_name(const enum handcrafted_file_type hft) {
49
52
  switch (hft) {
50
- case HANDCRAFTED_HEADER_BAD_MAGIC: return "HEADER_BAD_MAGIC";
51
- case HANDCRAFTED_HEADER_BAD_VERSION_1: return "HEADER_BAD_VERSION_1";
52
- case HANDCRAFTED_HEADER_BAD_VERSION_FUTURE: return "HEADER_BAD_VERSION_FUTURE";
53
- case HANDCRAFTED_HEADER_BAD_N_KV: return "HEADER_BAD_N_KV";
54
- case HANDCRAFTED_HEADER_BAD_N_TENSORS: return "HEADER_BAD_N_TENSORS";
55
- case HANDCRAFTED_HEADER_EMPTY: return "HEADER_EMPTY";
56
-
57
- case HANDCRAFTED_KV_BAD_KEY_SIZE: return "KV_BAD_KEY_SIZE";
58
- case HANDCRAFTED_KV_BAD_TYPE: return "KV_BAD_TYPE";
59
- case HANDCRAFTED_KV_BAD_VALUE_SIZE: return "KV_BAD_VALUE_SIZE";
60
- case HANDCRAFTED_KV_DUPLICATE_KEY: return "KV_DUPLICATE_KEY";
61
- case HANDCRAFTED_KV_SUCCESS: return "KV_RANDOM_KV";
62
-
63
- case HANDCRAFTED_TENSORS_BAD_NAME_SIZE: return "TENSORS_BAD_NAME_SIZE";
64
- case HANDCRAFTED_TENSORS_BAD_N_DIMS: return "TENSORS_BAD_N_DIMS";
65
- case HANDCRAFTED_TENSORS_BAD_SHAPE: return "TENSORS_BAD_SHAPE";
66
- case HANDCRAFTED_TENSORS_NE_TOO_BIG: return "TENSORS_NE_TOO_BIG";
67
- case HANDCRAFTED_TENSORS_BAD_TYPE: return "TENSORS_BAD_TYPE";
68
- case HANDCRAFTED_TENSORS_BAD_OFFSET: return "TENSORS_BAD_OFFSET";
69
- case HANDCRAFTED_TENSORS_DUPLICATE_NAME: return "TENSORS_DUPLICATE_NAME";
70
- case HANDCRAFTED_TENSORS_BAD_ALIGNMENT: return "TENSORS_BAD_ALIGNMENT";
71
- case HANDCRAFTED_TENSORS_SUCCESS: return "TENSORS_SUCCESS";
72
- case HANDCRAFTED_TENSORS_CUSTOM_ALIGN: return "TENSORS_CUSTOM_ALIGN";
73
-
74
- case HANDCRAFTED_DATA_NOT_ENOUGH_DATA: return "DATA_NOT_ENOUGH_DATA";
75
- case HANDCRAFTED_DATA_BAD_ALIGNMENT: return "DATA_BAD_ALIGNMENT";
76
- case HANDCRAFTED_DATA_SUCCESS: return "DATA_SUCCESS";
77
- case HANDCRAFTED_DATA_CUSTOM_ALIGN: return "DATA_CUSTOM_ALIGN";
53
+ case HANDCRAFTED_HEADER_BAD_MAGIC: return "HEADER_BAD_MAGIC";
54
+ case HANDCRAFTED_HEADER_BAD_VERSION_1: return "HEADER_BAD_VERSION_1";
55
+ case HANDCRAFTED_HEADER_BAD_VERSION_FUTURE: return "HEADER_BAD_VERSION_FUTURE";
56
+ case HANDCRAFTED_HEADER_BAD_N_KV: return "HEADER_BAD_N_KV";
57
+ case HANDCRAFTED_HEADER_BAD_N_TENSORS: return "HEADER_BAD_N_TENSORS";
58
+ case HANDCRAFTED_HEADER_EMPTY: return "HEADER_EMPTY";
59
+
60
+ case HANDCRAFTED_KV_BAD_KEY_SIZE: return "KV_BAD_KEY_SIZE";
61
+ case HANDCRAFTED_KV_BAD_TYPE: return "KV_BAD_TYPE";
62
+ case HANDCRAFTED_KV_DUPLICATE_KEY: return "KV_DUPLICATE_KEY";
63
+ case HANDCRAFTED_KV_BAD_ALIGN: return "KV_BAD_ALIGN";
64
+ case HANDCRAFTED_KV_SUCCESS: return "KV_RANDOM_KV";
65
+
66
+ case HANDCRAFTED_TENSORS_BAD_NAME_SIZE: return "TENSORS_BAD_NAME_SIZE";
67
+ case HANDCRAFTED_TENSORS_BAD_N_DIMS: return "TENSORS_BAD_N_DIMS";
68
+ case HANDCRAFTED_TENSORS_BAD_SHAPE: return "TENSORS_BAD_SHAPE";
69
+ case HANDCRAFTED_TENSORS_NE_TOO_BIG: return "TENSORS_NE_TOO_BIG";
70
+ case HANDCRAFTED_TENSORS_BAD_TYPE: return "TENSORS_BAD_TYPE";
71
+ case HANDCRAFTED_TENSORS_BAD_OFFSET: return "TENSORS_BAD_OFFSET";
72
+ case HANDCRAFTED_TENSORS_DUPLICATE_NAME: return "TENSORS_DUPLICATE_NAME";
73
+ case HANDCRAFTED_TENSORS_BAD_ALIGN: return "TENSORS_BAD_ALIGN";
74
+ case HANDCRAFTED_TENSORS_INCONSISTENT_ALIGN: return "TENSORS_INCONSISTENT_ALIGN";
75
+ case HANDCRAFTED_TENSORS_SUCCESS: return "TENSORS_SUCCESS";
76
+ case HANDCRAFTED_TENSORS_CUSTOM_ALIGN: return "TENSORS_CUSTOM_ALIGN";
77
+
78
+ case HANDCRAFTED_DATA_NOT_ENOUGH_DATA: return "DATA_NOT_ENOUGH_DATA";
79
+ case HANDCRAFTED_DATA_BAD_ALIGN: return "DATA_BAD_ALIGN";
80
+ case HANDCRAFTED_DATA_INCONSISTENT_ALIGN: return "DATA_INCONSISTENT_ALIGN";
81
+ case HANDCRAFTED_DATA_SUCCESS: return "DATA_SUCCESS";
82
+ case HANDCRAFTED_DATA_CUSTOM_ALIGN: return "DATA_CUSTOM_ALIGN";
78
83
  }
79
84
  GGML_ABORT("fatal error");
80
85
  }
@@ -94,7 +99,7 @@ static bool expect_context_not_null(const enum handcrafted_file_type hft) {
94
99
 
95
100
  typedef std::pair<enum ggml_type, std::array<int64_t, GGML_MAX_DIMS>> tensor_config_t;
96
101
 
97
- std::vector<tensor_config_t> get_tensor_configs(std::mt19937 & rng) {
102
+ static std::vector<tensor_config_t> get_tensor_configs(std::mt19937 & rng) {
98
103
  std::vector<tensor_config_t> tensor_configs;
99
104
  tensor_configs.reserve(100);
100
105
 
@@ -117,7 +122,7 @@ std::vector<tensor_config_t> get_tensor_configs(std::mt19937 & rng) {
117
122
  return tensor_configs;
118
123
  }
119
124
 
120
- std::vector<std::pair<enum gguf_type, enum gguf_type>> get_kv_types(std::mt19937 rng) {
125
+ static std::vector<std::pair<enum gguf_type, enum gguf_type>> get_kv_types(std::mt19937 rng) {
121
126
  std::vector<std::pair<enum gguf_type, enum gguf_type>> kv_types;
122
127
  kv_types.reserve(100);
123
128
 
@@ -140,31 +145,41 @@ std::vector<std::pair<enum gguf_type, enum gguf_type>> get_kv_types(std::mt19937
140
145
  return kv_types;
141
146
  }
142
147
 
143
- static void helper_write(const void * data, const size_t nbytes, FILE * file) {
148
+ template <typename T>
149
+ static void helper_write(FILE * file, const T & val) {
150
+ GGML_ASSERT(fwrite(&val, 1, sizeof(val), file) == sizeof(val));
151
+ }
152
+
153
+ static void helper_write(FILE * file, const void * data, const size_t nbytes) {
144
154
  GGML_ASSERT(fwrite(data, 1, nbytes, file) == nbytes);
145
155
  }
146
156
 
147
157
  static FILE * get_handcrafted_file(const unsigned int seed, const enum handcrafted_file_type hft, const int extra_bytes = 0) {
148
158
  FILE * file = tmpfile();
149
159
 
160
+ if (!file) {
161
+ return file;
162
+ }
163
+
150
164
  std::mt19937 rng(seed);
165
+ uint32_t alignment = GGUF_DEFAULT_ALIGNMENT;
151
166
 
152
167
  if (hft == HANDCRAFTED_HEADER_BAD_MAGIC) {
153
168
  const char bad_magic[4] = {'F', 'U', 'G', 'G'};
154
- helper_write(bad_magic, sizeof(bad_magic), file);
169
+ helper_write(file, bad_magic, sizeof(bad_magic));
155
170
  } else {
156
- helper_write(GGUF_MAGIC, 4, file);
171
+ helper_write(file, GGUF_MAGIC, 4);
157
172
  }
158
173
 
159
174
  if (hft == HANDCRAFTED_HEADER_BAD_VERSION_1) {
160
175
  const uint32_t version = 1;
161
- helper_write(&version, sizeof(version), file);
176
+ helper_write(file, version);
162
177
  } else if (hft == HANDCRAFTED_HEADER_BAD_VERSION_FUTURE) {
163
178
  const uint32_t version = GGUF_VERSION + 1;
164
- helper_write(&version, sizeof(version), file);
179
+ helper_write(file, version);
165
180
  } else {
166
181
  const uint32_t version = GGUF_VERSION;
167
- helper_write(&version, sizeof(version), file);
182
+ helper_write(file, version);
168
183
  }
169
184
 
170
185
  std::vector<tensor_config_t> tensor_configs;
@@ -174,10 +189,10 @@ static FILE * get_handcrafted_file(const unsigned int seed, const enum handcraft
174
189
 
175
190
  if (hft == HANDCRAFTED_HEADER_BAD_N_TENSORS) {
176
191
  const uint64_t n_tensors = -1;
177
- helper_write(&n_tensors, sizeof(n_tensors), file);
192
+ helper_write(file, n_tensors);
178
193
  } else {
179
194
  const uint64_t n_tensors = tensor_configs.size();
180
- helper_write(&n_tensors, sizeof(n_tensors), file);
195
+ helper_write(file, n_tensors);
181
196
  }
182
197
 
183
198
  std::vector<std::pair<enum gguf_type, enum gguf_type>> kv_types;
@@ -186,41 +201,49 @@ static FILE * get_handcrafted_file(const unsigned int seed, const enum handcraft
186
201
  }
187
202
  {
188
203
  uint64_t n_kv = kv_types.size();
189
- if (hft == HANDCRAFTED_TENSORS_CUSTOM_ALIGN || hft == HANDCRAFTED_DATA_CUSTOM_ALIGN) {
204
+ if (hft == HANDCRAFTED_KV_BAD_ALIGN ||
205
+ hft == HANDCRAFTED_TENSORS_BAD_ALIGN || hft == HANDCRAFTED_TENSORS_CUSTOM_ALIGN ||
206
+ hft == HANDCRAFTED_DATA_BAD_ALIGN || hft == HANDCRAFTED_DATA_CUSTOM_ALIGN) {
207
+
190
208
  n_kv += 1;
191
209
  } else if (hft == HANDCRAFTED_HEADER_BAD_N_KV) {
192
210
  n_kv = -1;
193
211
  }
194
- helper_write(&n_kv, sizeof(n_kv), file);
212
+ helper_write(file, n_kv);
195
213
  }
196
214
 
197
215
  if (hft < offset_has_kv) {
216
+ while (ftell(file) % alignment != 0) {
217
+ const char pad = 0;
218
+ helper_write(file, pad);
219
+ }
220
+
198
221
  for (int i = 0; i < extra_bytes; ++i) {
199
222
  const char tmp = 0;
200
- helper_write(&tmp, sizeof(tmp), file);
223
+ helper_write(file, tmp);
201
224
  }
202
225
  rewind(file);
203
226
  return file;
204
227
  }
205
228
 
206
229
  for (int i = 0; i < int(kv_types.size()); ++i) {
207
- const enum gguf_type type = gguf_type(hft == HANDCRAFTED_KV_BAD_TYPE ? -1 : kv_types[i].first);
208
- const enum gguf_type type_arr = gguf_type(hft == HANDCRAFTED_KV_BAD_TYPE ? -1 : kv_types[i].second);
230
+ const enum gguf_type type = gguf_type(hft == HANDCRAFTED_KV_BAD_TYPE ? GGUF_TYPE_COUNT : kv_types[i].first);
231
+ const enum gguf_type type_arr = gguf_type(hft == HANDCRAFTED_KV_BAD_TYPE ? GGUF_TYPE_COUNT : kv_types[i].second);
209
232
 
210
233
  const std::string key = "my_key_" + std::to_string((hft == HANDCRAFTED_KV_DUPLICATE_KEY ? i/2 : i));
211
234
 
212
235
  if (hft == HANDCRAFTED_KV_BAD_KEY_SIZE) {
213
236
  const uint64_t n = -1;
214
- helper_write(&n, sizeof(n), file);
237
+ helper_write(file, n);
215
238
  } else {
216
239
  const uint64_t n = key.length();
217
- helper_write(&n, sizeof(n), file);
240
+ helper_write(file, n);
218
241
  }
219
- helper_write(key.data(), key.length(), file);
242
+ helper_write(file, key.data(), key.length());
220
243
 
221
244
  {
222
245
  const int32_t type32 = int32_t(type);
223
- helper_write(&type32, sizeof(type32), file);
246
+ helper_write(file, type32);
224
247
  }
225
248
 
226
249
  uint32_t data[16];
@@ -233,69 +256,67 @@ static FILE * get_handcrafted_file(const unsigned int seed, const enum handcraft
233
256
 
234
257
  if (type == GGUF_TYPE_STRING) {
235
258
  const uint64_t n = rng() % sizeof(data);
236
- helper_write(&n, sizeof(n), file);
237
- helper_write(data, n, file);
259
+ helper_write(file, n);
260
+ helper_write(file, data, n);
238
261
  continue;
239
262
  }
240
263
 
241
264
  if (type == GGUF_TYPE_ARRAY) {
242
265
  {
243
266
  const int32_t type32 = int32_t(type_arr);
244
- helper_write(&type32, sizeof(type32), file);
267
+ helper_write(file, type32);
245
268
  }
246
269
  if (type_arr == GGUF_TYPE_STRING) {
247
270
  const uint64_t nstr = rng() % (16 + 1);
248
- helper_write(&nstr, sizeof(nstr), file);
271
+ helper_write(file, nstr);
249
272
  for (uint64_t istr = 0; istr < nstr; ++istr) {
250
273
  const uint64_t n = rng() % (sizeof(uint32_t) + 1);
251
- helper_write(&n, sizeof(n), file);
252
- helper_write(&data[istr], n, file);
274
+ helper_write(file, n);
275
+ helper_write(file, &data[istr], n);
253
276
  }
254
277
  continue;
255
278
  }
256
279
  const size_t type_size = gguf_type_size(type_arr);
257
280
  const uint64_t n = (rng() % sizeof(data)) / type_size;
258
- helper_write(&n, sizeof(n), file);
259
- helper_write(&data, n*type_size, file);
281
+ helper_write(file, n);
282
+ helper_write(file, &data, n*type_size);
260
283
  continue;
261
284
  }
262
285
 
263
- size_t type_size = hft == HANDCRAFTED_KV_BAD_TYPE ? 1 : gguf_type_size(type);
264
- if (hft == HANDCRAFTED_KV_BAD_VALUE_SIZE) {
265
- type_size += rng() % 3;
266
- }
267
- helper_write(data, type_size, file);
286
+ helper_write(file, data, hft == HANDCRAFTED_KV_BAD_TYPE ? 1 : gguf_type_size(type));
268
287
  }
269
288
 
270
- if (hft == HANDCRAFTED_TENSORS_CUSTOM_ALIGN || hft == HANDCRAFTED_DATA_CUSTOM_ALIGN) {
271
- const std::string key = "general.alignment";
272
- {
273
- const uint64_t n = key.length();
274
- helper_write(&n, sizeof(n), file);
275
- }
276
- helper_write(key.data(), key.length(), file);
289
+ if (hft == HANDCRAFTED_KV_BAD_ALIGN ||
290
+ hft == HANDCRAFTED_TENSORS_BAD_ALIGN || hft == HANDCRAFTED_TENSORS_CUSTOM_ALIGN ||
291
+ hft == HANDCRAFTED_DATA_BAD_ALIGN || hft == HANDCRAFTED_DATA_CUSTOM_ALIGN) {
292
+
293
+ const uint64_t n = strlen(GGUF_KEY_GENERAL_ALIGNMENT);
294
+ helper_write(file, n);
295
+ helper_write(file, GGUF_KEY_GENERAL_ALIGNMENT, n);
277
296
 
278
297
  const int32_t type = gguf_type(GGUF_TYPE_UINT32);
279
- helper_write(&type, sizeof(type), file);
298
+ helper_write(file, type);
280
299
 
281
- const uint32_t alignment = GGUF_DEFAULT_ALIGNMENT + 1;
282
- helper_write(&alignment, sizeof(alignment), file);
300
+ alignment = expect_context_not_null(hft) ? 1 : 13;
301
+ helper_write(file, alignment);
283
302
  }
284
303
 
285
304
  if (hft < offset_has_tensors) {
305
+ while (ftell(file) % alignment != 0) {
306
+ const char pad = 0;
307
+ helper_write(file, pad);
308
+ }
309
+
286
310
  for (int i = 0; i < extra_bytes; ++i) {
287
311
  const char tmp = 0;
288
- helper_write(&tmp, sizeof(tmp), file);
312
+ helper_write(file, tmp);
289
313
  }
290
314
  rewind(file);
291
315
  return file;
292
316
  }
293
317
 
294
- uint32_t alignment = GGUF_DEFAULT_ALIGNMENT;
295
- if (hft == HANDCRAFTED_TENSORS_BAD_ALIGNMENT || hft == HANDCRAFTED_DATA_BAD_ALIGNMENT) {
296
- alignment -= 1;
297
- } else if (hft == HANDCRAFTED_TENSORS_CUSTOM_ALIGN || hft == HANDCRAFTED_DATA_CUSTOM_ALIGN) {
298
- alignment += 1;
318
+ if (hft == HANDCRAFTED_TENSORS_INCONSISTENT_ALIGN || hft == HANDCRAFTED_DATA_INCONSISTENT_ALIGN) {
319
+ alignment = 1;
299
320
  }
300
321
 
301
322
  uint64_t offset = 0;
@@ -313,9 +334,9 @@ static FILE * get_handcrafted_file(const unsigned int seed, const enum handcraft
313
334
  }
314
335
  {
315
336
  const uint64_t n = name.length();
316
- helper_write(&n, sizeof(n), file);
337
+ helper_write(file, n);
317
338
  }
318
- helper_write(name.data(), name.length(), file);
339
+ helper_write(file, name.data(), name.length());
319
340
 
320
341
  uint32_t n_dims = hft == HANDCRAFTED_TENSORS_NE_TOO_BIG ? 2 : 1;
321
342
  for (int i = GGML_MAX_DIMS-1; i >= 1; --i) {
@@ -326,35 +347,35 @@ static FILE * get_handcrafted_file(const unsigned int seed, const enum handcraft
326
347
  }
327
348
  if (hft == HANDCRAFTED_TENSORS_BAD_N_DIMS) {
328
349
  const uint32_t n_dims_bad = GGML_MAX_DIMS + 1;
329
- helper_write(&n_dims_bad, sizeof(n_dims_bad), file);
350
+ helper_write(file, n_dims_bad);
330
351
  } else {
331
- helper_write(&n_dims, sizeof(n_dims), file);
352
+ helper_write(file, n_dims);
332
353
  }
333
354
 
334
355
  if (hft == HANDCRAFTED_TENSORS_BAD_SHAPE) {
335
356
  for (uint32_t j = 0; j < n_dims; ++j) {
336
357
  const int64_t bad_dim = -1;
337
- helper_write(&bad_dim, sizeof(bad_dim), file);
358
+ helper_write(file, bad_dim);
338
359
  }
339
360
  } else if (hft == HANDCRAFTED_TENSORS_NE_TOO_BIG){
340
361
  for (uint32_t j = 0; j < n_dims; ++j) {
341
362
  const int64_t big_dim = 4*int64_t(INT32_MAX);
342
- helper_write(&big_dim, sizeof(big_dim), file);
363
+ helper_write(file, big_dim);
343
364
  }
344
365
  } else {
345
- helper_write(shape.data(), n_dims*sizeof(int64_t), file);
366
+ helper_write(file, shape.data(), n_dims*sizeof(int64_t));
346
367
  }
347
368
 
348
369
  {
349
- const int32_t type32 = hft == HANDCRAFTED_TENSORS_BAD_TYPE ? -1 : int32_t(type);
350
- helper_write(&type32, sizeof(type32), file);
370
+ const int32_t type32 = hft == HANDCRAFTED_TENSORS_BAD_TYPE ? GGML_TYPE_COUNT : int32_t(type);
371
+ helper_write(file, type32);
351
372
  }
352
373
 
353
374
  if (hft == HANDCRAFTED_TENSORS_BAD_OFFSET) {
354
375
  const uint64_t bad_offset = -1;
355
- helper_write(&bad_offset, sizeof(bad_offset), file);
376
+ helper_write(file, bad_offset);
356
377
  } else {
357
- helper_write(&offset, sizeof(offset), file);
378
+ helper_write(file, offset);
358
379
  }
359
380
 
360
381
  int64_t ne = shape[0];
@@ -364,12 +385,9 @@ static FILE * get_handcrafted_file(const unsigned int seed, const enum handcraft
364
385
  offset += GGML_PAD(ggml_row_size(type, ne), alignment);
365
386
  }
366
387
 
367
- const uint32_t alignment_overshoot = ftell(file) % alignment;
368
- if (alignment_overshoot != 0) {
369
- for (size_t i = alignment_overshoot; i < alignment; ++i) {
370
- const char pad = 0;
371
- helper_write(&pad, sizeof(pad), file);
372
- }
388
+ while (ftell(file) % alignment != 0) {
389
+ const char pad = 0;
390
+ helper_write(file, pad);
373
391
  }
374
392
 
375
393
  if (hft >= offset_has_data) {
@@ -380,13 +398,13 @@ static FILE * get_handcrafted_file(const unsigned int seed, const enum handcraft
380
398
  }
381
399
  for (uint64_t i = 0; i < nbytes; ++i) {
382
400
  const uint8_t random_byte = i % 256;
383
- helper_write(&random_byte, sizeof(random_byte), file);
401
+ helper_write(file, random_byte);
384
402
  }
385
403
  }
386
404
 
387
405
  for (int i = 0; i < extra_bytes; ++i) {
388
406
  const char tmp = 0;
389
- helper_write(&tmp, sizeof(tmp), file);
407
+ helper_write(file, tmp);
390
408
  }
391
409
  rewind(file);
392
410
  return file;
@@ -505,6 +523,16 @@ static bool handcrafted_check_kv(const gguf_context * gguf_ctx, const unsigned i
505
523
  }
506
524
 
507
525
  const char * data_gguf = reinterpret_cast<const char *>(gguf_get_arr_data(gguf_ctx, id));
526
+
527
+ if (type_arr == GGUF_TYPE_BOOL) {
528
+ for (size_t arr_i = 0; arr_i < arr_n; ++arr_i) {
529
+ if (bool(data8[arr_i]) != bool(data_gguf[arr_i])) {
530
+ ok = false;
531
+ }
532
+ }
533
+ continue;
534
+ }
535
+
508
536
  if (!std::equal(data8, data8 + arr_n*type_size, data_gguf)) {
509
537
  ok = false;
510
538
  }
@@ -512,12 +540,20 @@ static bool handcrafted_check_kv(const gguf_context * gguf_ctx, const unsigned i
512
540
  }
513
541
 
514
542
  const char * data_gguf = reinterpret_cast<const char *>(gguf_get_val_data(gguf_ctx, id));
543
+
544
+ if (type == GGUF_TYPE_BOOL) {
545
+ if (bool(*data8) != bool(*data_gguf)) {
546
+ ok = false;
547
+ }
548
+ continue;
549
+ }
550
+
515
551
  if (!std::equal(data8, data8 + gguf_type_size(type), data_gguf)) {
516
552
  ok = false;
517
553
  }
518
554
  }
519
555
 
520
- const uint32_t expected_alignment = alignment_defined ? GGUF_DEFAULT_ALIGNMENT + 1 : GGUF_DEFAULT_ALIGNMENT;
556
+ const uint32_t expected_alignment = alignment_defined ? 1 : GGUF_DEFAULT_ALIGNMENT;
521
557
  if (gguf_get_alignment(gguf_ctx) != expected_alignment) {
522
558
  ok = false;
523
559
  }
@@ -539,7 +575,7 @@ static bool handcrafted_check_tensors(const gguf_context * gguf_ctx, const unsig
539
575
 
540
576
  bool ok = true;
541
577
 
542
- const int id_alignment = gguf_find_key(gguf_ctx, "general.alignment");
578
+ const int id_alignment = gguf_find_key(gguf_ctx, GGUF_KEY_GENERAL_ALIGNMENT);
543
579
  const uint32_t alignment = id_alignment >= 0 ? gguf_get_val_u32(gguf_ctx, id_alignment) : GGUF_DEFAULT_ALIGNMENT;
544
580
 
545
581
  uint64_t expected_offset = 0;
@@ -590,8 +626,6 @@ static bool handcrafted_check_tensor_data(const gguf_context * gguf_ctx, const u
590
626
 
591
627
  bool ok = true;
592
628
 
593
- const uint32_t alignment = GGUF_DEFAULT_ALIGNMENT;
594
-
595
629
  for (int i = 0; i < int(tensor_configs.size()); ++i) {
596
630
  const ggml_type type = tensor_configs[i].first;
597
631
  const std::array<int64_t, GGML_MAX_DIMS> shape = tensor_configs[i].second;
@@ -607,7 +641,7 @@ static bool handcrafted_check_tensor_data(const gguf_context * gguf_ctx, const u
607
641
 
608
642
  std::vector<uint8_t> data(size);
609
643
  GGML_ASSERT(fseek(file, gguf_get_data_offset(gguf_ctx) + offset, SEEK_SET) == 0);
610
- GGML_ASSERT(fread(data.data(), 1, size, file) == size);
644
+ GGML_ASSERT(fread(data.data(), 1, data.size(), file) == data.size());
611
645
 
612
646
  for (size_t j = 0; j < size; ++j) {
613
647
  const uint8_t expected_byte = (j + offset) % 256;
@@ -627,15 +661,15 @@ static std::pair<int, int> test_handcrafted_file(const unsigned int seed) {
627
661
  const std::vector<handcrafted_file_type> hfts = {
628
662
  HANDCRAFTED_HEADER_BAD_MAGIC,
629
663
  HANDCRAFTED_HEADER_BAD_VERSION_1,
630
- // HANDCRAFTED_FILE_TYPE_BAD_VERSION_FUTURE, // FIXME
664
+ HANDCRAFTED_HEADER_BAD_VERSION_FUTURE,
631
665
  HANDCRAFTED_HEADER_BAD_N_KV,
632
666
  HANDCRAFTED_HEADER_BAD_N_TENSORS,
633
667
  HANDCRAFTED_HEADER_EMPTY,
634
668
 
635
669
  HANDCRAFTED_KV_BAD_KEY_SIZE,
636
670
  HANDCRAFTED_KV_BAD_TYPE,
637
- // HANDCRAFTED_KV_BAD_VALUE_SIZE, // FIXME sanitizer limit
638
- // HANDCRAFTED_FILE_TYPE_DUPLICATE_KEY, // FIXME
671
+ HANDCRAFTED_KV_DUPLICATE_KEY,
672
+ HANDCRAFTED_KV_BAD_ALIGN,
639
673
  HANDCRAFTED_KV_SUCCESS,
640
674
 
641
675
  HANDCRAFTED_TENSORS_BAD_NAME_SIZE,
@@ -643,14 +677,16 @@ static std::pair<int, int> test_handcrafted_file(const unsigned int seed) {
643
677
  HANDCRAFTED_TENSORS_BAD_SHAPE,
644
678
  HANDCRAFTED_TENSORS_NE_TOO_BIG,
645
679
  HANDCRAFTED_TENSORS_BAD_TYPE,
646
- // HANDCRAFTED_TENSORS_BAD_OFFSET, // FIXME
680
+ HANDCRAFTED_TENSORS_BAD_OFFSET,
647
681
  HANDCRAFTED_TENSORS_DUPLICATE_NAME,
648
- // HANDCRAFTED_TENSORS_BAD_ALIGNMENT, // FIXME
682
+ HANDCRAFTED_TENSORS_BAD_ALIGN,
683
+ HANDCRAFTED_TENSORS_INCONSISTENT_ALIGN,
649
684
  HANDCRAFTED_TENSORS_SUCCESS,
650
685
  HANDCRAFTED_TENSORS_CUSTOM_ALIGN,
651
686
 
652
687
  HANDCRAFTED_DATA_NOT_ENOUGH_DATA,
653
- // HANDCRAFTED_DATA_BAD_ALIGNMENT, // FIXME
688
+ HANDCRAFTED_DATA_BAD_ALIGN,
689
+ HANDCRAFTED_DATA_INCONSISTENT_ALIGN,
654
690
  HANDCRAFTED_DATA_SUCCESS,
655
691
  HANDCRAFTED_DATA_CUSTOM_ALIGN,
656
692
  };
@@ -674,6 +710,7 @@ static std::pair<int, int> test_handcrafted_file(const unsigned int seed) {
674
710
  /*no_alloc =*/ false,
675
711
  /*ctx =*/ hft >= offset_has_data ? &ctx : nullptr,
676
712
  };
713
+
677
714
  struct gguf_context * gguf_ctx = gguf_init_from_file_impl(file, gguf_params);
678
715
 
679
716
  if (expect_context_not_null(hft)) {
@@ -689,7 +726,7 @@ static std::pair<int, int> test_handcrafted_file(const unsigned int seed) {
689
726
  }
690
727
  ntest++;
691
728
 
692
- if (false && hft >= offset_has_data && !expect_context_not_null(hft)) { // FIXME
729
+ if (hft >= offset_has_data && !expect_context_not_null(hft)) {
693
730
  printf("%s: - no_dangling_ggml_context_pointer: ", __func__);
694
731
  if (ctx) {
695
732
  printf("\033[1;31mFAIL\033[0m\n");
@@ -700,23 +737,6 @@ static std::pair<int, int> test_handcrafted_file(const unsigned int seed) {
700
737
  ntest++;
701
738
  }
702
739
 
703
- if (false && expect_context_not_null(hft)) { // FIXME
704
- FILE * file_eb = get_handcrafted_file(seed, hft, /*extra_bytes =*/ 1);
705
- struct gguf_context * gguf_ctx_eb = gguf_init_from_file_impl(file_eb, gguf_params);
706
-
707
- printf("%s: - context_null_with_extra_bytes: ", __func__);
708
- if (gguf_ctx_eb) {
709
- printf("\033[1;31mFAIL\033[0m\n");
710
- } else {
711
- printf("\033[1;32mOK\033[0m\n");
712
- npass++;
713
- }
714
- ntest++;
715
-
716
- gguf_free(gguf_ctx_eb);
717
- fclose(file_eb);
718
- }
719
-
720
740
  const bool alignment_defined = hft == HANDCRAFTED_TENSORS_CUSTOM_ALIGN || hft == HANDCRAFTED_DATA_CUSTOM_ALIGN;
721
741
 
722
742
  if (expect_context_not_null(hft)) {
@@ -763,14 +783,15 @@ static std::pair<int, int> test_handcrafted_file(const unsigned int seed) {
763
783
  ntest++;
764
784
  }
765
785
 
786
+ fclose(file);
766
787
  if (gguf_ctx) {
767
788
  ggml_free(ctx);
768
789
  gguf_free(gguf_ctx);
769
790
  }
770
- fclose(file);
771
791
  printf("\n");
772
792
  }
773
793
 
794
+
774
795
  return std::make_pair(npass, ntest);
775
796
  }
776
797
 
@@ -789,10 +810,6 @@ static struct random_gguf_context_result get_random_gguf_context(ggml_backend_t
789
810
  const std::string key = "my_key_" + std::to_string(rng() % 1024);
790
811
  const enum gguf_type type = gguf_type(rng() % GGUF_TYPE_COUNT);
791
812
 
792
- if (type == GGUF_TYPE_STRING || type == GGUF_TYPE_ARRAY) {
793
- continue; // FIXME memory leak
794
- }
795
-
796
813
  switch (type) {
797
814
  case GGUF_TYPE_UINT8: gguf_set_val_u8 (gguf_ctx, key.c_str(), rng() % (1 << 7)); break;
798
815
  case GGUF_TYPE_INT8: gguf_set_val_i8 (gguf_ctx, key.c_str(), rng() % (1 << 7) - (1 << 6)); break;
@@ -826,6 +843,9 @@ static struct random_gguf_context_result get_random_gguf_context(ggml_backend_t
826
843
  std::vector<uint32_t> random_data((nbytes + sizeof(uint32_t) - 1) / sizeof(uint32_t));
827
844
  for (size_t j = 0; j < random_data.size(); ++j) {
828
845
  random_data[j] = rng();
846
+ if (type_arr == GGUF_TYPE_BOOL) {
847
+ random_data[j] &= 0x01010101; // the sanitizer complains if booleans are not 0 or 1
848
+ }
829
849
  }
830
850
  gguf_set_arr_data(gguf_ctx, key.c_str(), type_arr, random_data.data(), ne);
831
851
  } break;
@@ -844,13 +864,13 @@ static struct random_gguf_context_result get_random_gguf_context(ggml_backend_t
844
864
  case GGUF_TYPE_COUNT:
845
865
  default: {
846
866
  GGML_ABORT("fatal error");
847
- } break;
867
+ }
848
868
  }
849
869
  } break;
850
870
  case GGUF_TYPE_COUNT:
851
871
  default: {
852
872
  GGML_ABORT("fatal error");
853
- } break;
873
+ }
854
874
  }
855
875
  }
856
876
 
@@ -916,7 +936,7 @@ static bool all_kv_in_other(const gguf_context * ctx, const gguf_context * other
916
936
  }
917
937
 
918
938
  if (type == GGUF_TYPE_ARRAY) {
919
- const int arr_n = gguf_get_arr_n(ctx, id);
939
+ const size_t arr_n = gguf_get_arr_n(ctx, id);
920
940
  if (arr_n != gguf_get_arr_n(other, idx_other)) {
921
941
  ok = false;
922
942
  continue;
@@ -928,8 +948,19 @@ static bool all_kv_in_other(const gguf_context * ctx, const gguf_context * other
928
948
  continue;
929
949
  }
930
950
 
951
+ if (type_arr == GGUF_TYPE_BOOL) {
952
+ const int8_t * data = reinterpret_cast<const int8_t *>(gguf_get_arr_data(ctx, id));
953
+ const int8_t * data_other = reinterpret_cast<const int8_t *>(gguf_get_arr_data(other, idx_other));
954
+ for (size_t arr_i = 0; arr_i < arr_n; ++arr_i) {
955
+ if (bool(data[arr_i]) != bool(data_other[arr_i])) {
956
+ ok = false;
957
+ }
958
+ }
959
+ continue;
960
+ }
961
+
931
962
  if (type_arr == GGUF_TYPE_STRING) {
932
- for (int arr_i = 0; arr_i < arr_n; ++arr_i) {
963
+ for (size_t arr_i = 0; arr_i < arr_n; ++arr_i) {
933
964
  const std::string str = gguf_get_arr_str(ctx, id, arr_i);
934
965
  const std::string str_other = gguf_get_arr_str(other, idx_other, arr_i);
935
966
  if (str != str_other) {
@@ -939,8 +970,8 @@ static bool all_kv_in_other(const gguf_context * ctx, const gguf_context * other
939
970
  continue;
940
971
  }
941
972
 
942
- const char * data = reinterpret_cast<const char *>(gguf_get_arr_data(ctx, id));
943
- const char * data_other = reinterpret_cast<const char *>(gguf_get_arr_data(other, idx_other));
973
+ const int8_t * data = reinterpret_cast<const int8_t *>(gguf_get_arr_data(ctx, id));
974
+ const int8_t * data_other = reinterpret_cast<const int8_t *>(gguf_get_arr_data(other, idx_other));
944
975
  if (!std::equal(data, data + arr_n*gguf_type_size(type_arr), data_other)) {
945
976
  ok = false;
946
977
  }
@@ -1000,6 +1031,12 @@ static bool same_tensor_data(const struct ggml_context * orig, const struct ggml
1000
1031
 
1001
1032
  struct ggml_tensor * t_orig = ggml_get_first_tensor(orig);
1002
1033
  struct ggml_tensor * t_read = ggml_get_first_tensor(read);
1034
+
1035
+ if (std::string(t_read->name) != "GGUF tensor data binary blob") {
1036
+ return false;
1037
+ }
1038
+ t_read = ggml_get_next_tensor(read, t_read);
1039
+
1003
1040
  while (t_orig) {
1004
1041
  if (!t_read) {
1005
1042
  ok = false;
@@ -1018,31 +1055,16 @@ static bool same_tensor_data(const struct ggml_context * orig, const struct ggml
1018
1055
  }
1019
1056
 
1020
1057
  t_orig = ggml_get_next_tensor(orig, t_orig);
1021
- t_read = ggml_get_next_tensor(orig, t_read);
1058
+ t_read = ggml_get_next_tensor(read, t_read);
1022
1059
  }
1023
1060
  if (t_read) {
1024
1061
  ok = false;
1025
1062
  }
1026
1063
 
1027
- return true;
1064
+ return ok;
1028
1065
  }
1029
1066
 
1030
1067
  static std::pair<int, int> test_roundtrip(ggml_backend_dev_t dev, const unsigned int seed, const bool only_meta) {
1031
- FILE * file = tmpfile();
1032
- #ifdef _WIN32
1033
- if (!file) {
1034
- printf("%s: failed to create tmpfile(), needs elevated privileges on Windows");
1035
- printf("%s: skipping tests");
1036
- return std::make_pair(0, 0);
1037
- }
1038
- #else
1039
- GGML_ASSERT(file);
1040
- #endif // _WIN32
1041
-
1042
- if (ggml_backend_dev_type(dev) != GGML_BACKEND_DEVICE_TYPE_CPU) {
1043
- return std::make_pair(0, 0); // FIXME
1044
- }
1045
-
1046
1068
  ggml_backend_t backend = ggml_backend_dev_init(dev, nullptr);
1047
1069
  printf("%s: device=%s, backend=%s, only_meta=%s\n",
1048
1070
  __func__, ggml_backend_dev_description(dev), ggml_backend_name(backend), only_meta ? "yes" : "no");
@@ -1060,10 +1082,24 @@ static std::pair<int, int> test_roundtrip(ggml_backend_dev_t dev, const unsigned
1060
1082
  bbuf = result.buffer;
1061
1083
  }
1062
1084
 
1063
- struct gguf_buf gbuf = gguf_buf_init(16 * 1024);
1064
- gguf_write_to_buf(gguf_ctx_0, &gbuf, only_meta);
1065
- helper_write(gbuf.data, gbuf.offset, file);
1066
- rewind(file);
1085
+ FILE * file = tmpfile();
1086
+
1087
+ #ifdef _WIN32
1088
+ if (!file) {
1089
+ printf("%s: failed to create tmpfile(), needs elevated privileges on Windows");
1090
+ printf("%s: skipping tests");
1091
+ return std::make_pair(0, 0);
1092
+ }
1093
+ #else
1094
+ GGML_ASSERT(file);
1095
+ #endif // _WIN32
1096
+
1097
+ {
1098
+ std::vector<int8_t> buf;
1099
+ gguf_write_to_buf(gguf_ctx_0, buf, only_meta);
1100
+ GGML_ASSERT(fwrite(buf.data(), 1, buf.size(), file) == buf.size());
1101
+ rewind(file);
1102
+ }
1067
1103
 
1068
1104
  struct ggml_context * ctx_1 = nullptr;
1069
1105
  struct gguf_init_params gguf_params = {
@@ -1151,9 +1187,8 @@ static std::pair<int, int> test_roundtrip(ggml_backend_dev_t dev, const unsigned
1151
1187
  ggml_free(ctx_1);
1152
1188
  gguf_free(gguf_ctx_0);
1153
1189
  gguf_free(gguf_ctx_1);
1154
- gguf_buf_free(gbuf);
1155
1190
  ggml_backend_free(backend);
1156
- GGML_ASSERT(fclose(file) == 0);
1191
+ fclose(file);
1157
1192
 
1158
1193
  printf("\n");
1159
1194
  return std::make_pair(npass, ntest);