CrashOverrideX commited on
Commit
41a5ab2
·
verified ·
1 Parent(s): e6c51f8

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +3 -0
  2. llama.cpp/models/templates/Apertus-8B-Instruct.jinja +327 -0
  3. llama.cpp/models/templates/ByteDance-Seed-OSS.jinja +171 -0
  4. llama.cpp/models/templates/CohereForAI-c4ai-command-r-plus-tool_use.jinja +202 -0
  5. llama.cpp/models/templates/CohereForAI-c4ai-command-r7b-12-2024-tool_use.jinja +156 -0
  6. llama.cpp/models/templates/GLM-4.6.jinja +106 -0
  7. llama.cpp/models/templates/Kimi-K2-Instruct.jinja +60 -0
  8. llama.cpp/models/templates/Kimi-K2-Thinking.jinja +108 -0
  9. llama.cpp/models/templates/MiMo-VL.jinja +54 -0
  10. llama.cpp/models/templates/MiniMax-M2.jinja +159 -0
  11. llama.cpp/models/templates/deepseek-ai-DeepSeek-R1-Distill-Llama-8B.jinja +1 -0
  12. llama.cpp/models/templates/deepseek-ai-DeepSeek-R1-Distill-Qwen-32B.jinja +1 -0
  13. llama.cpp/models/templates/deepseek-ai-DeepSeek-V3.1.jinja +3 -0
  14. llama.cpp/models/templates/fireworks-ai-llama-3-firefunction-v2.jinja +57 -0
  15. llama.cpp/models/templates/google-gemma-2-2b-it.jinja +4 -0
  16. llama.cpp/models/templates/ibm-granite-granite-3.3-2B-Instruct.jinja +59 -0
  17. llama.cpp/models/templates/llama-cpp-deepseek-r1.jinja +76 -0
  18. llama.cpp/models/templates/llama-cpp-lfm2.jinja +37 -0
  19. llama.cpp/models/templates/llama-cpp-rwkv-world.jinja +34 -0
  20. llama.cpp/models/templates/meetkai-functionary-medium-v3.1.jinja +58 -0
  21. llama.cpp/models/templates/meetkai-functionary-medium-v3.2.jinja +287 -0
  22. llama.cpp/models/templates/meta-llama-Llama-3.1-8B-Instruct.jinja +109 -0
  23. llama.cpp/models/templates/meta-llama-Llama-3.2-3B-Instruct.jinja +93 -0
  24. llama.cpp/models/templates/meta-llama-Llama-3.3-70B-Instruct.jinja +109 -0
  25. llama.cpp/models/templates/microsoft-Phi-3.5-mini-instruct.jinja +8 -0
  26. llama.cpp/pocs/vdot/CMakeLists.txt +9 -0
  27. llama.cpp/pocs/vdot/q8dot.cpp +173 -0
  28. llama.cpp/pocs/vdot/vdot.cpp +311 -0
  29. llama.cpp/scripts/apple/validate-apps.sh +5 -0
  30. llama.cpp/scripts/apple/validate-ios.sh +820 -0
  31. llama.cpp/scripts/apple/validate-macos.sh +781 -0
  32. llama.cpp/scripts/apple/validate-tvos.sh +813 -0
  33. llama.cpp/scripts/apple/validate-visionos.sh +811 -0
  34. llama.cpp/scripts/jinja/jinja-tester.py +504 -0
  35. llama.cpp/scripts/jinja/requirements.txt +2 -0
  36. llama.cpp/scripts/snapdragon/adb/llama-cli.farf +1 -0
  37. llama.cpp/scripts/snapdragon/adb/run-bench.sh +52 -0
  38. llama.cpp/scripts/snapdragon/adb/run-cli.sh +59 -0
  39. llama.cpp/scripts/snapdragon/adb/run-completion.sh +59 -0
  40. llama.cpp/scripts/snapdragon/adb/run-mtmd.sh +68 -0
  41. llama.cpp/scripts/snapdragon/adb/run-tool.sh +54 -0
  42. llama.cpp/scripts/snapdragon/qdc/readme.md +1 -0
  43. llama.cpp/scripts/snapdragon/qdc/requirements.txt +25 -0
  44. llama.cpp/scripts/snapdragon/qdc/tests/test_bench.py +63 -0
  45. llama.cpp/scripts/snapdragon/windows/run-bench.ps1 +40 -0
  46. llama.cpp/scripts/snapdragon/windows/run-cli.ps1 +53 -0
  47. llama.cpp/scripts/snapdragon/windows/run-tool.ps1 +56 -0
  48. llama.cpp/scripts/snapdragon/windows/setup-build.ps1 +105 -0
  49. llama.cpp/src/models/afmoe.cpp +191 -0
  50. llama.cpp/src/models/apertus.cpp +125 -0
.gitattributes CHANGED
@@ -76,3 +76,6 @@ llama.cpp/models/ggml-vocab-qwen2.gguf filter=lfs diff=lfs merge=lfs -text
76
  llama.cpp/models/ggml-vocab-refact.gguf filter=lfs diff=lfs merge=lfs -text
77
  llama.cpp/models/ggml-vocab-starcoder.gguf filter=lfs diff=lfs merge=lfs -text
78
  llama.cpp/tools/mtmd/test-1.jpeg filter=lfs diff=lfs merge=lfs -text
 
 
 
 
76
  llama.cpp/models/ggml-vocab-refact.gguf filter=lfs diff=lfs merge=lfs -text
77
  llama.cpp/models/ggml-vocab-starcoder.gguf filter=lfs diff=lfs merge=lfs -text
78
  llama.cpp/tools/mtmd/test-1.jpeg filter=lfs diff=lfs merge=lfs -text
79
+ llama.cpp/tools/server/themes/buttons-top/buttons_top.png filter=lfs diff=lfs merge=lfs -text
80
+ llama.cpp/tools/server/themes/wild/llamapattern.png filter=lfs diff=lfs merge=lfs -text
81
+ llama.cpp/tools/server/themes/wild/wild.png filter=lfs diff=lfs merge=lfs -text
llama.cpp/models/templates/Apertus-8B-Instruct.jinja ADDED
@@ -0,0 +1,327 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- macro render_typescript_type(param_spec, required_params, is_nullable=false) -%}
2
+ {%- if param_spec.type == "array" -%}
3
+ {%- if param_spec['items'] -%}
4
+ {%- if param_spec['items']['type'] == "string" -%}
5
+ {{- "string[]" }}
6
+ {%- elif param_spec['items']['type'] == "number" -%}
7
+ {{- "number[]" }}
8
+ {%- elif param_spec['items']['type'] == "integer" -%}
9
+ {{- "number[]" }}
10
+ {%- elif param_spec['items']['type'] == "boolean" -%}
11
+ {{- "boolean[]" }}
12
+ {%- else -%}
13
+ {%- set inner_type = render_typescript_type(param_spec['items'], required_params) -%}
14
+ {%- if inner_type == "object | object" or inner_type|length > 50 -%}
15
+ {{- "any[]" }}
16
+ {%- else -%}
17
+ {{- inner_type + "[]" }}
18
+ {%- endif -%}
19
+ {%- endif -%}
20
+ {%- if param_spec.nullable -%}
21
+ {{- " | null" }}
22
+ {%- endif -%}
23
+ {%- else -%}
24
+ {{- "any[]" }}
25
+ {%- if param_spec.nullable -%}
26
+ {{- " | null" }}
27
+ {%- endif -%}
28
+ {%- endif -%}
29
+ {%- elif param_spec.type is defined and param_spec.type is iterable and param_spec.type is not string and param_spec.type is not mapping and param_spec.type[0] is defined -%}
30
+ {#- Handle array of types like ["object", "object"] from Union[dict, list] #}
31
+ {%- if param_spec.type | length > 1 -%}
32
+ {{- param_spec.type | join(" | ") }}
33
+ {%- else -%}
34
+ {{- param_spec.type[0] }}
35
+ {%- endif -%}
36
+ {%- elif param_spec.oneOf -%}
37
+ {#- Handle oneOf schemas - check for complex unions and fallback to any #}
38
+ {%- set has_object_variants = false -%}
39
+ {%- for variant in param_spec.oneOf -%}
40
+ {%- if variant.type == "object" -%}
41
+ {%- set has_object_variants = true -%}
42
+ {%- endif -%}
43
+ {%- endfor -%}
44
+ {%- if has_object_variants and param_spec.oneOf|length > 1 -%}
45
+ {{- "any" }}
46
+ {%- else -%}
47
+ {%- for variant in param_spec.oneOf -%}
48
+ {{- render_typescript_type(variant, required_params) -}}
49
+ {%- if variant.description %}
50
+ {{- "// " + variant.description }}
51
+ {%- endif -%}
52
+ {%- if variant.default is defined %}
53
+ {{ "// default: " + variant.default|tojson }}
54
+ {%- endif -%}
55
+ {%- if not loop.last %}
56
+ {{- " | " }}
57
+ {% endif -%}
58
+ {%- endfor -%}
59
+ {%- endif -%}
60
+ {%- elif param_spec.type == "string" -%}
61
+ {%- if param_spec.enum -%}
62
+ {{- '"' + param_spec.enum|join('" | "') + '"' -}}
63
+ {%- else -%}
64
+ {{- "string" }}
65
+ {%- if param_spec.nullable %}
66
+ {{- " | null" }}
67
+ {%- endif -%}
68
+ {%- endif -%}
69
+ {%- elif param_spec.type == "number" -%}
70
+ {{- "number" }}
71
+ {%- elif param_spec.type == "integer" -%}
72
+ {{- "number" }}
73
+ {%- elif param_spec.type == "boolean" -%}
74
+ {{- "boolean" }}
75
+ {%- elif param_spec.type == "object" -%}
76
+ {%- if param_spec.properties -%}
77
+ {{- "{\n" }}
78
+ {%- for prop_name, prop_spec in param_spec.properties.items() -%}
79
+ {{- prop_name -}}
80
+ {%- if prop_name not in (param_spec.required or []) -%}
81
+ {{- "?" }}
82
+ {%- endif -%}
83
+ {{- ": " }}
84
+ {{ render_typescript_type(prop_spec, param_spec.required or []) }}
85
+ {%- if not loop.last -%}
86
+ {{-", " }}
87
+ {%- endif -%}
88
+ {%- endfor -%}
89
+ {{- "}" }}
90
+ {%- else -%}
91
+ {{- "object" }}
92
+ {%- endif -%}
93
+ {%- else -%}
94
+ {{- "any" }}
95
+ {%- endif -%}
96
+ {%- endmacro -%}
97
+
98
+ {%- macro render_tools(tools) -%}
99
+ {%- for tool in tools %}
100
+ {{- "// " + tool.description + "\n" }}
101
+ {{- "type "+ tool.name + " = " }}
102
+ {%- if tool.parameters and tool.parameters.properties %}
103
+ {{- "(_: {\n" }}
104
+ {%- for param_name, param_spec in tool.parameters.properties.items() %}
105
+ {%- if param_spec.description %}
106
+ {{- "// " + param_spec.description + "\n" }}
107
+ {%- endif %}
108
+ {{- param_name }}
109
+ {%- if param_name not in (tool.parameters.required or []) -%}
110
+ {{- "?" }}
111
+ {%- endif -%}
112
+ {{- ": " }}
113
+ {{- render_typescript_type(param_spec, tool.parameters.required or []) }}
114
+ {%- if param_spec.default is defined -%}
115
+ {%- if param_spec.enum %}
116
+ {{- ", // default: " + param_spec.default }}
117
+ {%- elif param_spec.oneOf %}
118
+ {{- "// default: " + param_spec.default }}
119
+ {%- else %}
120
+ {{- ", // default: " + param_spec.default|tojson }}
121
+ {%- endif -%}
122
+ {%- endif -%}
123
+ {%- if not loop.last %}
124
+ {{- ",\n" }}
125
+ {%- else %}
126
+ {{- "\n" }}
127
+ {%- endif -%}
128
+ {%- endfor %}
129
+ {{- "}) => any;" }}
130
+ {%- else -%}
131
+ {{- "() => any;" }}
132
+ {%- endif -%}
133
+ {%- if not loop.last -%}
134
+ {{- "\n" }}
135
+ {%- endif -%}
136
+ {%- endfor %}
137
+ {%- endmacro -%}
138
+
139
+ {{ bos_token }}
140
+
141
+ {%- set system_token = '<|system_start|>' -%}
142
+ {%- set end_system_token = '<|system_end|>' -%}
143
+ {%- set developer_token = '<|developer_start|>' -%}
144
+ {%- set end_developer_token = '<|developer_end|>' -%}
145
+ {%- set user_token = '<|user_start|>' -%}
146
+ {%- set end_user_token = '<|user_end|>' -%}
147
+ {%- set assistant_token = '<|assistant_start|>' -%}
148
+ {%- set end_assistant_token = '<|assistant_end|>' -%}
149
+ {%- set inner_token = '<|inner_prefix|>' -%}
150
+ {%- set outer_token = '<|inner_suffix|>' -%}
151
+ {%- set tool_calls_token = '<|tools_prefix|>' -%}
152
+ {%- set end_tool_calls_token = '<|tools_suffix|>' -%}
153
+
154
+ {%- set ns = namespace(in_assistant=false, in_tool=false, in_inner=false, assistant_format=none) -%}
155
+
156
+ {%- if messages and messages[0].role == 'system' -%}
157
+ {%- if "content" in messages[0] -%}
158
+ {%- if messages[0].content is string -%}
159
+ {{ system_token + messages[0].content + end_system_token }}
160
+ {%- elif messages[0].content is mapping and "text" in messages[0].content -%}
161
+ {{ system_token + messages[0].content.text + end_system_token }}
162
+ {%- else -%}
163
+ {{- raise_exception("Invalid system message") -}}
164
+ {%- endif -%}
165
+ {%- else -%}
166
+ {{- raise_exception("Invalid system message") -}}
167
+ {%- endif -%}
168
+ {%- set loop_messages = messages[1:] -%}
169
+ {%- else -%}
170
+ {{ system_token + 'You are Apertus, a helpful assistant created by the SwissAI initiative.\nKnowledge cutoff: 2024-04\nCurrent date: ' + strftime_now('%Y-%m-%d') + end_system_token }}
171
+ {%- set loop_messages = messages -%}
172
+ {%- endif -%}
173
+
174
+ {{ developer_token + 'Deliberation: ' }}
175
+ {%- if enable_thinking is defined and enable_thinking -%}
176
+ {{ 'enabled\n' }}
177
+ {%- else -%}
178
+ {{ 'disabled\n' }}
179
+ {%- endif -%}
180
+ {%- if tools is defined and tools -%}
181
+ {{ 'Tool Capabilities:\n' + render_tools(tools) }}
182
+ {%- else -%}
183
+ {{ 'Tool Capabilities: disabled' }}
184
+ {%- endif -%}
185
+ {{ end_developer_token }}
186
+
187
+ {%- for message in loop_messages -%}
188
+ {%- if message.role == 'user' -%}
189
+ {%- set ns.in_inner = false -%}
190
+ {%- if ns.in_tool -%}
191
+ {{ ']' }}
192
+ {%- set ns.in_tool = false -%}
193
+ {%- endif -%}
194
+ {%- if ns.in_assistant -%}
195
+ {{ end_assistant_token }}
196
+ {%- set ns.in_assistant = false -%}
197
+ {%- endif -%}
198
+ {%- if "content" in message -%}
199
+ {{ user_token }}
200
+ {%- if message.content is string -%}
201
+ {{ message.content }}
202
+ {%- elif message.content is mapping and "parts" in message.content -%}
203
+ {%- set parts = message.content.parts -%}
204
+ {%- for part in parts -%}
205
+ {%- if part.type == "text" -%}
206
+ {{ part.text }}
207
+ {%- else -%}
208
+ {{- raise_exception("Invalid user part: " + part.type) -}}
209
+ {%- endif -%}
210
+ {%- endfor -%}
211
+ {%- else -%}
212
+ {{- raise_exception("Invalid user message: " + message.role) -}}
213
+ {%- endif -%}
214
+ {{ end_user_token }}
215
+ {%- endif -%}
216
+ {%- elif message.role == 'assistant' -%}
217
+ {%- if not ns.in_assistant -%}
218
+ {{ assistant_token }}
219
+ {%- set ns.in_assistant = true -%}
220
+ {%- endif -%}
221
+ {%- if "content" in message and message.content is not none -%}
222
+ {%- if message.content is string and (ns.assistant_format is none or ns.assistant_format == "string") -%}
223
+ {%- if ns.in_tool -%}
224
+ {{ ']' }}
225
+ {%- set ns.in_tool = false -%}
226
+ {%- endif -%}
227
+ {%- set ns.assistant_format = "string" -%}
228
+ {{ message.content }}
229
+ {%- elif message.content is mapping and "blocks" in message.content and (ns.assistant_format is none or ns.assistant_format == "mapping") -%}
230
+ {%- set ns.assistant_format = "mapping" -%}
231
+ {%- set blocks = message.content.blocks -%}
232
+ {%- for block in blocks -%}
233
+ {%- if block.type == 'thoughts' -%}
234
+ {%- if ns.in_tool -%}
235
+ {{ ']' }}
236
+ {%- set ns.in_tool = false -%}
237
+ {%- endif -%}
238
+ {%- if not ns.in_inner -%}
239
+ {%- set ns.in_inner = true -%}
240
+ {{ inner_token }}
241
+ {%- endif -%}
242
+ {{ block.text }}
243
+ {%- elif block.type == 'tool_calls' -%}
244
+ {%- if ns.in_tool -%}
245
+ {{ ']' }}
246
+ {%- set ns.in_tool = false -%}
247
+ {%- endif -%}
248
+ {%- if ns.in_inner and not loop.first and block.calls|length == 1 and block.calls[0].name == 'display_answers' -%}
249
+ {%- set ns.in_inner = false -%}
250
+ {{ outer_token }}
251
+ {%- endif -%}
252
+ {{ tool_calls_token + '[' }}
253
+ {%- for tool_call in block.calls -%}
254
+ {{- '{"' + tool_call.name + '": ' + tool_call.arguments + '}' }}
255
+ {%- if not loop.last -%}
256
+ {{- ", " }}
257
+ {%- endif -%}
258
+ {%- endfor -%}
259
+ {{ ']' + end_tool_calls_token }}
260
+ {%- elif block.type == 'tool_outputs' -%}
261
+ {%- if ns.in_tool -%}
262
+ {{- raise_exception("Cannot have both tool outputs as separate messages and tool outputs as blocks") -}}
263
+ {%- endif -%}
264
+ {{ '[' }}
265
+ {%- for tool_output in block.outputs -%}
266
+ {{- tool_output.output }}
267
+ {%- if not loop.last -%}
268
+ {{- ", " }}
269
+ {%- endif -%}
270
+ {%- endfor -%}
271
+ {{- ']' }}
272
+ {%- elif block.type == 'response' -%}
273
+ {%- if ns.in_tool -%}
274
+ {{ ']' }}
275
+ {%- set ns.in_tool = false -%}
276
+ {%- endif -%}
277
+ {%- if (not loop.first and ns.in_inner) or (ns.in_assistant and ns.in_inner) -%}
278
+ {%- set ns.in_inner = false -%}
279
+ {{ outer_token }}
280
+ {%- endif -%}
281
+ {{ block.text }}
282
+ {%- else -%}
283
+ {{- raise_exception("Invalid assistant block type: " + block.type) -}}
284
+ {%- endif -%}
285
+ {%- endfor -%}
286
+ {%- else -%}
287
+ {{- raise_exception("Invalid assistant content '" + message.content + "', expected " + ns.assistant_format) -}}
288
+ {%- endif -%}
289
+ {%- elif "tool_calls" not in message -%}
290
+ {{- raise_exception("Invalid assistant message " + message) -}}
291
+ {%- endif -%}
292
+ {%- if "tool_calls" in message and message.tool_calls -%}
293
+ {{ tool_calls_token + '[' }}
294
+ {%- for tool_call in message.tool_calls -%}
295
+ {%- if tool_call.type == 'function' -%}
296
+ {%- set function = tool_call.function -%}
297
+ {{- '{"' + function.name + '": ' + function.arguments + '}' }}
298
+ {%- if not loop.last -%}
299
+ {{- ", " }}
300
+ {%- endif -%}
301
+ {%- else -%}
302
+ {{- raise_exception("Invalid tool call type: " + tool_call.type) -}}
303
+ {%- endif -%}
304
+ {%- endfor -%}
305
+ {{ ']' + end_tool_calls_token }}
306
+ {%- endif -%}
307
+ {%- elif message.role == 'tool' -%}
308
+ {%- if not ns.in_assistant -%}
309
+ {{- raise_exception("Tool message outside of assistant") -}}
310
+ {%- endif -%}
311
+ {%- if not ns.in_tool -%}
312
+ {{ '[' }}
313
+ {%- set ns.in_tool = true -%}
314
+ {%- else -%}
315
+ {{ ", "}}
316
+ {%- endif -%}
317
+ {{ message.content }}
318
+ {%- else -%}
319
+ {{- raise_exception("Invalid message role") -}}
320
+ {%- endif -%}
321
+ {%- endfor -%}
322
+ {%- if ns.in_tool -%}
323
+ {{ ']' }}
324
+ {%- endif -%}
325
+ {%- if add_generation_prompt -%}
326
+ {{ assistant_token }}
327
+ {%- endif -%}
llama.cpp/models/templates/ByteDance-Seed-OSS.jinja ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {# ----------‑‑‑ special token variables ‑‑‑---------- #}
2
+ {%- set bos_token = '<seed:bos>' -%}
3
+ {%- set eos_token = '<seed:eos>' -%}
4
+ {%- set pad_token = '<seed:pad>' -%}
5
+ {%- set toolcall_begin_token = '<seed:tool_call>' -%}
6
+ {%- set toolcall_end_token = '</seed:tool_call>' -%}
7
+ {%- set think_begin_token = '<seed:think>' -%}
8
+ {%- set think_end_token = '</seed:think>' -%}
9
+ {%- set budget_begin_token = '<seed:cot_budget_reflect>'-%}
10
+ {%- set budget_end_token = '</seed:cot_budget_reflect>'-%}
11
+ {# -------------- reflection-interval lookup -------------- #}
12
+ {%- if not thinking_budget is defined %}
13
+ {%- set thinking_budget = -1 -%}
14
+ {%- endif -%}
15
+ {%- set budget_reflections_v05 = {
16
+ 0: 0,
17
+ 512: 128,
18
+ 1024: 256,
19
+ 2048: 512,
20
+ 4096: 512,
21
+ 8192: 1024,
22
+ 16384: 1024
23
+ } -%}
24
+ {# Find the first gear that is greater than or equal to the thinking_budget. #}
25
+ {%- set ns = namespace(interval = None) -%}
26
+ {%- for k, v in budget_reflections_v05 | dictsort -%}
27
+ {%- if ns.interval is none and thinking_budget <= k -%}
28
+ {%- set ns.interval = v -%}
29
+ {%- endif -%}
30
+ {%- endfor -%}
31
+ {# If it exceeds the maximum gear, use the value of the last gear #}
32
+ {%- if ns.interval is none -%}
33
+ {%- set ns.interval = budget_reflections_v05[16384] -%}
34
+ {%- endif -%}
35
+ {# ---------- Preprocess the system message ---------- #}
36
+ {%- if messages[0]["role"] == "system" %}
37
+ {%- set system_message = messages[0]["content"] %}
38
+ {%- set loop_messages = messages[1:] %}
39
+ {%- else %}
40
+ {%- set loop_messages = messages %}
41
+ {%- endif %}
42
+ {# ---------- Ensure tools exist ---------- #}
43
+ {%- if not tools is defined or tools is none %}
44
+ {%- set tools = [] %}
45
+ {%- endif %}
46
+ {# tools2doc.jinja #}
47
+ {%- macro py_type(t) -%}
48
+ {%- if t == "string" -%}str
49
+ {%- elif t in ("number", "integer") -%}int
50
+ {%- elif t == "boolean" -%}bool
51
+ {%- elif t == "array" -%}list
52
+ {%- else -%}Any{%- endif -%}
53
+ {%- endmacro -%}
54
+ {# ---------- Output the system block ---------- #}
55
+ {%- if system_message is defined %}
56
+ {{ bos_token + "system\n" + system_message }}
57
+ {%- else %}
58
+ {%- if tools is iterable and tools | length > 0 %}
59
+ {{ bos_token + "system\nYou are Doubao, a helpful AI assistant. You may call one or more functions to assist with the user query." }}
60
+ {%- endif %}
61
+ {%- endif %}
62
+ {%- if use_json_tooldef is defined and use_json_tooldef %}
63
+
64
+ {{"Tool List:\nYou are authorized to use the following tools (described in JSON Schema format). Before performing any task, you must decide how to call them based on the descriptions and parameters of these tools."}}
65
+ {{ tools | tojson(ensure_ascii=False) }}
66
+ {%- else %}
67
+ {%- for item in tools if item.type == "function" %}
68
+
69
+
70
+ Function:
71
+ def {{ item.function.name }}(
72
+ {%- for name, spec in item.function.parameters.properties.items() %}
73
+ {{- name }}: {{ py_type(spec.type) }}{% if not loop.last %},{% endif %}
74
+ {%- endfor %}):
75
+ """
76
+ {{ item.function.description | trim }}
77
+
78
+ {# ---------- Args ---------- #}
79
+ {%- if item.function.parameters.properties %}
80
+ Args:
81
+ {%- for name, spec in item.function.parameters.properties.items() %}
82
+
83
+ - {{ name }} ({{ py_type(spec.type) }})
84
+ {%- if name in item.function.parameters.required %} [必填]{% else %} [选填]{% endif %}:
85
+ {{- " " ~ (spec.description or "") }}
86
+ {%- endfor %}
87
+ {%- endif %}
88
+
89
+ {# ---------- Returns ---------- #}
90
+ {%- if item.function.returns is defined
91
+ and item.function.returns.properties is defined
92
+ and item.function.returns.properties %}
93
+ Returns:
94
+ {%- for name, spec in item.function.returns.properties.items() %}
95
+
96
+ - {{ name }} ({{ py_type(spec.type) }}):
97
+ {{- " " ~ (spec.description or "") }}
98
+ {%- endfor %}
99
+ {%- endif %}
100
+
101
+ """
102
+ {%- endfor %}
103
+ {%- endif %}
104
+ {%- if tools is iterable and tools | length > 0 %}
105
+
106
+ {{"工具调用请遵循如下格式:\n<seed:tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>value_1</parameter>\n<parameter=example_parameter_2>This is the value for the second parameter\nthat can span\nmultiple lines</parameter>\n</function>\n</seed:tool_call>\n"}}
107
+ {%- endif %}
108
+ {# End the system block line #}
109
+ {%- if system_message is defined or tools is iterable and tools | length > 0 %}
110
+ {{ eos_token }}
111
+ {%- endif %}
112
+ {# ---------- Thinking Budget ---------- #}
113
+ {%- if thinking_budget is defined %}
114
+ {%- if thinking_budget == 0 %}
115
+ {{ bos_token+"system" }}
116
+ {{ "You are an intelligent assistant that can answer questions in one step without the need for reasoning and thinking, that is, your thinking budget is 0. Next, please skip the thinking process and directly start answering the user's questions." }}
117
+ {{ eos_token }}
118
+ {%- elif not thinking_budget == -1 %}
119
+ {{ bos_token+"system" }}
120
+ {{ "You are an intelligent assistant with reflective ability. In the process of thinking and reasoning, you need to strictly follow the thinking budget, which is "}}{{thinking_budget}}{{". That is, you need to complete your thinking within "}}{{thinking_budget}}{{" tokens and start answering the user's questions. You will reflect on your thinking process every "}}{{ns.interval}}{{" tokens, stating how many tokens have been used and how many are left."}}
121
+ {{ eos_token }}
122
+ {%- endif %}
123
+ {%- endif %}
124
+ {# ---------- List the historical messages one by one ---------- #}
125
+ {%- for message in loop_messages %}
126
+ {%- if message.role == "assistant"
127
+ and message.tool_calls is defined
128
+ and message.tool_calls is iterable
129
+ and message.tool_calls | length > 0 %}
130
+ {{ bos_token + message.role }}
131
+ {%- if message.reasoning_content is defined and message.reasoning_content is string and message.reasoning_content | trim | length > 0 %}
132
+ {{ "\n" + think_begin_token + message.reasoning_content | trim + think_end_token }}
133
+ {%- endif %}
134
+ {%- if message.content is defined and message.content is string and message.content | trim | length > 0 %}
135
+ {{ "\n" + message.content | trim + "\n" }}
136
+ {%- endif %}
137
+ {%- for tool_call in message.tool_calls %}
138
+ {%- if tool_call.function is defined %}{% set tool_call = tool_call.function %}{% endif %}
139
+ {{ "\n" + toolcall_begin_token + "\n<function=" + tool_call.name + ">\n" }}
140
+ {%- if tool_call.arguments is defined %}
141
+ {%- for arg_name, arg_value in tool_call.arguments | items %}
142
+ {{ "<parameter=" + arg_name + ">" }}
143
+ {%- set arg_value = arg_value if arg_value is string else arg_value | string %}
144
+ {{ arg_value+"</parameter>\n" }}
145
+ {%- endfor %}
146
+ {%- endif %}
147
+ {{ "</function>\n" + toolcall_end_token }}
148
+ {%- endfor %}
149
+ {{ eos_token }}
150
+ {%- elif message.role in ["user", "system"] %}
151
+ {{ bos_token + message.role + "\n" + message.content + eos_token }}
152
+ {%- elif message.role == "assistant" %}
153
+ {{ bos_token + message.role }}
154
+ {%- if message.reasoning_content is defined and message.reasoning_content is string and message.reasoning_content | trim | length > 0 %}
155
+ {{ "\n" + think_begin_token + message.reasoning_content | trim + think_end_token }}
156
+ {%- endif %}
157
+ {%- if message.content is defined and message.content is string and message.content | trim | length > 0 %}
158
+ {{ "\n" + message.content | trim + eos_token }}
159
+ {%- endif %}
160
+ {# Include the tool role #}
161
+ {%- else %}
162
+ {{ bos_token + message.role + "\n" + message.content + eos_token }}
163
+ {%- endif %}
164
+ {%- endfor %}
165
+ {# ---------- Control the model to start continuation ---------- #}
166
+ {%- if add_generation_prompt %}
167
+ {{ bos_token+"assistant\n" }}
168
+ {%- if thinking_budget == 0 %}
169
+ {{ think_begin_token + "\n" + budget_begin_token + "The current thinking budget is 0, so I will directly start answering the question." + budget_end_token + "\n" + think_end_token }}
170
+ {%- endif %}
171
+ {%- endif %}
llama.cpp/models/templates/CohereForAI-c4ai-command-r-plus-tool_use.jinja ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ {%- macro json_to_python_type(json_spec) %}
3
+ {%- set basic_type_map = {
4
+ "string": "str",
5
+ "number": "float",
6
+ "integer": "int",
7
+ "boolean": "bool"
8
+ } %}
9
+
10
+ {%- if basic_type_map[json_spec.type] is defined %}
11
+ {{- basic_type_map[json_spec.type] }}
12
+ {%- elif json_spec.type == "array" %}
13
+ {{- "List[" + json_to_python_type(json_spec.items) + "]"}}
14
+ {%- elif json_spec.type == "object" %}
15
+ {{- "Dict[str, " + json_to_python_type(json_spec.additionalProperties) + ']'}}
16
+ {%- elif json_spec.type is iterable %}
17
+ {{- "Union[" }}
18
+ {%- for t in json_spec.type %}
19
+ {{- json_to_python_type({"type": t}) }}
20
+ {%- if not loop.last %}
21
+ {{- "," }}
22
+ {%- endif %}
23
+ {%- endfor %}
24
+ {{- "]" }}
25
+ {%- else %}
26
+ {{- "Any" }}
27
+ {%- endif %}
28
+ {%- endmacro %}
29
+
30
+ {%- macro old_tool_parser(tools) %}
31
+ {%- for tool in tools %}
32
+ {%- if loop.index0 != 0 %}
33
+ {{- '\n\n' }}
34
+ {%- endif %}
35
+ {{- '```python\ndef ' + tool.name + '(' }}
36
+ {%- for param_name, param_fields in tool.parameter_definitions|items %}
37
+ {%- if loop.index0 != 0 %}
38
+ {{- ', '}}
39
+ {%- endif %}
40
+ {{- param_name + ': ' }}
41
+ {%- if not param_fields.required %}
42
+ {{- 'Optional[' + param_fields.type + '] = None'}}
43
+ {%- else %}
44
+ {{- param_fields.type }}
45
+ {%- endif %}
46
+ {%- endfor %}
47
+ {{- ') -> List[Dict]:\n """'}}
48
+ {{- tool.description }}
49
+ {%- if tool.parameter_definitions|length != 0 %}
50
+ {{- '\n\n Args:\n '}}
51
+ {%- for param_name, param_fields in tool.parameter_definitions|items %}
52
+ {%- if loop.index0 != 0 %}
53
+ {{- '\n ' }}
54
+ {%- endif %}
55
+ {{- param_name + ' ('}}
56
+ {%- if not param_fields.required %}
57
+ {{- 'Optional[' + param_fields.type + ']'}}
58
+ {%- else %}
59
+ {{- param_fields.type }}
60
+ {%- endif %}
61
+ {{- '): ' + param_fields.description }}
62
+ {%- endfor %}
63
+ {%- endif %}
64
+ {{- '\n """\n pass\n```' }}
65
+ {%- endfor %}
66
+ {%- endmacro %}
67
+
68
+ {%- macro new_tool_parser(tools) %}
69
+ {%- for tool in tools %}
70
+ {%- if loop.index0 != 0 %}
71
+ {{- '\n\n'}}
72
+ {%- endif %}
73
+ {%- if tool.function is defined %}
74
+ {%- set tool = tool.function %}
75
+ {%- endif %}
76
+ {{-'```python
77
+ def ' + tool.name + '('}}
78
+ {%- for param_name, param_fields in tool.parameters.properties|items %}
79
+ {%- if loop.index0 != 0 %}
80
+ {{- ', '}}
81
+ {%- endif %}
82
+ {{-param_name + ": "}}
83
+ {%- if not param_name in tool.parameters.required %}
84
+ {{-'Optional[' + json_to_python_type(param_fields) + '] = None'}}
85
+ {%- else %}
86
+ {{- json_to_python_type(param_fields) }}
87
+ {%- endif %}
88
+ {%- endfor %}
89
+ {{- ') -> List[Dict]:
90
+ """'}}
91
+ {{- tool.description }}
92
+ {%- if tool.parameters.properties|length != 0 %}
93
+ {{- '\n\n Args:\n '}}
94
+ {%- for param_name, param_fields in tool.parameters.properties|items %}
95
+ {%- if loop.index0 != 0 %}
96
+ {{- '\n ' }}
97
+ {%- endif %}
98
+ {{- param_name + ' ('}}
99
+ {%- if not param_name in tool.parameters.required %}
100
+ {{-'Optional[' + json_to_python_type(param_fields) + ']'}}
101
+ {%- else %}
102
+ {{- json_to_python_type(param_fields) }}
103
+ {%- endif %}
104
+ {{- '): ' + param_fields.description }}
105
+ {%- endfor %}
106
+ {%- endif %}
107
+ {{- '\n """\n pass\n```' }}
108
+ {%- endfor %}
109
+ {%- endmacro %}
110
+
111
+ {{- bos_token }}
112
+ {%- if messages[0]['role'] == 'system' %}
113
+ {%- set loop_messages = messages[1:] %}
114
+ {%- set system_message = messages[0]['content'] %}
115
+ {%- else %}
116
+ {%- set loop_messages = messages %}
117
+ {%- set system_message = '## Task and Context\nYou help people answer their questions and other requests interactively. You will be asked a very wide array of requests on all kinds of topics. You will be equipped with a wide range of search engines or similar tools to help you, which you use to research your answer. You should focus on serving the user\'s needs as best you can, which will be wide-ranging.\n\n## Style Guide\nUnless the user asks for a different style of answer, you should answer in full sentences, using proper grammar and spelling.' %}
118
+ {%- endif %}
119
+ {{- '<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|>' }}
120
+ {{- '# Safety Preamble' }}
121
+ {{- '
122
+ The instructions in this section override those in the task description and style guide sections. Don\'t answer questions that are harmful or immoral.' }}
123
+ {{- '
124
+
125
+ # System Preamble' }}
126
+ {{- '
127
+ ## Basic Rules' }}
128
+ {{- '
129
+ You are a powerful conversational AI trained by Cohere to help people. You are augmented by a number of tools, and your job is to use and consume the output of these tools to best help the user. You will see a conversation history between yourself and a user, ending with an utterance from the user. You will then see a specific instruction instructing you what kind of response to generate. When you answer the user\'s requests, you cite your sources in your answers, according to those instructions.' }}
130
+ {{- '
131
+
132
+ # User Preamble' }}
133
+ {{- '
134
+ ' + system_message }}
135
+ {{-'
136
+
137
+ ## Available Tools
138
+ Here is a list of tools that you have available to you:
139
+
140
+ '}}
141
+ {%- set ns = namespace(new_tools=true) %}
142
+ {%- for tool in tools %}
143
+ {%- if tool.parameter_definitions is defined %}
144
+ {%- set ns.new_tools = false %}
145
+ {%- endif %}
146
+ {%- endfor %}
147
+ {%- if ns.new_tools %}
148
+ {{- new_tool_parser(tools) }}
149
+ {%- else %}
150
+ {{- old_tool_parser(tools) }}
151
+ {%- endif %}
152
+ {{- '<|END_OF_TURN_TOKEN|>'}}
153
+ {%- for message in loop_messages %}
154
+ {%- set content = message['content'] %}
155
+ {%- if message.role == 'user' %}
156
+ {{- '<|START_OF_TURN_TOKEN|><|USER_TOKEN|>' + content|trim + '<|END_OF_TURN_TOKEN|>' }}
157
+ {%- elif message.role == 'system' %}
158
+ {{- '<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|>' + content|trim + '<|END_OF_TURN_TOKEN|>' }}
159
+ {%- elif message.role == 'assistant' and message.tool_calls is defined %}
160
+ {{- '<|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|>' }}
161
+ {%- if message.content is defined %}
162
+ {{- message.content|trim }}
163
+ {%- endif %}
164
+ {{- '\nAction:\n```json\n[\n' }}
165
+ {%- for tool_call in message.tool_calls %}
166
+ {%- if tool_call.function is defined %}
167
+ {%- set tool_call = tool_call.function %}
168
+ {%- endif %}
169
+ {{- '{\n'|indent(4, first=true) }}
170
+ {{- '"tool_name": "'|indent(8, first=true) + tool_call.name + '",\n' }}
171
+ {{- '"parameters": '|indent(8, first=true) }}
172
+ {%- if tool_call.arguments is defined and tool_call.arguments|length > 0 %}
173
+ {{- tool_call.arguments|tojson(indent=4)|indent(8) }}
174
+ {{- '\n' }}
175
+ {%- else %}
176
+ {{- '{}\n' }}
177
+ {%- endif %}
178
+ {{- '}'|indent(4, first=true) }}
179
+ {%- if not loop.last %}
180
+ {{- ',\n' }}
181
+ {%- endif %}
182
+ {%- endfor %}
183
+ {{- "\n]```\n" }}
184
+ {%- elif message.role == 'assistant' %}
185
+ {{- '<|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|>' + content|trim + '<|END_OF_TURN_TOKEN|>' }}
186
+ {%- elif message.role == 'tool' %}
187
+ {{- '<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|><results>\n' }}
188
+ {{- message.content|trim }}
189
+ {{- '</results><|END_OF_TURN_TOKEN|>' }}
190
+ {%- endif %}
191
+ {%- endfor %}
192
+ {{-'<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|>Write \'Action:\' followed by a json-formatted list of actions that you want to perform in order to produce a good response to the user\'s last input. You can use any of the supplied tools any number of times, but you should aim to execute the minimum number of necessary actions for the input. You should use the `directly-answer` tool if calling the other tools is unnecessary. The list of actions you want to call should be formatted as a list of json objects, for example:
193
+ ```json
194
+ [
195
+ {
196
+ "tool_name": title of the tool in the specification,
197
+ "parameters": a dict of parameters to input into the tool as they are defined in the specs, or {} if it takes no parameters
198
+ }
199
+ ]```<|END_OF_TURN_TOKEN|>'}}
200
+ {%- if add_generation_prompt %}
201
+ {{- '<|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|>' }}
202
+ {%- endif %}
llama.cpp/models/templates/CohereForAI-c4ai-command-r7b-12-2024-tool_use.jinja ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {{ bos_token }}{%- macro document_turn(documents) -%}
2
+ {# format documents into chat turn #}
3
+ <|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|><|START_THINKING|>I will look through the document to address the users needs.<|END_THINKING|><|START_ACTION|>[
4
+ {"tool_call_id": "0", "tool_name": "direct-injected-document", "parameters": {}}
5
+ ]<|END_ACTION|><|END_OF_TURN_TOKEN|><|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|><|START_TOOL_RESULT|>[
6
+ {
7
+ "tool_call_id": "0",
8
+ "results": {
9
+ {% for doc in documents %}
10
+ "{{ loop.index0 }}": {{doc|tojson}}{% if not loop.last %},
11
+ {% endif %}
12
+ {% endfor %}
13
+
14
+ },
15
+ "is_error": null
16
+ }
17
+ ]<|END_TOOL_RESULT|><|END_OF_TURN_TOKEN|>{%- endmacro %}
18
+ {%- macro tool_call_id_to_int(messages, tool_call_id) %}
19
+ {%- set counter = namespace(value=0) %}
20
+ {%- set tool_call_id_seen = namespace(value=false) %}
21
+ {%- for msg in messages %}
22
+ {%- if msg.tool_calls %}
23
+ {%- for tool_call in msg.tool_calls %}
24
+ {%- if tool_call.id == tool_call_id and not tool_call_id_seen.value -%}
25
+ {{ counter.value }}
26
+ {%- set tool_call_id_seen.value = true %}
27
+ {%- endif %}
28
+ {%- set counter.value = counter.value + 1 %}
29
+ {%- endfor %}
30
+ {%- endif %}
31
+ {%- endfor %}
32
+ {%- endmacro %}
33
+ {%- macro format_tool_message(messages, tool_msg) -%}
34
+ {# format tool message #}
35
+ {
36
+ "tool_call_id": "{{ tool_call_id_to_int(messages, tool_msg.tool_call_id) }}",
37
+ "results": {
38
+ "0": {{ tool_msg.content|tojson }}
39
+ },
40
+ "is_error": null
41
+ }
42
+ {%- endmacro -%}
43
+ {%- if messages and messages[0]['role']|lower == 'system' %}{%- set developer_preamble = messages[0]['content'] %}{% endif %}
44
+ {%- set tool_idx = namespace(value=0) %}
45
+ {%- set tool_ids_seen = namespace(value=[]) %}
46
+ {%- set sent_documents = namespace(value=false) %}
47
+ <|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|># System Preamble
48
+ You are in contextual safety mode. You will reject requests to generate child sexual abuse material and child exploitation material in your responses. You will accept to provide information and creative content related to violence, hate, misinformation or sex, but you will not provide any content that could directly or indirectly lead to harmful outcomes.
49
+
50
+ Your information cutoff date is June 2024.
51
+
52
+ You have been trained on data in English, French, Spanish, Italian, German, Portuguese, Japanese, Korean, Modern Standard Arabic, Mandarin, Russian, Indonesian, Turkish, Dutch, Polish, Persian, Vietnamese, Czech, Hindi, Ukrainian, Romanian, Greek and Hebrew but have the ability to speak many more languages.
53
+ {% if tools or documents %}
54
+
55
+ You have been trained to have advanced reasoning and tool-use capabilities and you should make best use of these skills to serve user's requests.
56
+
57
+ ## Tool Use
58
+ Think about how you can make best use of the provided tools to help with the task and come up with a high level plan that you will execute first.
59
+
60
+ 0. Start by writing <|START_THINKING|> followed by a detailed step by step plan of how you will solve the problem. For each step explain your thinking fully and give details of required tool calls (if needed). Unless specified otherwise, you write your plan in natural language. When you finish, close it out with <|END_THINKING|>.
61
+ You can optionally choose to skip this step when the user request is so straightforward to address that only a trivial plan would be needed.
62
+ NOTE: You MUST skip this step when you are directly responding to the user's request without using any tools.
63
+
64
+ Then carry out your plan by repeatedly executing the following steps.
65
+ 1. Action: write <|START_ACTION|> followed by a list of JSON-formatted tool calls, with each one containing "tool_name" and "parameters" fields.
66
+ When there are multiple tool calls which are completely independent of each other (i.e. they can be executed in parallel), you should list them out all together in one step. When you finish, close it out with <|END_ACTION|>.
67
+ 2. Observation: you will then receive results of those tool calls in JSON format in the very next turn, wrapped around by <|START_TOOL_RESULT|> and <|END_TOOL_RESULT|>. Carefully observe those results and think about what to do next. Note that these results will be provided to you in a separate turn. NEVER hallucinate results.
68
+ Every tool call produces a list of results (when a tool call produces no result or a single result, it'll still get wrapped inside a list). Each result is clearly linked to its originating tool call via its "tool_call_id".
69
+ 3. Reflection: start the next turn by writing <|START_THINKING|> followed by what you've figured out so far, any changes you need to make to your plan, and what you will do next. When you finish, close it out with <|END_THINKING|>.
70
+ You can optionally choose to skip this step when everything is going according to plan and no special pieces of information or reasoning chains need to be recorded.
71
+ NOTE: You MUST skip this step when you are done with tool-use actions and are ready to respond to the user.
72
+
73
+ You can repeat the above 3 steps multiple times (could be 0 times too if no suitable tool calls are available or needed), until you decide it's time to finally respond to the user.
74
+
75
+ 4. Response: then break out of the loop and write <|START_RESPONSE|> followed by a piece of text which serves as a response to the user's last request. Use all previous tool calls and results to help you when formulating your response. When you finish, close it out with <|END_RESPONSE|>.
76
+ {% if enable_citations %}
77
+
78
+ ## Grounding
79
+ Importantly, note that "Reflection" and "Response" above can be grounded.
80
+ Grounding means you associate pieces of texts (called "spans") with those specific tool results that support them (called "sources"). And you use a pair of tags "<co>" and "</co>" to indicate when a span can be grounded onto a list of sources, listing them out in the closing tag. Sources from the same tool call are grouped together and listed as "{tool_call_id}:[{list of result indices}]", before they are joined together by ",". E.g., "<co>span</co: 0:[1,2],1:[0]>" means that "span" is supported by result 1 and 2 from "tool_call_id=0" as well as result 0 from "tool_call_id=1".
81
+ {% endif %}
82
+
83
+ ## Available Tools
84
+ Here is the list of tools that you have available to you.
85
+ You can ONLY use the tools listed here. When a tool is not listed below, it is NOT available and you should NEVER attempt to use it.
86
+ Each tool is represented as a JSON object with fields like "name", "description", "parameters" (per JSON Schema), and optionally, "responses" (per JSON Schema).
87
+
88
+ ```json
89
+ [
90
+ {% if documents %}
91
+ {"name": "direct-injected-document", "description": "This is a special tool to directly inject user-uploaded documents into the chat as additional context. DO NOT use this tool by yourself!", "parameters": {"type": "object", "properties": {}, "required": []}, "responses": {"200": {"description": "Successfully returned a list of chunked text snippets from the directly uploaded documents.", "content": {"application/json": {"schema": {"type": "array", "items": {"type": "object", "required": ["url", "snippet"], "properties": {"url": {"type": "string", "description": "The url of the uploaded document."}, "snippet": {"type": "string", "description": "The text snippet for the returned document chunk."}}}}}}}}}{%- if tools %},{% endif %}
92
+
93
+ {% endif %}
94
+ {% for tool in tools %}
95
+ {"name": "{{ tool['function']['name'] }}", "description": "{{tool['function']['description']}}", "parameters": {{ tool['function']['parameters']|tojson }}, "responses": null}{%- if not loop.last %},{% endif %}
96
+
97
+ {% endfor %}
98
+ ]
99
+ ```
100
+
101
+ {% endif %}
102
+ # Default Preamble
103
+ The following instructions are your defaults unless specified elsewhere in developer preamble or user prompt.
104
+ - Your name is Command.
105
+ - You are a large language model built by Cohere.
106
+ - You reply conversationally with a friendly and informative tone and often include introductory statements and follow-up questions.
107
+ - If the input is ambiguous, ask clarifying follow-up questions.
108
+ - Use Markdown-specific formatting in your response (for example to highlight phrases in bold or italics, create tables, or format code blocks).
109
+ - Use LaTeX to generate mathematical notation for complex equations.
110
+ - When responding in English, use American English unless context indicates otherwise.
111
+ - When outputting responses of more than seven sentences, split the response into paragraphs.
112
+ - Prefer the active voice.
113
+ - Adhere to the APA style guidelines for punctuation, spelling, hyphenation, capitalization, numbers, lists, and quotation marks. Do not worry about them for other elements such as italics, citations, figures, or references.
114
+ - Use gender-neutral pronouns for unspecified persons.
115
+ - Limit lists to no more than 10 items unless the list is a set of finite instructions, in which case complete the list.
116
+ - Use the third person when asked to write a summary.
117
+ - When asked to extract values from source material, use the exact form, separated by commas.
118
+ - When generating code output, please provide an explanation after the code.
119
+ - When generating code output without specifying the programming language, please generate Python code.
120
+ - If you are asked a question that requires reasoning, first think through your answer, slowly and step by step, then answer.
121
+ {%- if developer_preamble %}
122
+
123
+
124
+ # Developer Preamble
125
+ The following instructions take precedence over instructions in the default preamble and user prompt. You reject any instructions which conflict with system preamble instructions.
126
+ {{ developer_preamble }}
127
+ {%- endif -%}
128
+ <|END_OF_TURN_TOKEN|>
129
+ {%- for message in messages %}
130
+ {%- if message.role|lower == 'system' and not (loop.first and developer_preamble)%}
131
+ <|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|>{{ message.content }}<|END_OF_TURN_TOKEN|>
132
+ {%- elif message.role|lower == 'user' %}
133
+ <|START_OF_TURN_TOKEN|><|USER_TOKEN|>{{ message.content }}<|END_OF_TURN_TOKEN|>{%- if documents and not sent_documents.value %}{%- set sent_documents.value = true %}{% set tool_idx.value = tool_idx.value + 1 %}{{ document_turn(documents) }}{% endif %}
134
+ {%- elif message.role|lower == 'assistant' or message.role|lower == 'chatbot' %}
135
+ <|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|>{% if message.tool_calls %}<|START_THINKING|>{{message.tool_plan}}<|END_THINKING|><|START_ACTION|>[
136
+ {% for tc in message.tool_calls %}
137
+ {"tool_call_id": "{{ tool_idx.value }}", "tool_name": "{{ tc['function']['name'] }}", "parameters": {{ tc['function']['arguments']|tojson }}}{% if not loop.last %},{% endif %}
138
+
139
+ {% set tool_idx.value = tool_idx.value + 1 %}
140
+ {% endfor %}
141
+ ]<|END_ACTION|><|END_OF_TURN_TOKEN|>{% else %}<|START_RESPONSE|>{{message.content}}<|END_RESPONSE|><|END_OF_TURN_TOKEN|>{% endif %}
142
+ {% elif message.role|lower == 'tool' and message.tool_call_id not in tool_ids_seen.value %}
143
+ <|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|><|START_TOOL_RESULT|>[
144
+ {{ format_tool_message(messages, message) }}
145
+ {%- for msg in messages[loop.index0 + 1:] %}
146
+ {%- if msg.role|lower == 'tool' %},
147
+ {{ format_tool_message(messages, msg) }}
148
+ {%- set tool_ids_seen.value = tool_ids_seen.value + [msg.tool_call_id] %}
149
+ {%- else %}
150
+ {%- break %}
151
+ {%- endif %}
152
+ {%- endfor %}
153
+
154
+ ]<|END_TOOL_RESULT|><|END_OF_TURN_TOKEN|>
155
+ {%- endif %}
156
+ {%- endfor %}<|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|>
llama.cpp/models/templates/GLM-4.6.jinja ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [gMASK]<sop>
2
+ {%- if tools -%}
3
+ <|system|>
4
+ # Tools
5
+
6
+ You may call one or more functions to assist with the user query.
7
+
8
+ You are provided with function signatures within <tools></tools> XML tags:
9
+ <tools>
10
+ {% for tool in tools %}
11
+ {{ tool | tojson(ensure_ascii=False) }}
12
+ {% endfor %}
13
+ </tools>
14
+
15
+ For each function call, output the function name and arguments within the following XML format:
16
+ <tool_call>{function-name}
17
+ <arg_key>{arg-key-1}</arg_key>
18
+ <arg_value>{arg-value-1}</arg_value>
19
+ <arg_key>{arg-key-2}</arg_key>
20
+ <arg_value>{arg-value-2}</arg_value>
21
+ ...
22
+ </tool_call>{%- endif -%}
23
+ {%- macro visible_text(content) -%}
24
+ {%- if content is string -%}
25
+ {{- content }}
26
+ {%- elif content is iterable and content is not mapping -%}
27
+ {%- for item in content -%}
28
+ {%- if item is mapping and item.type == 'text' -%}
29
+ {{- item.text }}
30
+ {%- elif item is string -%}
31
+ {{- item }}
32
+ {%- endif -%}
33
+ {%- endfor -%}
34
+ {%- else -%}
35
+ {{- content }}
36
+ {%- endif -%}
37
+ {%- endmacro -%}
38
+ {%- set ns = namespace(last_user_index=-1) %}
39
+ {%- for m in messages %}
40
+ {%- if m.role == 'user' %}
41
+ {% set ns.last_user_index = loop.index0 -%}
42
+ {%- endif %}
43
+ {%- endfor %}
44
+ {% for m in messages %}
45
+ {%- if m.role == 'user' -%}<|user|>
46
+ {{ visible_text(m.content) }}
47
+ {{- '/nothink' if (enable_thinking is defined and not enable_thinking and not visible_text(m.content).endswith("/nothink")) else '' -}}
48
+ {%- elif m.role == 'assistant' -%}
49
+ <|assistant|>
50
+ {%- set reasoning_content = '' %}
51
+ {%- set content = visible_text(m.content) %}
52
+ {%- if m.reasoning_content is string %}
53
+ {%- set reasoning_content = m.reasoning_content %}
54
+ {%- else %}
55
+ {%- if '</think>' in content %}
56
+ {%- set reasoning_content = content.split('</think>')[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
57
+ {%- set content = content.split('</think>')[-1].lstrip('\n') %}
58
+ {%- endif %}
59
+ {%- endif %}
60
+ {%- if loop.index0 > ns.last_user_index and reasoning_content -%}
61
+ {{ '\n<think>' + reasoning_content.strip() + '</think>'}}
62
+ {%- else -%}
63
+ {{ '\n<think></think>' }}
64
+ {%- endif -%}
65
+ {%- if content.strip() -%}
66
+ {{ '\n' + content.strip() }}
67
+ {%- endif -%}
68
+ {% if m.tool_calls %}
69
+ {% for tc in m.tool_calls %}
70
+ {%- if tc.function %}
71
+ {%- set tc = tc.function %}
72
+ {%- endif %}
73
+ {{ '\n<tool_call>' + tc.name }}
74
+ {% set _args = tc.arguments or {} %}
75
+ {% if _args is not mapping %}
76
+ {{ raise_exception("Invalid tool call arguments passed: " + _args | string) }}
77
+ {% endif %}
78
+ {% for k, v in _args.items() %}
79
+ <arg_key>{{ k }}</arg_key>
80
+ <arg_value>{{ v | tojson(ensure_ascii=False) if v is not string else v }}</arg_value>
81
+ {% endfor %}
82
+ </tool_call>{% endfor %}
83
+ {% endif %}
84
+ {%- elif m.role == 'tool' -%}
85
+ {%- if m.content is string -%}
86
+ {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %}
87
+ {{- '<|observation|>' }}
88
+ {%- endif %}
89
+ {{- '\n<tool_response>\n' }}
90
+ {{- m.content }}
91
+ {{- '\n</tool_response>' }}
92
+ {%- else -%}
93
+ <|observation|>{% for tr in m.content %}
94
+
95
+ <tool_response>
96
+ {{ tr.output if tr.output is defined else tr }}
97
+ </tool_response>{% endfor -%}
98
+ {% endif -%}
99
+ {%- elif m.role == 'system' -%}
100
+ <|system|>
101
+ {{ visible_text(m.content) }}
102
+ {%- endif -%}
103
+ {%- endfor -%}
104
+ {%- if add_generation_prompt -%}
105
+ <|assistant|>{{- '\n<think></think>' if (enable_thinking is defined and not enable_thinking) else '' -}}
106
+ {%- endif -%}
llama.cpp/models/templates/Kimi-K2-Instruct.jinja ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% macro render_content(msg) -%}
2
+ {%- set c = msg.get('content') -%}
3
+ {%- if c is string -%}
4
+ {{ c }}
5
+ {%- elif c is not none -%}
6
+ {% for content in c -%}
7
+ {% if content['type'] == 'image' or 'image' in content or 'image_url' in content -%}
8
+ <|media_start|>image<|media_content|><|media_pad|><|media_end|>
9
+ {% else -%}
10
+ {{ content['text'] }}
11
+ {%- endif -%}
12
+ {%- endfor -%}
13
+ {%- endif -%}
14
+ {%- endmacro %}
15
+
16
+ {%- set tool_response_queue = namespace(ids=[]) -%}
17
+ {%- set tool_call_counter = namespace(value=0) -%}
18
+
19
+ {%- if tools -%}
20
+ <|im_system|>tool_declare<|im_middle|>{{ tools | tojson }}<|im_end|>
21
+ {%- endif -%}
22
+ {% for message in messages %}
23
+ {%- if loop.first and messages[0]['role'] != 'system' -%}
24
+ <|im_system|>system<|im_middle|>You are Kimi, an AI assistant created by Moonshot AI.<|im_end|>
25
+ {% endif %}
26
+
27
+ {%- set role_name = message.get('name') or message['role'] -%}
28
+ {%- if message['role'] == 'user' -%}
29
+ <|im_user|>{{role_name}}<|im_middle|>
30
+ {%- elif message['role'] == 'assistant' -%}
31
+ <|im_assistant|>{{role_name}}<|im_middle|>
32
+ {%- else -%}
33
+ <|im_system|>{{role_name}}<|im_middle|>
34
+ {%- endif -%}
35
+
36
+ {%- if message['role'] == 'assistant' and message.get('tool_calls') -%}
37
+ {{render_content(message)}}<|tool_calls_section_begin|>
38
+ {%- for tool_call in message['tool_calls'] -%}
39
+ {%- set formatted_id = 'functions.' + tool_call['function']['name'] + ':' + (tool_call_counter.value | string) -%}
40
+ {%- set tool_call_counter.value = tool_call_counter.value + 1 -%}
41
+ {%- set _ = tool_response_queue.ids.append(formatted_id) -%}
42
+ <|tool_call_begin|>{{ formatted_id }}<|tool_call_argument_begin|>{% if tool_call['function']['arguments'] is string %}{{ tool_call['function']['arguments'] }}{% else %}{{ tool_call['function']['arguments'] | tojson }}{% endif %}<|tool_call_end|>
43
+ {%- endfor -%}
44
+ <|tool_calls_section_end|>
45
+ {%- elif message['role'] == 'tool' -%}
46
+ {%- if tool_response_queue.ids -%}
47
+ {%- set tool_call_id = tool_response_queue.ids.pop(0) -%}
48
+ {%- else -%}
49
+ {%- set tool_call_id = 'functions.' + message.get('name', 'unknown') + ':' + (tool_call_counter.value | string) -%}
50
+ {%- endif -%}
51
+ ## Return of {{ tool_call_id }}
52
+ {{render_content(message)}}
53
+ {%- elif message['content'] is not none -%}
54
+ {{render_content(message)}}
55
+ {%- endif -%}
56
+ <|im_end|>
57
+ {%- endfor -%}
58
+ {%- if add_generation_prompt -%}
59
+ <|im_assistant|>assistant<|im_middle|>
60
+ {%- endif -%}
llama.cpp/models/templates/Kimi-K2-Thinking.jinja ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- macro render_content(msg) -%}
2
+ {%- set c = msg.get('content') -%}
3
+ {%- if c is string -%}
4
+ {{ c }}
5
+ {%- elif c is not none -%}
6
+ {% for content in c -%}
7
+ {% if content['type'] == 'image' or 'image' in content or 'image_url' in content -%}
8
+ <|media_start|>image<|media_content|><|media_pad|><|media_end|>
9
+ {% else -%}
10
+ {{ content['text'] }}
11
+ {%- endif -%}
12
+ {%- endfor -%}
13
+ {%- endif -%}
14
+ {%- endmacro -%}
15
+
16
+ {% macro set_roles(message) -%}
17
+ {%- set role_name = message.get('name') or message['role'] -%}
18
+ {%- if message['role'] == 'user' -%}
19
+ <|im_user|>{{role_name}}<|im_middle|>
20
+ {%- elif message['role'] == 'assistant' -%}
21
+ <|im_assistant|>{{role_name}}<|im_middle|>
22
+ {%- else -%}
23
+ <|im_system|>{{role_name}}<|im_middle|>
24
+ {%- endif -%}
25
+ {%- endmacro -%}
26
+
27
+ {%- set tool_response_queue = namespace(ids=[]) -%}
28
+ {%- set tool_call_counter = namespace(value=0) -%}
29
+
30
+ {%- macro render_toolcalls(message) -%}
31
+ <|tool_calls_section_begin|>
32
+ {%- for tool_call in message['tool_calls'] -%}
33
+ {%- set formatted_id = 'functions.' + tool_call['function']['name'] + ':' + (tool_call_counter.value | string) -%}
34
+ {%- set tool_call_counter.value = tool_call_counter.value + 1 -%}
35
+ {%- set _ = tool_response_queue.ids.append(formatted_id) -%}
36
+ <|tool_call_begin|>{{ formatted_id }}<|tool_call_argument_begin|>{% if tool_call['function']['arguments'] is string %}{{ tool_call['function']['arguments'] }}{% else %}{{ tool_call['function']['arguments'] | tojson }}{% endif %}<|tool_call_end|>
37
+ {%- endfor -%}
38
+ <|tool_calls_section_end|>
39
+ {%- endmacro -%}
40
+
41
+
42
+ {# Find last non-tool-call assisitant message #}
43
+ {%- set ns = namespace(last_non_tool_call_assistant_msg=-1) -%}
44
+ {%- for idx in range(messages|length-1, -1, -1) -%}
45
+ {%- if messages[idx]['role'] == 'assistant' and not messages[idx].get('tool_calls') -%}
46
+ {%- set ns.last_non_tool_call_assistant_msg = idx -%}
47
+ {%- endif -%}
48
+ {%- endfor -%}
49
+
50
+ {# split all messages into history & suffix, reasoning_content in suffix should be reserved.#}
51
+ {%- set hist_msgs = messages[:ns.last_non_tool_call_assistant_msg+1] -%}
52
+ {%- set suffix_msgs = messages[ns.last_non_tool_call_assistant_msg+1:] -%}
53
+
54
+ {%- if tools -%}
55
+ <|im_system|>tool_declare<|im_middle|>{{ tools | tojson }}<|im_end|>
56
+ {%- endif -%}
57
+
58
+ {%- if messages|length == 0 or messages[0]['role'] != 'system' -%}
59
+ <|im_system|>system<|im_middle|>You are Kimi, an AI assistant created by Moonshot AI.<|im_end|>
60
+ {%- endif -%}
61
+
62
+ {%- for message in hist_msgs -%}
63
+ {{set_roles(message)}}
64
+ {%- if message['role'] == 'assistant' -%}
65
+ <think></think>{{render_content(message)}}
66
+ {%- if message.get('tool_calls') -%}
67
+ {{render_toolcalls(message)}}
68
+ {%- endif -%}
69
+ {%- elif message['role'] == 'tool' -%}
70
+ {%- if tool_response_queue.ids -%}
71
+ {%- set tool_call_id = tool_response_queue.ids.pop(0) -%}
72
+ {%- else -%}
73
+ {%- set tool_call_id = 'functions.' + message.get('name', 'unknown') + ':' + (tool_call_counter.value | string) -%}
74
+ {%- endif -%}
75
+ ## Return of {{ tool_call_id }}
76
+ {{render_content(message)}}
77
+ {%- elif message['content'] is not none -%}
78
+ {{render_content(message)}}
79
+ {%- endif -%}
80
+ <|im_end|>
81
+ {%- endfor -%}
82
+
83
+ {%- for message in suffix_msgs -%}
84
+ {{set_roles(message)}}
85
+ {%- if message['role'] == 'assistant' -%}
86
+ {%- set rc = message.get('reasoning_content', '') -%}
87
+ <think>{{rc}}</think>{{render_content(message)}}
88
+ {%- if message.get('tool_calls') -%}
89
+ {{render_toolcalls(message)}}
90
+ {%- endif -%}
91
+ {%- elif message['role'] == 'tool' -%}
92
+ {%- if tool_response_queue.ids -%}
93
+ {%- set tool_call_id = tool_response_queue.ids.pop(0) -%}
94
+ {%- else -%}
95
+ {%- set tool_call_id = 'functions.' + message.get('name', 'unknown') + ':' + (tool_call_counter.value | string) -%}
96
+ {%- endif -%}
97
+ ## Return of {{ tool_call_id }}
98
+ {{render_content(message)}}
99
+ {%- elif message['content'] is not none -%}
100
+ {{render_content(message)}}
101
+ {%- endif -%}
102
+ <|im_end|>
103
+ {%- endfor -%}
104
+
105
+
106
+ {%- if add_generation_prompt -%}
107
+ <|im_assistant|>assistant<|im_middle|>
108
+ {%- endif -%}
llama.cpp/models/templates/MiMo-VL.jinja ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- if tools %}
2
+ {{- '<|im_start|>system\n' }}
3
+ {%- if messages[0]['role'] == 'system' %}
4
+ {{- messages[0]['content'] }}
5
+ {%- else %}
6
+ {{- 'You are MiMo, an AI assistant developed by Xiaomi.' }}
7
+ {%- endif %}
8
+ {{- "\n\n# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>" }}
9
+ {%- for tool in tools %}
10
+ {{- "\n" }}
11
+ {{- tool | tojson }}
12
+ {%- endfor %}
13
+ {{- "\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call><|im_end|>\n" }}
14
+ {%- else %}
15
+ {%- if messages[0]['role'] == 'system' %}
16
+ {{- '<|im_start|>system\n' + messages[0]['content'] + '<|im_end|>\n' }}
17
+ {%- else %}
18
+ {{- '<|im_start|>system\nYou are MiMo, an AI assistant developed by Xiaomi.<|im_end|>\n' }}
19
+ {%- endif %}
20
+ {%- endif %}
21
+ {%- for message in messages %}
22
+ {%- if (message.role == "user") or (message.role == "system" and not loop.first) or (message.role == "assistant" and not message.tool_calls) %}
23
+ {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }}
24
+ {%- elif message.role == "assistant" %}
25
+ {{- '<|im_start|>' + message.role }}
26
+ {%- if message.content %}
27
+ {{- '\n' + message.content }}
28
+ {%- endif %}
29
+ {%- for tool_call in message.tool_calls %}
30
+ {%- if tool_call.function is defined %}
31
+ {%- set tool_call = tool_call.function %}
32
+ {%- endif %}
33
+ {{- '\n<tool_call>\n{"name": "' }}
34
+ {{- tool_call.name }}
35
+ {{- '", "arguments": ' }}
36
+ {{- tool_call.arguments | tojson }}
37
+ {{- '}\n</tool_call>' }}
38
+ {%- endfor %}
39
+ {{- '<|im_end|>\n' }}
40
+ {%- elif message.role == "tool" %}
41
+ {%- if (loop.index0 == 0) or (messages[loop.index0 - 1].role != "tool") %}
42
+ {{- '<|im_start|>user' }}
43
+ {%- endif %}
44
+ {{- '\n<tool_response>\n' }}
45
+ {{- message.content }}
46
+ {{- '\n</tool_response>' }}
47
+ {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %}
48
+ {{- '<|im_end|>\n' }}
49
+ {%- endif %}
50
+ {%- endif %}
51
+ {%- endfor %}
52
+ {%- if add_generation_prompt %}
53
+ {{- '<|im_start|>assistant\n' }}
54
+ {%- endif %}
llama.cpp/models/templates/MiniMax-M2.jinja ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {# ----------‑‑‑ special token variables ‑‑‑---------- #}
2
+ {%- set toolcall_begin_token = '<minimax:tool_call>' -%}
3
+ {%- set toolcall_end_token = '</minimax:tool_call>' -%}
4
+ {#- Tool Rendering Functions ============================================== -#}
5
+ {%- macro render_tool_namespace(namespace_name, tool_list) -%}
6
+ {%- for tool in tool_list -%}
7
+ <tool>{{ tool.function | tojson(ensure_ascii=False) }}</tool>
8
+ {% endfor -%}
9
+ {%- endmacro -%}
10
+ {%- macro visible_text(content) -%}
11
+ {%- if content is string -%}
12
+ {{ content }}
13
+ {%- elif content is iterable and content is not mapping -%}
14
+ {%- for item in content -%}
15
+ {%- if item is mapping and item.type == 'text' -%}
16
+ {{- item.text }}
17
+ {%- elif item is string -%}
18
+ {{- item }}
19
+ {%- endif -%}
20
+ {%- endfor -%}
21
+ {%- else -%}
22
+ {{- content }}
23
+ {%- endif -%}
24
+ {%- endmacro -%}
25
+ {#- System Message Construction ============================================ -#}
26
+ {%- macro build_system_message(system_message) -%}
27
+ {%- if system_message and system_message.content -%}
28
+ {{- visible_text(system_message.content) }}
29
+ {%- else -%}
30
+ {%- if model_identity is not defined -%}
31
+ {%- set model_identity = "You are a helpful assistant." -%}
32
+ {%- endif -%}
33
+ {{- model_identity }}
34
+ {%- endif -%}
35
+
36
+ {#- Handle current_date -#}
37
+ {%- if system_message and system_message.current_date -%}
38
+ {{- '\n' ~ 'Current date: ' + system_message.current_date }}
39
+ {%- endif -%}
40
+ {#- Handle current_location -#}
41
+ {%- if system_message and system_message.current_location -%}
42
+ {{- '\n' ~ 'Current location: ' + system_message.current_location }}
43
+ {%- endif -%}
44
+ {%- endmacro -%}
45
+ {#- Main Template Logic ================================================= -#}
46
+ {#- Extract system message (only first message if it's system) -#}
47
+ {%- set system_message = none -%}
48
+ {%- set conversation_messages = messages -%}
49
+ {%- if messages and messages[0].role == "system" -%}
50
+ {%- set system_message = messages[0] -%}
51
+ {%- set conversation_messages = messages[1:] -%}
52
+ {%- endif -%}
53
+ {#- Get the last user message turn, for interleved thinking -#}
54
+ {%- set ns = namespace(last_user_index=-1) %}
55
+ {% for m in conversation_messages %}
56
+ {%- if m.role == 'user' %}
57
+ {% set ns.last_user_index = loop.index0 -%}
58
+ {%- endif %}
59
+ {%- endfor %}
60
+ {#- Render system message -#}
61
+ {{- ']~!b[' ~ ']~b]system' ~ '\n' }}
62
+ {{- build_system_message(system_message) }}
63
+ {#- Render tools if available -#}
64
+ {%- if tools -%}
65
+ {{- '\n\n' ~ '# Tools' ~ '\n' ~ 'You may call one or more tools to assist with the user query.\nHere are the tools available in JSONSchema format:' ~ '\n' }}
66
+ {{- '\n' ~ '<tools>' ~ '\n' }}
67
+ {{- render_tool_namespace("functions", tools) }}
68
+ {{- '</tools>' ~ '\n\n' }}
69
+ {{- 'When making tool calls, use XML format to invoke tools and pass parameters:' ~ '\n' }}
70
+ {{- '\n' ~ toolcall_begin_token }}
71
+ <invoke name="tool-name-1">
72
+ <parameter name="param-key-1">param-value-1</parameter>
73
+ <parameter name="param-key-2">param-value-2</parameter>
74
+ ...
75
+ </invoke>
76
+ {{- '\n' ~ toolcall_end_token }}
77
+ {%- endif -%}
78
+ {{- '[e~[\n' }}
79
+
80
+ {#- Render messages -#}
81
+ {%- set last_tool_call = namespace(name=none) -%}
82
+ {%- for message in conversation_messages -%}
83
+ {%- if message.role == 'assistant' -%}
84
+ {#- Only render reasoning_content if no user message follows -#}
85
+ {{- ']~b]ai' ~ '\n' }}
86
+
87
+ {%- set reasoning_content = '' %}
88
+ {%- set content = visible_text(message.content) %}
89
+ {%- if message.reasoning_content is string %}
90
+ {%- set reasoning_content = message.reasoning_content %}
91
+ {%- else %}
92
+ {%- if '</think>' in content %}
93
+ {%- set reasoning_content = content.split('</think>')[0].strip('\n').split('<think>')[-1].strip('\n') %}
94
+ {%- set content = content.split('</think>')[-1].strip('\n') %}
95
+ {%- endif %}
96
+ {%- endif %}
97
+ {%- if reasoning_content and loop.index0 > ns.last_user_index -%}
98
+ {{- '<think>' ~ '\n' ~ reasoning_content ~ '\n' ~ '</think>' ~ '\n\n' }}
99
+ {%- endif -%}
100
+ {%- if content -%}
101
+ {{- content }}
102
+ {%- endif -%}
103
+ {%- if message.tool_calls -%}
104
+ {{- '\n' ~ toolcall_begin_token ~ '\n' }}
105
+
106
+ {%- for tool_call in message.tool_calls -%}
107
+ {%- if tool_call.function %}
108
+ {%- set tool_call = tool_call.function %}
109
+ {%- endif %}
110
+ {{- '<invoke name="' + tool_call.name + '">' }}
111
+ {% set _args = tool_call.arguments %}
112
+ {%- for k, v in _args.items() %}
113
+ {{- '<parameter name="' + k + '">' }}
114
+ {{- v | tojson(ensure_ascii=False) if v is not string else v }}
115
+ {{- '</parameter>' }}
116
+ {% endfor %}
117
+ {{- '</invoke>' ~ '\n' }}
118
+ {%- endfor -%}
119
+
120
+ {{- toolcall_end_token}}
121
+ {%- set last_tool_call.name = message.tool_calls[-1].function.name -%}
122
+ {%- else -%}
123
+ {%- set last_tool_call.name = none -%}
124
+ {%- endif -%}
125
+ {{- '[e~[' ~ '\n' }}
126
+
127
+ {%- elif message.role == 'tool' -%}
128
+ {%- if last_tool_call.name is none -%}
129
+ {{- raise_exception("Message has tool role, but there was no previous assistant message with a tool call!") }}
130
+ {%- endif -%}
131
+ {%- if loop.first or (conversation_messages[loop.index0 - 1].role != 'tool') -%}
132
+ {{- ']~b]tool' }}
133
+ {%- endif -%}
134
+ {%- if message.content is string -%}
135
+ {{- '\n<response>' }}
136
+ {{- message.content }}
137
+ {{- '</response>' }}
138
+ {%- else -%}
139
+ {%- for tr in message.content -%}
140
+ {{- '\n<response>' }}
141
+ {{- tr.output if tr.output is defined else (tr.text if tr.type == 'text' and tr.text is defined else tr) }}
142
+ {{- '\n</response>' }}
143
+ {%- endfor -%}
144
+ {%- endif -%}
145
+ {%- if loop.last or (conversation_messages[loop.index0 + 1].role != 'tool') -%}
146
+ {{- '[e~[\n' -}}
147
+ {%- endif -%}
148
+
149
+ {%- elif message.role == 'user' -%}
150
+ {{- ']~b]user' ~ '\n' }}
151
+ {{- visible_text(message.content) }}
152
+ {{- '[e~[' ~ '\n' }}
153
+ {%- endif -%}
154
+ {%- endfor -%}
155
+
156
+ {#- Generation prompt -#}
157
+ {%- if add_generation_prompt -%}
158
+ {{- ']~b]ai' ~ '\n' ~ '<think>' ~ '\n' }}
159
+ {%- endif -%}
llama.cpp/models/templates/deepseek-ai-DeepSeek-R1-Distill-Llama-8B.jinja ADDED
@@ -0,0 +1 @@
 
 
1
+ {% if not add_generation_prompt is defined %}{% set add_generation_prompt = false %}{% endif %}{% set ns = namespace(is_first=false, is_tool=false, is_output_first=true, system_prompt='') %}{%- for message in messages %}{%- if message['role'] == 'system' %}{% set ns.system_prompt = message['content'] %}{%- endif %}{%- endfor %}{{bos_token}}{{ns.system_prompt}}{%- for message in messages %}{%- if message['role'] == 'user' %}{%- set ns.is_tool = false -%}{{'<|User|>' + message['content']}}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is none %}{%- set ns.is_tool = false -%}{%- for tool in message['tool_calls']%}{%- if not ns.is_first %}{{'<|Assistant|><|tool▁calls▁begin|><|tool▁call▁begin|>' + tool['type'] + '<|tool▁sep|>' + tool['function']['name'] + '\n' + '```json' + '\n' + tool['function']['arguments'] + '\n' + '```' + '<|tool▁call▁end|>'}}{%- set ns.is_first = true -%}{%- else %}{{'\n' + '<|tool▁call▁begin|>' + tool['type'] + '<|tool▁sep|>' + tool['function']['name'] + '\n' + '```json' + '\n' + tool['function']['arguments'] + '\n' + '```' + '<|tool▁call▁end|>'}}{{'<|tool▁calls▁end|><|end▁of▁sentence|>'}}{%- endif %}{%- endfor %}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is not none %}{%- if ns.is_tool %}{{'<|tool▁outputs▁end|>' + message['content'] + '<|end▁of▁sentence|>'}}{%- set ns.is_tool = false -%}{%- else %}{% set content = message['content'] %}{% if '</think>' in content %}{% set content = content.split('</think>')[-1] %}{% endif %}{{'<|Assistant|>' + content + '<|end▁of▁sentence|>'}}{%- endif %}{%- endif %}{%- if message['role'] == 'tool' %}{%- set ns.is_tool = true -%}{%- if ns.is_output_first %}{{'<|tool▁outputs▁begin|><|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>'}}{%- set ns.is_output_first = false %}{%- else %}{{'\n<|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>'}}{%- endif %}{%- endif %}{%- endfor -%}{% if ns.is_tool %}{{'<|tool▁outputs▁end|>'}}{% endif %}{% if add_generation_prompt and not ns.is_tool %}{{'<|Assistant|><think>\n'}}{% endif %}
llama.cpp/models/templates/deepseek-ai-DeepSeek-R1-Distill-Qwen-32B.jinja ADDED
@@ -0,0 +1 @@
 
 
1
+ {% if not add_generation_prompt is defined %}{% set add_generation_prompt = false %}{% endif %}{% set ns = namespace(is_first=false, is_tool=false, is_output_first=true, system_prompt='') %}{%- for message in messages %}{%- if message['role'] == 'system' %}{% set ns.system_prompt = message['content'] %}{%- endif %}{%- endfor %}{{bos_token}}{{ns.system_prompt}}{%- for message in messages %}{%- if message['role'] == 'user' %}{%- set ns.is_tool = false -%}{{'<|User|>' + message['content']}}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is none %}{%- set ns.is_tool = false -%}{%- for tool in message['tool_calls']%}{%- if not ns.is_first %}{{'<|Assistant|><|tool▁calls▁begin|><|tool▁call▁begin|>' + tool['type'] + '<|tool▁sep|>' + tool['function']['name'] + '\n' + '```json' + '\n' + tool['function']['arguments'] + '\n' + '```' + '<|tool▁call▁end|>'}}{%- set ns.is_first = true -%}{%- else %}{{'\n' + '<|tool▁call▁begin|>' + tool['type'] + '<|tool▁sep|>' + tool['function']['name'] + '\n' + '```json' + '\n' + tool['function']['arguments'] + '\n' + '```' + '<|tool▁call▁end|>'}}{{'<|tool▁calls▁end|><|end▁of▁sentence|>'}}{%- endif %}{%- endfor %}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is not none %}{%- if ns.is_tool %}{{'<|tool▁outputs▁end|>' + message['content'] + '<|end▁of▁sentence|>'}}{%- set ns.is_tool = false -%}{%- else %}{% set content = message['content'] %}{% if '</think>' in content %}{% set content = content.split('</think>')[-1] %}{% endif %}{{'<|Assistant|>' + content + '<|end▁of▁sentence|>'}}{%- endif %}{%- endif %}{%- if message['role'] == 'tool' %}{%- set ns.is_tool = true -%}{%- if ns.is_output_first %}{{'<|tool▁outputs▁begin|><|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>'}}{%- set ns.is_output_first = false %}{%- else %}{{'\n<|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>'}}{%- endif %}{%- endif %}{%- endfor -%}{% if ns.is_tool %}{{'<|tool▁outputs▁end|>'}}{% endif %}{% if add_generation_prompt and not ns.is_tool %}{{'<|Assistant|><think>\n'}}{% endif %}
llama.cpp/models/templates/deepseek-ai-DeepSeek-V3.1.jinja ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ {% if not add_generation_prompt is defined %}{% set add_generation_prompt = false %}{% endif %}{% if not thinking is defined %}{% set thinking = false %}{% endif %}{% set ns = namespace(is_first=false, is_tool=false, system_prompt='', is_first_sp=true, is_last_user=false) %}{%- for message in messages %}{%- if message['role'] == 'system' %}{%- if ns.is_first_sp %}{% set ns.system_prompt = ns.system_prompt + message['content'] %}{% set ns.is_first_sp = false %}{%- else %}{% set ns.system_prompt = ns.system_prompt + '
2
+
3
+ ' + message['content'] %}{%- endif %}{%- endif %}{%- endfor %}{{ bos_token }}{{ ns.system_prompt }}{%- for message in messages %}{%- if message['role'] == 'user' %}{%- set ns.is_tool = false -%}{%- set ns.is_first = false -%}{%- set ns.is_last_user = true -%}{{'<|User|>' + message['content']}}{%- endif %}{%- if message['role'] == 'assistant' and message['tool_calls'] is defined and message['tool_calls'] is not none %}{%- if ns.is_last_user %}{{'<|Assistant|></think>'}}{%- endif %}{%- set ns.is_last_user = false -%}{%- set ns.is_first = false %}{%- set ns.is_tool = false -%}{%- for tool in message['tool_calls'] %}{%- if not ns.is_first %}{%- if message['content'] is none %}{{'<|tool▁calls▁begin|><|tool▁call▁begin|>'+ tool['function']['name'] + '<|tool▁sep|>' + tool['function']['arguments'] + '<|tool▁call▁end|>'}}{%- else %}{{message['content'] + '<|tool▁calls▁begin|><|tool▁call▁begin|>' + tool['function']['name'] + '<|tool▁sep|>' + tool['function']['arguments'] + '<|tool▁call▁end|>'}}{%- endif %}{%- set ns.is_first = true -%}{%- else %}{{'<|tool▁call▁begin|>'+ tool['function']['name'] + '<|tool▁sep|>' + tool['function']['arguments'] + '<|tool▁call▁end|>'}}{%- endif %}{%- endfor %}{{'<|tool▁calls▁end|><|end▁of▁sentence|>'}}{%- endif %}{%- if message['role'] == 'assistant' and (message['tool_calls'] is not defined or message['tool_calls'] is none) %}{%- if ns.is_last_user %}{{'<|Assistant|>'}}{%- if message['prefix'] is defined and message['prefix'] and thinking %}{{'<think>'}} {%- else %}{{'</think>'}}{%- endif %}{%- endif %}{%- set ns.is_last_user = false -%}{%- if ns.is_tool %}{{message['content'] + '<|end▁of▁sentence|>'}}{%- set ns.is_tool = false -%}{%- else %}{%- set content = message['content'] -%}{%- if '</think>' in content %}{%- set content = content.split('</think>', 1)[1] -%}{%- endif %}{{content + '<|end▁of▁sentence|>'}}{%- endif %}{%- endif %}{%- if message['role'] == 'tool' %}{%- set ns.is_last_user = false -%}{%- set ns.is_tool = true -%}{{'<|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>'}}{%- endif %}{%- endfor -%}{%- if add_generation_prompt and ns.is_last_user and not ns.is_tool %}{{'<|Assistant|>'}}{%- if not thinking %}{{'</think>'}}{%- else %}{{'<think>'}}{%- endif %}{% endif %}
llama.cpp/models/templates/fireworks-ai-llama-3-firefunction-v2.jinja ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- set loop_messages = messages -%}
2
+ {%- set message_roles = ['system', 'user', 'assistant', 'tool'] -%}
3
+ {%- set system_prompt_suffix -%}
4
+ {%- filter trim -%}
5
+ In addition to plain text responses, you can chose to call one or more of the provided functions.
6
+
7
+ Use the following rule to decide when to call a function:
8
+ * if the response can be generated from your internal knowledge (e.g., as in the case of queries like "What is the capital of Poland?"), do so
9
+ * if you need external information that can be obtained by calling one or more of the provided functions, generate a function calls
10
+
11
+ If you decide to call functions:
12
+ * prefix function calls with functools marker (no closing marker required)
13
+ * all function calls should be generated in a single JSON list formatted as functools[{"name": [function name], "arguments": [function arguments as JSON]}, ...]
14
+ * follow the provided JSON schema. Do not hallucinate arguments or values. Do to blindly copy values from the provided samples
15
+ * respect the argument type formatting. E.g., if the type if number and format is float, write value 7 as 7.0
16
+ * make sure you pick the right functions that match the user intent
17
+
18
+ Available functions as JSON spec:
19
+ {%- endfilter -%}
20
+ {%- endset -%}
21
+ {%- set system_prompt_suffix = system_prompt_suffix + "\n" + functions -%}
22
+ {%- set system_prompt_suffix = system_prompt_suffix + '\nToday is ' + datetime + '.' -%}
23
+ {%- set ns = namespace(role='', content='') -%}
24
+ {#- Basic consistency checks -#}
25
+ {%- if not loop_messages -%}
26
+ {{ raise_exception('Expected non-empty messages') }}
27
+ {%- endif -%}
28
+ {%- for message in loop_messages -%}
29
+ {%- set ns.role = message['role'] | lower -%}
30
+ {%- if ns.role not in message_roles -%}
31
+ {%- set message_roles_string = message_roles | join(', ') -%}
32
+ {{ raise_exception('Invalid role ' + message['role'] + '. Only ' + message_roles_string + ' are supported.') }}
33
+ {%- endif -%}
34
+ {%- set msg_content = message['content'] | default('', true) | trim -%}
35
+ {%- if loop.index0 == 0 -%}
36
+ {%- if ns.role == 'system' -%}
37
+ {%- set system_prompt = '<|start_header_id|>' + 'system' + '<|end_header_id|>\n\n' + message['content'] | trim + '\n' + system_prompt_suffix + '<|eot_id|>' -%}
38
+ {%- else -%}
39
+ {%- set system_prompt = '<|start_header_id|>' + 'system' + '<|end_header_id|>\n\nYou are a helpful assistant with access to functions.\n' + system_prompt_suffix + '<|eot_id|>' -%}
40
+ {%- endif -%}
41
+ {%- set ns.content = bos_token + system_prompt -%}
42
+ {{- ns.content -}}
43
+ {%- endif -%}
44
+ {%- if loop.index0 > 0 or ns.role != 'system' -%}
45
+ {%- set ns.content = '<|start_header_id|>' + ns.role + '<|end_header_id|>\n\n' + msg_content -%}
46
+ {%- if 'tool_calls' in message and message['tool_calls'] -%}
47
+ {%- set tool = namespace(calls=[]) -%}
48
+ {%- for call in message['tool_calls'] -%}
49
+ {%- set tool.calls = tool.calls + ['{"name": "' + call['function']['name'] + '", "arguments": ' + call['function']['arguments'] + '}'] -%}
50
+ {%- endfor -%}
51
+ {%- set ns.content = ns.content + ' functools[' + tool.calls | join(', ') + ']' -%}
52
+ {%- endif -%}
53
+ {%- set ns.content = ns.content + '<|eot_id|>' -%}
54
+ {{- ns.content -}}
55
+ {%- endif -%}
56
+ {%- endfor -%}
57
+ {{- '<|start_header_id|>assistant<|end_header_id|>\n\n' -}}
llama.cpp/models/templates/google-gemma-2-2b-it.jinja ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ {{ bos_token }}{% if messages[0]['role'] == 'system' %}{{ raise_exception('System role not supported') }}{% endif %}{% for message in messages %}{% if (message['role'] == 'user') != (loop.index0 % 2 == 0) %}{{ raise_exception('Conversation roles must alternate user/assistant/user/assistant/...') }}{% endif %}{% if (message['role'] == 'assistant') %}{% set role = 'model' %}{% else %}{% set role = message['role'] %}{% endif %}{{ '<start_of_turn>' + role + '
2
+ ' + message['content'] | trim + '<end_of_turn>
3
+ ' }}{% endfor %}{% if add_generation_prompt %}{{'<start_of_turn>model
4
+ '}}{% endif %}
llama.cpp/models/templates/ibm-granite-granite-3.3-2B-Instruct.jinja ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {# Alias tools -> available_tools #}
2
+ {%- if tools and not available_tools -%}
3
+ {%- set available_tools = tools -%}
4
+ {%- endif -%}
5
+ {%- if messages[0]['role'] == 'system' %}
6
+ {%- set system_message = messages[0]['content'] %}
7
+ {%- set loop_messages = messages[1:] %}
8
+ {%- else %}
9
+ {%- set system_message = "Knowledge Cutoff Date: April 2024. Today's Date: " + strftime_now('%B %d, %Y') + ". You are Granite, developed by IBM." %}
10
+ {%- if available_tools and documents %}
11
+ {%- set system_message = system_message + " You are a helpful assistant with access to the following tools. When a tool is required to answer the user's query, respond only with <|tool_call|> followed by a JSON list of tools used. If a tool does not exist in the provided list of tools, notify the user that you do not have the ability to fulfill the request. Write the response to the user's input by strictly aligning with the facts in the provided documents. If the information needed to answer the question is not available in the documents, inform the user that the question cannot be answered based on the available data." %}
12
+ {%- elif available_tools %}
13
+ {%- set system_message = system_message + " You are a helpful assistant with access to the following tools. When a tool is required to answer the user's query, respond only with <|tool_call|> followed by a JSON list of tools used. If a tool does not exist in the provided list of tools, notify the user that you do not have the ability to fulfill the request." %}
14
+ {%- elif documents %}
15
+ {%- set system_message = system_message + " Write the response to the user's input by strictly aligning with the facts in the provided documents. If the information needed to answer the question is not available in the documents, inform the user that the question cannot be answered based on the available data." %}
16
+ {%- elif thinking %}
17
+ {%- set system_message = system_message + " You are a helpful AI assistant.
18
+ Respond to every user query in a comprehensive and detailed way. You can write down your thoughts and reasoning process before responding. In the thought process, engage in a comprehensive cycle of analysis, summarization, exploration, reassessment, reflection, backtracing, and iteration to develop well-considered thinking process. In the response section, based on various attempts, explorations, and reflections from the thoughts section, systematically present the final solution that you deem correct. The response should summarize the thought process. Write your thoughts between <think></think> and write your response between <response></response> for each user query." %}
19
+ {%- else %}
20
+ {%- set system_message = system_message + " You are a helpful AI assistant." %}
21
+ {%- endif %}
22
+ {%- if 'citations' in controls and documents %}
23
+ {%- set system_message = system_message + '
24
+ Use the symbols <|start_of_cite|> and <|end_of_cite|> to indicate when a fact comes from a document in the search result, e.g <|start_of_cite|> {document_id: 1}my fact <|end_of_cite|> for a fact from document 1. Afterwards, list all the citations with their corresponding documents in an ordered list.' %}
25
+ {%- endif %}
26
+ {%- if 'hallucinations' in controls and documents %}
27
+ {%- set system_message = system_message + '
28
+ Finally, after the response is written, include a numbered list of sentences from the response with a corresponding risk value that are hallucinated and not based in the documents.' %}
29
+ {%- endif %}
30
+ {%- set loop_messages = messages %}
31
+ {%- endif %}
32
+ {{- '<|start_of_role|>system<|end_of_role|>' + system_message + '<|end_of_text|>
33
+ ' }}
34
+ {%- if available_tools %}
35
+ {{- '<|start_of_role|>available_tools<|end_of_role|>' }}
36
+ {{- available_tools | tojson(indent=4) }}
37
+ {{- '<|end_of_text|>
38
+ ' }}
39
+ {%- endif %}
40
+ {%- if documents %}
41
+ {%- for document in documents %}
42
+ {{- '<|start_of_role|>document {"document_id": "' + document['doc_id'] | string + '"}<|end_of_role|>
43
+ ' }}
44
+ {{- document['text'] }}
45
+ {{- '<|end_of_text|>
46
+ ' }}
47
+ {%- endfor %}
48
+ {%- endif %}
49
+ {%- for message in loop_messages %}
50
+ {{- '<|start_of_role|>' + message['role'] + '<|end_of_role|>' + message['content'] + '<|end_of_text|>
51
+ ' }}
52
+ {%- if loop.last and add_generation_prompt %}
53
+ {{- '<|start_of_role|>assistant' }}
54
+ {%- if controls %}
55
+ {{- ' ' + controls | tojson()}}
56
+ {%- endif %}
57
+ {{- '<|end_of_role|>' }}
58
+ {%- endif %}
59
+ {%- endfor %}
llama.cpp/models/templates/llama-cpp-deepseek-r1.jinja ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- if not add_generation_prompt is defined -%}
2
+ {%- set add_generation_prompt = false -%}
3
+ {%- endif -%}
4
+ {%- set ns = namespace(is_first=false, is_tool_outputs=false, is_output_first=true, system_prompt='') -%}
5
+ {%- for message in messages -%}
6
+ {%- if message['role'] == 'system' -%}
7
+ {%- set ns.system_prompt = message['content'] -%}
8
+ {%- endif -%}
9
+ {%- endfor -%}
10
+ {{bos_token}}
11
+ {%- if tools %}
12
+ You can call any of the following function tools to satisfy the user's requests: {{tools | map(attribute='function') | tojson(indent=2)}}
13
+
14
+ Example function tool call syntax:
15
+
16
+ <|tool▁calls▁begin|><|tool▁call▁begin|>function<|tool▁sep|>example_function_name
17
+ ```json
18
+ {
19
+ "arg1": "some_value"
20
+ ...
21
+ }
22
+ ```
23
+ <|tool▁call▁end|><|tool▁calls▁end|>
24
+
25
+ {% endif -%}
26
+ {{ns.system_prompt}}
27
+ {%- macro flush_tool_outputs() -%}
28
+ {%- if ns.is_tool_outputs -%}
29
+ {{- '<|tool▁outputs▁end|><|end▁of▁sentence|>' -}}
30
+ {%- set ns.is_tool_outputs = false -%}
31
+ {%- endif -%}
32
+ {%- endmacro -%}
33
+ {{- flush_tool_outputs() -}}
34
+ {%- for message in messages -%}
35
+ {%- if message['role'] != 'tool' -%}
36
+ {{- flush_tool_outputs() -}}
37
+ {%- endif -%}
38
+ {%- if message['role'] == 'user' -%}
39
+ {{- '<|User|>' + message['content'] + '<|end▁of▁sentence|>' -}}
40
+ {%- endif -%}
41
+ {%- if message['role'] == 'assistant' and not message['content'] -%}
42
+ {{- '<|Assistant|><|tool▁calls▁begin|>' -}}
43
+ {%- set ns.is_first = true -%}
44
+ {%- for tc in message['tool_calls'] -%}
45
+ {%- if ns.is_first -%}
46
+ {%- set ns.is_first = false -%}
47
+ {%- else -%}
48
+ {{- '\n' -}}
49
+ {%- endif -%}
50
+ {%- set tool_name = tc['function']['name'] -%}
51
+ {%- set tool_args = tc['function']['arguments'] -%}
52
+ {{- '<|tool▁call▁begin|>' + tc['type'] + '<|tool▁sep|>' + tool_name + '\n' + '```json' + '\n' + tool_args + '\n' + '```' + '<|tool▁call▁end|>' -}}
53
+ {%- endfor -%}
54
+ {{- '<|tool▁calls▁end|><|end▁of▁sentence|>' -}}
55
+ {%- endif -%}
56
+ {%- if message['role'] == 'assistant' and message['content'] -%}
57
+ {{- flush_tool_outputs() -}}
58
+ {%- set content = message['content'] -%}
59
+ {%- if '</think>' in content -%}
60
+ {%- set content = content.split('</think>')[-1] -%}
61
+ {%- endif -%}
62
+ {{- '<|Assistant|>' + content + '<|end▁of▁sentence|>' -}}
63
+ {%- endif -%}
64
+ {%- if message['role'] == 'tool' -%}
65
+ {%- set ns.is_tool_outputs = true -%}
66
+ {%- if ns.is_output_first -%}
67
+ {{- '<|tool▁outputs▁begin|>' -}}
68
+ {%- set ns.is_output_first = false -%}
69
+ {%- endif -%}
70
+ {{- '\n<|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>' -}}
71
+ {%- endif -%}
72
+ {%- endfor -%}
73
+ {{- flush_tool_outputs() -}}
74
+ {%- if add_generation_prompt and not ns.is_tool_outputs -%}
75
+ {{- '<|Assistant|><think>\n' -}}
76
+ {%- endif -%}
llama.cpp/models/templates/llama-cpp-lfm2.jinja ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {{- bos_token -}}
2
+ {%- set system_prompt = "" -%}
3
+ {%- set ns = namespace(system_prompt="") -%}
4
+ {%- if messages[0]["role"] == "system" -%}
5
+ {%- set ns.system_prompt = messages[0]["content"] -%}
6
+ {%- set messages = messages[1:] -%}
7
+ {%- endif -%}
8
+ {%- if tools -%}
9
+ {%- set ns.system_prompt = ns.system_prompt + ("\n" if ns.system_prompt else "") + "List of tools: <|tool_list_start|>[" -%}
10
+ {%- for tool in tools -%}
11
+ {%- if tool is not string -%}
12
+ {%- set tool = tool | tojson -%}
13
+ {%- endif -%}
14
+ {%- set ns.system_prompt = ns.system_prompt + tool -%}
15
+ {%- if not loop.last -%}
16
+ {%- set ns.system_prompt = ns.system_prompt + ", " -%}
17
+ {%- endif -%}
18
+ {%- endfor -%}
19
+ {%- set ns.system_prompt = ns.system_prompt + "]<|tool_list_end|>" -%}
20
+ {%- endif -%}
21
+ {%- if ns.system_prompt -%}
22
+ {{- "<|im_start|>system\n" + ns.system_prompt + "<|im_end|>\n" -}}
23
+ {%- endif -%}
24
+ {%- for message in messages -%}
25
+ {{- "<|im_start|>" + message["role"] + "\n" -}}
26
+ {%- set content = message["content"] -%}
27
+ {%- if content is not string -%}
28
+ {%- set content = content | tojson -%}
29
+ {%- endif -%}
30
+ {%- if message["role"] == "tool" -%}
31
+ {%- set content = "<|tool_response_start|>" + content + "<|tool_response_end|>" -%}
32
+ {%- endif -%}
33
+ {{- content + "<|im_end|>\n" -}}
34
+ {%- endfor -%}
35
+ {%- if add_generation_prompt -%}
36
+ {{- "<|im_start|>assistant\n" -}}
37
+ {%- endif -%}
llama.cpp/models/templates/llama-cpp-rwkv-world.jinja ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- if not add_generation_prompt is defined -%}
2
+ {%- set add_generation_prompt = true -%}
3
+ {%- endif -%}
4
+ {%- set ns = namespace(system_prompt='') -%}
5
+ {%- for message in messages -%}
6
+ {%- if message['role'] == 'system' -%}
7
+ {%- set ns.system_prompt = message['content'] -%}
8
+ {%- endif -%}
9
+ {%- endfor -%}
10
+ {{bos_token}}
11
+ {%- if ns.system_prompt != '' -%}
12
+ {{- 'System: ' + ns.system_prompt + '\n\n' -}}
13
+ {%- endif -%}
14
+ {%- for message in messages -%}
15
+ {%- if message['role'] == 'user' -%}
16
+ {{- 'User: ' + message['content']|trim + '\n\n' -}}
17
+ {%- endif -%}
18
+ {%- if message['role'] == 'assistant' and message['content'] is not none -%}
19
+ {%- set content = message['content'] -%}
20
+ {%- if '</think>' in content -%}
21
+ {%- set content = content.split('</think>')[-1] -%}
22
+ {%- endif -%}
23
+ {{- 'Assistant: ' + content|trim + '\n\n' -}}
24
+ {%- endif -%}
25
+ {%- endfor -%}
26
+ {%- if add_generation_prompt -%}
27
+ {{- 'Assistant:' -}}
28
+ {%- if enable_thinking is defined and enable_thinking is false %}
29
+ {{- ' <think>\n</think>' }}
30
+ {%- endif %}
31
+ {%- if enable_thinking is defined and enable_thinking is true %}
32
+ {{- ' <think>' }}
33
+ {%- endif %}
34
+ {%- endif -%}
llama.cpp/models/templates/meetkai-functionary-medium-v3.1.jinja ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {# version=v3-llama3.1 #}{%- if not tools is defined -%}
2
+ {%- set tools = none -%}
3
+ {%- endif -%}
4
+
5
+ {%- set has_code_interpreter = tools | selectattr("type", "equalto", "code_interpreter") | list | length > 0 -%}
6
+ {%- if has_code_interpreter -%}
7
+ {%- set tools = tools | rejectattr("type", "equalto", "code_interpreter") | list -%}
8
+ {%- endif -%}
9
+
10
+ {#- System message + builtin tools #}
11
+ {{- bos_token + "<|start_header_id|>system<|end_header_id|>\n\n" }}
12
+ {%- if has_code_interpreter %}
13
+ {{- "Environment: ipython\n\n" }}
14
+ {%- else -%}
15
+ {{ "\n"}}
16
+ {%- endif %}
17
+ {{- "Cutting Knowledge Date: December 2023\n\n" }}
18
+ {%- if tools %}
19
+ {{- "\nYou have access to the following functions:\n\n" }}
20
+ {%- for t in tools %}
21
+ {%- if "type" in t -%}
22
+ {{ "Use the function '"|safe + t["function"]["name"] + "' to '"|safe + t["function"]["description"] + "'\n"|safe + t["function"] | tojson() }}
23
+ {%- else -%}
24
+ {{ "Use the function '"|safe + t["name"] + "' to '"|safe + t["description"] + "'\n"|safe + t | tojson() }}
25
+ {%- endif -%}
26
+ {{- "\n\n" }}
27
+ {%- endfor %}
28
+ {{- '\nThink very carefully before calling functions.\nIf a you choose to call a function ONLY reply in the following format:\n<{start_tag}={function_name}>{parameters}{end_tag}\nwhere\n\nstart_tag => `<function`\nparameters => a JSON dict with the function argument name as key and function argument value as value.\nend_tag => `</function>`\n\nHere is an example,\n<function=example_function_name>{"example_name": "example_value"}</function>\n\nReminder:\n- If looking for real time information use relevant functions before falling back to brave_search\n- Function calls MUST follow the specified format, start with <function= and end with </function>\n- Required parameters MUST be specified\n- Only call one function at a time\n- Put the entire function call reply on one line\n\n' -}}
29
+ {%- endif %}
30
+ {{- "<|eot_id|>" -}}
31
+
32
+ {%- for message in messages -%}
33
+ {%- if message['role'] == 'user' or message['role'] == 'system' -%}
34
+ {{ '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n' + message['content'] + '<|eot_id|>' }}
35
+ {%- elif message['role'] == 'tool' -%}
36
+ {{ '<|start_header_id|>ipython<|end_header_id|>\n\n' + message['content'] + '<|eot_id|>' }}
37
+ {%- else -%}
38
+ {{ '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n'}}
39
+ {%- if message['content'] -%}
40
+ {{ message['content'] }}
41
+ {%- endif -%}
42
+ {%- if 'tool_calls' in message and message['tool_calls'] -%}
43
+ {%- for tool_call in message['tool_calls'] -%}
44
+ {%- if tool_call["function"]["name"] == "python" -%}
45
+ {{ '<|python_tag|>' + tool_call['function']['arguments'] }}
46
+ {%- else -%}
47
+ {{ '<function=' + tool_call['function']['name'] + '>' + tool_call['function']['arguments'] + '</function>' }}
48
+ {%- endif -%}
49
+ {%- endfor -%}
50
+ {{ '<|eom_id|>' }}
51
+ {%- else -%}
52
+ {{ '<|eot_id|>' }}
53
+ {%- endif -%}
54
+ {%- endif -%}
55
+ {%- endfor -%}
56
+ {%- if add_generation_prompt -%}
57
+ {{ '<|start_header_id|>assistant<|end_header_id|>\n\n' }}
58
+ {%- endif -%}
llama.cpp/models/templates/meetkai-functionary-medium-v3.2.jinja ADDED
@@ -0,0 +1,287 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {# version=v3.llama3 #}{%- macro append_new_param_info(param_declaration, comment_info, examples_info, depth) -%}
2
+ {%- set offset = "" -%}
3
+ {%- if depth >= 1 -%}
4
+ {%- set offset = " " * depth -%}
5
+ {%- endif -%}
6
+ {%- if comment_info != "<|NONE|>" -%}
7
+ {{ "\n" + offset + comment_info }}
8
+ {%- if examples_info | length > 0 -%}
9
+ {# Append each example info #}
10
+ {%- for example in examples_info -%}
11
+ {{ "\n" + offset + "// " + example|string|replace("'", '"') }}
12
+ {%- endfor -%}
13
+ {%- endif -%}
14
+ {%- endif -%}
15
+ {{ "\n" + offset + param_declaration }}
16
+ {%- endmacro -%}
17
+
18
+ {%- macro convert_data_type(param_type) -%}
19
+ {%- if param_type == "integer" or param_type == "float" -%}
20
+ {{ "number" }}
21
+ {%- else -%}
22
+ {{ param_type }}
23
+ {%- endif -%}
24
+ {%- endmacro -%}
25
+
26
+ {%- macro get_param_type(param) -%}
27
+ {%- set param_type = "any" -%}
28
+
29
+ {%- if "type" in param -%}
30
+ {%- set raw_param_type = param["type"] -%}
31
+ {%- if raw_param_type is iterable and raw_param_type is not string -%}
32
+ {%- set param_type = raw_param_type | join(" | ") -%}
33
+ {%- else -%}
34
+ {%- set param_type = raw_param_type -%}
35
+ {%- endif -%}
36
+ {{ convert_data_type(param_type) }}
37
+ {%- elif "oneOf" in param -%}
38
+ {%- set one_of_types = param["oneOf"]|selectattr("type", "defined")|list -%}
39
+ {%- set one_of_types = one_of_types|map(attribute="type")|unique|list -%}
40
+ {{ convert_data_type(one_of_types | join(" | ")) }}
41
+ {%- endif -%}
42
+ {%- endmacro -%}
43
+
44
+ {%- macro get_format_param(param) -%}
45
+ {%- if "format" in param -%}
46
+ {{ param["format"] }}
47
+ {%- elif "oneOf" in param -%}
48
+ {%- set formats = [] -%}
49
+ {%- for item in param["oneOf"] -%}
50
+ {%- if "format" in item -%}
51
+ {%- if item["format"] == param["oneOf"][-1]["format"] -%}
52
+ {{ item["format"] }}
53
+ {%- else -%}
54
+ {{ item["format"] + " or "}}
55
+ {%- endif -%}
56
+ {%- endif -%}
57
+ {%- endfor -%}
58
+ {%- else -%}
59
+ {{ "<|NONE|>" }}
60
+ {%- endif -%}
61
+ {%- endmacro -%}
62
+
63
+ {%- macro get_param_info(param) -%}
64
+ {%- set param_type = param.get("type", "any") -%}
65
+ {%- set format_param = get_format_param(param) -%}
66
+
67
+ {%- if "description" in param or "default" in param or format_param != "<|NONE|>" or param["maximum"] or param["minimum"] or param["maxLength"] or param["minLength"] -%}
68
+ {{ "//" }}
69
+ {%- if "description" in param -%}
70
+ {%- set desc = param["description"] -%}
71
+ {%- if not desc.endswith(".") -%}
72
+ {%- set desc = desc + "." -%}
73
+ {%- endif -%}
74
+ {{ " " + desc }}
75
+ {%- endif -%}
76
+
77
+ {%- if "default" in param -%}
78
+ {%- set default_value = param["default"] -%}
79
+ {%- if param_type == "string" -%}
80
+ {%- set default_value = '"' ~ default_value ~ '"' -%}
81
+ {%- endif -%}
82
+ {{ " Default=" ~ default_value ~ "." }}
83
+ {%- endif -%}
84
+
85
+ {%- set format_param = get_format_param(param) -%}
86
+ {%- if format_param != "<|NONE|>" -%}
87
+ {{ " Format=" ~ format_param }}
88
+ {%- endif -%}
89
+
90
+ {%- for field, field_name in [("maximum", "Maximum"), ("minimum", "Minimum"), ("maxLength", "Maximum length"), ("minLength", "Minimum length")] -%}
91
+ {%- if field in param -%}
92
+ {{ " " + field_name ~ "=" ~ param[field] }}
93
+ {%- endif -%}
94
+ {%- endfor -%}
95
+ {%- else -%}
96
+ {{ "<|NONE|>"}}
97
+ {%- endif -%}
98
+ {%- endmacro -%}
99
+
100
+ {%- macro get_enum_option_str(enum_options) -%}
101
+ {%- for v in enum_options -%}
102
+ {%- if v is string -%}
103
+ {{ '"' + v + '"' }}
104
+ {%- else -%}
105
+ {{ v }}
106
+ {%- endif -%}
107
+ {%- if enum_options|length > 0 and v != enum_options[-1] -%}
108
+ {{ " | " }}
109
+ {%- endif -%}
110
+ {%- endfor -%}
111
+ {%- endmacro -%}
112
+
113
+ {%- macro get_array_typescript(param_name, param_dic, depth) -%}
114
+ {%- set offset = '' -%}
115
+ {%- if depth >= 1 -%}
116
+ {%- set offset = " " * depth -%}
117
+ {%- endif -%}
118
+ {%- set items_info = param_dic.get('items', {}) -%}
119
+
120
+ {%- if items_info|length == 0 -%}
121
+ {%- if param_name -%}
122
+ {{ "\n" + offset + param_name + ": []" }}
123
+ {%- else -%}
124
+ {{ "\n" + offset + "[]" }}
125
+ {%- endif -%}
126
+ {%- else -%}
127
+ {%- set array_type = get_param_type(items_info) -%}
128
+ {%- if array_type == 'object' -%}
129
+ {%- if param_name -%}
130
+ {{ "\n" + offset + param_name + ": {" }}
131
+ {%- else -%}
132
+ {{ "\n" + offset + "{" }}
133
+ {%- endif -%}
134
+ {{ get_parameter_typescript(items_info.get('properties', {}), items_info.get('required', []), depth + 1) -}}
135
+ {{- "\n" + offset + "}[]" }}
136
+ {%- elif array_type == 'array' -%}
137
+ {%- set item_info = get_array_typescript(None, items_info, depth + 1) -%}
138
+ {%- if not param_name -%}
139
+ {{ "\n" + item_info + "[]" }}
140
+ {%- else -%}
141
+ {{ "\n" + offset + param_name + ": " + item_info|trim + "[]" }}
142
+ {%- endif -%}
143
+ {%- else -%}
144
+ {%- if 'enum' in items_info -%}
145
+ {%- set item_type = get_enum_option_str(items_info['enum']) -%}
146
+ {%- if param_name is none -%}
147
+ {{ "(" + item_type + ")[]"}}
148
+ {%- else -%}
149
+ {{ "\n" + offset + param_name + ": (" + item_type + ")[]" }}
150
+ {%- endif -%}
151
+ {%- else -%}
152
+ {%- if param_name is none -%}
153
+ {{ "\n" + array_type + "[]" }}
154
+ {%- else -%}
155
+ {{ "\n" + offset + param_name + ": " + array_type + "[]," }}
156
+ {%- endif -%}
157
+ {%- endif -%}
158
+ {%- endif -%}
159
+ {%- endif -%}
160
+ {%- endmacro -%}
161
+
162
+ {%- macro get_parameter_typescript(properties, required_params, depth=0) -%}
163
+ {%- set res = "" -%}
164
+ {%- for param_name, param in properties.items() -%}
165
+ {%- if param is mapping -%}
166
+ {%- set comment_info = get_param_info(param) -%}
167
+ {# Param Examples #}
168
+ {%- set examples_info = [] -%}
169
+ {%- if "examples" in param -%}
170
+ {%- set examples_info = ["Example " + param_name + ":"] -%}
171
+ {%- set examples_info = examples_info + param["examples"] -%}
172
+ {%- endif -%}
173
+
174
+ {# Param Name declaration #}
175
+ {%- set param_declaration = param_name -%}
176
+ {%- if required_params is iterable and param_name not in required_params -%}
177
+ {%- set param_declaration = param_declaration + "?" -%}
178
+ {%- endif -%}
179
+
180
+ {%- set param_type = get_param_type(param) -%}
181
+
182
+ {# Handle indentation based on depth #}
183
+ {%- set offset = "" -%}
184
+ {%- if depth >= 1 -%}
185
+ {%- set offset = " " * depth -%}
186
+ {%- endif -%}
187
+
188
+ {%- if param_type == "object" -%}
189
+ {%- if comment_info != "<|NONE|>" -%}
190
+ {{ "\n" + offset + comment_info }}
191
+ {%- endif -%}
192
+ {%- if examples_info|length > 0 -%}
193
+ {%- for example in examples_info -%}
194
+ {{ "\n" + offset + "// " + example|string|replace("'", '"') }}
195
+ {%- endfor -%}
196
+ {%- endif -%}
197
+ {%- set param_declaration = param_declaration + ": {" -%}
198
+ {{ "\n" + offset + param_declaration -}}
199
+ {{- get_parameter_typescript(param.get("properties", {}), param.get("required", []), depth + 1) -}}
200
+ {{- "\n" + offset + "}," }}
201
+ {%- elif param_type == "array" -%}
202
+ {%- set item_info = param.get("items", {}) -%}
203
+ {%- if "type" not in item_info -%}
204
+ {%- set param_declaration = param_declaration + ": []," -%}
205
+ {{ append_new_param_info(param_declaration, comment_info, examples_info, depth) }}
206
+ {%- else -%}
207
+ {%- if comment_info != "<|NONE|>" -%}
208
+ {{ "\n" + offset + comment_info }}
209
+ {%- endif -%}
210
+ {%- if examples_info|length > 0 -%}
211
+ {%- for example in examples_info -%}
212
+ {{ "\n" + offset + "// " + example|string|replace("'", '"') }}
213
+ {%- endfor -%}
214
+ {%- endif -%}
215
+ {%- set array_declaration = get_array_typescript(param_declaration, param, depth) -%}
216
+ {%- if not array_declaration.endswith(",") -%}
217
+ {%- set array_declaration = array_declaration + "," -%}
218
+ {%- endif -%}
219
+ {{ array_declaration}}
220
+ {%- endif -%}
221
+ {%- else -%}
222
+ {%- if "enum" in param -%}
223
+ {%- set param_type = get_enum_option_str(param["enum"]) -%}
224
+ {%- endif -%}
225
+ {%- if "nullable" in param and param["nullable"] -%}
226
+ {%- set param_type = param_type + " | null" -%}
227
+ {%- endif -%}
228
+ {%- set param_declaration = param_declaration + ": " + param_type + "," -%}
229
+ {{ append_new_param_info(param_declaration, comment_info, examples_info, depth) }}
230
+ {%- endif -%}
231
+ {%- endif -%}
232
+ {%- endfor -%}
233
+ {%- endmacro -%}
234
+
235
+ {%- macro generate_schema_from_functions(functions, namespace='functions') -%}
236
+ {{ "// Supported function definitions that should be called when necessary.\n" -}}
237
+ {{- "namespace " + namespace + " {\n\n" -}}
238
+
239
+ {%- for function in functions -%}
240
+ {%- if function.get("function") -%}
241
+ {%- set function = function.get("function") -%}
242
+ {%- endif -%}
243
+
244
+ {%- set function_name = function.get("name") -%}
245
+ {%- if function_name -%}
246
+ {%- set description = function.get('description', '') -%}
247
+ {%- set parameters = function.get('parameters', {}) -%}
248
+ {{- "// " + description + "\n" -}}
249
+ {{- "type " + function_name -}}
250
+ {%- if parameters and parameters.get("properties") -%}
251
+ {{- " = (_: {" -}}
252
+ {%- set required_params = parameters.get("required", []) -%}
253
+ {{ get_parameter_typescript(parameters.get("properties"), required_params, 0) -}}
254
+ {{- "\n}) => any;\n\n" }}
255
+ {%- else -%}
256
+ {{ " = () => any;\n\n" }}
257
+ {%- endif -%}
258
+ {%- endif -%}
259
+ {%- endfor -%}
260
+ {{ "} // namespace " + namespace }}
261
+ {%- endmacro -%}
262
+ {%- if not tools -%}
263
+ {%- set tools = [] -%}
264
+ {%- endif -%}
265
+ {{ bos_token + '<|start_header_id|>system<|end_header_id|>\n\nYou are capable of executing available function(s) if required.\nOnly execute function(s) when absolutely necessary.\nAsk for the required input to:recipient==all\nUse JSON for function arguments.\nRespond in this format:\n>>>${recipient}\n${content}\nAvailable functions:\n' + generate_schema_from_functions(tools) + '<|eot_id|>' -}}
266
+ {%- if tools|length > 0 and tools|selectattr("type", "equalto", "code_interpreter")|list|length > 0 -%}
267
+ {{ '<|start_header_id|>system<|end_header_id|>\n\nWhen you send a message containing Python code to python, it will be executed in a stateful Jupyter notebook environment. python will respond with the output of the execution or time out after 60.0 seconds. The drive at \'/mnt/data\' can be used to save and persist user files.<|eot_id|>' }}
268
+ {%- endif -%}
269
+ {%- for message in messages -%}
270
+ {%- if message['role'] == 'user' or message['role'] == 'system' -%}
271
+ {{ '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n' + message['content'] + '<|eot_id|>' }}
272
+ {%- elif message['role'] == 'tool' -%}
273
+ {{ '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n' + message['content'] + '<|eot_id|>' }}
274
+ {%- else -%}
275
+ {{ '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n'}}
276
+ {%- if message['content'] -%}
277
+ {{ '>>>all\n' + message['content'] }}
278
+ {%- endif -%}
279
+ {%- if 'tool_calls' in message and message['tool_calls'] -%}
280
+ {%- for tool_call in message['tool_calls'] -%}
281
+ {{ '>>>' + tool_call['function']['name'] + '\n' + tool_call['function']['arguments'] }}
282
+ {%- endfor -%}
283
+ {%- endif -%}
284
+ {{ '<|eot_id|>' }}
285
+ {%- endif -%}
286
+ {%- endfor -%}
287
+ {% if add_generation_prompt %}{{ '<|start_header_id|>assistant<|end_header_id|>\n\n>>>' }}{% endif %}
llama.cpp/models/templates/meta-llama-Llama-3.1-8B-Instruct.jinja ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {{- bos_token }}
2
+ {%- if custom_tools is defined %}
3
+ {%- set tools = custom_tools %}
4
+ {%- endif %}
5
+ {%- if not tools_in_user_message is defined %}
6
+ {%- set tools_in_user_message = true %}
7
+ {%- endif %}
8
+ {%- if not date_string is defined %}
9
+ {%- set date_string = "26 Jul 2024" %}
10
+ {%- endif %}
11
+ {%- if not tools is defined %}
12
+ {%- set tools = none %}
13
+ {%- endif %}
14
+
15
+ {#- This block extracts the system message, so we can slot it into the right place. #}
16
+ {%- if messages[0]['role'] == 'system' %}
17
+ {%- set system_message = messages[0]['content']|trim %}
18
+ {%- set messages = messages[1:] %}
19
+ {%- else %}
20
+ {%- set system_message = "" %}
21
+ {%- endif %}
22
+
23
+ {#- System message + builtin tools #}
24
+ {{- "<|start_header_id|>system<|end_header_id|>\n\n" }}
25
+ {%- if builtin_tools is defined or tools is not none %}
26
+ {{- "Environment: ipython\n" }}
27
+ {%- endif %}
28
+ {%- if builtin_tools is defined %}
29
+ {{- "Tools: " + builtin_tools | reject('equalto', 'code_interpreter') | join(", ") + "\n\n"}}
30
+ {%- endif %}
31
+ {{- "Cutting Knowledge Date: December 2023\n" }}
32
+ {{- "Today Date: " + date_string + "\n\n" }}
33
+ {%- if tools is not none and not tools_in_user_message %}
34
+ {{- "You have access to the following functions. To call a function, please respond with JSON for a function call." }}
35
+ {{- 'Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}.' }}
36
+ {{- "Do not use variables.\n\n" }}
37
+ {%- for t in tools %}
38
+ {{- t | tojson(indent=4) }}
39
+ {{- "\n\n" }}
40
+ {%- endfor %}
41
+ {%- endif %}
42
+ {{- system_message }}
43
+ {{- "<|eot_id|>" }}
44
+
45
+ {#- Custom tools are passed in a user message with some extra guidance #}
46
+ {%- if tools_in_user_message and not tools is none %}
47
+ {#- Extract the first user message so we can plug it in here #}
48
+ {%- if messages | length != 0 %}
49
+ {%- set first_user_message = messages[0]['content']|trim %}
50
+ {%- set messages = messages[1:] %}
51
+ {%- else %}
52
+ {{- raise_exception("Cannot put tools in the first user message when there's no first user message!") }}
53
+ {%- endif %}
54
+ {{- '<|start_header_id|>user<|end_header_id|>\n\n' -}}
55
+ {{- "Given the following functions, please respond with a JSON for a function call " }}
56
+ {{- "with its proper arguments that best answers the given prompt.\n\n" }}
57
+ {{- 'Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}.' }}
58
+ {{- "Do not use variables.\n\n" }}
59
+ {%- for t in tools %}
60
+ {{- t | tojson(indent=4) }}
61
+ {{- "\n\n" }}
62
+ {%- endfor %}
63
+ {{- first_user_message + "<|eot_id|>"}}
64
+ {%- endif %}
65
+
66
+ {%- for message in messages %}
67
+ {%- if not (message.role == 'ipython' or message.role == 'tool' or 'tool_calls' in message) %}
68
+ {{- '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n'+ message['content'] | trim + '<|eot_id|>' }}
69
+ {%- elif 'tool_calls' in message %}
70
+ {%- if not message.tool_calls|length == 1 %}
71
+ {{- raise_exception("This model only supports single tool-calls at once!") }}
72
+ {%- endif %}
73
+ {%- set tool_call = message.tool_calls[0].function %}
74
+ {%- if builtin_tools is defined and tool_call.name in builtin_tools %}
75
+ {{- '<|start_header_id|>assistant<|end_header_id|>\n\n' -}}
76
+ {{- "<|python_tag|>" + tool_call.name + ".call(" }}
77
+ {%- for arg_name, arg_val in tool_call.arguments | items %}
78
+ {{- arg_name + '="' + arg_val + '"' }}
79
+ {%- if not loop.last %}
80
+ {{- ", " }}
81
+ {%- endif %}
82
+ {%- endfor %}
83
+ {{- ")" }}
84
+ {%- else %}
85
+ {{- '<|start_header_id|>assistant<|end_header_id|>\n\n' -}}
86
+ {{- '{"name": "' + tool_call.name + '", ' }}
87
+ {{- '"parameters": ' }}
88
+ {{- tool_call.arguments | tojson }}
89
+ {{- "}" }}
90
+ {%- endif %}
91
+ {%- if builtin_tools is defined %}
92
+ {#- This means we're in ipython mode #}
93
+ {{- "<|eom_id|>" }}
94
+ {%- else %}
95
+ {{- "<|eot_id|>" }}
96
+ {%- endif %}
97
+ {%- elif message.role == "tool" or message.role == "ipython" %}
98
+ {{- "<|start_header_id|>ipython<|end_header_id|>\n\n" }}
99
+ {%- if message.content is mapping or message.content is iterable %}
100
+ {{- message.content | tojson }}
101
+ {%- else %}
102
+ {{- message.content }}
103
+ {%- endif %}
104
+ {{- "<|eot_id|>" }}
105
+ {%- endif %}
106
+ {%- endfor %}
107
+ {%- if add_generation_prompt %}
108
+ {{- '<|start_header_id|>assistant<|end_header_id|>\n\n' }}
109
+ {%- endif %}
llama.cpp/models/templates/meta-llama-Llama-3.2-3B-Instruct.jinja ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {{- bos_token }}
2
+ {%- if custom_tools is defined %}
3
+ {%- set tools = custom_tools %}
4
+ {%- endif %}
5
+ {%- if not tools_in_user_message is defined %}
6
+ {%- set tools_in_user_message = true %}
7
+ {%- endif %}
8
+ {%- if not date_string is defined %}
9
+ {%- if strftime_now is defined %}
10
+ {%- set date_string = strftime_now("%d %b %Y") %}
11
+ {%- else %}
12
+ {%- set date_string = "26 Jul 2024" %}
13
+ {%- endif %}
14
+ {%- endif %}
15
+ {%- if not tools is defined %}
16
+ {%- set tools = none %}
17
+ {%- endif %}
18
+
19
+ {#- This block extracts the system message, so we can slot it into the right place. #}
20
+ {%- if messages[0]['role'] == 'system' %}
21
+ {%- set system_message = messages[0]['content']|trim %}
22
+ {%- set messages = messages[1:] %}
23
+ {%- else %}
24
+ {%- set system_message = "" %}
25
+ {%- endif %}
26
+
27
+ {#- System message #}
28
+ {{- "<|start_header_id|>system<|end_header_id|>\n\n" }}
29
+ {%- if tools is not none %}
30
+ {{- "Environment: ipython\n" }}
31
+ {%- endif %}
32
+ {{- "Cutting Knowledge Date: December 2023\n" }}
33
+ {{- "Today Date: " + date_string + "\n\n" }}
34
+ {%- if tools is not none and not tools_in_user_message %}
35
+ {{- "You have access to the following functions. To call a function, please respond with JSON for a function call." }}
36
+ {{- 'Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}.' }}
37
+ {{- "Do not use variables.\n\n" }}
38
+ {%- for t in tools %}
39
+ {{- t | tojson(indent=4) }}
40
+ {{- "\n\n" }}
41
+ {%- endfor %}
42
+ {%- endif %}
43
+ {{- system_message }}
44
+ {{- "<|eot_id|>" }}
45
+
46
+ {#- Custom tools are passed in a user message with some extra guidance #}
47
+ {%- if tools_in_user_message and not tools is none %}
48
+ {#- Extract the first user message so we can plug it in here #}
49
+ {%- if messages | length != 0 %}
50
+ {%- set first_user_message = messages[0]['content']|trim %}
51
+ {%- set messages = messages[1:] %}
52
+ {%- else %}
53
+ {{- raise_exception("Cannot put tools in the first user message when there's no first user message!") }}
54
+ {%- endif %}
55
+ {{- '<|start_header_id|>user<|end_header_id|>\n\n' -}}
56
+ {{- "Given the following functions, please respond with a JSON for a function call " }}
57
+ {{- "with its proper arguments that best answers the given prompt.\n\n" }}
58
+ {{- 'Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}.' }}
59
+ {{- "Do not use variables.\n\n" }}
60
+ {%- for t in tools %}
61
+ {{- t | tojson(indent=4) }}
62
+ {{- "\n\n" }}
63
+ {%- endfor %}
64
+ {{- first_user_message + "<|eot_id|>"}}
65
+ {%- endif %}
66
+
67
+ {%- for message in messages %}
68
+ {%- if not (message.role == 'ipython' or message.role == 'tool' or 'tool_calls' in message) %}
69
+ {{- '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n'+ message['content'] | trim + '<|eot_id|>' }}
70
+ {%- elif 'tool_calls' in message %}
71
+ {%- if not message.tool_calls|length == 1 %}
72
+ {{- raise_exception("This model only supports single tool-calls at once!") }}
73
+ {%- endif %}
74
+ {%- set tool_call = message.tool_calls[0].function %}
75
+ {{- '<|start_header_id|>assistant<|end_header_id|>\n\n' -}}
76
+ {{- '{"name": "' + tool_call.name + '", ' }}
77
+ {{- '"parameters": ' }}
78
+ {{- tool_call.arguments | tojson }}
79
+ {{- "}" }}
80
+ {{- "<|eot_id|>" }}
81
+ {%- elif message.role == "tool" or message.role == "ipython" %}
82
+ {{- "<|start_header_id|>ipython<|end_header_id|>\n\n" }}
83
+ {%- if message.content is mapping or message.content is iterable %}
84
+ {{- message.content | tojson }}
85
+ {%- else %}
86
+ {{- message.content }}
87
+ {%- endif %}
88
+ {{- "<|eot_id|>" }}
89
+ {%- endif %}
90
+ {%- endfor %}
91
+ {%- if add_generation_prompt %}
92
+ {{- '<|start_header_id|>assistant<|end_header_id|>\n\n' }}
93
+ {%- endif %}
llama.cpp/models/templates/meta-llama-Llama-3.3-70B-Instruct.jinja ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {{- bos_token }}
2
+ {%- if custom_tools is defined %}
3
+ {%- set tools = custom_tools %}
4
+ {%- endif %}
5
+ {%- if not tools_in_user_message is defined %}
6
+ {%- set tools_in_user_message = true %}
7
+ {%- endif %}
8
+ {%- if not date_string is defined %}
9
+ {%- set date_string = "26 Jul 2024" %}
10
+ {%- endif %}
11
+ {%- if not tools is defined %}
12
+ {%- set tools = none %}
13
+ {%- endif %}
14
+
15
+ {#- This block extracts the system message, so we can slot it into the right place. #}
16
+ {%- if messages[0]['role'] == 'system' %}
17
+ {%- set system_message = messages[0]['content']|trim %}
18
+ {%- set messages = messages[1:] %}
19
+ {%- else %}
20
+ {%- set system_message = "" %}
21
+ {%- endif %}
22
+
23
+ {#- System message + builtin tools #}
24
+ {{- "<|start_header_id|>system<|end_header_id|>\n\n" }}
25
+ {%- if builtin_tools is defined or tools is not none %}
26
+ {{- "Environment: ipython\n" }}
27
+ {%- endif %}
28
+ {%- if builtin_tools is defined %}
29
+ {{- "Tools: " + builtin_tools | reject('equalto', 'code_interpreter') | join(", ") + "\n\n"}}
30
+ {%- endif %}
31
+ {{- "Cutting Knowledge Date: December 2023\n" }}
32
+ {{- "Today Date: " + date_string + "\n\n" }}
33
+ {%- if tools is not none and not tools_in_user_message %}
34
+ {{- "You have access to the following functions. To call a function, please respond with JSON for a function call." }}
35
+ {{- 'Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}.' }}
36
+ {{- "Do not use variables.\n\n" }}
37
+ {%- for t in tools %}
38
+ {{- t | tojson(indent=4) }}
39
+ {{- "\n\n" }}
40
+ {%- endfor %}
41
+ {%- endif %}
42
+ {{- system_message }}
43
+ {{- "<|eot_id|>" }}
44
+
45
+ {#- Custom tools are passed in a user message with some extra guidance #}
46
+ {%- if tools_in_user_message and not tools is none %}
47
+ {#- Extract the first user message so we can plug it in here #}
48
+ {%- if messages | length != 0 %}
49
+ {%- set first_user_message = messages[0]['content']|trim %}
50
+ {%- set messages = messages[1:] %}
51
+ {%- else %}
52
+ {{- raise_exception("Cannot put tools in the first user message when there's no first user message!") }}
53
+ {%- endif %}
54
+ {{- '<|start_header_id|>user<|end_header_id|>\n\n' -}}
55
+ {{- "Given the following functions, please respond with a JSON for a function call " }}
56
+ {{- "with its proper arguments that best answers the given prompt.\n\n" }}
57
+ {{- 'Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}.' }}
58
+ {{- "Do not use variables.\n\n" }}
59
+ {%- for t in tools %}
60
+ {{- t | tojson(indent=4) }}
61
+ {{- "\n\n" }}
62
+ {%- endfor %}
63
+ {{- first_user_message + "<|eot_id|>"}}
64
+ {%- endif %}
65
+
66
+ {%- for message in messages %}
67
+ {%- if not (message.role == 'ipython' or message.role == 'tool' or 'tool_calls' in message) %}
68
+ {{- '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n'+ message['content'] | trim + '<|eot_id|>' }}
69
+ {%- elif 'tool_calls' in message %}
70
+ {%- if not message.tool_calls|length == 1 %}
71
+ {{- raise_exception("This model only supports single tool-calls at once!") }}
72
+ {%- endif %}
73
+ {%- set tool_call = message.tool_calls[0].function %}
74
+ {%- if builtin_tools is defined and tool_call.name in builtin_tools %}
75
+ {{- '<|start_header_id|>assistant<|end_header_id|>\n\n' -}}
76
+ {{- "<|python_tag|>" + tool_call.name + ".call(" }}
77
+ {%- for arg_name, arg_val in tool_call.arguments | items %}
78
+ {{- arg_name + '="' + arg_val + '"' }}
79
+ {%- if not loop.last %}
80
+ {{- ", " }}
81
+ {%- endif %}
82
+ {%- endfor %}
83
+ {{- ")" }}
84
+ {%- else %}
85
+ {{- '<|start_header_id|>assistant<|end_header_id|>\n\n' -}}
86
+ {{- '{"name": "' + tool_call.name + '", ' }}
87
+ {{- '"parameters": ' }}
88
+ {{- tool_call.arguments | tojson }}
89
+ {{- "}" }}
90
+ {%- endif %}
91
+ {%- if builtin_tools is defined %}
92
+ {#- This means we're in ipython mode #}
93
+ {{- "<|eom_id|>" }}
94
+ {%- else %}
95
+ {{- "<|eot_id|>" }}
96
+ {%- endif %}
97
+ {%- elif message.role == "tool" or message.role == "ipython" %}
98
+ {{- "<|start_header_id|>ipython<|end_header_id|>\n\n" }}
99
+ {%- if message.content is mapping or message.content is iterable %}
100
+ {{- message.content | tojson }}
101
+ {%- else %}
102
+ {{- message.content }}
103
+ {%- endif %}
104
+ {{- "<|eot_id|>" }}
105
+ {%- endif %}
106
+ {%- endfor %}
107
+ {%- if add_generation_prompt %}
108
+ {{- '<|start_header_id|>assistant<|end_header_id|>\n\n' }}
109
+ {%- endif %}
llama.cpp/models/templates/microsoft-Phi-3.5-mini-instruct.jinja ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {% for message in messages %}{% if message['role'] == 'system' and message['content'] %}{{'<|system|>
2
+ ' + message['content'] + '<|end|>
3
+ '}}{% elif message['role'] == 'user' %}{{'<|user|>
4
+ ' + message['content'] + '<|end|>
5
+ '}}{% elif message['role'] == 'assistant' %}{{'<|assistant|>
6
+ ' + message['content'] + '<|end|>
7
+ '}}{% endif %}{% endfor %}{% if add_generation_prompt %}{{ '<|assistant|>
8
+ ' }}{% else %}{{ eos_token }}{% endif %}
llama.cpp/pocs/vdot/CMakeLists.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ set(TARGET llama-vdot)
2
+ add_executable(${TARGET} vdot.cpp)
3
+ target_link_libraries(${TARGET} PRIVATE common llama ${CMAKE_THREAD_LIBS_INIT})
4
+ target_compile_features(${TARGET} PRIVATE cxx_std_17)
5
+
6
+ set(TARGET llama-q8dot)
7
+ add_executable(${TARGET} q8dot.cpp)
8
+ target_link_libraries(${TARGET} PRIVATE common llama ${CMAKE_THREAD_LIBS_INIT})
9
+ target_compile_features(${TARGET} PRIVATE cxx_std_17)
llama.cpp/pocs/vdot/q8dot.cpp ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <cstdio>
2
+ #include <type_traits>
3
+ #include <vector>
4
+ #include <random>
5
+ #include <chrono>
6
+ #include <cstdlib>
7
+ #include <cmath>
8
+ #include <cassert>
9
+ #include <cstring>
10
+ #include <array>
11
+ #include <type_traits>
12
+
13
+ #include <ggml.h>
14
+ #include <ggml-cpu.h>
15
+
16
+ constexpr int kVecSize = 1 << 16;
17
+
18
+ // Copy-pasted from ggml.c
19
+ #define QK4_0 32
20
+ typedef struct {
21
+ float d; // delta
22
+ uint8_t qs[QK4_0 / 2]; // nibbles / quants
23
+ } block_q4_0;
24
+ static_assert(sizeof(block_q4_0) == sizeof(float) + QK4_0 / 2, "wrong q4_0 block size/padding");
25
+
26
+ #define QK4_1 32
27
+ typedef struct {
28
+ float d; // delta
29
+ float m; // min
30
+ uint8_t qs[QK4_1 / 2]; // nibbles / quants
31
+ } block_q4_1;
32
+ static_assert(sizeof(block_q4_1) == sizeof(float) * 2 + QK4_1 / 2, "wrong q4_1 block size/padding");
33
+
34
+ // Copy-pasted from ggml.c
35
+ #define QK8_0 32
36
+ typedef struct {
37
+ float d; // delta
38
+ float s; // d * sum(qs[i])
39
+ int8_t qs[QK8_0]; // quants
40
+ } block_q8_0;
41
+ static_assert(sizeof(block_q8_0) == 2*sizeof(float) + QK8_0, "wrong q8_0 block size/padding");
42
+
43
+ static_assert(QK4_1 == QK8_0, "QK4_1 and QK8_0 must be the same");
44
+ static_assert(QK4_0 == QK8_0, "QK4_0 and QK8_0 must be the same");
45
+
46
+ template <typename T>
47
+ static void fillQ4blocks(std::vector<T>& blocks, std::mt19937& rndm) {
48
+ for (auto& b : blocks) {
49
+ b.d = 1;
50
+ for (int i=0; i<QK4_1/2; ++i) {
51
+ uint8_t v1 = rndm() >> 28;
52
+ uint8_t v2 = rndm() >> 28;
53
+ b.qs[i] = v1 | (v2 << 4);
54
+ }
55
+ }
56
+ }
57
+
58
+ static void fillQ80blocks(std::vector<block_q8_0>& blocks, std::mt19937& rndm) {
59
+ for (auto& b : blocks) {
60
+ b.d = 1;
61
+ int sum = 0;
62
+ for (int i=0; i<QK8_0; ++i) {
63
+ b.qs[i] = (rndm() >> 24) - 128;
64
+ sum += b.qs[i];
65
+ }
66
+ b.s = b.d * sum;
67
+ }
68
+ }
69
+
70
+ static float simpleDot(const block_q4_0& x, const block_q8_0& y) {
71
+ int s1 = 0; //, s2 = 0;
72
+ for (int i=0; i<QK4_1/2; i+=2) {
73
+ int v1 = x.qs[i+0] & 0xf;
74
+ int v2 = x.qs[i+0] >> 4;
75
+ int v3 = x.qs[i+1] & 0xf;
76
+ int v4 = x.qs[i+1] >> 4;
77
+ int j = 2*i;
78
+ s1 += v1*y.qs[j] + v2*y.qs[j+1] + v3*y.qs[j+2] + v4*y.qs[j+3];
79
+ //s2 += y.qs[j] + y.qs[j+1] + y.qs[j+2] + y.qs[j+3];
80
+ }
81
+ return y.d * x.d * s1 - 8 * x.d * y.s;
82
+ //return y.d * x.d * (s1 - 8 * s2);
83
+ }
84
+
85
+ static float simpleDot(const block_q4_1& x, const block_q8_0& y) {
86
+ int s1 = 0; //, s2 = 0;
87
+ for (int i=0; i<QK4_1/2; i+=2) {
88
+ int v1 = x.qs[i+0] & 0xf;
89
+ int v2 = x.qs[i+0] >> 4;
90
+ int v3 = x.qs[i+1] & 0xf;
91
+ int v4 = x.qs[i+1] >> 4;
92
+ int j = 2*i;
93
+ s1 += v1*y.qs[j] + v2*y.qs[j+1] + v3*y.qs[j+2] + v4*y.qs[j+3];
94
+ //s2 += y.qs[j] + y.qs[j+1] + y.qs[j+2] + y.qs[j+3];
95
+ }
96
+ return y.d * x.d * s1 + y.s * x.m;
97
+ //return y.d * (x.d * s1 + x.m * s2);
98
+ }
99
+
100
+ struct Stat {
101
+ double sum = 0, sumt = 0, sumt2 = 0, maxt = 0;
102
+ int nloop = 0;
103
+ void addResult(double s, double t) {
104
+ sum += s;
105
+ sumt += t; sumt2 += t*t; maxt = std::max(maxt, t);
106
+ ++nloop;
107
+ }
108
+ void reportResult(const char* title) const {
109
+ if (nloop < 1) {
110
+ printf("%s(%s): no result\n",__func__,title);
111
+ return;
112
+ }
113
+ printf("============ %s\n",title);
114
+ printf("<dot> = %g\n",sum/nloop);
115
+ auto t = sumt/nloop, dt = sumt2/nloop - t*t;
116
+ if (dt > 0) dt = sqrt(dt);
117
+ printf("<time> = %g +/- %g us. Max. time = %g us.\n",t,dt,maxt);
118
+ }
119
+ };
120
+
121
+
122
+ int main(int argc, char** argv) {
123
+
124
+ int nloop = argc > 1 ? atoi(argv[1]) : 10;
125
+ int type = argc > 2 ? atoi(argv[2]) : 1;
126
+
127
+ std::mt19937 rndm(1234);
128
+
129
+ std::vector<block_q4_1> x41;
130
+ std::vector<block_q4_0> x40;
131
+ std::vector<block_q8_0> y(kVecSize);
132
+ if (type == 0) x40.resize(kVecSize);
133
+ else {
134
+ x41.resize(kVecSize);
135
+ for (auto& b : x41) b.m = 1;
136
+ }
137
+
138
+ auto ggml_type = type == 0 ? GGML_TYPE_Q4_0 : GGML_TYPE_Q4_1;
139
+
140
+ const auto * funcs = ggml_get_type_traits_cpu(ggml_type);
141
+
142
+ Stat simple, ggml;
143
+
144
+ for (int iloop=0; iloop<nloop; ++iloop) {
145
+
146
+ if (type == 0) fillQ4blocks(x40, rndm);
147
+ else fillQ4blocks(x41, rndm);
148
+ fillQ80blocks(y, rndm);
149
+
150
+ auto t1 = std::chrono::high_resolution_clock::now();
151
+ double s = 0;
152
+ if (type == 0) for (int i=0; i<kVecSize; ++i) s += simpleDot(x40[i], y[i]);
153
+ else for (int i=0; i<kVecSize; ++i) s += simpleDot(x41[i], y[i]);
154
+ auto t2 = std::chrono::high_resolution_clock::now();
155
+ auto t = 1e-3*std::chrono::duration_cast<std::chrono::nanoseconds>(t2-t1).count();
156
+ if (iloop > 3) simple.addResult(s, t);
157
+
158
+ t1 = std::chrono::high_resolution_clock::now();
159
+ float fs;
160
+ if (type == 0) funcs->vec_dot(kVecSize * QK4_1, &fs, 0, x40.data(), 0, y.data(), 0, 1);
161
+ else funcs->vec_dot(kVecSize * QK4_1, &fs, 0, x41.data(), 0, y.data(), 0, 1);
162
+ t2 = std::chrono::high_resolution_clock::now();
163
+ t = 1e-3*std::chrono::duration_cast<std::chrono::nanoseconds>(t2-t1).count();
164
+ if (iloop > 3) ggml.addResult(fs, t);
165
+
166
+ }
167
+
168
+ // Report the time (and the average of the dot products so the compiler does not come up with the idea
169
+ // of optimizing away the function calls after figuring that the result is not used).
170
+ simple.reportResult("Simple");
171
+ ggml.reportResult("ggml");
172
+ return 0;
173
+ }
llama.cpp/pocs/vdot/vdot.cpp ADDED
@@ -0,0 +1,311 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <cstdio>
2
+ #include <vector>
3
+ #include <random>
4
+ #include <chrono>
5
+ #include <cstdlib>
6
+ #include <cmath>
7
+ #include <cassert>
8
+ #include <cstring>
9
+ #include <array>
10
+
11
+ #include <ggml.h>
12
+ #include <ggml-cpu.h>
13
+
14
+ #if defined(_MSC_VER)
15
+ #pragma warning(disable: 4244 4267) // possible loss of data
16
+ #endif
17
+
18
+ constexpr int kVecSize = 1 << 18;
19
+
20
+ static float drawFromGaussianPdf(std::mt19937& rndm) {
21
+ constexpr double kScale = 1./(1. + std::mt19937::max());
22
+ constexpr double kTwoPiTimesScale = 6.28318530717958647692*kScale;
23
+ static float lastX;
24
+ static bool haveX = false;
25
+ if (haveX) { haveX = false; return lastX; }
26
+ auto r = sqrt(-2*log(1 - kScale*rndm()));
27
+ auto phi = kTwoPiTimesScale * rndm();
28
+ lastX = r*sin(phi);
29
+ haveX = true;
30
+ return r*cos(phi);
31
+ }
32
+
33
+ static void fillRandomGaussianFloats(std::vector<float>& values, std::mt19937& rndm, float mean = 0) {
34
+ for (auto& v : values) v = mean + drawFromGaussianPdf(rndm);
35
+ }
36
+
37
+ // Copy-pasted from ggml.c
38
+ #define QK4_0 32
39
+ typedef struct {
40
+ float d; // delta
41
+ uint8_t qs[QK4_0 / 2]; // nibbles / quants
42
+ } block_q4_0;
43
+ static_assert(sizeof(block_q4_0) == sizeof(float) + QK4_0 / 2, "wrong q4_0 block size/padding");
44
+
45
+ #define QK4_1 32
46
+ typedef struct {
47
+ float d; // delta
48
+ float m; // min
49
+ uint8_t qs[QK4_1 / 2]; // nibbles / quants
50
+ } block_q4_1;
51
+ static_assert(sizeof(block_q4_1) == sizeof(float) * 2 + QK4_1 / 2, "wrong q4_1 block size/padding");
52
+
53
+ // Copy-pasted from ggml.c
54
+ #define QK8_0 32
55
+ typedef struct {
56
+ float d; // delta
57
+ int8_t qs[QK8_0]; // quants
58
+ } block_q8_0;
59
+ static_assert(sizeof(block_q8_0) == sizeof(float) + QK8_0, "wrong q8_0 block size/padding");
60
+
61
+ // "Scalar" dot product between the quantized vector x and float vector y
62
+ inline double dot(int n, const block_q4_0* x, const float* y) {
63
+ const static float kValues[16] = {-8.f, -7.f, -6.f, -5.f, -4.f, -3.f, -2.f, -1.f, 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f};
64
+ constexpr uint32_t kMask1 = 0x0f0f0f0f;
65
+ uint32_t u1, u2;
66
+ auto q1 = (const uint8_t*)&u1;
67
+ auto q2 = (const uint8_t*)&u2;
68
+ double sum = 0;
69
+ for (int i=0; i<n; ++i) {
70
+ float d = x->d;
71
+ auto u = (const uint32_t*)x->qs;
72
+ float s = 0;
73
+ for (int k=0; k<4; ++k) {
74
+ u1 = u[k] & kMask1;
75
+ u2 = (u[k] >> 4) & kMask1;
76
+ s += y[0]*kValues[q1[0]] + y[1]*kValues[q2[0]] +
77
+ y[2]*kValues[q1[1]] + y[3]*kValues[q2[1]] +
78
+ y[4]*kValues[q1[2]] + y[5]*kValues[q2[2]] +
79
+ y[6]*kValues[q1[3]] + y[7]*kValues[q2[3]];
80
+ y += 8;
81
+ }
82
+ sum += s*d;
83
+ ++x;
84
+ }
85
+ return sum;
86
+ }
87
+ // Alternative version of the above. Faster on my Mac (~45 us vs ~55 us per dot product),
88
+ // but about the same on X86_64 (Ryzen 7950X CPU).
89
+ inline double dot3(int n, const block_q4_0* x, const float* y) {
90
+ const static std::pair<float,float> kValues[256] = {
91
+ {-8.f, -8.f}, {-7.f, -8.f}, {-6.f, -8.f}, {-5.f, -8.f}, {-4.f, -8.f}, {-3.f, -8.f}, {-2.f, -8.f}, {-1.f, -8.f},
92
+ { 0.f, -8.f}, { 1.f, -8.f}, { 2.f, -8.f}, { 3.f, -8.f}, { 4.f, -8.f}, { 5.f, -8.f}, { 6.f, -8.f}, { 7.f, -8.f},
93
+ {-8.f, -7.f}, {-7.f, -7.f}, {-6.f, -7.f}, {-5.f, -7.f}, {-4.f, -7.f}, {-3.f, -7.f}, {-2.f, -7.f}, {-1.f, -7.f},
94
+ { 0.f, -7.f}, { 1.f, -7.f}, { 2.f, -7.f}, { 3.f, -7.f}, { 4.f, -7.f}, { 5.f, -7.f}, { 6.f, -7.f}, { 7.f, -7.f},
95
+ {-8.f, -6.f}, {-7.f, -6.f}, {-6.f, -6.f}, {-5.f, -6.f}, {-4.f, -6.f}, {-3.f, -6.f}, {-2.f, -6.f}, {-1.f, -6.f},
96
+ { 0.f, -6.f}, { 1.f, -6.f}, { 2.f, -6.f}, { 3.f, -6.f}, { 4.f, -6.f}, { 5.f, -6.f}, { 6.f, -6.f}, { 7.f, -6.f},
97
+ {-8.f, -5.f}, {-7.f, -5.f}, {-6.f, -5.f}, {-5.f, -5.f}, {-4.f, -5.f}, {-3.f, -5.f}, {-2.f, -5.f}, {-1.f, -5.f},
98
+ { 0.f, -5.f}, { 1.f, -5.f}, { 2.f, -5.f}, { 3.f, -5.f}, { 4.f, -5.f}, { 5.f, -5.f}, { 6.f, -5.f}, { 7.f, -5.f},
99
+ {-8.f, -4.f}, {-7.f, -4.f}, {-6.f, -4.f}, {-5.f, -4.f}, {-4.f, -4.f}, {-3.f, -4.f}, {-2.f, -4.f}, {-1.f, -4.f},
100
+ { 0.f, -4.f}, { 1.f, -4.f}, { 2.f, -4.f}, { 3.f, -4.f}, { 4.f, -4.f}, { 5.f, -4.f}, { 6.f, -4.f}, { 7.f, -4.f},
101
+ {-8.f, -3.f}, {-7.f, -3.f}, {-6.f, -3.f}, {-5.f, -3.f}, {-4.f, -3.f}, {-3.f, -3.f}, {-2.f, -3.f}, {-1.f, -3.f},
102
+ { 0.f, -3.f}, { 1.f, -3.f}, { 2.f, -3.f}, { 3.f, -3.f}, { 4.f, -3.f}, { 5.f, -3.f}, { 6.f, -3.f}, { 7.f, -3.f},
103
+ {-8.f, -2.f}, {-7.f, -2.f}, {-6.f, -2.f}, {-5.f, -2.f}, {-4.f, -2.f}, {-3.f, -2.f}, {-2.f, -2.f}, {-1.f, -2.f},
104
+ { 0.f, -2.f}, { 1.f, -2.f}, { 2.f, -2.f}, { 3.f, -2.f}, { 4.f, -2.f}, { 5.f, -2.f}, { 6.f, -2.f}, { 7.f, -2.f},
105
+ {-8.f, -1.f}, {-7.f, -1.f}, {-6.f, -1.f}, {-5.f, -1.f}, {-4.f, -1.f}, {-3.f, -1.f}, {-2.f, -1.f}, {-1.f, -1.f},
106
+ { 0.f, -1.f}, { 1.f, -1.f}, { 2.f, -1.f}, { 3.f, -1.f}, { 4.f, -1.f}, { 5.f, -1.f}, { 6.f, -1.f}, { 7.f, -1.f},
107
+ {-8.f, 0.f}, {-7.f, 0.f}, {-6.f, 0.f}, {-5.f, 0.f}, {-4.f, 0.f}, {-3.f, 0.f}, {-2.f, 0.f}, {-1.f, 0.f},
108
+ { 0.f, 0.f}, { 1.f, 0.f}, { 2.f, 0.f}, { 3.f, 0.f}, { 4.f, 0.f}, { 5.f, 0.f}, { 6.f, 0.f}, { 7.f, 0.f},
109
+ {-8.f, 1.f}, {-7.f, 1.f}, {-6.f, 1.f}, {-5.f, 1.f}, {-4.f, 1.f}, {-3.f, 1.f}, {-2.f, 1.f}, {-1.f, 1.f},
110
+ { 0.f, 1.f}, { 1.f, 1.f}, { 2.f, 1.f}, { 3.f, 1.f}, { 4.f, 1.f}, { 5.f, 1.f}, { 6.f, 1.f}, { 7.f, 1.f},
111
+ {-8.f, 2.f}, {-7.f, 2.f}, {-6.f, 2.f}, {-5.f, 2.f}, {-4.f, 2.f}, {-3.f, 2.f}, {-2.f, 2.f}, {-1.f, 2.f},
112
+ { 0.f, 2.f}, { 1.f, 2.f}, { 2.f, 2.f}, { 3.f, 2.f}, { 4.f, 2.f}, { 5.f, 2.f}, { 6.f, 2.f}, { 7.f, 2.f},
113
+ {-8.f, 3.f}, {-7.f, 3.f}, {-6.f, 3.f}, {-5.f, 3.f}, {-4.f, 3.f}, {-3.f, 3.f}, {-2.f, 3.f}, {-1.f, 3.f},
114
+ { 0.f, 3.f}, { 1.f, 3.f}, { 2.f, 3.f}, { 3.f, 3.f}, { 4.f, 3.f}, { 5.f, 3.f}, { 6.f, 3.f}, { 7.f, 3.f},
115
+ {-8.f, 4.f}, {-7.f, 4.f}, {-6.f, 4.f}, {-5.f, 4.f}, {-4.f, 4.f}, {-3.f, 4.f}, {-2.f, 4.f}, {-1.f, 4.f},
116
+ { 0.f, 4.f}, { 1.f, 4.f}, { 2.f, 4.f}, { 3.f, 4.f}, { 4.f, 4.f}, { 5.f, 4.f}, { 6.f, 4.f}, { 7.f, 4.f},
117
+ {-8.f, 5.f}, {-7.f, 5.f}, {-6.f, 5.f}, {-5.f, 5.f}, {-4.f, 5.f}, {-3.f, 5.f}, {-2.f, 5.f}, {-1.f, 5.f},
118
+ { 0.f, 5.f}, { 1.f, 5.f}, { 2.f, 5.f}, { 3.f, 5.f}, { 4.f, 5.f}, { 5.f, 5.f}, { 6.f, 5.f}, { 7.f, 5.f},
119
+ {-8.f, 6.f}, {-7.f, 6.f}, {-6.f, 6.f}, {-5.f, 6.f}, {-4.f, 6.f}, {-3.f, 6.f}, {-2.f, 6.f}, {-1.f, 6.f},
120
+ { 0.f, 6.f}, { 1.f, 6.f}, { 2.f, 6.f}, { 3.f, 6.f}, { 4.f, 6.f}, { 5.f, 6.f}, { 6.f, 6.f}, { 7.f, 6.f},
121
+ {-8.f, 7.f}, {-7.f, 7.f}, {-6.f, 7.f}, {-5.f, 7.f}, {-4.f, 7.f}, {-3.f, 7.f}, {-2.f, 7.f}, {-1.f, 7.f},
122
+ { 0.f, 7.f}, { 1.f, 7.f}, { 2.f, 7.f}, { 3.f, 7.f}, { 4.f, 7.f}, { 5.f, 7.f}, { 6.f, 7.f}, { 7.f, 7.f}
123
+ };
124
+ double sum = 0;
125
+ for (int i=0; i<n; ++i) {
126
+ float d = x->d;
127
+ auto q = x->qs;
128
+ float s = 0;
129
+ for (int k=0; k<4; ++k) {
130
+ s += y[0]*kValues[q[0]].first + y[1]*kValues[q[0]].second +
131
+ y[2]*kValues[q[1]].first + y[3]*kValues[q[1]].second +
132
+ y[4]*kValues[q[2]].first + y[5]*kValues[q[2]].second +
133
+ y[6]*kValues[q[3]].first + y[7]*kValues[q[3]].second;
134
+ y += 8; q += 4;
135
+ }
136
+ sum += s*d;
137
+ ++x;
138
+ }
139
+ return sum;
140
+ }
141
+
142
+ inline double dot41(int n, const block_q4_1* x, const float* y) {
143
+ const static float kValues[16] = {0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f, 11.f, 12.f, 13.f, 14.f, 15.f};
144
+ constexpr uint32_t kMask1 = 0x0f0f0f0f;
145
+ uint32_t u1, u2;
146
+ auto q1 = (const uint8_t*)&u1;
147
+ auto q2 = (const uint8_t*)&u2;
148
+ double sum = 0;
149
+ for (int i=0; i<n; ++i) {
150
+ auto u = (const uint32_t*)x->qs;
151
+ float s = 0, s1 = 0;
152
+ for (int k=0; k<4; ++k) {
153
+ u1 = u[k] & kMask1;
154
+ u2 = (u[k] >> 4) & kMask1;
155
+ s += y[0]*kValues[q1[0]] + y[1]*kValues[q2[0]] +
156
+ y[2]*kValues[q1[1]] + y[3]*kValues[q2[1]] +
157
+ y[4]*kValues[q1[2]] + y[5]*kValues[q2[2]] +
158
+ y[6]*kValues[q1[3]] + y[7]*kValues[q2[3]];
159
+ s1 += y[0] + y[1] + y[2] + y[3] + y[4] + y[5] + y[6] + y[7];
160
+ y += 8;
161
+ }
162
+ sum += s*x->d + s1*x->m;
163
+ ++x;
164
+ }
165
+ return sum;
166
+ }
167
+
168
+ // Copy-pasted from ggml.c
169
+ static void quantize_row_q8_0_reference(const float *x, block_q8_0 *y, int k) {
170
+ assert(k % QK8_0 == 0);
171
+ const int nb = k / QK8_0;
172
+
173
+ for (int i = 0; i < nb; i++) {
174
+ float amax = 0.0f; // absolute max
175
+
176
+ for (int l = 0; l < QK8_0; l++) {
177
+ const float v = x[i*QK8_0 + l];
178
+ amax = std::max(amax, fabsf(v));
179
+ }
180
+
181
+ const float d = amax / ((1 << 7) - 1);
182
+ const float id = d ? 1.0f/d : 0.0f;
183
+
184
+ y[i].d = d;
185
+
186
+ for (int l = 0; l < QK8_0; ++l) {
187
+ const float v = x[i*QK8_0 + l]*id;
188
+ y[i].qs[l] = roundf(v);
189
+ }
190
+ }
191
+ }
192
+
193
+ // Copy-pasted from ggml.c
194
+ static void dot_q4_q8(const int n, float* s, const void* vx, const void* vy) {
195
+ const int nb = n / QK8_0;
196
+ const block_q4_0* x = (const block_q4_0*)vx;
197
+ const block_q8_0* y = (const block_q8_0*)vy;
198
+ float sumf = 0;
199
+ for (int i = 0; i < nb; i++) {
200
+ const float d0 = x[i].d;
201
+ const float d1 = y[i].d;
202
+
203
+ const uint8_t * p0 = x[i].qs;
204
+ const int8_t * p1 = y[i].qs;
205
+
206
+ int sumi = 0;
207
+ for (int j = 0; j < QK8_0/2; j++) {
208
+ const uint8_t v0 = p0[j];
209
+
210
+ const int i0 = (int8_t) (v0 & 0xf) - 8;
211
+ const int i1 = (int8_t) (v0 >> 4) - 8;
212
+
213
+ const int i2 = p1[2*j + 0];
214
+ const int i3 = p1[2*j + 1];
215
+
216
+ sumi += i0*i2 + i1*i3;
217
+ }
218
+ sumf += d0*d1*sumi;
219
+ }
220
+ *s = sumf;
221
+ }
222
+
223
+ int main(int argc, char** argv) {
224
+
225
+ int nloop = argc > 1 ? atoi(argv[1]) : 10;
226
+ bool scalar = argc > 2 ? atoi(argv[2]) : false;
227
+ bool useQ4_1 = argc > 3 ? atoi(argv[3]) : false;
228
+
229
+ if (scalar && useQ4_1) {
230
+ printf("It is not possible to use Q4_1 quantization and scalar implementations\n");
231
+ return 1;
232
+ }
233
+
234
+ std::mt19937 rndm(1234);
235
+
236
+ std::vector<float> x1(kVecSize), y1(kVecSize);
237
+ int n4 = useQ4_1 ? kVecSize / QK4_1 : kVecSize / QK4_0; n4 = 64*((n4 + 63)/64);
238
+ int n8 = kVecSize / QK8_0; n8 = 64*((n8 + 63)/64);
239
+
240
+ const auto * funcs_cpu = ggml_get_type_traits_cpu(useQ4_1 ? GGML_TYPE_Q4_1 : GGML_TYPE_Q4_0);
241
+
242
+ std::vector<block_q4_0> q40;
243
+ std::vector<block_q4_1> q41;
244
+ if (useQ4_1) q41.resize(n4);
245
+ else q40.resize(n4);
246
+ std::vector<block_q8_0> q8(n8);
247
+ double sumt = 0, sumt2 = 0, maxt = 0;
248
+ double sumqt = 0, sumqt2 = 0, maxqt = 0;
249
+ double sum = 0, sumq = 0, exactSum = 0;
250
+ for (int iloop=0; iloop<nloop; ++iloop) {
251
+
252
+ // Fill vector x with random numbers
253
+ fillRandomGaussianFloats(x1, rndm);
254
+
255
+ // Fill vector y with random numbers
256
+ fillRandomGaussianFloats(y1, rndm);
257
+
258
+ // Compute the exact dot product
259
+ for (int k=0; k<kVecSize; ++k) exactSum += x1[k]*y1[k];
260
+
261
+ // quantize x.
262
+ // Note, we do not include this in the timing as in practical application
263
+ // we already have the quantized model weights.
264
+ if (useQ4_1) {
265
+ funcs_cpu->from_float(x1.data(), q41.data(), kVecSize);
266
+ } else {
267
+ funcs_cpu->from_float(x1.data(), q40.data(), kVecSize);
268
+ }
269
+
270
+ // Now measure time the dot product needs using the "scalar" version above
271
+ auto t1 = std::chrono::high_resolution_clock::now();
272
+ if (useQ4_1) sum += dot41(kVecSize / QK4_1, q41.data(), y1.data());
273
+ else sum += dot(kVecSize / QK4_0, q40.data(), y1.data());
274
+ auto t2 = std::chrono::high_resolution_clock::now();
275
+ auto t = 1e-3*std::chrono::duration_cast<std::chrono::nanoseconds>(t2-t1).count();
276
+ sumt += t; sumt2 += t*t; maxt = std::max(maxt, t);
277
+
278
+ // And now measure the time needed to quantize y and perform the dot product with the quantized y
279
+ t1 = std::chrono::high_resolution_clock::now();
280
+ float result;
281
+ if (scalar) {
282
+ quantize_row_q8_0_reference(y1.data(), q8.data(), kVecSize);
283
+ dot_q4_q8(kVecSize, &result, q40.data(), q8.data());
284
+ }
285
+ else {
286
+ const auto * vdot = ggml_get_type_traits_cpu(funcs_cpu->vec_dot_type);
287
+ vdot->from_float(y1.data(), q8.data(), kVecSize);
288
+ if (useQ4_1) funcs_cpu->vec_dot(kVecSize, &result, 0, q41.data(), 0, q8.data(), 0, 1);
289
+ else funcs_cpu->vec_dot(kVecSize, &result, 0, q40.data(), 0, q8.data(), 0, 1);
290
+ }
291
+ sumq += result;
292
+ t2 = std::chrono::high_resolution_clock::now();
293
+ t = 1e-3*std::chrono::duration_cast<std::chrono::nanoseconds>(t2-t1).count();
294
+ sumqt += t; sumqt2 += t*t; maxqt = std::max(maxqt, t);
295
+
296
+ }
297
+
298
+ // Report the time (and the average of the dot products so the compiler does not come up with the idea
299
+ // of optimizing away the function calls after figuring that the result is not used).
300
+ sum /= nloop; sumq /= nloop;
301
+ exactSum /= nloop;
302
+ printf("Exact result: <dot> = %g\n",exactSum);
303
+ printf("<dot> = %g, %g\n",sum,sumq);
304
+ sumt /= nloop; sumt2 /= nloop; sumt2 -= sumt*sumt;
305
+ if (sumt2 > 0) sumt2 = sqrt(sumt2);
306
+ printf("time = %g +/- %g us. maxt = %g us\n",sumt,sumt2,maxt);
307
+ sumqt /= nloop; sumqt2 /= nloop; sumqt2 -= sumqt*sumqt;
308
+ if (sumqt2 > 0) sumqt2 = sqrt(sumqt2);
309
+ printf("timeq = %g +/- %g us. maxt = %g us\n",sumqt,sumqt2,maxqt);
310
+ return 0;
311
+ }
llama.cpp/scripts/apple/validate-apps.sh ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ ./scripts/apple/validate-ios.sh
3
+ ./scripts/apple/validate-macos.sh
4
+ ./scripts/apple/validate-visionos.sh
5
+ ./scripts/apple/validate-tvos.sh
llama.cpp/scripts/apple/validate-ios.sh ADDED
@@ -0,0 +1,820 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ # validate-ios.sh - Validate iOS Application with embedded llama.xcframework using SwiftUI
3
+
4
+ # Authentication options (optional) (can be set via environment variables)
5
+ # To use: export APPLE_ID=your.email@example.com
6
+ # export APPLE_PASSWORD=your-app-specific-password
7
+ # ./validate-ios.sh
8
+ APPLE_ID=${APPLE_ID:-""}
9
+ APPLE_PASSWORD=${APPLE_PASSWORD:-""}
10
+
11
+ # Ensure the script exits on error
12
+ set -e
13
+
14
+ # Function to print usage instructions
15
+ print_usage() {
16
+ echo "Usage: ./validate-ios.sh [OPTIONS]"
17
+ echo ""
18
+ echo "Options:"
19
+ echo " --help Show this help message"
20
+ echo " --apple-id EMAIL Apple ID email for validation"
21
+ echo " --apple-password PWD App-specific password for Apple ID"
22
+ echo ""
23
+ echo "Environment variables:"
24
+ echo " APPLE_ID Apple ID email for validation"
25
+ echo " APPLE_PASSWORD App-specific password for Apple ID"
26
+ echo ""
27
+ echo "Notes:"
28
+ echo " - Command line options take precedence over environment variables"
29
+ echo " - Authentication is optional. If not provided, alternative validation will be performed"
30
+ echo " - For APPLE_PASSWORD, use an app-specific password generated at https://appleid.apple.com/account/manage"
31
+ }
32
+
33
+ # Parse command line arguments
34
+ while [[ $# -gt 0 ]]; do
35
+ case $1 in
36
+ --help)
37
+ print_usage
38
+ exit 0
39
+ ;;
40
+ --apple-id)
41
+ APPLE_ID="$2"
42
+ shift 2
43
+ ;;
44
+ --apple-password)
45
+ APPLE_PASSWORD="$2"
46
+ shift 2
47
+ ;;
48
+ *)
49
+ echo "Unknown option: $1"
50
+ print_usage
51
+ exit 1
52
+ ;;
53
+ esac
54
+ done
55
+
56
+ # Function to clean up in case of error
57
+ cleanup() {
58
+ # Don't clean up temp files on error to help with debugging
59
+ echo "===== iOS Validation Process Failed ====="
60
+ exit 1
61
+ }
62
+
63
+ # Set up trap to call cleanup function on error
64
+ trap cleanup ERR
65
+
66
+ set -e # Exit on any error
67
+
68
+ ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )"
69
+ BUILD_DIR="${ROOT_DIR}/validation-builds/ios"
70
+
71
+ # Configuration
72
+ APP_NAME="iOSLlamaTest"
73
+ BUNDLE_ID="org.ggml.iOSLlamaTest"
74
+ XCFRAMEWORK_PATH="${ROOT_DIR}/build-apple/llama.xcframework"
75
+ TEMP_DIR="${BUILD_DIR}/temp"
76
+ ARCHIVE_PATH="${BUILD_DIR}/${APP_NAME}.xcarchive"
77
+ IPA_PATH="${BUILD_DIR}/${APP_NAME}.ipa"
78
+ VALIDATION_DIR="${BUILD_DIR}/validation"
79
+
80
+ # Create necessary directories
81
+ mkdir -p "${BUILD_DIR}"
82
+ mkdir -p "${TEMP_DIR}"
83
+ mkdir -p "${VALIDATION_DIR}"
84
+
85
+ echo "===== iOS Validation Process Started ====="
86
+
87
+ # 1. Create a simple test app project
88
+ echo "Creating test iOS app project..."
89
+ mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}"
90
+ cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Info.plist" << EOF
91
+ <?xml version="1.0" encoding="UTF-8"?>
92
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
93
+ <plist version="1.0">
94
+ <dict>
95
+ <key>CFBundleDevelopmentRegion</key>
96
+ <string>en</string>
97
+ <key>CFBundleExecutable</key>
98
+ <string>${APP_NAME}</string>
99
+ <key>CFBundleIdentifier</key>
100
+ <string>${BUNDLE_ID}</string>
101
+ <key>CFBundleInfoDictionaryVersion</key>
102
+ <string>6.0</string>
103
+ <key>CFBundleName</key>
104
+ <string>${APP_NAME}</string>
105
+ <key>CFBundlePackageType</key>
106
+ <string>APPL</string>
107
+ <key>CFBundleShortVersionString</key>
108
+ <string>1.0</string>
109
+ <key>CFBundleVersion</key>
110
+ <string>1</string>
111
+ <key>LSRequiresIPhoneOS</key>
112
+ <true/>
113
+ <key>UILaunchScreen</key>
114
+ <dict/>
115
+ <key>UIRequiredDeviceCapabilities</key>
116
+ <array>
117
+ <string>armv7</string>
118
+ </array>
119
+ <key>UISupportedInterfaceOrientations</key>
120
+ <array>
121
+ <string>UIInterfaceOrientationPortrait</string>
122
+ </array>
123
+ </dict>
124
+ </plist>
125
+ EOF
126
+
127
+ # Create SwiftUI app files
128
+ mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources"
129
+
130
+ # Create App.swift
131
+ cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/App.swift" << EOF
132
+ import SwiftUI
133
+ import llama
134
+
135
+ @main
136
+ struct LlamaTestApp: App {
137
+ var body: some Scene {
138
+ WindowGroup {
139
+ ContentView()
140
+ }
141
+ }
142
+ }
143
+ EOF
144
+
145
+ # Create ContentView.swift
146
+ cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/ContentView.swift" << EOF
147
+ import SwiftUI
148
+ import llama
149
+
150
+ struct ContentView: View {
151
+ // Test that we can initialize a llama context params struct
152
+ let params = llama_context_default_params()
153
+
154
+ var body: some View {
155
+ VStack(spacing: 20) {
156
+ Text("Llama Framework Test")
157
+ .font(.largeTitle)
158
+ .padding()
159
+
160
+ Text("llama_context_default_params() created successfully")
161
+ .font(.headline)
162
+ .multilineTextAlignment(.center)
163
+ .padding()
164
+
165
+ // Display some param values to confirm the framework is working
166
+ Text("n_ctx: \(params.n_ctx)")
167
+ .font(.body)
168
+
169
+ Text("n_batch: \(params.n_batch)")
170
+ .font(.body)
171
+
172
+ Spacer()
173
+ }
174
+ .padding()
175
+ }
176
+ }
177
+
178
+ struct ContentView_Previews: PreviewProvider {
179
+ static var previews: some View {
180
+ ContentView()
181
+ }
182
+ }
183
+ EOF
184
+
185
+ # Create project.pbxproj, fixing the framework search paths issues
186
+ mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj"
187
+ cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
188
+ // !$*UTF8*$!
189
+ {
190
+ archiveVersion = 1;
191
+ classes = {
192
+ };
193
+ objectVersion = 54;
194
+ objects = {
195
+
196
+ /* Begin PBXBuildFile section */
197
+ 11111111111111111111111 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22222222222222222222222; };
198
+ 33333333333333333333333 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44444444444444444444444; };
199
+ 55555555555555555555555 /* llama.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
200
+ 77777777777777777777777 /* llama.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
201
+ /* End PBXBuildFile section */
202
+
203
+ /* Begin PBXCopyFilesBuildPhase section */
204
+ 88888888888888888888888 /* Embed Frameworks */ = {
205
+ isa = PBXCopyFilesBuildPhase;
206
+ buildActionMask = 2147483647;
207
+ dstPath = "";
208
+ dstSubfolderSpec = 10;
209
+ files = (
210
+ 77777777777777777777777 /* llama.xcframework in Embed Frameworks */,
211
+ );
212
+ name = "Embed Frameworks";
213
+ runOnlyForDeploymentPostprocessing = 0;
214
+ };
215
+ /* End PBXCopyFilesBuildPhase section */
216
+
217
+ /* Begin PBXFileReference section */
218
+ EOF
219
+
220
+ # Continue with the project.pbxproj file, using the APP_NAME variable appropriately
221
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
222
+ 99999999999999999999999 /* ${APP_NAME}.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "${APP_NAME}.app"; sourceTree = BUILT_PRODUCTS_DIR; };
223
+ 22222222222222222222222 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
224
+ 44444444444444444444444 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
225
+ AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
226
+ 66666666666666666666666 /* llama.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = llama.xcframework; sourceTree = "<group>"; };
227
+ /* End PBXFileReference section */
228
+ EOF
229
+
230
+ # Add the rest of the project file with fixed framework search paths
231
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
232
+ /* Begin PBXFrameworksBuildPhase section */
233
+ BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */ = {
234
+ isa = PBXFrameworksBuildPhase;
235
+ buildActionMask = 2147483647;
236
+ files = (
237
+ 55555555555555555555555 /* llama.xcframework in Frameworks */,
238
+ );
239
+ runOnlyForDeploymentPostprocessing = 0;
240
+ };
241
+ /* End PBXFrameworksBuildPhase section */
242
+
243
+ /* Begin PBXGroup section */
244
+ EOF
245
+
246
+ # Continue with the project.pbxproj file, using the APP_NAME variable appropriately
247
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
248
+ CCCCCCCCCCCCCCCCCCCCCCCC /* Products */ = {
249
+ isa = PBXGroup;
250
+ children = (
251
+ 99999999999999999999999 /* ${APP_NAME}.app */,
252
+ );
253
+ name = Products;
254
+ sourceTree = "<group>";
255
+ };
256
+ EOF
257
+
258
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
259
+ DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */ = {
260
+ isa = PBXGroup;
261
+ children = (
262
+ 66666666666666666666666 /* llama.xcframework */,
263
+ );
264
+ name = Frameworks;
265
+ sourceTree = "<group>";
266
+ };
267
+ EEEEEEEEEEEEEEEEEEEEEEEE = {
268
+ isa = PBXGroup;
269
+ children = (
270
+ FFFFFFFFFFFFFFFFFFFFFFFF /* iOSLlamaTest */,
271
+ CCCCCCCCCCCCCCCCCCCCCCCC /* Products */,
272
+ DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */,
273
+ );
274
+ sourceTree = "<group>";
275
+ };
276
+ FFFFFFFFFFFFFFFFFFFFFFFF /* iOSLlamaTest */ = {
277
+ isa = PBXGroup;
278
+ children = (
279
+ 1111111111111111111111AA /* Sources */,
280
+ AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */,
281
+ );
282
+ path = "iOSLlamaTest";
283
+ sourceTree = "<group>";
284
+ };
285
+ 1111111111111111111111AA /* Sources */ = {
286
+ isa = PBXGroup;
287
+ children = (
288
+ 22222222222222222222222 /* App.swift */,
289
+ 44444444444444444444444 /* ContentView.swift */,
290
+ );
291
+ path = Sources;
292
+ sourceTree = "<group>";
293
+ };
294
+ /* End PBXGroup section */
295
+ EOF
296
+
297
+ # Continue with the project.pbxproj file, using the APP_NAME variable appropriately
298
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
299
+ /* Begin PBXNativeTarget section */
300
+ 3333333333333333333333AA /* ${APP_NAME} */ = {
301
+ isa = PBXNativeTarget;
302
+ buildConfigurationList = 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */;
303
+ buildPhases = (
304
+ 5555555555555555555555AA /* Sources */,
305
+ BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */,
306
+ 6666666666666666666666AA /* Resources */,
307
+ 88888888888888888888888 /* Embed Frameworks */,
308
+ );
309
+ buildRules = (
310
+ );
311
+ dependencies = (
312
+ );
313
+ name = "${APP_NAME}";
314
+ productName = "${APP_NAME}";
315
+ productReference = 99999999999999999999999 /* ${APP_NAME}.app */;
316
+ productType = "com.apple.product-type.application";
317
+ };
318
+ /* End PBXNativeTarget section */
319
+
320
+ /* Begin PBXProject section */
321
+ 7777777777777777777777AA /* Project object */ = {
322
+ isa = PBXProject;
323
+ attributes = {
324
+ LastSwiftUpdateCheck = 1240;
325
+ LastUpgradeCheck = 1240;
326
+ TargetAttributes = {
327
+ 3333333333333333333333AA = {
328
+ CreatedOnToolsVersion = 12.4;
329
+ };
330
+ };
331
+ };
332
+ buildConfigurationList = 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */;
333
+ compatibilityVersion = "Xcode 12.0";
334
+ developmentRegion = en;
335
+ hasScannedForEncodings = 0;
336
+ knownRegions = (
337
+ en,
338
+ Base,
339
+ );
340
+ mainGroup = EEEEEEEEEEEEEEEEEEEEEEEE;
341
+ productRefGroup = CCCCCCCCCCCCCCCCCCCCCCCC /* Products */;
342
+ projectDirPath = "";
343
+ projectRoot = "";
344
+ targets = (
345
+ 3333333333333333333333AA /* ${APP_NAME} */,
346
+ );
347
+ };
348
+ /* End PBXProject section */
349
+ EOF
350
+
351
+ # Add the rest of the file with correct FRAMEWORK_SEARCH_PATHS
352
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
353
+ /* Begin PBXResourcesBuildPhase section */
354
+ 6666666666666666666666AA /* Resources */ = {
355
+ isa = PBXResourcesBuildPhase;
356
+ buildActionMask = 2147483647;
357
+ files = (
358
+ );
359
+ runOnlyForDeploymentPostprocessing = 0;
360
+ };
361
+ /* End PBXResourcesBuildPhase section */
362
+
363
+ /* Begin PBXSourcesBuildPhase section */
364
+ 5555555555555555555555AA /* Sources */ = {
365
+ isa = PBXSourcesBuildPhase;
366
+ buildActionMask = 2147483647;
367
+ files = (
368
+ 33333333333333333333333 /* ContentView.swift in Sources */,
369
+ 11111111111111111111111 /* App.swift in Sources */,
370
+ );
371
+ runOnlyForDeploymentPostprocessing = 0;
372
+ };
373
+ /* End PBXSourcesBuildPhase section */
374
+
375
+ /* Begin XCBuildConfiguration section */
376
+ 9999999999999999999999AA /* Debug */ = {
377
+ isa = XCBuildConfiguration;
378
+ buildSettings = {
379
+ ALWAYS_SEARCH_USER_PATHS = NO;
380
+ CLANG_ANALYZER_NONNULL = YES;
381
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
382
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
383
+ CLANG_CXX_LIBRARY = "libc++";
384
+ CLANG_ENABLE_MODULES = YES;
385
+ CLANG_ENABLE_OBJC_ARC = YES;
386
+ CLANG_ENABLE_OBJC_WEAK = YES;
387
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
388
+ CLANG_WARN_BOOL_CONVERSION = YES;
389
+ CLANG_WARN_COMMA = YES;
390
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
391
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
392
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
393
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
394
+ CLANG_WARN_EMPTY_BODY = YES;
395
+ CLANG_WARN_ENUM_CONVERSION = YES;
396
+ CLANG_WARN_INFINITE_RECURSION = YES;
397
+ CLANG_WARN_INT_CONVERSION = YES;
398
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
399
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
400
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
401
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
402
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
403
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
404
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
405
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
406
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
407
+ CLANG_WARN_UNREACHABLE_CODE = YES;
408
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
409
+ COPY_PHASE_STRIP = NO;
410
+ DEBUG_INFORMATION_FORMAT = dwarf;
411
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
412
+ ENABLE_TESTABILITY = YES;
413
+ GCC_C_LANGUAGE_STANDARD = gnu11;
414
+ GCC_DYNAMIC_NO_PIC = NO;
415
+ GCC_NO_COMMON_BLOCKS = YES;
416
+ GCC_OPTIMIZATION_LEVEL = 0;
417
+ GCC_PREPROCESSOR_DEFINITIONS = (
418
+ "DEBUG=1",
419
+ "$(inherited)",
420
+ );
421
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
422
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
423
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
424
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
425
+ GCC_WARN_UNUSED_FUNCTION = YES;
426
+ GCC_WARN_UNUSED_VARIABLE = YES;
427
+ IPHONEOS_DEPLOYMENT_TARGET = 16.4;
428
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
429
+ MTL_FAST_MATH = YES;
430
+ ONLY_ACTIVE_ARCH = YES;
431
+ SDKROOT = iphoneos;
432
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
433
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
434
+ };
435
+ name = Debug;
436
+ };
437
+ AAAAAAAAAAAAAAAAAAAAABBB /* Release */ = {
438
+ isa = XCBuildConfiguration;
439
+ buildSettings = {
440
+ ALWAYS_SEARCH_USER_PATHS = NO;
441
+ CLANG_ANALYZER_NONNULL = YES;
442
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
443
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
444
+ CLANG_CXX_LIBRARY = "libc++";
445
+ CLANG_ENABLE_MODULES = YES;
446
+ CLANG_ENABLE_OBJC_ARC = YES;
447
+ CLANG_ENABLE_OBJC_WEAK = YES;
448
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
449
+ CLANG_WARN_BOOL_CONVERSION = YES;
450
+ CLANG_WARN_COMMA = YES;
451
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
452
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
453
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
454
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
455
+ CLANG_WARN_EMPTY_BODY = YES;
456
+ CLANG_WARN_ENUM_CONVERSION = YES;
457
+ CLANG_WARN_INFINITE_RECURSION = YES;
458
+ CLANG_WARN_INT_CONVERSION = YES;
459
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
460
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
461
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
462
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
463
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
464
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
465
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
466
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
467
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
468
+ CLANG_WARN_UNREACHABLE_CODE = YES;
469
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
470
+ COPY_PHASE_STRIP = NO;
471
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
472
+ ENABLE_NS_ASSERTIONS = NO;
473
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
474
+ GCC_C_LANGUAGE_STANDARD = gnu11;
475
+ GCC_NO_COMMON_BLOCKS = YES;
476
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
477
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
478
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
479
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
480
+ GCC_WARN_UNUSED_FUNCTION = YES;
481
+ GCC_WARN_UNUSED_VARIABLE = YES;
482
+ IPHONEOS_DEPLOYMENT_TARGET = 16.4;
483
+ MTL_ENABLE_DEBUG_INFO = NO;
484
+ MTL_FAST_MATH = YES;
485
+ SDKROOT = iphoneos;
486
+ SWIFT_COMPILATION_MODE = wholemodule;
487
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
488
+ VALIDATE_PRODUCT = YES;
489
+ };
490
+ name = Release;
491
+ };
492
+ BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */ = {
493
+ isa = XCBuildConfiguration;
494
+ buildSettings = {
495
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
496
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
497
+ CODE_SIGN_STYLE = Manual;
498
+ DEVELOPMENT_TEAM = "";
499
+ ENABLE_PREVIEWS = YES;
500
+ FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)";
501
+ INFOPLIST_FILE = "iOSLlamaTest/Info.plist";
502
+ LD_RUNPATH_SEARCH_PATHS = (
503
+ "$(inherited)",
504
+ "@executable_path/Frameworks",
505
+ );
506
+ PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.iOSLlamaTest";
507
+ PRODUCT_NAME = "$(TARGET_NAME)";
508
+ PROVISIONING_PROFILE_SPECIFIER = "";
509
+ SWIFT_VERSION = 5.0;
510
+ TARGETED_DEVICE_FAMILY = "1,2";
511
+ };
512
+ name = Debug;
513
+ };
514
+ CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */ = {
515
+ isa = XCBuildConfiguration;
516
+ buildSettings = {
517
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
518
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
519
+ CODE_SIGN_STYLE = Manual;
520
+ DEVELOPMENT_TEAM = "";
521
+ ENABLE_PREVIEWS = YES;
522
+ FRAMEWORK_SEARCH_PATHS = (
523
+ "$(inherited)",
524
+ "$(PROJECT_DIR)",
525
+ );
526
+ INFOPLIST_FILE = "iOSLlamaTest/Info.plist";
527
+ LD_RUNPATH_SEARCH_PATHS = (
528
+ "$(inherited)",
529
+ "@executable_path/Frameworks",
530
+ );
531
+ PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.iOSLlamaTest";
532
+ PRODUCT_NAME = "$(TARGET_NAME)";
533
+ PROVISIONING_PROFILE_SPECIFIER = "";
534
+ SWIFT_VERSION = 5.0;
535
+ TARGETED_DEVICE_FAMILY = "1,2";
536
+ };
537
+ name = Release;
538
+ };
539
+ /* End XCBuildConfiguration section */
540
+ EOF
541
+
542
+ # Finish the project.pbxproj file
543
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
544
+ /* Begin XCConfigurationList section */
545
+ 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */ = {
546
+ isa = XCConfigurationList;
547
+ buildConfigurations = (
548
+ 9999999999999999999999AA /* Debug */,
549
+ AAAAAAAAAAAAAAAAAAAAABBB /* Release */,
550
+ );
551
+ defaultConfigurationIsVisible = 0;
552
+ defaultConfigurationName = Release;
553
+ };
554
+ 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */ = {
555
+ isa = XCConfigurationList;
556
+ buildConfigurations = (
557
+ BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */,
558
+ CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */,
559
+ );
560
+ defaultConfigurationIsVisible = 0;
561
+ defaultConfigurationName = Release;
562
+ };
563
+ /* End XCConfigurationList section */
564
+ };
565
+ rootObject = 7777777777777777777777AA /* Project object */;
566
+ }
567
+ EOF
568
+
569
+ # 2. Copy XCFramework to test project
570
+ echo "Copying XCFramework to test project..."
571
+ cp -R "${XCFRAMEWORK_PATH}" "${TEMP_DIR}/${APP_NAME}/"
572
+
573
+ # 3. Build and archive the app
574
+ echo "Building and archiving test app..."
575
+ cd "${TEMP_DIR}/${APP_NAME}"
576
+
577
+ # Create a simple xcscheme file to avoid xcodebuild scheme issues
578
+ mkdir -p "${APP_NAME}.xcodeproj/xcshareddata/xcschemes"
579
+ cat > "${APP_NAME}.xcodeproj/xcshareddata/xcschemes/${APP_NAME}.xcscheme" << EOF
580
+ <?xml version="1.0" encoding="UTF-8"?>
581
+ <Scheme
582
+ LastUpgradeVersion = "1240"
583
+ version = "1.3">
584
+ <BuildAction
585
+ parallelizeBuildables = "YES"
586
+ buildImplicitDependencies = "YES">
587
+ <BuildActionEntries>
588
+ <BuildActionEntry
589
+ buildForTesting = "YES"
590
+ buildForRunning = "YES"
591
+ buildForProfiling = "YES"
592
+ buildForArchiving = "YES"
593
+ buildForAnalyzing = "YES">
594
+ <BuildableReference
595
+ BuildableIdentifier = "primary"
596
+ BlueprintIdentifier = "3333333333333333333333AA"
597
+ BuildableName = "${APP_NAME}.app"
598
+ BlueprintName = "${APP_NAME}"
599
+ ReferencedContainer = "container:${APP_NAME}.xcodeproj">
600
+ </BuildableReference>
601
+ </BuildActionEntry>
602
+ </BuildActionEntries>
603
+ </BuildAction>
604
+ <TestAction
605
+ buildConfiguration = "Debug"
606
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
607
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
608
+ shouldUseLaunchSchemeArgsEnv = "YES">
609
+ <Testables>
610
+ </Testables>
611
+ </TestAction>
612
+ <LaunchAction
613
+ buildConfiguration = "Debug"
614
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
615
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
616
+ launchStyle = "0"
617
+ useCustomWorkingDirectory = "NO"
618
+ ignoresPersistentStateOnLaunch = "NO"
619
+ debugDocumentVersioning = "YES"
620
+ debugServiceExtension = "internal"
621
+ allowLocationSimulation = "YES">
622
+ <BuildableProductRunnable
623
+ runnableDebuggingMode = "0">
624
+ <BuildableReference
625
+ BuildableIdentifier = "primary"
626
+ BlueprintIdentifier = "3333333333333333333333AA"
627
+ BuildableName = "${APP_NAME}.app"
628
+ BlueprintName = "${APP_NAME}"
629
+ ReferencedContainer = "container:${APP_NAME}.xcodeproj">
630
+ </BuildableReference>
631
+ </BuildableProductRunnable>
632
+ </LaunchAction>
633
+ <ProfileAction
634
+ buildConfiguration = "Release"
635
+ shouldUseLaunchSchemeArgsEnv = "YES"
636
+ savedToolIdentifier = ""
637
+ useCustomWorkingDirectory = "NO"
638
+ debugDocumentVersioning = "YES">
639
+ <BuildableProductRunnable
640
+ runnableDebuggingMode = "0">
641
+ <BuildableReference
642
+ BuildableIdentifier = "primary"
643
+ BlueprintIdentifier = "3333333333333333333333AA"
644
+ BuildableName = "${APP_NAME}.app"
645
+ BlueprintName = "${APP_NAME}"
646
+ ReferencedContainer = "container:${APP_NAME}.xcodeproj">
647
+ </BuildableReference>
648
+ </BuildableProductRunnable>
649
+ </ProfileAction>
650
+ <AnalyzeAction
651
+ buildConfiguration = "Debug">
652
+ </AnalyzeAction>
653
+ <ArchiveAction
654
+ buildConfiguration = "Release"
655
+ revealArchiveInOrganizer = "YES">
656
+ </ArchiveAction>
657
+ </Scheme>
658
+ EOF
659
+
660
+ # Now use xcodebuild with an explicitly defined product name
661
+ xcodebuild -project "${APP_NAME}.xcodeproj" -scheme "${APP_NAME}" -sdk iphoneos -configuration Release archive -archivePath "${ARCHIVE_PATH}" CODE_SIGN_IDENTITY="-" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO PRODUCT_NAME="${APP_NAME}" SWIFT_OPTIMIZATION_LEVEL="-Onone" -quiet
662
+
663
+ # 4. Create IPA from archive
664
+ echo "Creating IPA from archive..."
665
+ mkdir -p "${TEMP_DIR}/Payload"
666
+ cp -R "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" "${TEMP_DIR}/Payload/"
667
+
668
+ # Check and log app structure before zipping
669
+ echo "App structure:"
670
+ ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/"
671
+ echo "Frameworks:"
672
+ ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
673
+
674
+ cd "${TEMP_DIR}"
675
+ zip -r "${IPA_PATH}" Payload
676
+
677
+ # Check embedded provisioning profile
678
+ echo "Checking provisioning profile (if any)..."
679
+ PROVISIONING_PROFILE=$(find "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" -name "embedded.mobileprovision" 2>/dev/null)
680
+ if [ -n "$PROVISIONING_PROFILE" ]; then
681
+ echo "Found embedded provisioning profile:"
682
+ security cms -D -i "$PROVISIONING_PROFILE" || echo "Unable to decode provisioning profile"
683
+ else
684
+ echo "No embedded provisioning profile found (expected for ad-hoc builds)"
685
+ fi
686
+
687
+ # 5. Validate the IPA
688
+ echo "Validating IPA..."
689
+ VALIDATION_OUTPUT="${VALIDATION_DIR}/validation_output.txt"
690
+
691
+ # Check if authentication credentials are provided
692
+ AUTH_ARGS=""
693
+ if [ -n "$APPLE_ID" ] && [ -n "$APPLE_PASSWORD" ]; then
694
+ echo "Using Apple ID authentication for validation..."
695
+ AUTH_ARGS="--username \"$APPLE_ID\" --password \"$APPLE_PASSWORD\""
696
+ else
697
+ echo "No authentication credentials provided. Will perform basic validation."
698
+ echo "To use your personal developer account, you can run the script with:"
699
+ echo " APPLE_ID='your.email@example.com' APPLE_PASSWORD='your-app-specific-password' ./validate-ios.sh"
700
+ echo "Note: You need to create an app-specific password at https://appleid.apple.com/account/manage"
701
+ fi
702
+
703
+ # Run validation with detailed output
704
+ echo "Running validation with altool..."
705
+ if [ -n "$AUTH_ARGS" ]; then
706
+ # Use eval to properly handle the quoted arguments
707
+ eval "xcrun altool --validate-app -f \"${IPA_PATH}\" --type ios --output-format xml $AUTH_ARGS" 2>&1 | tee "${VALIDATION_OUTPUT}"
708
+ else
709
+ xcrun altool --validate-app -f "${IPA_PATH}" --type ios --output-format xml 2>&1 | tee "${VALIDATION_OUTPUT}"
710
+ fi
711
+ VALIDATION_RESULT=$?
712
+
713
+ # Final validation result
714
+ FINAL_VALIDATION_RESULT=0
715
+
716
+ # Check if validation failed because the app isn't in App Store Connect
717
+ if grep -q "No suitable application records were found" "${VALIDATION_OUTPUT}"; then
718
+ echo "⚠️ App Store Connect Warning: The app bundle identifier is not found in App Store Connect"
719
+ echo "This is expected for apps that haven't been registered in App Store Connect yet."
720
+ echo "This doesn't indicate a problem with the build or framework."
721
+
722
+ # Perform alternative validation
723
+ echo "Performing alternative validation checks..."
724
+
725
+ # Check if IPA was created successfully
726
+ if [ -f "${IPA_PATH}" ] && [ -s "${IPA_PATH}" ]; then
727
+ echo "✅ IPA file created successfully"
728
+ else
729
+ echo "❌ IPA file not created or empty"
730
+ FINAL_VALIDATION_RESULT=1
731
+ fi
732
+
733
+ # Check if app binary exists and is executable
734
+ if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ] && [ -x "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ]; then
735
+ echo "✅ App binary exists and is executable"
736
+ else
737
+ echo "❌ App binary missing or not executable"
738
+ FINAL_VALIDATION_RESULT=1
739
+ fi
740
+
741
+ # Check if framework was properly embedded
742
+ if [ -d "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework" ]; then
743
+ echo "✅ llama.framework properly embedded"
744
+ else
745
+ echo "❌ llama.framework not properly embedded"
746
+ FINAL_VALIDATION_RESULT=1
747
+ fi
748
+
749
+ # Check if framework binary exists
750
+ if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework/llama" ]; then
751
+ echo "✅ Framework binary exists"
752
+
753
+ # Further validate framework by checking architecture
754
+ ARCHS=$(lipo -info "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework/llama" 2>/dev/null | grep -o "arm64\\|armv7\\|x86_64" | tr '\n' ' ')
755
+ if [ -n "$ARCHS" ]; then
756
+ echo "✅ Framework architecture(s): $ARCHS"
757
+ else
758
+ echo "⚠️ Could not determine framework architecture"
759
+ fi
760
+ else
761
+ echo "❌ Framework binary missing"
762
+ FINAL_VALIDATION_RESULT=1
763
+ fi
764
+
765
+ if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
766
+ echo "✅ Alternative validation PASSED: App built successfully with embedded framework"
767
+ else
768
+ echo "❌ Alternative validation FAILED: Issues found with the app or framework"
769
+ fi
770
+ elif grep -q "You must specify authentication credentials" "${VALIDATION_OUTPUT}" && [ -z "$AUTH_ARGS" ]; then
771
+ echo "✅ iOS Validation PASSED: IPA successfully validated"
772
+ echo "Results saved to ${VALIDATION_OUTPUT}"
773
+ else
774
+ echo "❌ iOS Validation FAILED: IPA validation found issues"
775
+ echo "See validation output at ${VALIDATION_OUTPUT}"
776
+ echo ""
777
+ echo "==== VALIDATION ERRORS ===="
778
+
779
+ # Try to extract specific errors from the output
780
+ if grep -q "Error" "${VALIDATION_OUTPUT}"; then
781
+ grep -A 5 "Error" "${VALIDATION_OUTPUT}"
782
+ else
783
+ # If no specific error found, show the whole log
784
+ cat "${VALIDATION_OUTPUT}"
785
+ fi
786
+
787
+ # Additional debugging: check IPA contents
788
+ echo ""
789
+ echo "==== IPA CONTENTS ===="
790
+ mkdir -p "${TEMP_DIR}/ipa_contents"
791
+ unzip -q "${IPA_PATH}" -d "${TEMP_DIR}/ipa_contents"
792
+ ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/"
793
+
794
+ # Check for code signing issues
795
+ echo ""
796
+ echo "==== CODE SIGNING INFO ===="
797
+ codesign -vv -d "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app" 2>&1 || echo "Code signing verification failed"
798
+
799
+ # Check embedded frameworks
800
+ echo ""
801
+ echo "==== FRAMEWORK INFO ===="
802
+ ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
803
+ fi
804
+
805
+ # Don't clean up on error to allow inspection
806
+ if [ $FINAL_VALIDATION_RESULT -ne 0 ]; then
807
+ echo ""
808
+ echo "Temporary files kept for inspection at: ${TEMP_DIR}"
809
+ echo "===== iOS Validation Process Failed ====="
810
+ exit 1
811
+ fi
812
+
813
+ # Clean up temporary files but keep build artifacts
814
+ if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
815
+ echo "Cleaning up temporary files..."
816
+ #rm -rf "${TEMP_DIR}"
817
+ fi
818
+
819
+ echo "===== iOS Validation Process Completed ====="
820
+ exit $FINAL_VALIDATION_RESULT
llama.cpp/scripts/apple/validate-macos.sh ADDED
@@ -0,0 +1,781 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ # validate-macos.sh - Validate macOS Application with embedded llama.xcframework using SwiftUI
3
+
4
+ # Authentication options (optional) (can be set via environment variables)
5
+ # To use: export APPLE_ID=your.email@example.com
6
+ # export APPLE_PASSWORD=your-app-specific-password
7
+ # ./validate-macos.sh
8
+ APPLE_ID=${APPLE_ID:-""}
9
+ APPLE_PASSWORD=${APPLE_PASSWORD:-""}
10
+
11
+ # Ensure the script exits on error
12
+ set -e
13
+
14
+ # Function to print usage instructions
15
+ print_usage() {
16
+ echo "Usage: ./validate-macos.sh [OPTIONS]"
17
+ echo ""
18
+ echo "Options:"
19
+ echo " --help Show this help message"
20
+ echo " --apple-id EMAIL Apple ID email for validation"
21
+ echo " --apple-password PWD App-specific password for Apple ID"
22
+ echo ""
23
+ echo "Environment variables:"
24
+ echo " APPLE_ID Apple ID email for validation"
25
+ echo " APPLE_PASSWORD App-specific password for Apple ID"
26
+ echo ""
27
+ echo "Notes:"
28
+ echo " - Command line options take precedence over environment variables"
29
+ echo " - Authentication is optional. If not provided, alternative validation will be performed"
30
+ echo " - For APPLE_PASSWORD, use an app-specific password generated at https://appleid.apple.com/account/manage"
31
+ }
32
+
33
+ # Parse command line arguments
34
+ while [[ $# -gt 0 ]]; do
35
+ case $1 in
36
+ --help)
37
+ print_usage
38
+ exit 0
39
+ ;;
40
+ --apple-id)
41
+ APPLE_ID="$2"
42
+ shift 2
43
+ ;;
44
+ --apple-password)
45
+ APPLE_PASSWORD="$2"
46
+ shift 2
47
+ ;;
48
+ *)
49
+ echo "Unknown option: $1"
50
+ print_usage
51
+ exit 1
52
+ ;;
53
+ esac
54
+ done
55
+
56
+ # Function to clean up in case of error
57
+ cleanup() {
58
+ # Don't clean up temp files on error to help with debugging
59
+ echo "===== macOS Validation Process Failed ====="
60
+ exit 1
61
+ }
62
+
63
+ # Set up trap to call cleanup function on error
64
+ trap cleanup ERR
65
+
66
+ set -e # Exit on any error
67
+
68
+ ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )"
69
+ BUILD_DIR="${ROOT_DIR}/validation-builds/ios"
70
+
71
+ # Configuration
72
+ APP_NAME="MacOSLlamaTest"
73
+ BUNDLE_ID="org.ggml.MacOSLlamaTest"
74
+ XCFRAMEWORK_PATH="${ROOT_DIR}/build-apple/llama.xcframework"
75
+ TEMP_DIR="${BUILD_DIR}/temp"
76
+ ARCHIVE_PATH="${BUILD_DIR}/${APP_NAME}.xcarchive"
77
+ APP_PATH="${BUILD_DIR}/${APP_NAME}.app"
78
+ ZIP_PATH="${BUILD_DIR}/${APP_NAME}.zip"
79
+ VALIDATION_DIR="${BUILD_DIR}/validation"
80
+
81
+ # Create necessary directories
82
+ mkdir -p "${BUILD_DIR}"
83
+ mkdir -p "${TEMP_DIR}"
84
+ mkdir -p "${VALIDATION_DIR}"
85
+
86
+ echo "===== macOS Validation Process Started ====="
87
+
88
+ # 1. Create a simple test app project
89
+ echo "Creating test macOS app project..."
90
+ mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}"
91
+ cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Info.plist" << EOF
92
+ <?xml version="1.0" encoding="UTF-8"?>
93
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
94
+ <plist version="1.0">
95
+ <dict>
96
+ <key>CFBundleDevelopmentRegion</key>
97
+ <string>en</string>
98
+ <key>CFBundleExecutable</key>
99
+ <string>${APP_NAME}</string>
100
+ <key>CFBundleIdentifier</key>
101
+ <string>${BUNDLE_ID}</string>
102
+ <key>CFBundleInfoDictionaryVersion</key>
103
+ <string>6.0</string>
104
+ <key>CFBundleName</key>
105
+ <string>${APP_NAME}</string>
106
+ <key>CFBundlePackageType</key>
107
+ <string>APPL</string>
108
+ <key>CFBundleShortVersionString</key>
109
+ <string>1.0</string>
110
+ <key>CFBundleVersion</key>
111
+ <string>1</string>
112
+ <key>LSMinimumSystemVersion</key>
113
+ <string>12.0</string>
114
+ <key>NSHumanReadableCopyright</key>
115
+ <string>Copyright © 2025 GGML. All rights reserved.</string>
116
+ <key>NSPrincipalClass</key>
117
+ <string>NSApplication</string>
118
+ </dict>
119
+ </plist>
120
+ EOF
121
+
122
+ # Create SwiftUI app files
123
+ mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources"
124
+
125
+ # Create App.swift
126
+ cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/App.swift" << EOF
127
+ import SwiftUI
128
+ import llama
129
+
130
+ @main
131
+ struct LlamaTestApp: App {
132
+ var body: some Scene {
133
+ WindowGroup {
134
+ ContentView()
135
+ }
136
+ }
137
+ }
138
+ EOF
139
+
140
+ # Create ContentView.swift with macOS specific elements
141
+ cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/ContentView.swift" << EOF
142
+ import SwiftUI
143
+ import llama
144
+
145
+ struct ContentView: View {
146
+ // Test that we can initialize a llama context params struct
147
+ let params = llama_context_default_params()
148
+
149
+ var body: some View {
150
+ VStack(spacing: 20) {
151
+ Text("Llama Framework Test on macOS")
152
+ .font(.largeTitle)
153
+ .padding()
154
+
155
+ Text("llama_context_default_params() created successfully")
156
+ .font(.headline)
157
+ .multilineTextAlignment(.center)
158
+ .padding()
159
+
160
+ // Display some param values to confirm the framework is working
161
+ Text("n_ctx: \(params.n_ctx)")
162
+ .font(.body)
163
+
164
+ Text("n_batch: \(params.n_batch)")
165
+ .font(.body)
166
+
167
+ Spacer()
168
+ }
169
+ .padding()
170
+ .frame(width: 600, height: 400)
171
+ }
172
+ }
173
+
174
+ struct ContentView_Previews: PreviewProvider {
175
+ static var previews: some View {
176
+ ContentView()
177
+ }
178
+ }
179
+ EOF
180
+
181
+ # Create project.pbxproj, fixing the framework search paths issues
182
+ mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj"
183
+ cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
184
+ // !$*UTF8*$!
185
+ {
186
+ archiveVersion = 1;
187
+ classes = {
188
+ };
189
+ objectVersion = 54;
190
+ objects = {
191
+
192
+ /* Begin PBXBuildFile section */
193
+ 11111111111111111111111 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22222222222222222222222; };
194
+ 33333333333333333333333 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44444444444444444444444; };
195
+ 55555555555555555555555 /* llama.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
196
+ 77777777777777777777777 /* llama.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
197
+ /* End PBXBuildFile section */
198
+
199
+ /* Begin PBXCopyFilesBuildPhase section */
200
+ 88888888888888888888888 /* Embed Frameworks */ = {
201
+ isa = PBXCopyFilesBuildPhase;
202
+ buildActionMask = 2147483647;
203
+ dstPath = "";
204
+ dstSubfolderSpec = 10;
205
+ files = (
206
+ 77777777777777777777777 /* llama.xcframework in Embed Frameworks */,
207
+ );
208
+ name = "Embed Frameworks";
209
+ runOnlyForDeploymentPostprocessing = 0;
210
+ };
211
+ /* End PBXCopyFilesBuildPhase section */
212
+
213
+ /* Begin PBXFileReference section */
214
+ EOF
215
+
216
+ # Continue with the project.pbxproj file, using the APP_NAME variable appropriately
217
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
218
+ 99999999999999999999999 /* ${APP_NAME}.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "${APP_NAME}.app"; sourceTree = BUILT_PRODUCTS_DIR; };
219
+ 22222222222222222222222 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
220
+ 44444444444444444444444 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
221
+ AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
222
+ 66666666666666666666666 /* llama.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = llama.xcframework; sourceTree = "<group>"; };
223
+ /* End PBXFileReference section */
224
+ EOF
225
+
226
+ # Add the rest of the project file with fixed framework search paths
227
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
228
+ /* Begin PBXFrameworksBuildPhase section */
229
+ BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */ = {
230
+ isa = PBXFrameworksBuildPhase;
231
+ buildActionMask = 2147483647;
232
+ files = (
233
+ 55555555555555555555555 /* llama.xcframework in Frameworks */,
234
+ );
235
+ runOnlyForDeploymentPostprocessing = 0;
236
+ };
237
+ /* End PBXFrameworksBuildPhase section */
238
+
239
+ /* Begin PBXGroup section */
240
+ EOF
241
+
242
+ # Continue with the project.pbxproj file, using the APP_NAME variable appropriately
243
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
244
+ CCCCCCCCCCCCCCCCCCCCCCCC /* Products */ = {
245
+ isa = PBXGroup;
246
+ children = (
247
+ 99999999999999999999999 /* ${APP_NAME}.app */,
248
+ );
249
+ name = Products;
250
+ sourceTree = "<group>";
251
+ };
252
+ EOF
253
+
254
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
255
+ DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */ = {
256
+ isa = PBXGroup;
257
+ children = (
258
+ 66666666666666666666666 /* llama.xcframework */,
259
+ );
260
+ name = Frameworks;
261
+ sourceTree = "<group>";
262
+ };
263
+ EEEEEEEEEEEEEEEEEEEEEEEE = {
264
+ isa = PBXGroup;
265
+ children = (
266
+ FFFFFFFFFFFFFFFFFFFFFFFF /* MacOSLlamaTest */,
267
+ CCCCCCCCCCCCCCCCCCCCCCCC /* Products */,
268
+ DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */,
269
+ );
270
+ sourceTree = "<group>";
271
+ };
272
+ FFFFFFFFFFFFFFFFFFFFFFFF /* MacOSLlamaTest */ = {
273
+ isa = PBXGroup;
274
+ children = (
275
+ 1111111111111111111111AA /* Sources */,
276
+ AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */,
277
+ );
278
+ path = "MacOSLlamaTest";
279
+ sourceTree = "<group>";
280
+ };
281
+ 1111111111111111111111AA /* Sources */ = {
282
+ isa = PBXGroup;
283
+ children = (
284
+ 22222222222222222222222 /* App.swift */,
285
+ 44444444444444444444444 /* ContentView.swift */,
286
+ );
287
+ path = Sources;
288
+ sourceTree = "<group>";
289
+ };
290
+ /* End PBXGroup section */
291
+ EOF
292
+
293
+ # Continue with the project.pbxproj file, using the APP_NAME variable appropriately
294
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
295
+ /* Begin PBXNativeTarget section */
296
+ 3333333333333333333333AA /* ${APP_NAME} */ = {
297
+ isa = PBXNativeTarget;
298
+ buildConfigurationList = 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */;
299
+ buildPhases = (
300
+ 5555555555555555555555AA /* Sources */,
301
+ BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */,
302
+ 6666666666666666666666AA /* Resources */,
303
+ 88888888888888888888888 /* Embed Frameworks */,
304
+ );
305
+ buildRules = (
306
+ );
307
+ dependencies = (
308
+ );
309
+ name = "${APP_NAME}";
310
+ productName = "${APP_NAME}";
311
+ productReference = 99999999999999999999999 /* ${APP_NAME}.app */;
312
+ productType = "com.apple.product-type.application";
313
+ };
314
+ /* End PBXNativeTarget section */
315
+
316
+ /* Begin PBXProject section */
317
+ 7777777777777777777777AA /* Project object */ = {
318
+ isa = PBXProject;
319
+ attributes = {
320
+ LastSwiftUpdateCheck = 1240;
321
+ LastUpgradeCheck = 1240;
322
+ TargetAttributes = {
323
+ 3333333333333333333333AA = {
324
+ CreatedOnToolsVersion = 12.4;
325
+ };
326
+ };
327
+ };
328
+ buildConfigurationList = 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */;
329
+ compatibilityVersion = "Xcode 12.0";
330
+ developmentRegion = en;
331
+ hasScannedForEncodings = 0;
332
+ knownRegions = (
333
+ en,
334
+ Base,
335
+ );
336
+ mainGroup = EEEEEEEEEEEEEEEEEEEEEEEE;
337
+ productRefGroup = CCCCCCCCCCCCCCCCCCCCCCCC /* Products */;
338
+ projectDirPath = "";
339
+ projectRoot = "";
340
+ targets = (
341
+ 3333333333333333333333AA /* ${APP_NAME} */,
342
+ );
343
+ };
344
+ /* End PBXProject section */
345
+ EOF
346
+
347
+ # Add the rest of the file with correct FRAMEWORK_SEARCH_PATHS and macOS settings
348
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
349
+ /* Begin PBXResourcesBuildPhase section */
350
+ 6666666666666666666666AA /* Resources */ = {
351
+ isa = PBXResourcesBuildPhase;
352
+ buildActionMask = 2147483647;
353
+ files = (
354
+ );
355
+ runOnlyForDeploymentPostprocessing = 0;
356
+ };
357
+ /* End PBXResourcesBuildPhase section */
358
+
359
+ /* Begin PBXSourcesBuildPhase section */
360
+ 5555555555555555555555AA /* Sources */ = {
361
+ isa = PBXSourcesBuildPhase;
362
+ buildActionMask = 2147483647;
363
+ files = (
364
+ 33333333333333333333333 /* ContentView.swift in Sources */,
365
+ 11111111111111111111111 /* App.swift in Sources */,
366
+ );
367
+ runOnlyForDeploymentPostprocessing = 0;
368
+ };
369
+ /* End PBXSourcesBuildPhase section */
370
+
371
+ /* Begin XCBuildConfiguration section */
372
+ 9999999999999999999999AA /* Debug */ = {
373
+ isa = XCBuildConfiguration;
374
+ buildSettings = {
375
+ ALWAYS_SEARCH_USER_PATHS = NO;
376
+ CLANG_ANALYZER_NONNULL = YES;
377
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
378
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
379
+ CLANG_CXX_LIBRARY = "libc++";
380
+ CLANG_ENABLE_MODULES = YES;
381
+ CLANG_ENABLE_OBJC_ARC = YES;
382
+ CLANG_ENABLE_OBJC_WEAK = YES;
383
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
384
+ CLANG_WARN_BOOL_CONVERSION = YES;
385
+ CLANG_WARN_COMMA = YES;
386
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
387
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
388
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
389
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
390
+ CLANG_WARN_EMPTY_BODY = YES;
391
+ CLANG_WARN_ENUM_CONVERSION = YES;
392
+ CLANG_WARN_INFINITE_RECURSION = YES;
393
+ CLANG_WARN_INT_CONVERSION = YES;
394
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
395
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
396
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
397
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
398
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
399
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
400
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
401
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
402
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
403
+ CLANG_WARN_UNREACHABLE_CODE = YES;
404
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
405
+ COPY_PHASE_STRIP = NO;
406
+ DEBUG_INFORMATION_FORMAT = dwarf;
407
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
408
+ ENABLE_TESTABILITY = YES;
409
+ GCC_C_LANGUAGE_STANDARD = gnu11;
410
+ GCC_DYNAMIC_NO_PIC = NO;
411
+ GCC_NO_COMMON_BLOCKS = YES;
412
+ GCC_OPTIMIZATION_LEVEL = 0;
413
+ GCC_PREPROCESSOR_DEFINITIONS = (
414
+ "DEBUG=1",
415
+ "$(inherited)",
416
+ );
417
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
418
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
419
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
420
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
421
+ GCC_WARN_UNUSED_FUNCTION = YES;
422
+ GCC_WARN_UNUSED_VARIABLE = YES;
423
+ MACOSX_DEPLOYMENT_TARGET = 12.0;
424
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
425
+ MTL_FAST_MATH = YES;
426
+ ONLY_ACTIVE_ARCH = YES;
427
+ SDKROOT = macosx;
428
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
429
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
430
+ };
431
+ name = Debug;
432
+ };
433
+ AAAAAAAAAAAAAAAAAAAAABBB /* Release */ = {
434
+ isa = XCBuildConfiguration;
435
+ buildSettings = {
436
+ ALWAYS_SEARCH_USER_PATHS = NO;
437
+ CLANG_ANALYZER_NONNULL = YES;
438
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
439
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
440
+ CLANG_CXX_LIBRARY = "libc++";
441
+ CLANG_ENABLE_MODULES = YES;
442
+ CLANG_ENABLE_OBJC_ARC = YES;
443
+ CLANG_ENABLE_OBJC_WEAK = YES;
444
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
445
+ CLANG_WARN_BOOL_CONVERSION = YES;
446
+ CLANG_WARN_COMMA = YES;
447
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
448
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
449
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
450
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
451
+ CLANG_WARN_EMPTY_BODY = YES;
452
+ CLANG_WARN_ENUM_CONVERSION = YES;
453
+ CLANG_WARN_INFINITE_RECURSION = YES;
454
+ CLANG_WARN_INT_CONVERSION = YES;
455
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
456
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
457
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
458
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
459
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
460
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
461
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
462
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
463
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
464
+ CLANG_WARN_UNREACHABLE_CODE = YES;
465
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
466
+ COPY_PHASE_STRIP = NO;
467
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
468
+ ENABLE_NS_ASSERTIONS = NO;
469
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
470
+ GCC_C_LANGUAGE_STANDARD = gnu11;
471
+ GCC_NO_COMMON_BLOCKS = YES;
472
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
473
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
474
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
475
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
476
+ GCC_WARN_UNUSED_FUNCTION = YES;
477
+ GCC_WARN_UNUSED_VARIABLE = YES;
478
+ MACOSX_DEPLOYMENT_TARGET = 12.0;
479
+ MTL_ENABLE_DEBUG_INFO = NO;
480
+ MTL_FAST_MATH = YES;
481
+ SDKROOT = macosx;
482
+ SWIFT_COMPILATION_MODE = wholemodule;
483
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
484
+ };
485
+ name = Release;
486
+ };
487
+ BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */ = {
488
+ isa = XCBuildConfiguration;
489
+ buildSettings = {
490
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
491
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
492
+ CODE_SIGN_STYLE = Manual;
493
+ COMBINE_HIDPI_IMAGES = YES;
494
+ DEVELOPMENT_TEAM = "";
495
+ ENABLE_HARDENED_RUNTIME = YES;
496
+ ENABLE_PREVIEWS = YES;
497
+ FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)";
498
+ INFOPLIST_FILE = "MacOSLlamaTest/Info.plist";
499
+ LD_RUNPATH_SEARCH_PATHS = (
500
+ "$(inherited)",
501
+ "@executable_path/../Frameworks",
502
+ );
503
+ PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.MacOSLlamaTest";
504
+ PRODUCT_NAME = "$(TARGET_NAME)";
505
+ PROVISIONING_PROFILE_SPECIFIER = "";
506
+ SWIFT_VERSION = 5.0;
507
+ };
508
+ name = Debug;
509
+ };
510
+ CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */ = {
511
+ isa = XCBuildConfiguration;
512
+ buildSettings = {
513
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
514
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
515
+ CODE_SIGN_STYLE = Manual;
516
+ COMBINE_HIDPI_IMAGES = YES;
517
+ DEVELOPMENT_TEAM = "";
518
+ ENABLE_HARDENED_RUNTIME = YES;
519
+ ENABLE_PREVIEWS = YES;
520
+ FRAMEWORK_SEARCH_PATHS = (
521
+ "$(inherited)",
522
+ "$(PROJECT_DIR)",
523
+ );
524
+ INFOPLIST_FILE = "MacOSLlamaTest/Info.plist";
525
+ LD_RUNPATH_SEARCH_PATHS = (
526
+ "$(inherited)",
527
+ "@executable_path/../Frameworks",
528
+ );
529
+ PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.MacOSLlamaTest";
530
+ PRODUCT_NAME = "$(TARGET_NAME)";
531
+ PROVISIONING_PROFILE_SPECIFIER = "";
532
+ SWIFT_VERSION = 5.0;
533
+ };
534
+ name = Release;
535
+ };
536
+ /* End XCBuildConfiguration section */
537
+ EOF
538
+
539
+ # Finish the project.pbxproj file
540
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
541
+ /* Begin XCConfigurationList section */
542
+ 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */ = {
543
+ isa = XCConfigurationList;
544
+ buildConfigurations = (
545
+ 9999999999999999999999AA /* Debug */,
546
+ AAAAAAAAAAAAAAAAAAAAABBB /* Release */,
547
+ );
548
+ defaultConfigurationIsVisible = 0;
549
+ defaultConfigurationName = Release;
550
+ };
551
+ 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */ = {
552
+ isa = XCConfigurationList;
553
+ buildConfigurations = (
554
+ BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */,
555
+ CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */,
556
+ );
557
+ defaultConfigurationIsVisible = 0;
558
+ defaultConfigurationName = Release;
559
+ };
560
+ /* End XCConfigurationList section */
561
+ };
562
+ rootObject = 7777777777777777777777AA /* Project object */;
563
+ }
564
+ EOF
565
+
566
+ # 2. Copy XCFramework to test project
567
+ echo "Copying XCFramework to test project..."
568
+ cp -R "${XCFRAMEWORK_PATH}" "${TEMP_DIR}/${APP_NAME}/"
569
+
570
+ # 3. Build and archive the app
571
+ echo "Building and archiving test app..."
572
+ cd "${TEMP_DIR}/${APP_NAME}"
573
+
574
+ # Create a simple xcscheme file to avoid xcodebuild scheme issues
575
+ mkdir -p "${APP_NAME}.xcodeproj/xcshareddata/xcschemes"
576
+ cat > "${APP_NAME}.xcodeproj/xcshareddata/xcschemes/${APP_NAME}.xcscheme" << EOF
577
+ <?xml version="1.0" encoding="UTF-8"?>
578
+ <Scheme
579
+ LastUpgradeVersion = "1240"
580
+ version = "1.3">
581
+ <BuildAction
582
+ parallelizeBuildables = "YES"
583
+ buildImplicitDependencies = "YES">
584
+ <BuildActionEntries>
585
+ <BuildActionEntry
586
+ buildForTesting = "YES"
587
+ buildForRunning = "YES"
588
+ buildForProfiling = "YES"
589
+ buildForArchiving = "YES"
590
+ buildForAnalyzing = "YES">
591
+ <BuildableReference
592
+ BuildableIdentifier = "primary"
593
+ BlueprintIdentifier = "3333333333333333333333AA"
594
+ BuildableName = "${APP_NAME}.app"
595
+ BlueprintName = "${APP_NAME}"
596
+ ReferencedContainer = "container:${APP_NAME}.xcodeproj">
597
+ </BuildableReference>
598
+ </BuildActionEntry>
599
+ </BuildActionEntries>
600
+ </BuildAction>
601
+ <TestAction
602
+ buildConfiguration = "Debug"
603
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
604
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
605
+ shouldUseLaunchSchemeArgsEnv = "YES">
606
+ <Testables>
607
+ </Testables>
608
+ </TestAction>
609
+ <LaunchAction
610
+ buildConfiguration = "Debug"
611
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
612
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
613
+ launchStyle = "0"
614
+ useCustomWorkingDirectory = "NO"
615
+ ignoresPersistentStateOnLaunch = "NO"
616
+ debugDocumentVersioning = "YES"
617
+ debugServiceExtension = "internal"
618
+ allowLocationSimulation = "YES">
619
+ <BuildableProductRunnable
620
+ runnableDebuggingMode = "0">
621
+ <BuildableReference
622
+ BuildableIdentifier = "primary"
623
+ BlueprintIdentifier = "3333333333333333333333AA"
624
+ BuildableName = "${APP_NAME}.app"
625
+ BlueprintName = "${APP_NAME}"
626
+ ReferencedContainer = "container:${APP_NAME}.xcodeproj">
627
+ </BuildableReference>
628
+ </BuildableProductRunnable>
629
+ </LaunchAction>
630
+ <ProfileAction
631
+ buildConfiguration = "Release"
632
+ shouldUseLaunchSchemeArgsEnv = "YES"
633
+ savedToolIdentifier = ""
634
+ useCustomWorkingDirectory = "NO"
635
+ debugDocumentVersioning = "YES">
636
+ <BuildableProductRunnable
637
+ runnableDebuggingMode = "0">
638
+ <BuildableReference
639
+ BuildableIdentifier = "primary"
640
+ BlueprintIdentifier = "3333333333333333333333AA"
641
+ BuildableName = "${APP_NAME}.app"
642
+ BlueprintName = "${APP_NAME}"
643
+ ReferencedContainer = "container:${APP_NAME}.xcodeproj">
644
+ </BuildableReference>
645
+ </BuildableProductRunnable>
646
+ </ProfileAction>
647
+ <AnalyzeAction
648
+ buildConfiguration = "Debug">
649
+ </AnalyzeAction>
650
+ <ArchiveAction
651
+ buildConfiguration = "Release"
652
+ revealArchiveInOrganizer = "YES">
653
+ </ArchiveAction>
654
+ </Scheme>
655
+ EOF
656
+
657
+ # Now use xcodebuild with an explicitly defined product name for macOS
658
+ xcodebuild -project "${APP_NAME}.xcodeproj" -scheme "${APP_NAME}" -sdk macosx -configuration Release archive -archivePath "${ARCHIVE_PATH}" CODE_SIGN_IDENTITY="-" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO PRODUCT_NAME="${APP_NAME}" SWIFT_OPTIMIZATION_LEVEL="-Onone" -quiet
659
+
660
+ # 4. Create a package for distribution
661
+ echo "Creating distributable package from archive..."
662
+ cp -R "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" "${APP_PATH}"
663
+
664
+ # Check and log app structure
665
+ echo "App structure:"
666
+ ls -la "${APP_PATH}"
667
+ echo "Frameworks:"
668
+ ls -la "${APP_PATH}/Contents/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
669
+
670
+ # Create a zip file for potential distribution
671
+ cd "${BUILD_DIR}"
672
+ zip -r "${ZIP_PATH}" "${APP_NAME}.app"
673
+
674
+ # Check embedded provisioning profile
675
+ echo "Checking provisioning profile (if any)..."
676
+ PROVISIONING_PROFILE=$(find "${APP_PATH}/Contents" -name "embedded.provisionprofile" 2>/dev/null)
677
+ if [ -n "$PROVISIONING_PROFILE" ]; then
678
+ echo "Found embedded provisioning profile:"
679
+ security cms -D -i "$PROVISIONING_PROFILE" || echo "Unable to decode provisioning profile"
680
+ else
681
+ echo "No embedded provisioning profile found (expected for ad-hoc builds)"
682
+ fi
683
+
684
+ # 5. Validate the app
685
+ echo "Validating macOS app..."
686
+ VALIDATION_OUTPUT="${VALIDATION_DIR}/validation_output.txt"
687
+
688
+ # Check if authentication credentials are provided
689
+ AUTH_ARGS=""
690
+ if [ -n "$APPLE_ID" ] && [ -n "$APPLE_PASSWORD" ]; then
691
+ echo "Using Apple ID authentication for validation..."
692
+ AUTH_ARGS="--username \"$APPLE_ID\" --password \"$APPLE_PASSWORD\""
693
+ else
694
+ echo "No authentication credentials provided. Will perform basic validation."
695
+ echo "To use your personal developer account, you can run the script with:"
696
+ echo " APPLE_ID='your.email@example.com' APPLE_PASSWORD='your-app-specific-password' ./validate-macos.sh"
697
+ echo "Note: You need to create an app-specific password at https://appleid.apple.com/account/manage"
698
+ fi
699
+
700
+ # For macOS we need to use notarytool or alternative checks because altool doesn't support macOS apps in the same way
701
+ echo "Note: For macOS, formal notarization process would require Apple Developer credentials."
702
+ echo "Performing alternative validation checks..."
703
+
704
+ # Final validation result
705
+ FINAL_VALIDATION_RESULT=0
706
+
707
+ # Check if app was created successfully
708
+ if [ -d "${APP_PATH}" ] && [ -s "${APP_PATH}/Contents/MacOS/${APP_NAME}" ]; then
709
+ echo "✅ App package created successfully"
710
+ else
711
+ echo "❌ App package not created or binary missing"
712
+ FINAL_VALIDATION_RESULT=1
713
+ fi
714
+
715
+ # Check if app binary exists and is executable
716
+ if [ -f "${APP_PATH}/Contents/MacOS/${APP_NAME}" ] && [ -x "${APP_PATH}/Contents/MacOS/${APP_NAME}" ]; then
717
+ echo "✅ App binary exists and is executable"
718
+ else
719
+ echo "❌ App binary missing or not executable"
720
+ FINAL_VALIDATION_RESULT=1
721
+ fi
722
+
723
+ # Check if framework was properly embedded
724
+ if [ -d "${APP_PATH}/Contents/Frameworks/llama.framework" ]; then
725
+ echo "✅ llama.framework properly embedded"
726
+ else
727
+ echo "❌ llama.framework not properly embedded"
728
+ FINAL_VALIDATION_RESULT=1
729
+ fi
730
+
731
+ # Check if framework binary exists
732
+ if [ -f "${APP_PATH}/Contents/Frameworks/llama.framework/Versions/A/llama" ]; then
733
+ echo "✅ Framework binary exists"
734
+
735
+ # Further validate framework by checking architecture
736
+ ARCHS=$(lipo -info "${APP_PATH}/Contents/Frameworks/llama.framework/Versions/A/llama" 2>/dev/null | grep -o "arm64\\|x86_64" | tr '\n' ' ')
737
+ if [ -n "$ARCHS" ]; then
738
+ echo "✅ Framework architecture(s): $ARCHS"
739
+ else
740
+ echo "⚠️ Could not determine framework architecture"
741
+ fi
742
+ else
743
+ echo "❌ Framework binary missing"
744
+ FINAL_VALIDATION_RESULT=1
745
+ fi
746
+
747
+ # Check code signing
748
+ echo ""
749
+ echo "==== CODE SIGNING INFO ===="
750
+ codesign -vv -d "${APP_PATH}" 2>&1 || echo "Code signing verification not available (expected for ad-hoc builds)"
751
+
752
+ if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
753
+ if [ -n "$AUTH_ARGS" ]; then
754
+ echo ""
755
+ echo "To notarize this app with Apple (requires Apple Developer account):"
756
+ echo "xcrun notarytool submit \"${ZIP_PATH}\" --apple-id \"your-apple-id\" --password \"your-app-specific-password\" --team-id \"your-team-id\" --wait"
757
+ echo ""
758
+ fi
759
+ echo "✅ Validation PASSED: macOS app built successfully with embedded framework"
760
+ else
761
+ echo "❌ Validation FAILED: Issues found with the app or framework"
762
+ fi
763
+
764
+ # Don't clean up on error to allow inspection
765
+ if [ $FINAL_VALIDATION_RESULT -ne 0 ]; then
766
+ echo ""
767
+ echo "Temporary files kept for inspection at: ${TEMP_DIR}"
768
+ echo "===== macOS Validation Process Failed ====="
769
+ exit 1
770
+ fi
771
+
772
+ # Clean up temporary files but keep build artifacts
773
+ if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
774
+ echo "Cleaning up temporary files..."
775
+ #rm -rf "${TEMP_DIR}"
776
+ fi
777
+
778
+ echo "===== macOS Validation Process Completed ====="
779
+ echo "App package available at: ${APP_PATH}"
780
+ echo "Zipped app available at: ${ZIP_PATH}"
781
+ exit $FINAL_VALIDATION_RESULT
llama.cpp/scripts/apple/validate-tvos.sh ADDED
@@ -0,0 +1,813 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ # validate-tvos.sh - Validate tvOS Application with embedded llama.xcframework using SwiftUI
3
+
4
+ # Authentication options (optional) (can be set via environment variables)
5
+ # To use: export APPLE_ID=your.email@example.com
6
+ # export APPLE_PASSWORD=your-app-specific-password
7
+ # ./validate-tvos.sh
8
+ APPLE_ID=${APPLE_ID:-""}
9
+ APPLE_PASSWORD=${APPLE_PASSWORD:-""}
10
+
11
+ # Ensure the script exits on error
12
+ set -e
13
+
14
+ # Function to print usage instructions
15
+ print_usage() {
16
+ echo "Usage: ./validate-tvos.sh [OPTIONS]"
17
+ echo ""
18
+ echo "Options:"
19
+ echo " --help Show this help message"
20
+ echo " --apple-id EMAIL Apple ID email for validation"
21
+ echo " --apple-password PWD App-specific password for Apple ID"
22
+ echo ""
23
+ echo "Environment variables:"
24
+ echo " APPLE_ID Apple ID email for validation"
25
+ echo " APPLE_PASSWORD App-specific password for Apple ID"
26
+ echo ""
27
+ echo "Notes:"
28
+ echo " - Command line options take precedence over environment variables"
29
+ echo " - Authentication is optional. If not provided, alternative validation will be performed"
30
+ echo " - For APPLE_PASSWORD, use an app-specific password generated at https://appleid.apple.com/account/manage"
31
+ }
32
+
33
+ # Parse command line arguments
34
+ while [[ $# -gt 0 ]]; do
35
+ case $1 in
36
+ --help)
37
+ print_usage
38
+ exit 0
39
+ ;;
40
+ --apple-id)
41
+ APPLE_ID="$2"
42
+ shift 2
43
+ ;;
44
+ --apple-password)
45
+ APPLE_PASSWORD="$2"
46
+ shift 2
47
+ ;;
48
+ *)
49
+ echo "Unknown option: $1"
50
+ print_usage
51
+ exit 1
52
+ ;;
53
+ esac
54
+ done
55
+
56
+ # Function to clean up in case of error
57
+ cleanup() {
58
+ # Don't clean up temp files on error to help with debugging
59
+ echo "===== tvOS Validation Process Failed ====="
60
+ exit 1
61
+ }
62
+
63
+ # Set up trap to call cleanup function on error
64
+ trap cleanup ERR
65
+
66
+ set -e # Exit on any error
67
+
68
+ ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )"
69
+ BUILD_DIR="${ROOT_DIR}/validation-builds/ios"
70
+
71
+ # Configuration
72
+ APP_NAME="TVOSLlamaTest"
73
+ BUNDLE_ID="org.ggml.TVOSLlamaTest"
74
+ XCFRAMEWORK_PATH="${ROOT_DIR}/build-apple/llama.xcframework"
75
+ TEMP_DIR="${BUILD_DIR}/temp"
76
+ ARCHIVE_PATH="${BUILD_DIR}/${APP_NAME}.xcarchive"
77
+ IPA_PATH="${BUILD_DIR}/${APP_NAME}.ipa"
78
+ VALIDATION_DIR="${BUILD_DIR}/validation"
79
+
80
+ # Create necessary directories
81
+ mkdir -p "${BUILD_DIR}"
82
+ mkdir -p "${TEMP_DIR}"
83
+ mkdir -p "${VALIDATION_DIR}"
84
+
85
+ echo "===== tvOS Validation Process Started ====="
86
+
87
+ # 1. Create a simple test app project
88
+ echo "Creating test tvOS app project..."
89
+ mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}"
90
+ cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Info.plist" << EOF
91
+ <?xml version="1.0" encoding="UTF-8"?>
92
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
93
+ <plist version="1.0">
94
+ <dict>
95
+ <key>CFBundleDevelopmentRegion</key>
96
+ <string>en</string>
97
+ <key>CFBundleExecutable</key>
98
+ <string>${APP_NAME}</string>
99
+ <key>CFBundleIdentifier</key>
100
+ <string>${BUNDLE_ID}</string>
101
+ <key>CFBundleInfoDictionaryVersion</key>
102
+ <string>6.0</string>
103
+ <key>CFBundleName</key>
104
+ <string>${APP_NAME}</string>
105
+ <key>CFBundlePackageType</key>
106
+ <string>APPL</string>
107
+ <key>CFBundleShortVersionString</key>
108
+ <string>1.0</string>
109
+ <key>CFBundleVersion</key>
110
+ <string>1</string>
111
+ <key>UIRequiredDeviceCapabilities</key>
112
+ <array>
113
+ <string>arm64</string>
114
+ </array>
115
+ </dict>
116
+ </plist>
117
+ EOF
118
+
119
+ # Create SwiftUI app files
120
+ mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources"
121
+
122
+ # Create App.swift
123
+ cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/App.swift" << EOF
124
+ import SwiftUI
125
+ import llama
126
+
127
+ @main
128
+ struct LlamaTestApp: App {
129
+ var body: some Scene {
130
+ WindowGroup {
131
+ ContentView()
132
+ }
133
+ }
134
+ }
135
+ EOF
136
+
137
+ # Create ContentView.swift with tvOS specific elements
138
+ cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/ContentView.swift" << EOF
139
+ import SwiftUI
140
+ import llama
141
+
142
+ struct ContentView: View {
143
+ // Test that we can initialize a llama context params struct
144
+ let params = llama_context_default_params()
145
+
146
+ var body: some View {
147
+ VStack(spacing: 40) {
148
+ Text("Llama Framework Test on tvOS")
149
+ .font(.largeTitle)
150
+ .padding()
151
+
152
+ Text("llama_context_default_params() created successfully")
153
+ .font(.headline)
154
+ .multilineTextAlignment(.center)
155
+ .padding()
156
+
157
+ // Display some param values to confirm the framework is working
158
+ Text("n_ctx: \(params.n_ctx)")
159
+ .font(.title2)
160
+
161
+ Text("n_batch: \(params.n_batch)")
162
+ .font(.title2)
163
+
164
+ Spacer()
165
+ }
166
+ .padding(50)
167
+ // Larger size suitable for TV display
168
+ }
169
+ }
170
+
171
+ struct ContentView_Previews: PreviewProvider {
172
+ static var previews: some View {
173
+ ContentView()
174
+ }
175
+ }
176
+ EOF
177
+
178
+ # Create project.pbxproj, fixing the framework search paths issues
179
+ mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj"
180
+ cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
181
+ // !$*UTF8*$!
182
+ {
183
+ archiveVersion = 1;
184
+ classes = {
185
+ };
186
+ objectVersion = 54;
187
+ objects = {
188
+
189
+ /* Begin PBXBuildFile section */
190
+ 11111111111111111111111 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22222222222222222222222; };
191
+ 33333333333333333333333 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44444444444444444444444; };
192
+ 55555555555555555555555 /* llama.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
193
+ 77777777777777777777777 /* llama.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
194
+ /* End PBXBuildFile section */
195
+
196
+ /* Begin PBXCopyFilesBuildPhase section */
197
+ 88888888888888888888888 /* Embed Frameworks */ = {
198
+ isa = PBXCopyFilesBuildPhase;
199
+ buildActionMask = 2147483647;
200
+ dstPath = "";
201
+ dstSubfolderSpec = 10;
202
+ files = (
203
+ 77777777777777777777777 /* llama.xcframework in Embed Frameworks */,
204
+ );
205
+ name = "Embed Frameworks";
206
+ runOnlyForDeploymentPostprocessing = 0;
207
+ };
208
+ /* End PBXCopyFilesBuildPhase section */
209
+
210
+ /* Begin PBXFileReference section */
211
+ EOF
212
+
213
+ # Continue with the project.pbxproj file, using the APP_NAME variable appropriately
214
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
215
+ 99999999999999999999999 /* ${APP_NAME}.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "${APP_NAME}.app"; sourceTree = BUILT_PRODUCTS_DIR; };
216
+ 22222222222222222222222 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
217
+ 44444444444444444444444 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
218
+ AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
219
+ 66666666666666666666666 /* llama.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = llama.xcframework; sourceTree = "<group>"; };
220
+ /* End PBXFileReference section */
221
+ EOF
222
+
223
+ # Add the rest of the project file with fixed framework search paths
224
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
225
+ /* Begin PBXFrameworksBuildPhase section */
226
+ BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */ = {
227
+ isa = PBXFrameworksBuildPhase;
228
+ buildActionMask = 2147483647;
229
+ files = (
230
+ 55555555555555555555555 /* llama.xcframework in Frameworks */,
231
+ );
232
+ runOnlyForDeploymentPostprocessing = 0;
233
+ };
234
+ /* End PBXFrameworksBuildPhase section */
235
+
236
+ /* Begin PBXGroup section */
237
+ EOF
238
+
239
+ # Continue with the project.pbxproj file, using the APP_NAME variable appropriately
240
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
241
+ CCCCCCCCCCCCCCCCCCCCCCCC /* Products */ = {
242
+ isa = PBXGroup;
243
+ children = (
244
+ 99999999999999999999999 /* ${APP_NAME}.app */,
245
+ );
246
+ name = Products;
247
+ sourceTree = "<group>";
248
+ };
249
+ EOF
250
+
251
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
252
+ DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */ = {
253
+ isa = PBXGroup;
254
+ children = (
255
+ 66666666666666666666666 /* llama.xcframework */,
256
+ );
257
+ name = Frameworks;
258
+ sourceTree = "<group>";
259
+ };
260
+ EEEEEEEEEEEEEEEEEEEEEEEE = {
261
+ isa = PBXGroup;
262
+ children = (
263
+ FFFFFFFFFFFFFFFFFFFFFFFF /* TVOSLlamaTest */,
264
+ CCCCCCCCCCCCCCCCCCCCCCCC /* Products */,
265
+ DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */,
266
+ );
267
+ sourceTree = "<group>";
268
+ };
269
+ FFFFFFFFFFFFFFFFFFFFFFFF /* TVOSLlamaTest */ = {
270
+ isa = PBXGroup;
271
+ children = (
272
+ 1111111111111111111111AA /* Sources */,
273
+ AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */,
274
+ );
275
+ path = "TVOSLlamaTest";
276
+ sourceTree = "<group>";
277
+ };
278
+ 1111111111111111111111AA /* Sources */ = {
279
+ isa = PBXGroup;
280
+ children = (
281
+ 22222222222222222222222 /* App.swift */,
282
+ 44444444444444444444444 /* ContentView.swift */,
283
+ );
284
+ path = Sources;
285
+ sourceTree = "<group>";
286
+ };
287
+ /* End PBXGroup section */
288
+ EOF
289
+
290
+ # Continue with the project.pbxproj file, using the APP_NAME variable appropriately
291
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
292
+ /* Begin PBXNativeTarget section */
293
+ 3333333333333333333333AA /* ${APP_NAME} */ = {
294
+ isa = PBXNativeTarget;
295
+ buildConfigurationList = 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */;
296
+ buildPhases = (
297
+ 5555555555555555555555AA /* Sources */,
298
+ BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */,
299
+ 6666666666666666666666AA /* Resources */,
300
+ 88888888888888888888888 /* Embed Frameworks */,
301
+ );
302
+ buildRules = (
303
+ );
304
+ dependencies = (
305
+ );
306
+ name = "${APP_NAME}";
307
+ productName = "${APP_NAME}";
308
+ productReference = 99999999999999999999999 /* ${APP_NAME}.app */;
309
+ productType = "com.apple.product-type.application";
310
+ };
311
+ /* End PBXNativeTarget section */
312
+
313
+ /* Begin PBXProject section */
314
+ 7777777777777777777777AA /* Project object */ = {
315
+ isa = PBXProject;
316
+ attributes = {
317
+ LastSwiftUpdateCheck = 1240;
318
+ LastUpgradeCheck = 1240;
319
+ TargetAttributes = {
320
+ 3333333333333333333333AA = {
321
+ CreatedOnToolsVersion = 12.4;
322
+ };
323
+ };
324
+ };
325
+ buildConfigurationList = 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */;
326
+ compatibilityVersion = "Xcode 12.0";
327
+ developmentRegion = en;
328
+ hasScannedForEncodings = 0;
329
+ knownRegions = (
330
+ en,
331
+ Base,
332
+ );
333
+ mainGroup = EEEEEEEEEEEEEEEEEEEEEEEE;
334
+ productRefGroup = CCCCCCCCCCCCCCCCCCCCCCCC /* Products */;
335
+ projectDirPath = "";
336
+ projectRoot = "";
337
+ targets = (
338
+ 3333333333333333333333AA /* ${APP_NAME} */,
339
+ );
340
+ };
341
+ /* End PBXProject section */
342
+ EOF
343
+
344
+ # Add the rest of the file with correct FRAMEWORK_SEARCH_PATHS and tvOS settings
345
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
346
+ /* Begin PBXResourcesBuildPhase section */
347
+ 6666666666666666666666AA /* Resources */ = {
348
+ isa = PBXResourcesBuildPhase;
349
+ buildActionMask = 2147483647;
350
+ files = (
351
+ );
352
+ runOnlyForDeploymentPostprocessing = 0;
353
+ };
354
+ /* End PBXResourcesBuildPhase section */
355
+
356
+ /* Begin PBXSourcesBuildPhase section */
357
+ 5555555555555555555555AA /* Sources */ = {
358
+ isa = PBXSourcesBuildPhase;
359
+ buildActionMask = 2147483647;
360
+ files = (
361
+ 33333333333333333333333 /* ContentView.swift in Sources */,
362
+ 11111111111111111111111 /* App.swift in Sources */,
363
+ );
364
+ runOnlyForDeploymentPostprocessing = 0;
365
+ };
366
+ /* End PBXSourcesBuildPhase section */
367
+
368
+ /* Begin XCBuildConfiguration section */
369
+ 9999999999999999999999AA /* Debug */ = {
370
+ isa = XCBuildConfiguration;
371
+ buildSettings = {
372
+ ALWAYS_SEARCH_USER_PATHS = NO;
373
+ CLANG_ANALYZER_NONNULL = YES;
374
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
375
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
376
+ CLANG_CXX_LIBRARY = "libc++";
377
+ CLANG_ENABLE_MODULES = YES;
378
+ CLANG_ENABLE_OBJC_ARC = YES;
379
+ CLANG_ENABLE_OBJC_WEAK = YES;
380
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
381
+ CLANG_WARN_BOOL_CONVERSION = YES;
382
+ CLANG_WARN_COMMA = YES;
383
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
384
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
385
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
386
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
387
+ CLANG_WARN_EMPTY_BODY = YES;
388
+ CLANG_WARN_ENUM_CONVERSION = YES;
389
+ CLANG_WARN_INFINITE_RECURSION = YES;
390
+ CLANG_WARN_INT_CONVERSION = YES;
391
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
392
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
393
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
394
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
395
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
396
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
397
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
398
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
399
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
400
+ CLANG_WARN_UNREACHABLE_CODE = YES;
401
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
402
+ COPY_PHASE_STRIP = NO;
403
+ DEBUG_INFORMATION_FORMAT = dwarf;
404
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
405
+ ENABLE_TESTABILITY = YES;
406
+ GCC_C_LANGUAGE_STANDARD = gnu11;
407
+ GCC_DYNAMIC_NO_PIC = NO;
408
+ GCC_NO_COMMON_BLOCKS = YES;
409
+ GCC_OPTIMIZATION_LEVEL = 0;
410
+ GCC_PREPROCESSOR_DEFINITIONS = (
411
+ "DEBUG=1",
412
+ "$(inherited)",
413
+ );
414
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
415
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
416
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
417
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
418
+ GCC_WARN_UNUSED_FUNCTION = YES;
419
+ GCC_WARN_UNUSED_VARIABLE = YES;
420
+ TVOS_DEPLOYMENT_TARGET = 15.0;
421
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
422
+ MTL_FAST_MATH = YES;
423
+ ONLY_ACTIVE_ARCH = YES;
424
+ SDKROOT = appletvos;
425
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
426
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
427
+ };
428
+ name = Debug;
429
+ };
430
+ AAAAAAAAAAAAAAAAAAAAABBB /* Release */ = {
431
+ isa = XCBuildConfiguration;
432
+ buildSettings = {
433
+ ALWAYS_SEARCH_USER_PATHS = NO;
434
+ CLANG_ANALYZER_NONNULL = YES;
435
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
436
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
437
+ CLANG_CXX_LIBRARY = "libc++";
438
+ CLANG_ENABLE_MODULES = YES;
439
+ CLANG_ENABLE_OBJC_ARC = YES;
440
+ CLANG_ENABLE_OBJC_WEAK = YES;
441
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
442
+ CLANG_WARN_BOOL_CONVERSION = YES;
443
+ CLANG_WARN_COMMA = YES;
444
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
445
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
446
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
447
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
448
+ CLANG_WARN_EMPTY_BODY = YES;
449
+ CLANG_WARN_ENUM_CONVERSION = YES;
450
+ CLANG_WARN_INFINITE_RECURSION = YES;
451
+ CLANG_WARN_INT_CONVERSION = YES;
452
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
453
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
454
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
455
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
456
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
457
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
458
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
459
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
460
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
461
+ CLANG_WARN_UNREACHABLE_CODE = YES;
462
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
463
+ COPY_PHASE_STRIP = NO;
464
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
465
+ ENABLE_NS_ASSERTIONS = NO;
466
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
467
+ GCC_C_LANGUAGE_STANDARD = gnu11;
468
+ GCC_NO_COMMON_BLOCKS = YES;
469
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
470
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
471
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
472
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
473
+ GCC_WARN_UNUSED_FUNCTION = YES;
474
+ GCC_WARN_UNUSED_VARIABLE = YES;
475
+ TVOS_DEPLOYMENT_TARGET = 15.0;
476
+ MTL_ENABLE_DEBUG_INFO = NO;
477
+ MTL_FAST_MATH = YES;
478
+ SDKROOT = appletvos;
479
+ SWIFT_COMPILATION_MODE = wholemodule;
480
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
481
+ VALIDATE_PRODUCT = YES;
482
+ };
483
+ name = Release;
484
+ };
485
+ BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */ = {
486
+ isa = XCBuildConfiguration;
487
+ buildSettings = {
488
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
489
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
490
+ CODE_SIGN_STYLE = Manual;
491
+ DEVELOPMENT_TEAM = "";
492
+ ENABLE_PREVIEWS = YES;
493
+ FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)";
494
+ INFOPLIST_FILE = "TVOSLlamaTest/Info.plist";
495
+ LD_RUNPATH_SEARCH_PATHS = (
496
+ "$(inherited)",
497
+ "@executable_path/Frameworks",
498
+ );
499
+ PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.TVOSLlamaTest";
500
+ PRODUCT_NAME = "$(TARGET_NAME)";
501
+ PROVISIONING_PROFILE_SPECIFIER = "";
502
+ SWIFT_VERSION = 5.0;
503
+ TARGETED_DEVICE_FAMILY = 3;
504
+ };
505
+ name = Debug;
506
+ };
507
+ CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */ = {
508
+ isa = XCBuildConfiguration;
509
+ buildSettings = {
510
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
511
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
512
+ CODE_SIGN_STYLE = Manual;
513
+ DEVELOPMENT_TEAM = "";
514
+ ENABLE_PREVIEWS = YES;
515
+ FRAMEWORK_SEARCH_PATHS = (
516
+ "$(inherited)",
517
+ "$(PROJECT_DIR)",
518
+ );
519
+ INFOPLIST_FILE = "TVOSLlamaTest/Info.plist";
520
+ LD_RUNPATH_SEARCH_PATHS = (
521
+ "$(inherited)",
522
+ "@executable_path/Frameworks",
523
+ );
524
+ PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.TVOSLlamaTest";
525
+ PRODUCT_NAME = "$(TARGET_NAME)";
526
+ PROVISIONING_PROFILE_SPECIFIER = "";
527
+ SWIFT_VERSION = 5.0;
528
+ TARGETED_DEVICE_FAMILY = 3;
529
+ };
530
+ name = Release;
531
+ };
532
+ /* End XCBuildConfiguration section */
533
+ EOF
534
+
535
+ # Finish the project.pbxproj file
536
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
537
+ /* Begin XCConfigurationList section */
538
+ 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */ = {
539
+ isa = XCConfigurationList;
540
+ buildConfigurations = (
541
+ 9999999999999999999999AA /* Debug */,
542
+ AAAAAAAAAAAAAAAAAAAAABBB /* Release */,
543
+ );
544
+ defaultConfigurationIsVisible = 0;
545
+ defaultConfigurationName = Release;
546
+ };
547
+ 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */ = {
548
+ isa = XCConfigurationList;
549
+ buildConfigurations = (
550
+ BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */,
551
+ CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */,
552
+ );
553
+ defaultConfigurationIsVisible = 0;
554
+ defaultConfigurationName = Release;
555
+ };
556
+ /* End XCConfigurationList section */
557
+ };
558
+ rootObject = 7777777777777777777777AA /* Project object */;
559
+ }
560
+ EOF
561
+
562
+ # 2. Copy XCFramework to test project
563
+ echo "Copying XCFramework to test project..."
564
+ cp -R "${XCFRAMEWORK_PATH}" "${TEMP_DIR}/${APP_NAME}/"
565
+
566
+ # 3. Build and archive the app
567
+ echo "Building and archiving test app..."
568
+ cd "${TEMP_DIR}/${APP_NAME}"
569
+
570
+ # Create a simple xcscheme file to avoid xcodebuild scheme issues
571
+ mkdir -p "${APP_NAME}.xcodeproj/xcshareddata/xcschemes"
572
+ cat > "${APP_NAME}.xcodeproj/xcshareddata/xcschemes/${APP_NAME}.xcscheme" << EOF
573
+ <?xml version="1.0" encoding="UTF-8"?>
574
+ <Scheme
575
+ LastUpgradeVersion = "1240"
576
+ version = "1.3">
577
+ <BuildAction
578
+ parallelizeBuildables = "YES"
579
+ buildImplicitDependencies = "YES">
580
+ <BuildActionEntries>
581
+ <BuildActionEntry
582
+ buildForTesting = "YES"
583
+ buildForRunning = "YES"
584
+ buildForProfiling = "YES"
585
+ buildForArchiving = "YES"
586
+ buildForAnalyzing = "YES">
587
+ <BuildableReference
588
+ BuildableIdentifier = "primary"
589
+ BlueprintIdentifier = "3333333333333333333333AA"
590
+ BuildableName = "${APP_NAME}.app"
591
+ BlueprintName = "${APP_NAME}"
592
+ ReferencedContainer = "container:${APP_NAME}.xcodeproj">
593
+ </BuildableReference>
594
+ </BuildActionEntry>
595
+ </BuildActionEntries>
596
+ </BuildAction>
597
+ <TestAction
598
+ buildConfiguration = "Debug"
599
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
600
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
601
+ shouldUseLaunchSchemeArgsEnv = "YES">
602
+ <Testables>
603
+ </Testables>
604
+ </TestAction>
605
+ <LaunchAction
606
+ buildConfiguration = "Debug"
607
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
608
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
609
+ launchStyle = "0"
610
+ useCustomWorkingDirectory = "NO"
611
+ ignoresPersistentStateOnLaunch = "NO"
612
+ debugDocumentVersioning = "YES"
613
+ debugServiceExtension = "internal"
614
+ allowLocationSimulation = "YES">
615
+ <BuildableProductRunnable
616
+ runnableDebuggingMode = "0">
617
+ <BuildableReference
618
+ BuildableIdentifier = "primary"
619
+ BlueprintIdentifier = "3333333333333333333333AA"
620
+ BuildableName = "${APP_NAME}.app"
621
+ BlueprintName = "${APP_NAME}"
622
+ ReferencedContainer = "container:${APP_NAME}.xcodeproj">
623
+ </BuildableReference>
624
+ </BuildableProductRunnable>
625
+ </LaunchAction>
626
+ <ProfileAction
627
+ buildConfiguration = "Release"
628
+ shouldUseLaunchSchemeArgsEnv = "YES"
629
+ savedToolIdentifier = ""
630
+ useCustomWorkingDirectory = "NO"
631
+ debugDocumentVersioning = "YES">
632
+ <BuildableProductRunnable
633
+ runnableDebuggingMode = "0">
634
+ <BuildableReference
635
+ BuildableIdentifier = "primary"
636
+ BlueprintIdentifier = "3333333333333333333333AA"
637
+ BuildableName = "${APP_NAME}.app"
638
+ BlueprintName = "${APP_NAME}"
639
+ ReferencedContainer = "container:${APP_NAME}.xcodeproj">
640
+ </BuildableReference>
641
+ </BuildableProductRunnable>
642
+ </ProfileAction>
643
+ <AnalyzeAction
644
+ buildConfiguration = "Debug">
645
+ </AnalyzeAction>
646
+ <ArchiveAction
647
+ buildConfiguration = "Release"
648
+ revealArchiveInOrganizer = "YES">
649
+ </ArchiveAction>
650
+ </Scheme>
651
+ EOF
652
+
653
+ # Now use xcodebuild with an explicitly defined product name for tvOS
654
+ xcodebuild -project "${APP_NAME}.xcodeproj" -scheme "${APP_NAME}" -sdk appletvos -configuration Release archive -archivePath "${ARCHIVE_PATH}" CODE_SIGN_IDENTITY="-" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO PRODUCT_NAME="${APP_NAME}" SWIFT_OPTIMIZATION_LEVEL="-Onone" -quiet
655
+
656
+ # 4. Create IPA from archive
657
+ echo "Creating IPA from archive..."
658
+ mkdir -p "${TEMP_DIR}/Payload"
659
+ cp -R "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" "${TEMP_DIR}/Payload/"
660
+
661
+ # Check and log app structure before zipping
662
+ echo "App structure:"
663
+ ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/"
664
+ echo "Frameworks:"
665
+ ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
666
+
667
+ cd "${TEMP_DIR}"
668
+ zip -r "${IPA_PATH}" Payload
669
+
670
+ # Check embedded provisioning profile
671
+ echo "Checking provisioning profile (if any)..."
672
+ PROVISIONING_PROFILE=$(find "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" -name "embedded.mobileprovision" 2>/dev/null)
673
+ if [ -n "$PROVISIONING_PROFILE" ]; then
674
+ echo "Found embedded provisioning profile:"
675
+ security cms -D -i "$PROVISIONING_PROFILE" || echo "Unable to decode provisioning profile"
676
+ else
677
+ echo "No embedded provisioning profile found (expected for ad-hoc builds)"
678
+ fi
679
+
680
+ # 5. Validate the IPA
681
+ echo "Validating IPA..."
682
+ VALIDATION_OUTPUT="${VALIDATION_DIR}/validation_output.txt"
683
+
684
+ # Check if authentication credentials are provided
685
+ AUTH_ARGS=""
686
+ if [ -n "$APPLE_ID" ] && [ -n "$APPLE_PASSWORD" ]; then
687
+ echo "Using Apple ID authentication for validation..."
688
+ AUTH_ARGS="--username \"$APPLE_ID\" --password \"$APPLE_PASSWORD\""
689
+ else
690
+ echo "No authentication credentials provided. Will perform basic validation."
691
+ echo "To use your personal developer account, you can run the script with:"
692
+ echo " APPLE_ID='your.email@example.com' APPLE_PASSWORD='your-app-specific-password' ./validate-tvos.sh"
693
+ echo "Note: You need to create an app-specific password at https://appleid.apple.com/account/manage"
694
+ fi
695
+
696
+ # Run validation with detailed output
697
+ echo "Running validation with altool..."
698
+ if [ -n "$AUTH_ARGS" ]; then
699
+ # Use eval to properly handle the quoted arguments
700
+ eval "xcrun altool --validate-app -f \"${IPA_PATH}\" --type tvos --output-format xml $AUTH_ARGS" 2>&1 | tee "${VALIDATION_OUTPUT}"
701
+ else
702
+ xcrun altool --validate-app -f "${IPA_PATH}" --type tvos --output-format xml 2>&1 | tee "${VALIDATION_OUTPUT}"
703
+ fi
704
+ VALIDATION_RESULT=$?
705
+
706
+ # Final validation result
707
+ FINAL_VALIDATION_RESULT=0
708
+
709
+ # Check if validation failed because the app isn't in App Store Connect
710
+ if grep -q "No suitable application records were found" "${VALIDATION_OUTPUT}"; then
711
+ echo "⚠️ App Store Connect Warning: The app bundle identifier is not found in App Store Connect"
712
+ echo "This is expected for apps that haven't been registered in App Store Connect yet."
713
+ echo "This doesn't indicate a problem with the build or framework."
714
+
715
+ # Perform alternative validation
716
+ echo "Performing alternative validation checks..."
717
+
718
+ # Check if IPA was created successfully
719
+ if [ -f "${IPA_PATH}" ] && [ -s "${IPA_PATH}" ]; then
720
+ echo "✅ IPA file created successfully"
721
+ else
722
+ echo "❌ IPA file not created or empty"
723
+ FINAL_VALIDATION_RESULT=1
724
+ fi
725
+
726
+ # Check if app binary exists and is executable
727
+ if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ] && [ -x "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ]; then
728
+ echo "✅ App binary exists and is executable"
729
+ else
730
+ echo "❌ App binary missing or not executable"
731
+ FINAL_VALIDATION_RESULT=1
732
+ fi
733
+
734
+ # Check if framework was properly embedded
735
+ if [ -d "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework" ]; then
736
+ echo "✅ llama.framework properly embedded"
737
+ else
738
+ echo "❌ llama.framework not properly embedded"
739
+ FINAL_VALIDATION_RESULT=1
740
+ fi
741
+
742
+ # Check if framework binary exists
743
+ if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework/llama" ]; then
744
+ echo "✅ Framework binary exists"
745
+
746
+ # Further validate framework by checking architecture
747
+ ARCHS=$(lipo -info "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework/llama" 2>/dev/null | grep -o "arm64\\|x86_64" | tr '\n' ' ')
748
+ if [ -n "$ARCHS" ]; then
749
+ echo "✅ Framework architecture(s): $ARCHS"
750
+ else
751
+ echo "⚠️ Could not determine framework architecture"
752
+ fi
753
+ else
754
+ echo "❌ Framework binary missing"
755
+ FINAL_VALIDATION_RESULT=1
756
+ fi
757
+
758
+ if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
759
+ echo "✅ Alternative validation PASSED: App built successfully with embedded framework"
760
+ else
761
+ echo "❌ Alternative validation FAILED: Issues found with the app or framework"
762
+ fi
763
+ elif grep -q "You must specify authentication credentials" "${VALIDATION_OUTPUT}" && [ -z "$AUTH_ARGS" ]; then
764
+ echo "✅ tvOS Validation PASSED: IPA successfully validated"
765
+ echo "Results saved to ${VALIDATION_OUTPUT}"
766
+ else
767
+ echo "❌ tvOS Validation FAILED: IPA validation found issues"
768
+ echo "See validation output at ${VALIDATION_OUTPUT}"
769
+ echo ""
770
+ echo "==== VALIDATION ERRORS ===="
771
+
772
+ # Try to extract specific errors from the output
773
+ if grep -q "Error" "${VALIDATION_OUTPUT}"; then
774
+ grep -A 5 "Error" "${VALIDATION_OUTPUT}"
775
+ else
776
+ # If no specific error found, show the whole log
777
+ cat "${VALIDATION_OUTPUT}"
778
+ fi
779
+
780
+ # Additional debugging: check IPA contents
781
+ echo ""
782
+ echo "==== IPA CONTENTS ===="
783
+ mkdir -p "${TEMP_DIR}/ipa_contents"
784
+ unzip -q "${IPA_PATH}" -d "${TEMP_DIR}/ipa_contents"
785
+ ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/"
786
+
787
+ # Check for code signing issues
788
+ echo ""
789
+ echo "==== CODE SIGNING INFO ===="
790
+ codesign -vv -d "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app" 2>&1 || echo "Code signing verification failed"
791
+
792
+ # Check embedded frameworks
793
+ echo ""
794
+ echo "==== FRAMEWORK INFO ===="
795
+ ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
796
+ fi
797
+
798
+ # Don't clean up on error to allow inspection
799
+ if [ $FINAL_VALIDATION_RESULT -ne 0 ]; then
800
+ echo ""
801
+ echo "Temporary files kept for inspection at: ${TEMP_DIR}"
802
+ echo "===== tvOS Validation Process Failed ====="
803
+ exit 1
804
+ fi
805
+
806
+ # Clean up temporary files but keep build artifacts
807
+ if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
808
+ echo "Cleaning up temporary files..."
809
+ #rm -rf "${TEMP_DIR}"
810
+ fi
811
+
812
+ echo "===== tvOS Validation Process Completed ====="
813
+ exit $FINAL_VALIDATION_RESULT
llama.cpp/scripts/apple/validate-visionos.sh ADDED
@@ -0,0 +1,811 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ # validate-visionos.sh - Validate visionOS Application with embedded llama.xcframework using SwiftUI
3
+
4
+ # Authentication options (optional) (can be set via environment variables)
5
+ # To use: export APPLE_ID=your.email@example.com
6
+ # export APPLE_PASSWORD=your-app-specific-password
7
+ # ./validate-visionos.sh
8
+ APPLE_ID=${APPLE_ID:-""}
9
+ APPLE_PASSWORD=${APPLE_PASSWORD:-""}
10
+
11
+ # Ensure the script exits on error
12
+ set -e
13
+
14
+ # Function to print usage instructions
15
+ print_usage() {
16
+ echo "Usage: ./validate-visionos.sh [OPTIONS]"
17
+ echo ""
18
+ echo "Options:"
19
+ echo " --help Show this help message"
20
+ echo " --apple-id EMAIL Apple ID email for validation"
21
+ echo " --apple-password PWD App-specific password for Apple ID"
22
+ echo ""
23
+ echo "Environment variables:"
24
+ echo " APPLE_ID Apple ID email for validation"
25
+ echo " APPLE_PASSWORD App-specific password for Apple ID"
26
+ echo ""
27
+ echo "Notes:"
28
+ echo " - Command line options take precedence over environment variables"
29
+ echo " - Authentication is optional. If not provided, alternative validation will be performed"
30
+ echo " - For APPLE_PASSWORD, use an app-specific password generated at https://appleid.apple.com/account/manage"
31
+ }
32
+
33
+ # Parse command line arguments
34
+ while [[ $# -gt 0 ]]; do
35
+ case $1 in
36
+ --help)
37
+ print_usage
38
+ exit 0
39
+ ;;
40
+ --apple-id)
41
+ APPLE_ID="$2"
42
+ shift 2
43
+ ;;
44
+ --apple-password)
45
+ APPLE_PASSWORD="$2"
46
+ shift 2
47
+ ;;
48
+ *)
49
+ echo "Unknown option: $1"
50
+ print_usage
51
+ exit 1
52
+ ;;
53
+ esac
54
+ done
55
+
56
+ # Function to clean up in case of error
57
+ cleanup() {
58
+ # Don't clean up temp files on error to help with debugging
59
+ echo "===== visionOS Validation Process Failed ====="
60
+ exit 1
61
+ }
62
+
63
+ # Set up trap to call cleanup function on error
64
+ trap cleanup ERR
65
+
66
+ set -e # Exit on any error
67
+
68
+ ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )"
69
+ BUILD_DIR="${ROOT_DIR}/validation-builds/visionos"
70
+
71
+ # Configuration
72
+ APP_NAME="VisionOSLlamaTest"
73
+ BUNDLE_ID="org.ggml.VisionOSLlamaTest"
74
+ XCFRAMEWORK_PATH="${ROOT_DIR}/build-apple/llama.xcframework"
75
+ TEMP_DIR="${BUILD_DIR}/temp"
76
+ ARCHIVE_PATH="${BUILD_DIR}/${APP_NAME}.xcarchive"
77
+ IPA_PATH="${BUILD_DIR}/${APP_NAME}.ipa"
78
+ VALIDATION_DIR="${BUILD_DIR}/validation"
79
+
80
+ # Create necessary directories
81
+ mkdir -p "${BUILD_DIR}"
82
+ mkdir -p "${TEMP_DIR}"
83
+ mkdir -p "${VALIDATION_DIR}"
84
+
85
+ echo "===== visionOS Validation Process Started ====="
86
+
87
+ # 1. Create a simple test app project
88
+ echo "Creating test visionOS app project..."
89
+ mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}"
90
+ cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Info.plist" << EOF
91
+ <?xml version="1.0" encoding="UTF-8"?>
92
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
93
+ <plist version="1.0">
94
+ <dict>
95
+ <key>CFBundleDevelopmentRegion</key>
96
+ <string>en</string>
97
+ <key>CFBundleExecutable</key>
98
+ <string>${APP_NAME}</string>
99
+ <key>CFBundleIdentifier</key>
100
+ <string>${BUNDLE_ID}</string>
101
+ <key>CFBundleInfoDictionaryVersion</key>
102
+ <string>6.0</string>
103
+ <key>CFBundleName</key>
104
+ <string>${APP_NAME}</string>
105
+ <key>CFBundlePackageType</key>
106
+ <string>APPL</string>
107
+ <key>CFBundleShortVersionString</key>
108
+ <string>1.0</string>
109
+ <key>CFBundleVersion</key>
110
+ <string>1</string>
111
+ </dict>
112
+ </plist>
113
+ EOF
114
+
115
+ # Create SwiftUI app files
116
+ mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources"
117
+
118
+ # Create App.swift
119
+ cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/App.swift" << EOF
120
+ import SwiftUI
121
+ import llama
122
+
123
+ @main
124
+ struct LlamaTestApp: App {
125
+ var body: some Scene {
126
+ WindowGroup {
127
+ ContentView()
128
+ }
129
+ }
130
+ }
131
+ EOF
132
+
133
+ # Create ContentView.swift with visionOS specific elements
134
+ cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/ContentView.swift" << EOF
135
+ import SwiftUI
136
+ import llama
137
+
138
+ struct ContentView: View {
139
+ // Test that we can initialize a llama context params struct
140
+ let params = llama_context_default_params()
141
+
142
+ var body: some View {
143
+ VStack(spacing: 20) {
144
+ Text("Llama Framework Test on visionOS")
145
+ .font(.largeTitle)
146
+ .padding()
147
+
148
+ Text("llama_context_default_params() created successfully")
149
+ .font(.headline)
150
+ .multilineTextAlignment(.center)
151
+ .padding()
152
+
153
+ // Display some param values to confirm the framework is working
154
+ Text("n_ctx: \(params.n_ctx)")
155
+ .font(.body)
156
+
157
+ Text("n_batch: \(params.n_batch)")
158
+ .font(.body)
159
+
160
+ Spacer()
161
+ }
162
+ .padding()
163
+ .frame(width: 500, height: 400)
164
+ }
165
+ }
166
+
167
+ struct ContentView_Previews: PreviewProvider {
168
+ static var previews: some View {
169
+ ContentView()
170
+ }
171
+ }
172
+ EOF
173
+
174
+ # Create project.pbxproj, fixing the framework search paths issues
175
+ mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj"
176
+ cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
177
+ // !$*UTF8*$!
178
+ {
179
+ archiveVersion = 1;
180
+ classes = {
181
+ };
182
+ objectVersion = 54;
183
+ objects = {
184
+
185
+ /* Begin PBXBuildFile section */
186
+ 11111111111111111111111 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22222222222222222222222; };
187
+ 33333333333333333333333 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44444444444444444444444; };
188
+ 55555555555555555555555 /* llama.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
189
+ 77777777777777777777777 /* llama.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
190
+ /* End PBXBuildFile section */
191
+
192
+ /* Begin PBXCopyFilesBuildPhase section */
193
+ 88888888888888888888888 /* Embed Frameworks */ = {
194
+ isa = PBXCopyFilesBuildPhase;
195
+ buildActionMask = 2147483647;
196
+ dstPath = "";
197
+ dstSubfolderSpec = 10;
198
+ files = (
199
+ 77777777777777777777777 /* llama.xcframework in Embed Frameworks */,
200
+ );
201
+ name = "Embed Frameworks";
202
+ runOnlyForDeploymentPostprocessing = 0;
203
+ };
204
+ /* End PBXCopyFilesBuildPhase section */
205
+
206
+ /* Begin PBXFileReference section */
207
+ EOF
208
+
209
+ # Continue with the project.pbxproj file, using the APP_NAME variable appropriately
210
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
211
+ 99999999999999999999999 /* ${APP_NAME}.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "${APP_NAME}.app"; sourceTree = BUILT_PRODUCTS_DIR; };
212
+ 22222222222222222222222 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
213
+ 44444444444444444444444 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
214
+ AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
215
+ 66666666666666666666666 /* llama.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = llama.xcframework; sourceTree = "<group>"; };
216
+ /* End PBXFileReference section */
217
+ EOF
218
+
219
+ # Add the rest of the project file with fixed framework search paths
220
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
221
+ /* Begin PBXFrameworksBuildPhase section */
222
+ BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */ = {
223
+ isa = PBXFrameworksBuildPhase;
224
+ buildActionMask = 2147483647;
225
+ files = (
226
+ 55555555555555555555555 /* llama.xcframework in Frameworks */,
227
+ );
228
+ runOnlyForDeploymentPostprocessing = 0;
229
+ };
230
+ /* End PBXFrameworksBuildPhase section */
231
+
232
+ /* Begin PBXGroup section */
233
+ EOF
234
+
235
+ # Continue with the project.pbxproj file, using the APP_NAME variable appropriately
236
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
237
+ CCCCCCCCCCCCCCCCCCCCCCCC /* Products */ = {
238
+ isa = PBXGroup;
239
+ children = (
240
+ 99999999999999999999999 /* ${APP_NAME}.app */,
241
+ );
242
+ name = Products;
243
+ sourceTree = "<group>";
244
+ };
245
+ EOF
246
+
247
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
248
+ DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */ = {
249
+ isa = PBXGroup;
250
+ children = (
251
+ 66666666666666666666666 /* llama.xcframework */,
252
+ );
253
+ name = Frameworks;
254
+ sourceTree = "<group>";
255
+ };
256
+ EEEEEEEEEEEEEEEEEEEEEEEE = {
257
+ isa = PBXGroup;
258
+ children = (
259
+ FFFFFFFFFFFFFFFFFFFFFFFF /* VisionOSLlamaTest */,
260
+ CCCCCCCCCCCCCCCCCCCCCCCC /* Products */,
261
+ DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */,
262
+ );
263
+ sourceTree = "<group>";
264
+ };
265
+ FFFFFFFFFFFFFFFFFFFFFFFF /* VisionOSLlamaTest */ = {
266
+ isa = PBXGroup;
267
+ children = (
268
+ 1111111111111111111111AA /* Sources */,
269
+ AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */,
270
+ );
271
+ path = "VisionOSLlamaTest";
272
+ sourceTree = "<group>";
273
+ };
274
+ 1111111111111111111111AA /* Sources */ = {
275
+ isa = PBXGroup;
276
+ children = (
277
+ 22222222222222222222222 /* App.swift */,
278
+ 44444444444444444444444 /* ContentView.swift */,
279
+ );
280
+ path = Sources;
281
+ sourceTree = "<group>";
282
+ };
283
+ /* End PBXGroup section */
284
+ EOF
285
+
286
+ # Continue with the project.pbxproj file, using the APP_NAME variable appropriately
287
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
288
+ /* Begin PBXNativeTarget section */
289
+ 3333333333333333333333AA /* ${APP_NAME} */ = {
290
+ isa = PBXNativeTarget;
291
+ buildConfigurationList = 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */;
292
+ buildPhases = (
293
+ 5555555555555555555555AA /* Sources */,
294
+ BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */,
295
+ 6666666666666666666666AA /* Resources */,
296
+ 88888888888888888888888 /* Embed Frameworks */,
297
+ );
298
+ buildRules = (
299
+ );
300
+ dependencies = (
301
+ );
302
+ name = "${APP_NAME}";
303
+ productName = "${APP_NAME}";
304
+ productReference = 99999999999999999999999 /* ${APP_NAME}.app */;
305
+ productType = "com.apple.product-type.application";
306
+ };
307
+ /* End PBXNativeTarget section */
308
+
309
+ /* Begin PBXProject section */
310
+ 7777777777777777777777AA /* Project object */ = {
311
+ isa = PBXProject;
312
+ attributes = {
313
+ LastSwiftUpdateCheck = 1510;
314
+ LastUpgradeCheck = 1510;
315
+ TargetAttributes = {
316
+ 3333333333333333333333AA = {
317
+ CreatedOnToolsVersion = 15.1;
318
+ };
319
+ };
320
+ };
321
+ buildConfigurationList = 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */;
322
+ compatibilityVersion = "Xcode 15.0";
323
+ developmentRegion = en;
324
+ hasScannedForEncodings = 0;
325
+ knownRegions = (
326
+ en,
327
+ Base,
328
+ );
329
+ mainGroup = EEEEEEEEEEEEEEEEEEEEEEEE;
330
+ productRefGroup = CCCCCCCCCCCCCCCCCCCCCCCC /* Products */;
331
+ projectDirPath = "";
332
+ projectRoot = "";
333
+ targets = (
334
+ 3333333333333333333333AA /* ${APP_NAME} */,
335
+ );
336
+ };
337
+ /* End PBXProject section */
338
+ EOF
339
+
340
+ # Add the rest of the file with correct FRAMEWORK_SEARCH_PATHS
341
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
342
+ /* Begin PBXResourcesBuildPhase section */
343
+ 6666666666666666666666AA /* Resources */ = {
344
+ isa = PBXResourcesBuildPhase;
345
+ buildActionMask = 2147483647;
346
+ files = (
347
+ );
348
+ runOnlyForDeploymentPostprocessing = 0;
349
+ };
350
+ /* End PBXResourcesBuildPhase section */
351
+
352
+ /* Begin PBXSourcesBuildPhase section */
353
+ 5555555555555555555555AA /* Sources */ = {
354
+ isa = PBXSourcesBuildPhase;
355
+ buildActionMask = 2147483647;
356
+ files = (
357
+ 33333333333333333333333 /* ContentView.swift in Sources */,
358
+ 11111111111111111111111 /* App.swift in Sources */,
359
+ );
360
+ runOnlyForDeploymentPostprocessing = 0;
361
+ };
362
+ /* End PBXSourcesBuildPhase section */
363
+
364
+ /* Begin XCBuildConfiguration section */
365
+ 9999999999999999999999AA /* Debug */ = {
366
+ isa = XCBuildConfiguration;
367
+ buildSettings = {
368
+ ALWAYS_SEARCH_USER_PATHS = NO;
369
+ CLANG_ANALYZER_NONNULL = YES;
370
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
371
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
372
+ CLANG_CXX_LIBRARY = "libc++";
373
+ CLANG_ENABLE_MODULES = YES;
374
+ CLANG_ENABLE_OBJC_ARC = YES;
375
+ CLANG_ENABLE_OBJC_WEAK = YES;
376
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
377
+ CLANG_WARN_BOOL_CONVERSION = YES;
378
+ CLANG_WARN_COMMA = YES;
379
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
380
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
381
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
382
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
383
+ CLANG_WARN_EMPTY_BODY = YES;
384
+ CLANG_WARN_ENUM_CONVERSION = YES;
385
+ CLANG_WARN_INFINITE_RECURSION = YES;
386
+ CLANG_WARN_INT_CONVERSION = YES;
387
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
388
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
389
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
390
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
391
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
392
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
393
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
394
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
395
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
396
+ CLANG_WARN_UNREACHABLE_CODE = YES;
397
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
398
+ COPY_PHASE_STRIP = NO;
399
+ DEBUG_INFORMATION_FORMAT = dwarf;
400
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
401
+ ENABLE_TESTABILITY = YES;
402
+ GCC_C_LANGUAGE_STANDARD = gnu11;
403
+ GCC_DYNAMIC_NO_PIC = NO;
404
+ GCC_NO_COMMON_BLOCKS = YES;
405
+ GCC_OPTIMIZATION_LEVEL = 0;
406
+ GCC_PREPROCESSOR_DEFINITIONS = (
407
+ "DEBUG=1",
408
+ "$(inherited)",
409
+ );
410
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
411
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
412
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
413
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
414
+ GCC_WARN_UNUSED_FUNCTION = YES;
415
+ GCC_WARN_UNUSED_VARIABLE = YES;
416
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
417
+ MTL_FAST_MATH = YES;
418
+ ONLY_ACTIVE_ARCH = YES;
419
+ SDKROOT = xros;
420
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
421
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
422
+ XROS_DEPLOYMENT_TARGET = 1.0;
423
+ };
424
+ name = Debug;
425
+ };
426
+ AAAAAAAAAAAAAAAAAAAAABBB /* Release */ = {
427
+ isa = XCBuildConfiguration;
428
+ buildSettings = {
429
+ ALWAYS_SEARCH_USER_PATHS = NO;
430
+ CLANG_ANALYZER_NONNULL = YES;
431
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
432
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
433
+ CLANG_CXX_LIBRARY = "libc++";
434
+ CLANG_ENABLE_MODULES = YES;
435
+ CLANG_ENABLE_OBJC_ARC = YES;
436
+ CLANG_ENABLE_OBJC_WEAK = YES;
437
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
438
+ CLANG_WARN_BOOL_CONVERSION = YES;
439
+ CLANG_WARN_COMMA = YES;
440
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
441
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
442
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
443
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
444
+ CLANG_WARN_EMPTY_BODY = YES;
445
+ CLANG_WARN_ENUM_CONVERSION = YES;
446
+ CLANG_WARN_INFINITE_RECURSION = YES;
447
+ CLANG_WARN_INT_CONVERSION = YES;
448
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
449
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
450
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
451
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
452
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
453
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
454
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
455
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
456
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
457
+ CLANG_WARN_UNREACHABLE_CODE = YES;
458
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
459
+ COPY_PHASE_STRIP = NO;
460
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
461
+ ENABLE_NS_ASSERTIONS = NO;
462
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
463
+ GCC_C_LANGUAGE_STANDARD = gnu11;
464
+ GCC_NO_COMMON_BLOCKS = YES;
465
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
466
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
467
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
468
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
469
+ GCC_WARN_UNUSED_FUNCTION = YES;
470
+ GCC_WARN_UNUSED_VARIABLE = YES;
471
+ MTL_ENABLE_DEBUG_INFO = NO;
472
+ MTL_FAST_MATH = YES;
473
+ SDKROOT = xros;
474
+ SWIFT_COMPILATION_MODE = wholemodule;
475
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
476
+ VALIDATE_PRODUCT = YES;
477
+ XROS_DEPLOYMENT_TARGET = 1.0;
478
+ };
479
+ name = Release;
480
+ };
481
+ BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */ = {
482
+ isa = XCBuildConfiguration;
483
+ buildSettings = {
484
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
485
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
486
+ CODE_SIGN_STYLE = Manual;
487
+ DEVELOPMENT_TEAM = "";
488
+ ENABLE_PREVIEWS = YES;
489
+ FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)";
490
+ INFOPLIST_FILE = "VisionOSLlamaTest/Info.plist";
491
+ LD_RUNPATH_SEARCH_PATHS = (
492
+ "$(inherited)",
493
+ "@executable_path/Frameworks",
494
+ );
495
+ PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.VisionOSLlamaTest";
496
+ PRODUCT_NAME = "$(TARGET_NAME)";
497
+ PROVISIONING_PROFILE_SPECIFIER = "";
498
+ SUPPORTED_PLATFORMS = "xros xrsimulator";
499
+ SWIFT_VERSION = 5.0;
500
+ TARGETED_DEVICE_FAMILY = "1,2,7";
501
+ };
502
+ name = Debug;
503
+ };
504
+ CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */ = {
505
+ isa = XCBuildConfiguration;
506
+ buildSettings = {
507
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
508
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
509
+ CODE_SIGN_STYLE = Manual;
510
+ DEVELOPMENT_TEAM = "";
511
+ ENABLE_PREVIEWS = YES;
512
+ FRAMEWORK_SEARCH_PATHS = (
513
+ "$(inherited)",
514
+ "$(PROJECT_DIR)",
515
+ );
516
+ INFOPLIST_FILE = "VisionOSLlamaTest/Info.plist";
517
+ LD_RUNPATH_SEARCH_PATHS = (
518
+ "$(inherited)",
519
+ "@executable_path/Frameworks",
520
+ );
521
+ PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.VisionOSLlamaTest";
522
+ PRODUCT_NAME = "$(TARGET_NAME)";
523
+ PROVISIONING_PROFILE_SPECIFIER = "";
524
+ SUPPORTED_PLATFORMS = "xros xrsimulator";
525
+ SWIFT_VERSION = 5.0;
526
+ TARGETED_DEVICE_FAMILY = "1,2,7";
527
+ };
528
+ name = Release;
529
+ };
530
+ /* End XCBuildConfiguration section */
531
+ EOF
532
+
533
+ # Finish the project.pbxproj file
534
+ cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
535
+ /* Begin XCConfigurationList section */
536
+ 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */ = {
537
+ isa = XCConfigurationList;
538
+ buildConfigurations = (
539
+ 9999999999999999999999AA /* Debug */,
540
+ AAAAAAAAAAAAAAAAAAAAABBB /* Release */,
541
+ );
542
+ defaultConfigurationIsVisible = 0;
543
+ defaultConfigurationName = Release;
544
+ };
545
+ 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */ = {
546
+ isa = XCConfigurationList;
547
+ buildConfigurations = (
548
+ BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */,
549
+ CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */,
550
+ );
551
+ defaultConfigurationIsVisible = 0;
552
+ defaultConfigurationName = Release;
553
+ };
554
+ /* End XCConfigurationList section */
555
+ };
556
+ rootObject = 7777777777777777777777AA /* Project object */;
557
+ }
558
+ EOF
559
+
560
+ # 2. Copy XCFramework to test project
561
+ echo "Copying XCFramework to test project..."
562
+ cp -R "${XCFRAMEWORK_PATH}" "${TEMP_DIR}/${APP_NAME}/"
563
+
564
+ # 3. Build and archive the app
565
+ echo "Building and archiving test app..."
566
+ cd "${TEMP_DIR}/${APP_NAME}"
567
+
568
+ # Create a simple xcscheme file to avoid xcodebuild scheme issues
569
+ mkdir -p "${APP_NAME}.xcodeproj/xcshareddata/xcschemes"
570
+ cat > "${APP_NAME}.xcodeproj/xcshareddata/xcschemes/${APP_NAME}.xcscheme" << EOF
571
+ <?xml version="1.0" encoding="UTF-8"?>
572
+ <Scheme
573
+ LastUpgradeVersion = "1510"
574
+ version = "1.3">
575
+ <BuildAction
576
+ parallelizeBuildables = "YES"
577
+ buildImplicitDependencies = "YES">
578
+ <BuildActionEntries>
579
+ <BuildActionEntry
580
+ buildForTesting = "YES"
581
+ buildForRunning = "YES"
582
+ buildForProfiling = "YES"
583
+ buildForArchiving = "YES"
584
+ buildForAnalyzing = "YES">
585
+ <BuildableReference
586
+ BuildableIdentifier = "primary"
587
+ BlueprintIdentifier = "3333333333333333333333AA"
588
+ BuildableName = "${APP_NAME}.app"
589
+ BlueprintName = "${APP_NAME}"
590
+ ReferencedContainer = "container:${APP_NAME}.xcodeproj">
591
+ </BuildableReference>
592
+ </BuildActionEntry>
593
+ </BuildActionEntries>
594
+ </BuildAction>
595
+ <TestAction
596
+ buildConfiguration = "Debug"
597
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
598
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
599
+ shouldUseLaunchSchemeArgsEnv = "YES">
600
+ <Testables>
601
+ </Testables>
602
+ </TestAction>
603
+ <LaunchAction
604
+ buildConfiguration = "Debug"
605
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
606
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
607
+ launchStyle = "0"
608
+ useCustomWorkingDirectory = "NO"
609
+ ignoresPersistentStateOnLaunch = "NO"
610
+ debugDocumentVersioning = "YES"
611
+ debugServiceExtension = "internal"
612
+ allowLocationSimulation = "YES">
613
+ <BuildableProductRunnable
614
+ runnableDebuggingMode = "0">
615
+ <BuildableReference
616
+ BuildableIdentifier = "primary"
617
+ BlueprintIdentifier = "3333333333333333333333AA"
618
+ BuildableName = "${APP_NAME}.app"
619
+ BlueprintName = "${APP_NAME}"
620
+ ReferencedContainer = "container:${APP_NAME}.xcodeproj">
621
+ </BuildableReference>
622
+ </BuildableProductRunnable>
623
+ </LaunchAction>
624
+ <ProfileAction
625
+ buildConfiguration = "Release"
626
+ shouldUseLaunchSchemeArgsEnv = "YES"
627
+ savedToolIdentifier = ""
628
+ useCustomWorkingDirectory = "NO"
629
+ debugDocumentVersioning = "YES">
630
+ <BuildableProductRunnable
631
+ runnableDebuggingMode = "0">
632
+ <BuildableReference
633
+ BuildableIdentifier = "primary"
634
+ BlueprintIdentifier = "3333333333333333333333AA"
635
+ BuildableName = "${APP_NAME}.app"
636
+ BlueprintName = "${APP_NAME}"
637
+ ReferencedContainer = "container:${APP_NAME}.xcodeproj">
638
+ </BuildableReference>
639
+ </BuildableProductRunnable>
640
+ </ProfileAction>
641
+ <AnalyzeAction
642
+ buildConfiguration = "Debug">
643
+ </AnalyzeAction>
644
+ <ArchiveAction
645
+ buildConfiguration = "Release"
646
+ revealArchiveInOrganizer = "YES">
647
+ </ArchiveAction>
648
+ </Scheme>
649
+ EOF
650
+
651
+ # Now use xcodebuild with an explicitly defined product name for visionOS
652
+ xcodebuild -project "${APP_NAME}.xcodeproj" -scheme "${APP_NAME}" -sdk xros -configuration Release archive -archivePath "${ARCHIVE_PATH}" CODE_SIGN_IDENTITY="-" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO PRODUCT_NAME="${APP_NAME}" SWIFT_OPTIMIZATION_LEVEL="-Onone" -quiet
653
+
654
+ # 4. Create IPA from archive
655
+ echo "Creating IPA from archive..."
656
+ mkdir -p "${TEMP_DIR}/Payload"
657
+ cp -R "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" "${TEMP_DIR}/Payload/"
658
+
659
+ # Check and log app structure before zipping
660
+ echo "App structure:"
661
+ ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/"
662
+ echo "Frameworks:"
663
+ ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
664
+
665
+ cd "${TEMP_DIR}"
666
+ zip -r "${IPA_PATH}" Payload
667
+
668
+ # Check embedded provisioning profile
669
+ echo "Checking provisioning profile (if any)..."
670
+ PROVISIONING_PROFILE=$(find "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" -name "embedded.mobileprovision" 2>/dev/null)
671
+ if [ -n "$PROVISIONING_PROFILE" ]; then
672
+ echo "Found embedded provisioning profile:"
673
+ security cms -D -i "$PROVISIONING_PROFILE" || echo "Unable to decode provisioning profile"
674
+ else
675
+ echo "No embedded provisioning profile found (expected for ad-hoc builds)"
676
+ fi
677
+
678
+ # 5. Validate the IPA
679
+ echo "Validating IPA..."
680
+ VALIDATION_OUTPUT="${VALIDATION_DIR}/validation_output.txt"
681
+
682
+ # Check if authentication credentials are provided
683
+ AUTH_ARGS=""
684
+ if [ -n "$APPLE_ID" ] && [ -n "$APPLE_PASSWORD" ]; then
685
+ echo "Using Apple ID authentication for validation..."
686
+ AUTH_ARGS="--username \"$APPLE_ID\" --password \"$APPLE_PASSWORD\""
687
+ else
688
+ echo "No authentication credentials provided. Will perform basic validation."
689
+ echo "To use your personal developer account, you can run the script with:"
690
+ echo " APPLE_ID='your.email@example.com' APPLE_PASSWORD='your-app-specific-password' ./validate-visionos.sh"
691
+ echo "Note: You need to create an app-specific password at https://appleid.apple.com/account/manage"
692
+ fi
693
+
694
+ # Run validation with detailed output
695
+ echo "Running validation with altool..."
696
+ if [ -n "$AUTH_ARGS" ]; then
697
+ # Use eval to properly handle the quoted arguments
698
+ eval "xcrun altool --validate-app -f \"${IPA_PATH}\" --type visionos --output-format xml $AUTH_ARGS" 2>&1 | tee "${VALIDATION_OUTPUT}"
699
+ else
700
+ xcrun altool --validate-app -f "${IPA_PATH}" --type visionos --output-format xml 2>&1 | tee "${VALIDATION_OUTPUT}"
701
+ fi
702
+ VALIDATION_RESULT=$?
703
+
704
+ # Final validation result
705
+ FINAL_VALIDATION_RESULT=0
706
+
707
+ # Check if validation failed because the app isn't in App Store Connect
708
+ if grep -q "No suitable application records were found" "${VALIDATION_OUTPUT}"; then
709
+ echo "⚠️ App Store Connect Warning: The app bundle identifier is not found in App Store Connect"
710
+ echo "This is expected for apps that haven't been registered in App Store Connect yet."
711
+ echo "This doesn't indicate a problem with the build or framework."
712
+
713
+ # Perform alternative validation
714
+ echo "Performing alternative validation checks..."
715
+
716
+ # Check if IPA was created successfully
717
+ if [ -f "${IPA_PATH}" ] && [ -s "${IPA_PATH}" ]; then
718
+ echo "✅ IPA file created successfully"
719
+ else
720
+ echo "❌ IPA file not created or empty"
721
+ FINAL_VALIDATION_RESULT=1
722
+ fi
723
+
724
+ # Check if app binary exists and is executable
725
+ if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ] && [ -x "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ]; then
726
+ echo "✅ App binary exists and is executable"
727
+ else
728
+ echo "❌ App binary missing or not executable"
729
+ FINAL_VALIDATION_RESULT=1
730
+ fi
731
+
732
+ # Check if framework was properly embedded
733
+ if [ -d "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework" ]; then
734
+ echo "✅ llama.framework properly embedded"
735
+ else
736
+ echo "❌ llama.framework not properly embedded"
737
+ FINAL_VALIDATION_RESULT=1
738
+ fi
739
+
740
+ # Check if framework binary exists
741
+ if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework/llama" ]; then
742
+ echo "✅ Framework binary exists"
743
+
744
+ # Further validate framework by checking architecture
745
+ ARCHS=$(lipo -info "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework/llama" 2>/dev/null | grep -o "arm64\\|x86_64" | tr '\n' ' ')
746
+ if [ -n "$ARCHS" ]; then
747
+ echo "✅ Framework architecture(s): $ARCHS"
748
+ else
749
+ echo "⚠️ Could not determine framework architecture"
750
+ fi
751
+ else
752
+ echo "❌ Framework binary missing"
753
+ FINAL_VALIDATION_RESULT=1
754
+ fi
755
+
756
+ if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
757
+ echo "✅ Alternative validation PASSED: App built successfully with embedded framework"
758
+ else
759
+ echo "❌ Alternative validation FAILED: Issues found with the app or framework"
760
+ fi
761
+ elif grep -q "You must specify authentication credentials" "${VALIDATION_OUTPUT}" && [ -z "$AUTH_ARGS" ]; then
762
+ echo "✅ visionOS Validation PASSED: IPA successfully validated"
763
+ echo "Results saved to ${VALIDATION_OUTPUT}"
764
+ else
765
+ echo "❌ visionOS Validation FAILED: IPA validation found issues"
766
+ echo "See validation output at ${VALIDATION_OUTPUT}"
767
+ echo ""
768
+ echo "==== VALIDATION ERRORS ===="
769
+
770
+ # Try to extract specific errors from the output
771
+ if grep -q "Error" "${VALIDATION_OUTPUT}"; then
772
+ grep -A 5 "Error" "${VALIDATION_OUTPUT}"
773
+ else
774
+ # If no specific error found, show the whole log
775
+ cat "${VALIDATION_OUTPUT}"
776
+ fi
777
+
778
+ # Additional debugging: check IPA contents
779
+ echo ""
780
+ echo "==== IPA CONTENTS ===="
781
+ mkdir -p "${TEMP_DIR}/ipa_contents"
782
+ unzip -q "${IPA_PATH}" -d "${TEMP_DIR}/ipa_contents"
783
+ ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/"
784
+
785
+ # Check for code signing issues
786
+ echo ""
787
+ echo "==== CODE SIGNING INFO ===="
788
+ codesign -vv -d "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app" 2>&1 || echo "Code signing verification failed"
789
+
790
+ # Check embedded frameworks
791
+ echo ""
792
+ echo "==== FRAMEWORK INFO ===="
793
+ ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
794
+ fi
795
+
796
+ # Don't clean up on error to allow inspection
797
+ if [ $FINAL_VALIDATION_RESULT -ne 0 ]; then
798
+ echo ""
799
+ echo "Temporary files kept for inspection at: ${TEMP_DIR}"
800
+ echo "===== visionOS Validation Process Failed ====="
801
+ exit 1
802
+ fi
803
+
804
+ # Clean up temporary files but keep build artifacts
805
+ if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
806
+ echo "Cleaning up temporary files..."
807
+ #rm -rf "${TEMP_DIR}"
808
+ fi
809
+
810
+ echo "===== visionOS Validation Process Completed ====="
811
+ exit $FINAL_VALIDATION_RESULT
llama.cpp/scripts/jinja/jinja-tester.py ADDED
@@ -0,0 +1,504 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import sys
3
+ import json
4
+ import argparse
5
+ import jinja2.ext as jinja2_ext
6
+ from PySide6.QtWidgets import (
7
+ QApplication,
8
+ QMainWindow,
9
+ QWidget,
10
+ QVBoxLayout,
11
+ QHBoxLayout,
12
+ QLabel,
13
+ QPlainTextEdit,
14
+ QTextEdit,
15
+ QPushButton,
16
+ QFileDialog,
17
+ )
18
+ from PySide6.QtGui import QColor, QColorConstants, QTextCursor, QTextFormat
19
+ from PySide6.QtCore import Qt, QRect, QSize
20
+ from jinja2 import TemplateSyntaxError
21
+ from jinja2.sandbox import ImmutableSandboxedEnvironment
22
+ from datetime import datetime
23
+
24
+
25
+ def format_template_content(template_content):
26
+ """Format the Jinja template content using Jinja2's lexer."""
27
+ if not template_content.strip():
28
+ return template_content
29
+
30
+ env = ImmutableSandboxedEnvironment()
31
+ tc_rstrip = template_content.rstrip()
32
+ tokens = list(env.lex(tc_rstrip))
33
+ result = ""
34
+ indent_level = 0
35
+ i = 0
36
+
37
+ while i < len(tokens):
38
+ token = tokens[i]
39
+ _, token_type, token_value = token
40
+
41
+ if token_type == "block_begin":
42
+ block_start = i
43
+ # Collect all tokens for this block construct
44
+ construct_content = token_value
45
+ end_token_type = token_type.replace("_begin", "_end")
46
+ j = i + 1
47
+ while j < len(tokens) and tokens[j][1] != end_token_type:
48
+ construct_content += tokens[j][2]
49
+ j += 1
50
+
51
+ if j < len(tokens): # Found the end token
52
+ construct_content += tokens[j][2]
53
+ i = j # Skip to the end token
54
+
55
+ # Check for control structure keywords for indentation
56
+ stripped_content = construct_content.strip()
57
+ instr = block_start + 1
58
+ while tokens[instr][1] == "whitespace":
59
+ instr = instr + 1
60
+
61
+ instruction_token = tokens[instr][2]
62
+ start_control_tokens = ["if", "for", "macro", "call", "block"]
63
+ end_control_tokens = ["end" + t for t in start_control_tokens]
64
+ is_control_start = any(
65
+ instruction_token.startswith(kw) for kw in start_control_tokens
66
+ )
67
+ is_control_end = any(
68
+ instruction_token.startswith(kw) for kw in end_control_tokens
69
+ )
70
+
71
+ # Adjust indentation for control structures
72
+ # For control end blocks, decrease indent BEFORE adding the content
73
+ if is_control_end:
74
+ indent_level = max(0, indent_level - 1)
75
+
76
+ # Remove all previous whitespace before this block
77
+ result = result.rstrip()
78
+
79
+ # Add proper indent, but only if this is not the first token
80
+ added_newline = False
81
+ if result: # Only add newline and indent if there's already content
82
+ result += (
83
+ "\n" + " " * indent_level
84
+ ) # Use 2 spaces per indent level
85
+ added_newline = True
86
+ else: # For the first token, don't add any indent
87
+ result += ""
88
+
89
+ # Add the block content
90
+ result += stripped_content
91
+
92
+ # Add '-' after '%' if it wasn't there and we added a newline or indent
93
+ if (
94
+ added_newline
95
+ and stripped_content.startswith("{%")
96
+ and not stripped_content.startswith("{%-")
97
+ ):
98
+ # Add '-' at the beginning
99
+ result = (
100
+ result[: result.rfind("{%")]
101
+ + "{%-"
102
+ + result[result.rfind("{%") + 2 :]
103
+ )
104
+ if stripped_content.endswith("%}") and not stripped_content.endswith(
105
+ "-%}"
106
+ ):
107
+ # Only add '-' if this is not the last token or if there's content after
108
+ if i + 1 < len(tokens) and tokens[i + 1][1] != "eof":
109
+ result = result[:-2] + "-%}"
110
+
111
+ # For control start blocks, increase indent AFTER adding the content
112
+ if is_control_start:
113
+ indent_level += 1
114
+ else:
115
+ # Malformed template, just add the token
116
+ result += token_value
117
+ elif token_type == "variable_begin":
118
+ # Collect all tokens for this variable construct
119
+ construct_content = token_value
120
+ end_token_type = token_type.replace("_begin", "_end")
121
+ j = i + 1
122
+ while j < len(tokens) and tokens[j][1] != end_token_type:
123
+ construct_content += tokens[j][2]
124
+ j += 1
125
+
126
+ if j < len(tokens): # Found the end token
127
+ construct_content += tokens[j][2]
128
+ i = j # Skip to the end token
129
+
130
+ # For variable constructs, leave them alone
131
+ # Do not add indent or whitespace before or after them
132
+ result += construct_content
133
+ else:
134
+ # Malformed template, just add the token
135
+ result += token_value
136
+ elif token_type == "data":
137
+ # Handle data (text between Jinja constructs)
138
+ # For data content, preserve it as is
139
+ result += token_value
140
+ else:
141
+ # Handle any other tokens
142
+ result += token_value
143
+
144
+ i += 1
145
+
146
+ # Clean up trailing newlines and spaces
147
+ result = result.rstrip()
148
+
149
+ # Copy the newline / space count from the original
150
+ if (trailing_length := len(template_content) - len(tc_rstrip)):
151
+ result += template_content[-trailing_length:]
152
+
153
+ return result
154
+
155
+
156
+ # ------------------------
157
+ # Line Number Widget
158
+ # ------------------------
159
+ class LineNumberArea(QWidget):
160
+ def __init__(self, editor):
161
+ super().__init__(editor)
162
+ self.code_editor = editor
163
+
164
+ def sizeHint(self):
165
+ return QSize(self.code_editor.line_number_area_width(), 0)
166
+
167
+ def paintEvent(self, event):
168
+ self.code_editor.line_number_area_paint_event(event)
169
+
170
+
171
+ class CodeEditor(QPlainTextEdit):
172
+ def __init__(self):
173
+ super().__init__()
174
+ self.line_number_area = LineNumberArea(self)
175
+
176
+ self.blockCountChanged.connect(self.update_line_number_area_width)
177
+ self.updateRequest.connect(self.update_line_number_area)
178
+ self.cursorPositionChanged.connect(self.highlight_current_line)
179
+
180
+ self.update_line_number_area_width(0)
181
+ self.highlight_current_line()
182
+
183
+ def line_number_area_width(self):
184
+ digits = len(str(self.blockCount()))
185
+ space = 3 + self.fontMetrics().horizontalAdvance("9") * digits
186
+ return space
187
+
188
+ def update_line_number_area_width(self, _):
189
+ self.setViewportMargins(self.line_number_area_width(), 0, 0, 0)
190
+
191
+ def update_line_number_area(self, rect, dy):
192
+ if dy:
193
+ self.line_number_area.scroll(0, dy)
194
+ else:
195
+ self.line_number_area.update(
196
+ 0, rect.y(), self.line_number_area.width(), rect.height()
197
+ )
198
+
199
+ if rect.contains(self.viewport().rect()):
200
+ self.update_line_number_area_width(0)
201
+
202
+ def resizeEvent(self, event):
203
+ super().resizeEvent(event)
204
+ cr = self.contentsRect()
205
+ self.line_number_area.setGeometry(
206
+ QRect(cr.left(), cr.top(), self.line_number_area_width(), cr.height())
207
+ )
208
+
209
+ def line_number_area_paint_event(self, event):
210
+ from PySide6.QtGui import QPainter
211
+
212
+ painter = QPainter(self.line_number_area)
213
+ painter.fillRect(event.rect(), QColorConstants.LightGray)
214
+
215
+ block = self.firstVisibleBlock()
216
+ block_number = block.blockNumber()
217
+ top = int(
218
+ self.blockBoundingGeometry(block).translated(self.contentOffset()).top()
219
+ )
220
+ bottom = top + int(self.blockBoundingRect(block).height())
221
+
222
+ while block.isValid() and top <= event.rect().bottom():
223
+ if block.isVisible() and bottom >= event.rect().top():
224
+ number = str(block_number + 1)
225
+ painter.setPen(QColorConstants.Black)
226
+ painter.drawText(
227
+ 0,
228
+ top,
229
+ self.line_number_area.width() - 2,
230
+ self.fontMetrics().height(),
231
+ Qt.AlignmentFlag.AlignRight,
232
+ number,
233
+ )
234
+ block = block.next()
235
+ top = bottom
236
+ bottom = top + int(self.blockBoundingRect(block).height())
237
+ block_number += 1
238
+
239
+ def highlight_current_line(self):
240
+ extra_selections = []
241
+ if not self.isReadOnly():
242
+ selection = QTextEdit.ExtraSelection()
243
+ line_color = QColorConstants.Yellow.lighter(160)
244
+ selection.format.setBackground(line_color) # pyright: ignore[reportAttributeAccessIssue]
245
+ selection.format.setProperty(QTextFormat.Property.FullWidthSelection, True) # pyright: ignore[reportAttributeAccessIssue]
246
+ selection.cursor = self.textCursor() # pyright: ignore[reportAttributeAccessIssue]
247
+ selection.cursor.clearSelection() # pyright: ignore[reportAttributeAccessIssue]
248
+ extra_selections.append(selection)
249
+ self.setExtraSelections(extra_selections)
250
+
251
+ def highlight_position(self, lineno: int, col: int, color: QColor):
252
+ block = self.document().findBlockByLineNumber(lineno - 1)
253
+ if block.isValid():
254
+ cursor = QTextCursor(block)
255
+ text = block.text()
256
+ start = block.position() + max(0, col - 1)
257
+ cursor.setPosition(start)
258
+ if col <= len(text):
259
+ cursor.movePosition(
260
+ QTextCursor.MoveOperation.NextCharacter,
261
+ QTextCursor.MoveMode.KeepAnchor,
262
+ )
263
+
264
+ extra = QTextEdit.ExtraSelection()
265
+ extra.format.setBackground(color.lighter(160)) # pyright: ignore[reportAttributeAccessIssue]
266
+ extra.cursor = cursor # pyright: ignore[reportAttributeAccessIssue]
267
+
268
+ self.setExtraSelections(self.extraSelections() + [extra])
269
+
270
+ def highlight_line(self, lineno: int, color: QColor):
271
+ block = self.document().findBlockByLineNumber(lineno - 1)
272
+ if block.isValid():
273
+ cursor = QTextCursor(block)
274
+ cursor.select(QTextCursor.SelectionType.LineUnderCursor)
275
+
276
+ extra = QTextEdit.ExtraSelection()
277
+ extra.format.setBackground(color.lighter(160)) # pyright: ignore[reportAttributeAccessIssue]
278
+ extra.cursor = cursor # pyright: ignore[reportAttributeAccessIssue]
279
+
280
+ self.setExtraSelections(self.extraSelections() + [extra])
281
+
282
+ def clear_highlighting(self):
283
+ self.highlight_current_line()
284
+
285
+
286
+ # ------------------------
287
+ # Main App
288
+ # ------------------------
289
+ class JinjaTester(QMainWindow):
290
+ def __init__(self):
291
+ super().__init__()
292
+ self.setWindowTitle("Jinja Template Tester")
293
+ self.resize(1200, 800)
294
+
295
+ central = QWidget()
296
+ main_layout = QVBoxLayout(central)
297
+
298
+ # -------- Top input area --------
299
+ input_layout = QHBoxLayout()
300
+
301
+ # Template editor with label
302
+ template_layout = QVBoxLayout()
303
+ template_label = QLabel("Jinja2 Template")
304
+ template_layout.addWidget(template_label)
305
+ self.template_edit = CodeEditor()
306
+ template_layout.addWidget(self.template_edit)
307
+ input_layout.addLayout(template_layout)
308
+
309
+ # JSON editor with label
310
+ json_layout = QVBoxLayout()
311
+ json_label = QLabel("Context (JSON)")
312
+ json_layout.addWidget(json_label)
313
+ self.json_edit = CodeEditor()
314
+ self.json_edit.setPlainText("""
315
+ {
316
+ "add_generation_prompt": true,
317
+ "bos_token": "",
318
+ "eos_token": "",
319
+ "messages": [
320
+ {
321
+ "role": "user",
322
+ "content": "What is the capital of Poland?"
323
+ }
324
+ ]
325
+ }
326
+ """.strip())
327
+ json_layout.addWidget(self.json_edit)
328
+ input_layout.addLayout(json_layout)
329
+
330
+ main_layout.addLayout(input_layout)
331
+
332
+ # -------- Rendered output area --------
333
+ output_label = QLabel("Rendered Output")
334
+ main_layout.addWidget(output_label)
335
+ self.output_edit = QPlainTextEdit()
336
+ self.output_edit.setReadOnly(True)
337
+ main_layout.addWidget(self.output_edit)
338
+
339
+ # -------- Render button and status --------
340
+ btn_layout = QHBoxLayout()
341
+
342
+ # Load template button
343
+ self.load_btn = QPushButton("Load Template")
344
+ self.load_btn.clicked.connect(self.load_template)
345
+ btn_layout.addWidget(self.load_btn)
346
+
347
+ # Format template button
348
+ self.format_btn = QPushButton("Format")
349
+ self.format_btn.clicked.connect(self.format_template)
350
+ btn_layout.addWidget(self.format_btn)
351
+
352
+ self.render_btn = QPushButton("Render")
353
+ self.render_btn.clicked.connect(self.render_template)
354
+ btn_layout.addWidget(self.render_btn)
355
+ main_layout.addLayout(btn_layout)
356
+
357
+ # Status label below buttons
358
+ self.status_label = QLabel("Ready")
359
+ main_layout.addWidget(self.status_label)
360
+
361
+ self.setCentralWidget(central)
362
+
363
+ def render_template(self):
364
+ self.template_edit.clear_highlighting()
365
+ self.output_edit.clear()
366
+
367
+ template_str = self.template_edit.toPlainText()
368
+ json_str = self.json_edit.toPlainText()
369
+
370
+ # Parse JSON context
371
+ try:
372
+ context = json.loads(json_str) if json_str.strip() else {}
373
+ except Exception as e:
374
+ self.status_label.setText(f"❌ JSON Error: {e}")
375
+ return
376
+
377
+ def raise_exception(text: str) -> str:
378
+ raise RuntimeError(text)
379
+
380
+ env = ImmutableSandboxedEnvironment(
381
+ trim_blocks=True,
382
+ lstrip_blocks=True,
383
+ extensions=[jinja2_ext.loopcontrols],
384
+ )
385
+ env.filters["tojson"] = (
386
+ lambda x,
387
+ indent=None,
388
+ separators=None,
389
+ sort_keys=False,
390
+ ensure_ascii=False: json.dumps(
391
+ x,
392
+ indent=indent,
393
+ separators=separators,
394
+ sort_keys=sort_keys,
395
+ ensure_ascii=ensure_ascii,
396
+ )
397
+ )
398
+ env.globals["strftime_now"] = lambda format: datetime.now().strftime(format)
399
+ env.globals["raise_exception"] = raise_exception
400
+ try:
401
+ template = env.from_string(template_str)
402
+ output = template.render(context)
403
+ self.output_edit.setPlainText(output)
404
+ self.status_label.setText("✅ Render successful")
405
+ except TemplateSyntaxError as e:
406
+ self.status_label.setText(f"❌ Syntax Error (line {e.lineno}): {e.message}")
407
+ if e.lineno:
408
+ self.template_edit.highlight_line(e.lineno, QColor("red"))
409
+ except Exception as e:
410
+ # Catch all runtime errors
411
+ # Try to extract template line number
412
+ lineno = None
413
+ tb = e.__traceback__
414
+ while tb:
415
+ frame = tb.tb_frame
416
+ if frame.f_code.co_filename == "<template>":
417
+ lineno = tb.tb_lineno
418
+ break
419
+ tb = tb.tb_next
420
+
421
+ error_msg = f"Runtime Error: {type(e).__name__}: {e}"
422
+ if lineno:
423
+ error_msg = f"Runtime Error at line {lineno} in template: {type(e).__name__}: {e}"
424
+ self.template_edit.highlight_line(lineno, QColor("orange"))
425
+
426
+ self.output_edit.setPlainText(error_msg)
427
+ self.status_label.setText(f"❌ {error_msg}")
428
+
429
+ def load_template(self):
430
+ """Load a Jinja template from a file using a file dialog."""
431
+ file_path, _ = QFileDialog.getOpenFileName(
432
+ self,
433
+ "Load Jinja Template",
434
+ "",
435
+ "Template Files (*.jinja *.j2 *.html *.txt);;All Files (*)",
436
+ )
437
+
438
+ if file_path:
439
+ try:
440
+ with open(file_path, "r", encoding="utf-8") as file:
441
+ content = file.read()
442
+ self.template_edit.setPlainText(content)
443
+ self.status_label.setText(f"✅ Loaded template from {file_path}")
444
+ except Exception as e:
445
+ self.status_label.setText(f"❌ Error loading file: {str(e)}")
446
+
447
+ def format_template(self):
448
+ """Format the Jinja template using Jinja2's lexer for proper parsing."""
449
+ try:
450
+ template_content = self.template_edit.toPlainText()
451
+ if not template_content.strip():
452
+ self.status_label.setText("⚠️ Template is empty")
453
+ return
454
+
455
+ formatted_content = format_template_content(template_content)
456
+ self.template_edit.setPlainText(formatted_content)
457
+ self.status_label.setText("✅ Template formatted")
458
+ except Exception as e:
459
+ self.status_label.setText(f"❌ Error formatting template: {str(e)}")
460
+
461
+
462
+ if __name__ == "__main__":
463
+ if len(sys.argv) > 1:
464
+ # CLI mode
465
+ parser = argparse.ArgumentParser(description="Jinja Template Tester")
466
+ parser.add_argument(
467
+ "--template", required=True, help="Path to Jinja template file"
468
+ )
469
+ parser.add_argument("--context", required=True, help="JSON string for context")
470
+ parser.add_argument(
471
+ "--action",
472
+ choices=["format", "render"],
473
+ default="render",
474
+ help="Action to perform",
475
+ )
476
+ args = parser.parse_args()
477
+
478
+ # Load template
479
+ with open(args.template, "r", encoding="utf-8") as f:
480
+ template_content = f.read()
481
+
482
+ # Load JSON
483
+ context = json.loads(args.context)
484
+ # Add missing variables
485
+ context.setdefault("bos_token", "")
486
+ context.setdefault("eos_token", "")
487
+ context.setdefault("add_generation_prompt", False)
488
+
489
+ env = ImmutableSandboxedEnvironment()
490
+
491
+ if args.action == "format":
492
+ formatted = format_template_content(template_content)
493
+ print(formatted) # noqa: NP100
494
+ elif args.action == "render":
495
+ template = env.from_string(template_content)
496
+ output = template.render(context)
497
+ print(output) # noqa: NP100
498
+
499
+ else:
500
+ # GUI mode
501
+ app = QApplication(sys.argv)
502
+ window = JinjaTester()
503
+ window.show()
504
+ sys.exit(app.exec())
llama.cpp/scripts/jinja/requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ PySide6
2
+ jinja2
llama.cpp/scripts/snapdragon/adb/llama-cli.farf ADDED
@@ -0,0 +1 @@
 
 
1
+ 0xffff
llama.cpp/scripts/snapdragon/adb/run-bench.sh ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/sh
2
+ #
3
+
4
+ # Basedir on device
5
+ basedir=/data/local/tmp/llama.cpp
6
+
7
+ branch=.
8
+ [ "$B" != "" ] && branch=$B
9
+
10
+ adbserial=
11
+ [ "$S" != "" ] && adbserial="-s $S"
12
+
13
+ adbhost=
14
+ [ "$H" != "" ] && adbhost="-H $H"
15
+
16
+ model="Llama-3.2-3B-Instruct-Q4_0.gguf"
17
+ [ "$M" != "" ] && model="$M"
18
+
19
+ device="HTP0"
20
+ [ "$D" != "" ] && device="$D"
21
+
22
+ verbose=
23
+ [ "$V" != "" ] && verbose="GGML_HEXAGON_VERBOSE=$V" cli_opts="$cli_opts -v"
24
+
25
+ experimental=
26
+ [ "$E" != "" ] && experimental="GGML_HEXAGON_EXPERIMENTAL=$E"
27
+
28
+ profile=
29
+ [ "$PROF" != "" ] && profile="GGML_HEXAGON_PROFILE=$PROF GGML_HEXAGON_OPSYNC=1" cli_opts="$cli_opts -v"
30
+
31
+ opmask=
32
+ [ "$OPMASK" != "" ] && opmask="GGML_HEXAGON_OPMASK=$OPMASK"
33
+
34
+ nhvx=
35
+ [ "$NHVX" != "" ] && nhvx="GGML_HEXAGON_NHVX=$NHVX"
36
+
37
+ ndev=
38
+ [ "$NDEV" != "" ] && ndev="GGML_HEXAGON_NDEV=$NDEV"
39
+
40
+ hb=
41
+ [ "$HB" != "" ] && hb="GGML_HEXAGON_HOSTBUF=$HB"
42
+
43
+ set -x
44
+
45
+ adb $adbserial $adbhost shell " \
46
+ cd $basedir; \
47
+ LD_LIBRARY_PATH=$basedir/$branch/lib \
48
+ ADSP_LIBRARY_PATH=$basedir/$branch/lib \
49
+ $ndev $nhvx $opmask $verbose $experimental $profile $hb ./$branch/bin/llama-bench --device $device --mmap 0 -m $basedir/../gguf/$model \
50
+ --poll 1000 -t 6 --cpu-mask 0xfc --cpu-strict 1 \
51
+ --batch-size 128 -ngl 99 $cli_opts $@ \
52
+ "
llama.cpp/scripts/snapdragon/adb/run-cli.sh ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/sh
2
+ #
3
+
4
+ # Basedir on device
5
+ basedir=/data/local/tmp/llama.cpp
6
+
7
+ cli_opts=
8
+
9
+ branch=.
10
+ [ "$B" != "" ] && branch=$B
11
+
12
+ adbserial=
13
+ [ "$S" != "" ] && adbserial="-s $S"
14
+
15
+ adbhost=
16
+ [ "$H" != "" ] && adbhost="-H $H"
17
+
18
+ model="Llama-3.2-3B-Instruct-Q4_0.gguf"
19
+ [ "$M" != "" ] && model="$M"
20
+
21
+ device="HTP0"
22
+ [ "$D" != "" ] && device="$D"
23
+
24
+ experimental=
25
+ [ "$E" != "" ] && experimental="GGML_HEXAGON_EXPERIMENTAL=$E"
26
+
27
+ verbose=
28
+ [ "$V" != "" ] && verbose="GGML_HEXAGON_VERBOSE=$V" cli_opts="$cli_opts -v"
29
+
30
+ sched=
31
+ [ "$SCHED" != "" ] && sched="GGML_SCHED_DEBUG=2" cli_opts="$cli_opts -v"
32
+
33
+ profile=
34
+ [ "$PROF" != "" ] && profile="GGML_HEXAGON_PROFILE=$PROF GGML_HEXAGON_OPSYNC=1" cli_opts="$cli_opts -v"
35
+
36
+ opmask=
37
+ [ "$OPMASK" != "" ] && opmask="GGML_HEXAGON_OPMASK=$OPMASK"
38
+
39
+ nhvx=
40
+ [ "$NHVX" != "" ] && nhvx="GGML_HEXAGON_NHVX=$NHVX"
41
+
42
+ ndev=
43
+ [ "$NDEV" != "" ] && ndev="GGML_HEXAGON_NDEV=$NDEV"
44
+
45
+ hb=
46
+ [ "$HB" != "" ] && hb="GGML_HEXAGON_HOSTBUF=$HB"
47
+
48
+ set -x
49
+
50
+ adb $adbserial $adbhost shell " \
51
+ cd $basedir; ulimit -c unlimited; \
52
+ LD_LIBRARY_PATH=$basedir/$branch/lib \
53
+ ADSP_LIBRARY_PATH=$basedir/$branch/lib \
54
+ $verbose $experimental $sched $opmask $profile $nhvx $ndev $hb \
55
+ ./$branch/bin/llama-cli --no-mmap -m $basedir/../gguf/$model \
56
+ --poll 1000 -t 6 --cpu-mask 0xfc --cpu-strict 1 \
57
+ --ctx-size 8192 --ubatch-size 256 -fa on \
58
+ -ngl 99 --device $device $cli_opts $@ \
59
+ "
llama.cpp/scripts/snapdragon/adb/run-completion.sh ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/sh
2
+ #
3
+
4
+ # Basedir on device
5
+ basedir=/data/local/tmp/llama.cpp
6
+
7
+ cli_opts=
8
+
9
+ branch=.
10
+ [ "$B" != "" ] && branch=$B
11
+
12
+ adbserial=
13
+ [ "$S" != "" ] && adbserial="-s $S"
14
+
15
+ adbhost=
16
+ [ "$H" != "" ] && adbhost="-H $H"
17
+
18
+ model="Llama-3.2-3B-Instruct-Q4_0.gguf"
19
+ [ "$M" != "" ] && model="$M"
20
+
21
+ device="HTP0"
22
+ [ "$D" != "" ] && device="$D"
23
+
24
+ experimental=
25
+ [ "$E" != "" ] && experimental="GGML_HEXAGON_EXPERIMENTAL=$E"
26
+
27
+ verbose=
28
+ [ "$V" != "" ] && verbose="GGML_HEXAGON_VERBOSE=$V" cli_opts="$cli_opts -v"
29
+
30
+ sched=
31
+ [ "$SCHED" != "" ] && sched="GGML_SCHED_DEBUG=2" cli_opts="$cli_opts -v"
32
+
33
+ profile=
34
+ [ "$PROF" != "" ] && profile="GGML_HEXAGON_PROFILE=$PROF GGML_HEXAGON_OPSYNC=1" cli_opts="$cli_opts -v"
35
+
36
+ opmask=
37
+ [ "$OPMASK" != "" ] && opmask="GGML_HEXAGON_OPMASK=$OPMASK"
38
+
39
+ nhvx=
40
+ [ "$NHVX" != "" ] && nhvx="GGML_HEXAGON_NHVX=$NHVX"
41
+
42
+ ndev=
43
+ [ "$NDEV" != "" ] && ndev="GGML_HEXAGON_NDEV=$NDEV"
44
+
45
+ hb=
46
+ [ "$HB" != "" ] && hb="GGML_HEXAGON_HOSTBUF=$HB"
47
+
48
+ set -x
49
+
50
+ adb $adbserial $adbhost shell " \
51
+ cd $basedir; ulimit -c unlimited; \
52
+ LD_LIBRARY_PATH=$basedir/$branch/lib \
53
+ ADSP_LIBRARY_PATH=$basedir/$branch/lib \
54
+ $verbose $experimental $sched $opmask $profile $nhvx $ndev $hb \
55
+ ./$branch/bin/llama-completion --no-mmap -m $basedir/../gguf/$model \
56
+ --poll 1000 -t 6 --cpu-mask 0xfc --cpu-strict 1 \
57
+ --ctx-size 8192 --ubatch-size 256 -fa on \
58
+ -ngl 99 -no-cnv --device $device $cli_opts $@ \
59
+ "
llama.cpp/scripts/snapdragon/adb/run-mtmd.sh ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/sh
2
+ #
3
+
4
+ # Basedir on device
5
+ basedir=/data/local/tmp/llama.cpp
6
+
7
+ cli_opts=
8
+
9
+ branch=.
10
+ [ "$B" != "" ] && branch=$B
11
+
12
+ adbserial=
13
+ [ "$S" != "" ] && adbserial="-s $S"
14
+
15
+ adbhost=
16
+ [ "$H" != "" ] && adbhost="-H $H"
17
+
18
+ model="gemma-3-4b-it-Q4_0.gguf"
19
+ [ "$M" != "" ] && model="$M"
20
+
21
+ mmproj="mmproj-F16.gguf"
22
+ [ "$MMPROJ" != "" ] && mmproj="$MMPROJ"
23
+
24
+ image=
25
+ [ "$IMG" != "" ] && image="$IMG"
26
+
27
+ device="HTP0"
28
+ [ "$D" != "" ] && device="$D"
29
+
30
+ verbose=
31
+ [ "$V" != "" ] && verbose="GGML_HEXAGON_VERBOSE=$V"
32
+
33
+ experimental="GGML_HEXAGON_EXPERIMENTAL=1"
34
+ [ "$E" != "" ] && experimental="GGML_HEXAGON_EXPERIMENTAL=$E"
35
+
36
+ sched=
37
+ [ "$SCHED" != "" ] && sched="GGML_SCHED_DEBUG=2" cli_opts="$cli_opts -v"
38
+
39
+ profile=
40
+ [ "$PROF" != "" ] && profile="GGML_HEXAGON_PROFILE=$PROF GGML_HEXAGON_OPSYNC=1"
41
+
42
+ opmask=
43
+ [ "$OPMASK" != "" ] && opmask="GGML_HEXAGON_OPMASK=$OPMASK"
44
+
45
+ nhvx=
46
+ [ "$NHVX" != "" ] && nhvx="GGML_HEXAGON_NHVX=$NHVX"
47
+
48
+ ndev=
49
+ [ "$NDEV" != "" ] && ndev="GGML_HEXAGON_NDEV=$NDEV"
50
+
51
+ # MTMD backend device for vision model (defaults to CPU if not set)
52
+ mtmd_backend=
53
+ [ "$MTMD_DEVICE" != "" ] && mtmd_backend="MTMD_BACKEND_DEVICE=$MTMD_DEVICE"
54
+
55
+ set -x
56
+
57
+ adb $adbserial $adbhost shell " \
58
+ cd $basedir; ulimit -c unlimited; \
59
+ LD_LIBRARY_PATH=$basedir/$branch/lib \
60
+ ADSP_LIBRARY_PATH=$basedir/$branch/lib \
61
+ $verbose $experimental $sched $opmask $profile $nhvx $ndev $mtmd_backend \
62
+ ./$branch/bin/llama-mtmd-cli --no-mmap -m $basedir/../gguf/$model \
63
+ --mmproj $basedir/../gguf/$mmproj \
64
+ --image $basedir/../gguf/$image \
65
+ --poll 1000 -t 6 --cpu-mask 0xfc --cpu-strict 1 \
66
+ --ctx-size 8192 --ubatch-size 256 -fa on \
67
+ -ngl 99 --device $device -v $cli_opts $@ \
68
+ "
llama.cpp/scripts/snapdragon/adb/run-tool.sh ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/sh
2
+ #
3
+
4
+ # Basedir on device
5
+ basedir=/data/local/tmp/llama.cpp
6
+
7
+ cli_opts=
8
+
9
+ branch=.
10
+ [ "$B" != "" ] && branch=$B
11
+
12
+ adbserial=
13
+ [ "$S" != "" ] && adbserial="-s $S"
14
+
15
+ adbhost=
16
+ [ "$H" != "" ] && adbhost="-H $H"
17
+
18
+ device="HTP0"
19
+ [ "$D" != "" ] && device="$D"
20
+
21
+ verbose=
22
+ [ "$V" != "" ] && verbose="GGML_HEXAGON_VERBOSE=$V"
23
+
24
+ experimental=
25
+ [ "$E" != "" ] && experimental="GGML_HEXAGON_EXPERIMENTAL=$E"
26
+
27
+ sched=
28
+ [ "$SCHED" != "" ] && sched="GGML_SCHED_DEBUG=2" cli_opts="$cli_opts -v"
29
+
30
+ profile=
31
+ [ "$PROF" != "" ] && profile="GGML_HEXAGON_PROFILE=$PROF GGML_HEXAGON_OPSYNC=1"
32
+
33
+ opmask=
34
+ [ "$OPMASK" != "" ] && opmask="GGML_HEXAGON_OPMASK=$OPMASK"
35
+
36
+ nhvx=
37
+ [ "$NHVX" != "" ] && nhvx="GGML_HEXAGON_NHVX=$NHVX"
38
+
39
+ ndev=
40
+ [ "$NDEV" != "" ] && ndev="GGML_HEXAGON_NDEV=$NDEV"
41
+
42
+ hb=
43
+ [ "$HB" != "" ] && hb="GGML_HEXAGON_HOSTBUF=$HB"
44
+
45
+ set -x
46
+
47
+ tool=$1; shift
48
+
49
+ adb $adbserial $adbhost shell " \
50
+ cd $basedir; ulimit -c unlimited; \
51
+ LD_LIBRARY_PATH=$basedir/$branch/lib \
52
+ ADSP_LIBRARY_PATH=$basedir/$branch/lib \
53
+ $verbose $experimental $sched $opmask $profile $nhvx $ndev $hb ./$branch/bin/$tool $@ \
54
+ "
llama.cpp/scripts/snapdragon/qdc/readme.md ADDED
@@ -0,0 +1 @@
 
 
1
+ This directory includes pytest based scripts for running CI jobs on Qualcomm Device Cloud (QDC).
llama.cpp/scripts/snapdragon/qdc/requirements.txt ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Appium-Python-Client==5.2.4
2
+ attrs==25.4.0
3
+ certifi==2025.10.5
4
+ exceptiongroup==1.3.0
5
+ h11==0.16.0
6
+ idna==3.11
7
+ iniconfig==2.1.0
8
+ outcome==1.3.0.post0
9
+ packaging==25.0
10
+ pluggy==1.6.0
11
+ Pygments==2.19.2
12
+ PySocks==1.7.1
13
+ pytest==8.4.2
14
+ pytest-dependency==0.6.0
15
+ selenium==4.36.0
16
+ setuptools==80.9.0
17
+ sniffio==1.3.1
18
+ sortedcontainers==2.4.0
19
+ tomli==2.3.0
20
+ trio==0.31.0
21
+ trio-websocket==0.12.2
22
+ typing_extensions==4.15.0
23
+ urllib3==2.5.0
24
+ websocket-client==1.9.0
25
+ wsproto==1.2.0
llama.cpp/scripts/snapdragon/qdc/tests/test_bench.py ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pytest
2
+ import subprocess
3
+ import sys
4
+
5
+ tmp_path='/data/local/tmp'
6
+ pkg_path=f'{tmp_path}/llama.cpp'
7
+ lib_path=f'{pkg_path}/lib'
8
+ bin_path=f'{pkg_path}/bin'
9
+
10
+ model='../gguf/Llama-3.2-1B-Instruct-Q4_0.gguf'
11
+ cli_pref=f'cd {pkg_path} && LD_LIBRARY_PATH={lib_path} ADSP_LIBRARY_PATH={lib_path} {bin_path}'
12
+
13
+
14
+ def run_cmd(cmd):
15
+ p = subprocess.run(cmd, text = True, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
16
+ sys.stdout.write(p.stdout)
17
+ assert(p.returncode == 0)
18
+
19
+
20
+ @pytest.mark.dependency()
21
+ def test_install():
22
+ run_cmd(['adb', 'push', 'llama.cpp', f'{tmp_path}'])
23
+ run_cmd(['adb', 'shell', f'chmod 755 {bin_path}/*'])
24
+
25
+
26
+ ## Basic cli tests
27
+ def run_llama_cli(dev, opts):
28
+ prompt='what is the most popular cookie in the world?\nPlease provide a very brief bullet point summary.\nBegin your answer with **BEGIN**.'
29
+ opts = '--batch-size 128 -n 128 -no-cnv --seed 42 ' + opts
30
+ run_cmd(['adb', 'shell', f'{cli_pref}/llama-cli -m {model} --device {dev} -ngl 99 -t 4 {opts} -p "{prompt}"'])
31
+
32
+
33
+ @pytest.mark.dependency(depends=['test_install'])
34
+ def test_llama_cli_cpu():
35
+ run_llama_cli('none', '-ctk q8_0 -ctv q8_0 -fa on')
36
+
37
+
38
+ @pytest.mark.dependency(depends=['test_install'])
39
+ def test_llama_cli_gpu():
40
+ run_llama_cli('GPUOpenCL', '-fa on')
41
+
42
+
43
+ @pytest.mark.dependency(depends=['test_install'])
44
+ def test_llama_cli_npu():
45
+ run_llama_cli('HTP0', '-ctk q8_0 -ctv q8_0 -fa on')
46
+
47
+
48
+ ## Basic bench tests
49
+ def run_llama_bench(dev):
50
+ run_cmd(['adb', 'shell', f'{cli_pref}/llama-bench -m {model} --device {dev} -ngl 99 --batch-size 128 -t 4 -p 128 -n 32'])
51
+
52
+
53
+ @pytest.mark.dependency(depends=['test_install'])
54
+ def test_llama_bench_cpu():
55
+ run_llama_bench('none')
56
+
57
+
58
+ def test_llama_bench_gpu():
59
+ run_llama_bench('GPUOpenCL')
60
+
61
+
62
+ def test_llama_bench_npu():
63
+ run_llama_bench('HTP0')
llama.cpp/scripts/snapdragon/windows/run-bench.ps1 ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #!/usr/bin/env pwsh
3
+
4
+ # Basedir on device
5
+ $basedir=".\pkg-snapdragon"
6
+
7
+ $cli_opts=$args
8
+
9
+ $model="Llama-3.2-3B-Instruct-Q4_0.gguf"
10
+ if ($null -ne $env:M) {
11
+ $model=$env:M
12
+ }
13
+
14
+ $device="HTP0"
15
+ if ($null -ne $env:D) {
16
+ $device=$env:D
17
+ }
18
+
19
+ if ($null -ne $env:V) {
20
+ $env:GGML_HEXAGON_VERBOSE=$env:V
21
+ }
22
+
23
+ if ($null -ne $env:OPMASK) {
24
+ $env:GGML_HEXAGON_OPMASK=$env:OPMASK
25
+ }
26
+
27
+ if ($null -ne $env:NHVX) {
28
+ $env:GGML_HEXAGON_NHVX=$env:NHVX
29
+ }
30
+
31
+ if ($null -ne $env:NDEV) {
32
+ $env:GGML_HEXAGON_NDEV=$env:NDEV
33
+ }
34
+
35
+ $env:ADSP_LIBRARY_PATH="$basedir\lib"
36
+
37
+ & "$basedir\bin\llama-bench.exe" `
38
+ --mmap 0 -m $basedir\..\..\gguf\$model `
39
+ --poll 1000 -t 6 --cpu-mask 0xfc --cpu-strict 1 `
40
+ --batch-size 128 -ngl 99 --device $device $cli_opts
llama.cpp/scripts/snapdragon/windows/run-cli.ps1 ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #!/usr/bin/env pwsh
3
+
4
+ # Basedir on device
5
+ $basedir=".\pkg-snapdragon"
6
+
7
+ $cli_opts=$args
8
+
9
+ $model="Llama-3.2-3B-Instruct-Q4_0.gguf"
10
+ if ($null -ne $env:M) {
11
+ $model=$env:M
12
+ }
13
+
14
+ $device="HTP0"
15
+ if ($null -ne $env:D) {
16
+ $device=$env:D
17
+ }
18
+
19
+ if ($null -ne $env:V) {
20
+ $env:GGML_HEXAGON_VERBOSE=$env:V
21
+ }
22
+
23
+ if ($null -ne $env:E) {
24
+ $env:GGML_HEXAGON_EXPERIMENTAL=$env:E
25
+ }
26
+
27
+ if ($null -ne $env:SCHED) {
28
+ $env:GGML_SCHED_DEBUG=$env:SCHED; $cli_opts="$cli_opts -v"
29
+ }
30
+
31
+ if ($null -ne $env:PROF) {
32
+ $env:GGML_HEXAGON_PROFILE=$env:PROF; $env:GGML_HEXAGON_OPSYNC=1
33
+ }
34
+
35
+ if ($null -ne $env:OPMASK) {
36
+ $env:GGML_HEXAGON_OPMASK=$env:OPMASK
37
+ }
38
+
39
+ if ($null -ne $env:NHVX) {
40
+ $env:GGML_HEXAGON_NHVX=$env:NHVX
41
+ }
42
+
43
+ if ($null -ne $env:NDEV) {
44
+ $env:GGML_HEXAGON_NDEV=$env:NDEV
45
+ }
46
+
47
+ $env:ADSP_LIBRARY_PATH="$basedir\lib"
48
+
49
+ & "$basedir\bin\llama-completion.exe" `
50
+ --no-mmap -no-cnv -m $basedir\..\..\gguf\$model `
51
+ --poll 1000 -t 6 --cpu-mask 0xfc --cpu-strict 1 `
52
+ --ctx-size 8192 --ubatch-size 128 -fa on `
53
+ -ngl 99 --device $device $cli_opts
llama.cpp/scripts/snapdragon/windows/run-tool.ps1 ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #!/usr/bin/env pwsh
3
+
4
+ # Basedir on device
5
+ $basedir=".\pkg-snapdragon"
6
+
7
+ if ($args.Count -eq 0) {
8
+ Write-Host "No arguments provided.Expected the tool and argument to run."
9
+ exit -1
10
+ }
11
+
12
+ $tool=$args[0]
13
+ $cli_opts=@()
14
+
15
+ if ($args.Count -gt 1) {
16
+ $cli_opts=$args[1..($args.Count - 1)]
17
+ $remainingArgs = $args[1..($args.Count - 1)]
18
+ }
19
+
20
+ $device="HTP0"
21
+ if ($null -ne $env:D) {
22
+ $device=$env:D
23
+ }
24
+
25
+ if ($null -ne $env:V) {
26
+ $env:GGML_HEXAGON_VERBOSE=$env:V
27
+ }
28
+
29
+ if ($null -ne $env:E) {
30
+ $env:GGML_HEXAGON_EXPERIMENTAL=$env:E
31
+ }
32
+
33
+ if ($null -ne $env:SCHED) {
34
+ $env:GGML_SCHED_DEBUG=$env:SCHED; $cli_opts="$cli_opts -v"
35
+ }
36
+
37
+ if ($null -ne $env:PROF) {
38
+ $env:GGML_HEXAGON_PROFILE=$env:PROF; $env:GGML_HEXAGON_OPSYNC=1
39
+ }
40
+
41
+ if ($null -ne $env:OPMASK) {
42
+ $env:GGML_HEXAGON_OPMASK=$env:OPMASK
43
+ }
44
+
45
+ if ($null -ne $env:NHVX) {
46
+ $env:GGML_HEXAGON_NHVX=$env:NHVX
47
+ }
48
+
49
+ if ($null -ne $env:NDEV) {
50
+ $env:GGML_HEXAGON_NDEV=$env:NDEV
51
+ }
52
+
53
+ $env:ADSP_LIBRARY_PATH="$basedir\lib"
54
+
55
+ & "$basedir\bin\$tool" `
56
+ $cli_opts
llama.cpp/scripts/snapdragon/windows/setup-build.ps1 ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Requires Run as Administrator is NOT strictly necessary for User-scope env vars,
2
+ # but recommended for creating directories in C:\ root if permissions are restricted.
3
+
4
+ $ErrorActionPreference = "Stop"
5
+
6
+ # --- Configuration ---
7
+ $BaseDir = "C:\Qualcomm"
8
+
9
+ # SDK 1: Hexagon
10
+ $HexagonUrl = "https://github.com/snapdragon-toolchain/hexagon-sdk/releases/download/v6.4.0.2/hexagon-sdk-v6.4.0.2-arm64-wos.tar.xz"
11
+ $HexagonParent = Join-Path $BaseDir "Hexagon_SDK"
12
+ $HexagonSdkVersion = "6.4.0.2"
13
+ $HexagonToolsVersion = "19.0.04"
14
+ $HexagonSdkTarget = Join-Path $HexagonParent $HexagonSdkVersion
15
+ $HexagonToolsTarget = Join-Path $HexagonSdkTarget "\tools\HEXAGON_Tools\$HexagonToolsVersion"
16
+
17
+ # SDK 2: OpenCL
18
+ $OpenCLUrl = "https://github.com/snapdragon-toolchain/opencl-sdk/releases/download/v2.3.2/adreno-opencl-sdk-v2.3.2-arm64-wos.tar.xz"
19
+ $OpenCLParent = Join-Path $BaseDir "OpenCL_SDK"
20
+ $OpenCLVersion = "2.3.2"
21
+ $OpenCLTarget = Join-Path $OpenCLParent $OpenCLVersion
22
+
23
+ # --- Helper Function ---
24
+ function Install-QualcommSDK {
25
+ param (
26
+ [string]$Url,
27
+ [string]$ParentDir,
28
+ [string]$TargetDir,
29
+ [string]$Name
30
+ )
31
+
32
+ # 1. Create Parent Directory
33
+ if (-not (Test-Path -Path $ParentDir)) {
34
+ Write-Host "Creating directory: $ParentDir" -ForegroundColor Cyan
35
+ New-Item -Path $ParentDir -ItemType Directory -Force | Out-Null
36
+ }
37
+
38
+ # 2. Check for Specific Version Directory
39
+ if (Test-Path -Path $TargetDir) {
40
+ Write-Host "$Name ($TargetDir) already exists. Skipping download." -ForegroundColor Green
41
+ }
42
+ else {
43
+ Write-Host "$Name not found. preparing to download..." -ForegroundColor Yellow
44
+
45
+ # Create the target directory to extract into
46
+ New-Item -Path $TargetDir -ItemType Directory -Force | Out-Null
47
+
48
+ # Define temporary archive path
49
+ $TempFile = Join-Path $ParentDir "temp_sdk.tar.xz"
50
+
51
+ try {
52
+ # Download
53
+ Write-Host "Downloading from: $Url"
54
+ Invoke-WebRequest -Uri $Url -OutFile $TempFile
55
+
56
+ # Untar
57
+ # Note: We assume Windows includes tar.exe (Win 10 build 17063+)
58
+ Write-Host "Extracting archive to $TargetDir..."
59
+
60
+ # We use -C to extract contents INTO the target directory created above
61
+ tar -xJvf $TempFile -C $TargetDir\..
62
+
63
+ Write-Host "Extraction complete." -ForegroundColor Green
64
+ }
65
+ catch {
66
+ Write-Error "Failed to download or extract $Name. Error: $_"
67
+ # Cleanup target dir if failed so script tries again next time
68
+ Remove-Item -Path $TargetDir -Recurse -Force -ErrorAction SilentlyContinue
69
+ }
70
+ finally {
71
+ # Cleanup Archive
72
+ if (Test-Path $TempFile) { Remove-Item $TempFile -Force }
73
+ }
74
+ }
75
+ }
76
+
77
+ # --- Execution ---
78
+
79
+ # 1. Ensure Base C:\Qualcomm exists
80
+ if (-not (Test-Path $BaseDir)) {
81
+ New-Item -Path $BaseDir -ItemType Directory -Force | Out-Null
82
+ }
83
+
84
+ # 2. Run Install Logic
85
+ Install-QualcommSDK -Url $HexagonUrl -ParentDir $HexagonParent -TargetDir $HexagonSdkTarget -Name "Hexagon SDK"
86
+ Install-QualcommSDK -Url $OpenCLUrl -ParentDir $OpenCLParent -TargetDir $OpenCLTarget -Name "OpenCL SDK"
87
+
88
+ # --- Environment Variables ---
89
+
90
+ Write-Host "`nSetting Environment Variables..." -ForegroundColor Cyan
91
+
92
+ # Set OPENCL_SDK_ROOT
93
+ [System.Environment]::SetEnvironmentVariable('OPENCL_SDK_ROOT', $OpenCLTarget, [System.EnvironmentVariableTarget]::User)
94
+ $env:OPENCL_SDK_ROOT = $OpenCLTarget # Set for current session as well
95
+ Write-Host "OPENCL_SDK_ROOT set to: $OpenCLTarget"
96
+
97
+ # Set HEXAGON_SDK_ROOT
98
+ [System.Environment]::SetEnvironmentVariable('HEXAGON_SDK_ROOT', $HexagonSdkTarget, [System.EnvironmentVariableTarget]::User)
99
+ $env:HEXAGON_SDK_ROOT = $HexagonSdkTarget # Set for current session as well
100
+ Write-Host "HEXAGON_SDK_ROOT set to: $HexagonSdkTarget"
101
+
102
+ # Set HEXAGON_SDK_ROOT
103
+ [System.Environment]::SetEnvironmentVariable('HEXAGON_TOOLS_ROOT', $HexagonToolsTarget, [System.EnvironmentVariableTarget]::User)
104
+ $env:HEXAGON_TOOLS_ROOT = $HexagonToolsTarget # Set for current session as well
105
+ Write-Host "HEXAGON_TOOLS_ROOT set to: $HexagonToolsTarget"
llama.cpp/src/models/afmoe.cpp ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include "models.h"
2
+
3
+ llm_build_afmoe::llm_build_afmoe(const llama_model & model, const llm_graph_params & params) : llm_graph_context(params) {
4
+ const int64_t n_embd_head = hparams.n_embd_head_v;
5
+ GGML_ASSERT(n_embd_head == hparams.n_embd_head_k);
6
+
7
+ ggml_tensor * cur;
8
+ ggml_tensor * inpL;
9
+
10
+ inpL = build_inp_embd(model.tok_embd);
11
+
12
+ // MuP scaling: embeddings * sqrt(hidden_size)
13
+ // mup_enabled = true, hidden_size = 1024, scale = 32.0
14
+ inpL = ggml_scale(ctx0, inpL, sqrtf(float(n_embd)));
15
+ cb(inpL, "inp_embd_scaled", -1);
16
+
17
+ // inp_pos - contains the positions
18
+ ggml_tensor * inp_pos = build_inp_pos();
19
+ auto * inp_attn = build_attn_inp_kv_iswa();
20
+ ggml_tensor * inp_out_ids = build_inp_out_ids();
21
+
22
+ const float kq_scale = 1.0f/sqrtf(float(n_embd_head));
23
+
24
+ for (int il = 0; il < n_layer; ++il) {
25
+ const float freq_base_l = model.get_rope_freq_base (cparams, il);
26
+ const float freq_scale_l = model.get_rope_freq_scale(cparams, il);
27
+
28
+ ggml_tensor * inpSA = inpL;
29
+
30
+ // This overlaps with SWA layers in current models, so get_rope_freq_base/scale may be superfluous
31
+ const bool use_rope = hparams.n_no_rope_layer_step > 0 &&
32
+ (il + 1) % hparams.n_no_rope_layer_step != 0;
33
+
34
+ // dual attention normalization (pre)
35
+ cur = build_norm(inpL,
36
+ model.layers[il].attn_norm, NULL,
37
+ LLM_NORM_RMS, il);
38
+ cb(cur, "attn_norm", il);
39
+
40
+ // self-attention
41
+ {
42
+ ggml_tensor * attn_inp = cur; // save input for gate computation
43
+
44
+ ggml_tensor * Qcur = build_lora_mm(model.layers[il].wq, cur);
45
+ cb(Qcur, "Qcur", il);
46
+
47
+ ggml_tensor * Kcur = build_lora_mm(model.layers[il].wk, cur);
48
+ cb(Kcur, "Kcur", il);
49
+
50
+ ggml_tensor * Vcur = build_lora_mm(model.layers[il].wv, cur);
51
+ cb(Vcur, "Vcur", il);
52
+
53
+ // compute gate from input
54
+ ggml_tensor * gate = build_lora_mm(model.layers[il].wqkv_gate, attn_inp);
55
+ cb(gate, "attn_gate_proj", il);
56
+
57
+ Qcur = ggml_reshape_3d(ctx0, Qcur, n_embd_head, n_head, n_tokens);
58
+ Kcur = ggml_reshape_3d(ctx0, Kcur, n_embd_head, n_head_kv, n_tokens);
59
+
60
+ // Q/K normalization
61
+ Qcur = build_norm(Qcur, model.layers[il].attn_q_norm, NULL, LLM_NORM_RMS, il);
62
+ Kcur = build_norm(Kcur, model.layers[il].attn_k_norm, NULL, LLM_NORM_RMS, il);
63
+ cb(Qcur, "Qcur_normed", il);
64
+ cb(Kcur, "Kcur_normed", il);
65
+
66
+ if (use_rope) {
67
+ Qcur = ggml_rope_ext(
68
+ ctx0, Qcur, inp_pos, nullptr,
69
+ n_rot, rope_type, n_ctx_orig, freq_base_l, freq_scale_l,
70
+ ext_factor, attn_factor, beta_fast, beta_slow);
71
+ cb(Qcur, "Qcur_rope", il);
72
+
73
+ Kcur = ggml_rope_ext(
74
+ ctx0, Kcur, inp_pos, nullptr,
75
+ n_rot, rope_type, n_ctx_orig, freq_base_l, freq_scale_l,
76
+ ext_factor, attn_factor, beta_fast, beta_slow);
77
+ cb(Kcur, "Kcur_rope", il);
78
+ }
79
+
80
+ Vcur = ggml_reshape_3d(ctx0, Vcur, n_embd_head, n_head_kv, n_tokens);
81
+
82
+ cur = build_attn(inp_attn,
83
+ NULL, NULL, // wo will be applied after gating
84
+ Qcur, Kcur, Vcur, nullptr, nullptr, nullptr, kq_scale, il);
85
+ cb(cur, "attn_out", il);
86
+
87
+ // attention gating: attn_out * sigmoid(gate) BEFORE o_proj
88
+ gate = ggml_sigmoid(ctx0, gate);
89
+ cb(gate, "attn_gate_sig", il);
90
+ cur = ggml_mul(ctx0, cur, gate);
91
+ cb(cur, "attn_gated", il);
92
+
93
+ // now apply output projection
94
+ cur = build_lora_mm(model.layers[il].wo, cur);
95
+ cb(cur, "attn_o_proj", il);
96
+ }
97
+
98
+ // dual attention normalization (post)
99
+ cur = build_norm(cur,
100
+ model.layers[il].attn_post_norm, NULL,
101
+ LLM_NORM_RMS, il);
102
+ cb(cur, "attn_post_norm", il);
103
+
104
+ if (il == n_layer - 1 && inp_out_ids) {
105
+ cur = ggml_get_rows(ctx0, cur, inp_out_ids);
106
+ inpSA = ggml_get_rows(ctx0, inpSA, inp_out_ids);
107
+ }
108
+
109
+ ggml_tensor * ffn_inp = ggml_add(ctx0, cur, inpSA);
110
+ cb(ffn_inp, "ffn_inp", il);
111
+
112
+ // dual ffn normalization (pre)
113
+ cur = build_norm(ffn_inp,
114
+ model.layers[il].ffn_norm, NULL,
115
+ LLM_NORM_RMS, il);
116
+ cb(cur, "ffn_norm", il);
117
+
118
+ // MoE or dense FFN
119
+ if ((uint32_t)il >= hparams.n_layer_dense_lead) {
120
+ // MoE layer with sigmoid routing, normalization, and scaling
121
+ ggml_tensor * moe_out = build_moe_ffn(cur,
122
+ model.layers[il].ffn_gate_inp,
123
+ model.layers[il].ffn_up_exps,
124
+ model.layers[il].ffn_gate_exps,
125
+ model.layers[il].ffn_down_exps,
126
+ model.layers[il].ffn_exp_probs_b,
127
+ n_expert, n_expert_used,
128
+ LLM_FFN_SILU,
129
+ hparams.expert_weights_norm, // norm_w (route_norm=True)
130
+ hparams.expert_weights_scale, // scale_w
131
+ hparams.expert_weights_scale, // w_scale (route_scale=2.826)
132
+ (llama_expert_gating_func_type) hparams.expert_gating_func,
133
+ il);
134
+ cb(moe_out, "ffn_moe_out", il);
135
+
136
+ // shared expert
137
+ if (hparams.n_expert_shared > 0) {
138
+ ggml_tensor * ffn_shexp = build_ffn(cur,
139
+ model.layers[il].ffn_up_shexp, NULL, NULL,
140
+ model.layers[il].ffn_gate_shexp, NULL, NULL,
141
+ model.layers[il].ffn_down_shexp, NULL, NULL,
142
+ NULL,
143
+ LLM_FFN_SILU, LLM_FFN_PAR, il);
144
+ cb(ffn_shexp, "ffn_shexp", il);
145
+
146
+ cur = ggml_add(ctx0, moe_out, ffn_shexp);
147
+ cb(cur, "ffn_out", il);
148
+ } else {
149
+ cur = moe_out;
150
+ }
151
+ } else {
152
+ // dense layer
153
+ cur = build_ffn(cur,
154
+ model.layers[il].ffn_up, NULL, NULL,
155
+ model.layers[il].ffn_gate, NULL, NULL,
156
+ model.layers[il].ffn_down, NULL, NULL,
157
+ NULL,
158
+ LLM_FFN_SILU, LLM_FFN_PAR, il);
159
+ cb(cur, "ffn_out", il);
160
+ }
161
+
162
+ // dual ffn normalization (post)
163
+ cur = build_norm(cur,
164
+ model.layers[il].ffn_post_norm, NULL,
165
+ LLM_NORM_RMS, il);
166
+ cb(cur, "ffn_post_norm", il);
167
+
168
+ cur = ggml_add(ctx0, cur, ffn_inp);
169
+ cur = build_cvec(cur, il);
170
+ cb(cur, "l_out", il);
171
+
172
+ // input for next layer
173
+ inpL = cur;
174
+ }
175
+
176
+ cur = inpL;
177
+
178
+ cur = build_norm(cur,
179
+ model.output_norm, NULL,
180
+ LLM_NORM_RMS, -1);
181
+ cb(cur, "result_norm", -1);
182
+
183
+ res->t_embd = cur;
184
+
185
+ // lm_head
186
+ cur = build_lora_mm(model.output, cur);
187
+ cb(cur, "result_output", -1);
188
+ res->t_logits = cur;
189
+
190
+ ggml_build_forward_expand(gf, cur);
191
+ }
llama.cpp/src/models/apertus.cpp ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include "models.h"
2
+
3
+
4
+
5
+ llm_build_apertus::llm_build_apertus(const llama_model & model, const llm_graph_params & params) : llm_graph_context(params) {
6
+ const int64_t n_embd_head = hparams.n_embd_head_v;
7
+
8
+ GGML_ASSERT(n_embd_head == hparams.n_embd_head_k);
9
+ GGML_ASSERT(n_embd_head == hparams.n_rot);
10
+
11
+ ggml_tensor * cur;
12
+ ggml_tensor * inpL;
13
+
14
+ inpL = build_inp_embd(model.tok_embd);
15
+
16
+ ggml_tensor * inp_pos = build_inp_pos();
17
+ auto * inp_attn = build_attn_inp_kv();
18
+
19
+ const float kq_scale =
20
+ hparams.f_attention_scale == 0.0f ? 1.0f / sqrtf(float(n_embd_head)) : hparams.f_attention_scale;
21
+
22
+ ggml_tensor * inp_out_ids = build_inp_out_ids();
23
+
24
+ for (int il = 0; il < n_layer; ++il) {
25
+ ggml_tensor * inpSA = inpL;
26
+
27
+ cur = build_norm(inpL, model.layers[il].attn_norm, nullptr, LLM_NORM_RMS, il);
28
+ cb(cur, "attn_norm", il);
29
+
30
+ // self-attention
31
+ {
32
+ ggml_tensor * rope_factors = model.get_rope_factors(cparams, il);
33
+
34
+ // compute Q and K and RoPE them
35
+ ggml_tensor * Qcur = build_lora_mm(model.layers[il].wq, cur);
36
+ cb(Qcur, "Qcur", il);
37
+
38
+ ggml_tensor * Kcur = build_lora_mm(model.layers[il].wk, cur);
39
+ cb(Kcur, "Kcur", il);
40
+
41
+ ggml_tensor * Vcur = build_lora_mm(model.layers[il].wv, cur);
42
+ cb(Vcur, "Vcur", il);
43
+
44
+ Qcur = ggml_reshape_3d(ctx0, Qcur, n_embd_head, n_head, n_tokens);
45
+ Qcur = build_norm(Qcur, model.layers[il].attn_q_norm, NULL, LLM_NORM_RMS, il);
46
+ cb(Qcur, "Qcur_normed", il);
47
+
48
+ Kcur = ggml_reshape_3d(ctx0, Kcur, n_embd_head, n_head_kv, n_tokens);
49
+ Kcur = build_norm(Kcur, model.layers[il].attn_k_norm, NULL, LLM_NORM_RMS, il);
50
+ cb(Kcur, "Kcur_normed", il);
51
+
52
+ Vcur = ggml_reshape_3d(ctx0, Vcur, n_embd_head, n_head_kv, n_tokens);
53
+
54
+ Qcur = ggml_rope_ext(ctx0, Qcur, inp_pos, rope_factors, n_rot, rope_type, n_ctx_orig, freq_base, freq_scale,
55
+ ext_factor, attn_factor, beta_fast, beta_slow);
56
+
57
+ Kcur = ggml_rope_ext(ctx0, Kcur, inp_pos, rope_factors, n_rot, rope_type, n_ctx_orig, freq_base, freq_scale,
58
+ ext_factor, attn_factor, beta_fast, beta_slow);
59
+
60
+ cb(Qcur, "Qcur_pos", il);
61
+ cb(Kcur, "Kcur_pos", il);
62
+ cb(Vcur, "Vcur_pos", il);
63
+
64
+ cur = build_attn(inp_attn,
65
+ model.layers[il].wo, model.layers[il].bo,
66
+ Qcur, Kcur, Vcur, nullptr, nullptr, nullptr, kq_scale, il);
67
+ cb(cur, "attn_out", il);
68
+ }
69
+
70
+ if (il == n_layer - 1 && inp_out_ids) {
71
+ cur = ggml_get_rows(ctx0, cur, inp_out_ids);
72
+ inpSA = ggml_get_rows(ctx0, inpSA, inp_out_ids);
73
+ }
74
+
75
+ ggml_tensor * ffn_inp = ggml_add(ctx0, cur, inpSA);
76
+ cb(ffn_inp, "ffn_inp", il);
77
+
78
+ // feed-forward network with xIELU activation
79
+ {
80
+ cur = build_norm(ffn_inp, model.layers[il].ffn_norm, nullptr, LLM_NORM_RMS, il);
81
+ cb(cur, "ffn_norm", il);
82
+
83
+ // Up projection
84
+ ggml_tensor * up = build_lora_mm(model.layers[il].ffn_up, cur);
85
+ cb(up, "ffn_up", il);
86
+
87
+ float alpha_n_val = hparams.xielu_alpha_n[il];
88
+ float alpha_p_val = hparams.xielu_alpha_p[il];
89
+ float beta_val = hparams.xielu_beta[il];
90
+ float eps_val = hparams.xielu_eps[il];
91
+
92
+ // Apply xIELU activation
93
+ ggml_tensor * activated = ggml_xielu(ctx0, up, alpha_n_val, alpha_p_val, beta_val, eps_val);
94
+ cb(activated, "ffn_xielu", il);
95
+
96
+ // Down projection
97
+ cur = build_lora_mm(model.layers[il].ffn_down, activated);
98
+ cb(cur, "ffn_down", il);
99
+ }
100
+
101
+ cur = ggml_add(ctx0, cur, ffn_inp);
102
+ cb(cur, "ffn_out", il);
103
+
104
+ cur = build_cvec(cur, il);
105
+ cb(cur, "l_out", il);
106
+
107
+ // input for next layer
108
+ inpL = cur;
109
+ }
110
+
111
+ cur = inpL;
112
+
113
+ cur = build_norm(cur, model.output_norm, nullptr, LLM_NORM_RMS, -1);
114
+
115
+ cb(cur, "result_norm", -1);
116
+ res->t_embd = cur;
117
+
118
+ // lm_head
119
+ cur = build_lora_mm(model.output, cur);
120
+
121
+ cb(cur, "result_output", -1);
122
+ res->t_logits = cur;
123
+
124
+ ggml_build_forward_expand(gf, cur);
125
+ }