Prepare inspected static Metal runtime inventory for macOS staging

This commit is contained in:
karl committed 2026-10-13 13:26:16 +02:00
1 parent 07bbcb76e8
commit 4a7c4acdcb
11 files changed
+236 -13

No files matched your search

+10
View File
@@ -10,6 +10,7 @@ import shutil
import subprocess
import sys
from runtime_provenance import fingerprint, UPSTREAM_COMMIT
from macos_runtime import inspect as inspect_macos
ROOT = Path(__file__).resolve().parents[2]
TAG = "b11461"
@@ -215,6 +216,15 @@ def main():
os.replace(temporary, directory / "runtime-libraries.json")
if linux_dispatch(args.backend):
bundle_linux_libraries(build, provenance)
if sys.platform == "darwin" and args.backend in {"auto", "metal"}:
worker = build / "searchi-gemma-worker"
inventory = inspect_macos(worker)
with worker.open("rb") as stream:
inventory["worker_sha256"] = hashlib.file_digest(stream, "sha256").hexdigest()
inventory["build_provenance"] = provenance
temporary = build / "runtime-libraries.json.partial"
temporary.write_text(json.dumps(inventory, indent=2), encoding="utf-8")
os.replace(temporary, build / "runtime-libraries.json")
print(f"Runtime build complete: {build}")
+69
View File
@@ -0,0 +1,69 @@
"""Inspect a static Metal worker using Apple's tools, without executing it."""
import re
import subprocess
from pathlib import Path
MAGIC = {b"\xcf\xfa\xed\xfe", b"\xfe\xed\xfa\xcf", b"\xca\xfe\xba\xbe",
b"\xbe\xba\xfe\xca", b"\xca\xfe\xba\xbf", b"\xbf\xba\xfe\xca"}
SYSTEM_LIBRARIES = {"/usr/lib/libSystem.B.dylib", "/usr/lib/libc++.1.dylib",
"/usr/lib/libc++abi.dylib", "/usr/lib/libobjc.A.dylib"}
FRAMEWORKS = {"Foundation", "CoreFoundation", "Metal", "MetalKit", "Accelerate"}
def system_dependency(name):
if name in SYSTEM_LIBRARIES:
return True
return any(re.fullmatch(rf"/System/Library/Frameworks/{framework}\.framework/Versions/[A-Z]/{framework}", name)
for framework in FRAMEWORKS)
def validate_inventory(manifest, worker):
with Path(worker).open("rb") as stream:
if stream.read(4) not in MAGIC:
raise RuntimeError("macOS worker is not a Mach-O artifact")
arches = manifest.get("architectures")
dependencies = manifest.get("system_libraries")
if (manifest.get("platform") != "macos" or manifest.get("layout") != "static-metal-embedded" or manifest.get("libraries") != []
or manifest.get("metal_embedded") is not True
or not isinstance(arches, list) or not 1 <= len(arches) <= 2
or not all(isinstance(arch, str) for arch in arches)
or len(set(arches)) != len(arches) or not set(arches) <= {"arm64", "x86_64"}
or not isinstance(dependencies, list) or not 1 <= len(dependencies) <= 32
or not all(isinstance(name, str) and system_dependency(name) for name in dependencies)
or not any("/Metal.framework/" in name for name in dependencies)):
raise RuntimeError("Invalid static Metal runtime inventory")
def inspect(worker):
worker = Path(worker)
def tool(arguments):
try:
output = subprocess.check_output(arguments, text=True, timeout=30)
except FileNotFoundError as error:
raise RuntimeError("macOS runtime inspection requires Apple lipo/otool") from error
if len(output.encode("utf-8")) > 65536:
raise RuntimeError("macOS metadata exceeds inspection limit")
return output
arches = tool(["lipo", "-archs", str(worker)]).split()
dependencies = []
for line in tool(["otool", "-L", str(worker)]).splitlines():
if not line.strip():
continue
if line == f"{worker}:" or line in {f"{worker} (architecture {arch}):" for arch in arches}:
continue
match = re.fullmatch(r"\s+(.+?) \(compatibility version [0-9.]+, current version [0-9.]+\)", line)
if not match:
raise RuntimeError("Unrecognized Mach-O dependency metadata")
if match[1] not in dependencies:
dependencies.append(match[1])
sections = tool(["otool", "-l", str(worker)])
sizes = re.findall(r"sectname\s+__ggml_metallib\s+segname\s+__DATA\s+addr\s+0x[0-9a-fA-F]+\s+size\s+(0x[0-9a-fA-F]+)", sections)
if len(sizes) != len(arches) or not all(int(size, 16) > 0 for size in sizes):
raise RuntimeError("Each Mach-O architecture must contain nonempty embedded Metal kernels")
result = {"platform": "macos", "layout": "static-metal-embedded",
"architectures": arches, "system_libraries": sorted(dependencies),
"metal_embedded": True, "libraries": []}
validate_inventory(result, worker)
return result
@@ -8,6 +8,7 @@ INPUTS = (
"crates/searchi-semantic/native/worker.cpp",
"crates/searchi-semantic/native/CMakeLists.txt",
"tools/embeddinggemma2/build_runtime.py",
"tools/embeddinggemma2/macos_runtime.py",
"tools/embeddinggemma2/no-logits.patch",
"tools/embeddinggemma2/cpu-dispatch.patch",
"tools/embeddinggemma2/cpu-only-loader.patch",
+15 -4
View File
@@ -11,11 +11,17 @@ import stat
import time
import uuid
from runtime_provenance import verify as verify_provenance
from macos_runtime import validate_inventory as validate_macos
ROOT = Path(__file__).resolve().parents[2]
CRT_LIBRARIES = {"concrt140.dll", "msvcp140.dll", "msvcp140_1.dll", "msvcp140_2.dll", "msvcp140_atomic_wait.dll", "msvcp140_codecvt_ids.dll", "vccorlib140.dll", "vcruntime140.dll", "vcruntime140_1.dll", "vcruntime140_threads.dll"}
def inventory_required(backend, windows, system):
return ((windows or system.startswith("linux")) and backend in {"auto", "vulkan"}
or system == "darwin" and backend in {"auto", "metal"})
def library_name(name):
return isinstance(name, str) and bool(re.fullmatch(
r"(?:[A-Za-z0-9_-]+\.dll|lib[A-Za-z0-9_-]+\.so(?:\.\d+)*)", name))
@@ -349,7 +355,8 @@ def verify_runtime(source, required=False):
if hashlib.file_digest(stream, "sha256").hexdigest() != manifest.get("worker_sha256"):
raise RuntimeError("Runtime worker checksum mismatch")
records = manifest.get("libraries")
if not isinstance(records, list) or not 1 <= len(records) <= 64:
macos = manifest.get("platform") == "macos"
if not isinstance(records, list) or not (0 if macos else 1) <= len(records) <= 64:
raise RuntimeError("Invalid runtime dependency inventory")
paths, names = [], set()
for record in records:
@@ -373,9 +380,13 @@ def verify_runtime(source, required=False):
raise RuntimeError(f"Runtime library checksum mismatch: {name}")
paths.append(artifact)
if required:
if (source.suffix == ".exe") == (manifest.get("platform") == "linux"):
platform = manifest.get("platform")
if (source.suffix == ".exe" and platform not in {None, "windows"}) or (source.suffix != ".exe" and platform not in {"linux", "macos"}):
raise RuntimeError("Runtime inventory platform does not match worker")
if manifest.get("platform") == "linux":
if macos:
validate_macos(manifest, source)
complete = not names and source.suffix != ".exe"
elif manifest.get("platform") == "linux":
core = {"ggml", "ggml-base", "llama", "mtmd"}
present = {name for name in core if any(re.fullmatch(rf"lib{re.escape(name)}\.so(?:\.\d+)*", file) for file in names)}
complete = present == core and {"libggml-cpu-x64.so", "libggml-vulkan.so"}.issubset(names)
@@ -421,7 +432,7 @@ def main():
license_path = ROOT / ".searchi/references/llama.cpp/LICENSE"
if not license_path.is_file():
raise RuntimeError("Native worker license is missing")
required_inventory = (os.name == "nt" or os.sys.platform.startswith("linux")) and args.backend in {"auto", "vulkan"}
required_inventory = inventory_required(args.backend, os.name == "nt", os.sys.platform)
dependencies = verify_runtime(source, required_inventory)
crt_notice = source.parent / "MSVC-REDISTRIBUTION.txt"
if os.name == "nt" and args.backend != "cpu":
@@ -0,0 +1,50 @@
from pathlib import Path
import tempfile
import unittest
from unittest.mock import patch
import macos_runtime
class MacRuntimeTests(unittest.TestCase):
def inspect_fixture(self, dependency=None, sections=1, arches="arm64"):
with tempfile.TemporaryDirectory(prefix="mac metadata ") as directory:
worker = Path(directory) / "searchi-gemma-worker"
worker.write_bytes(b"\xcf\xfa\xed\xfe" + b"metadata fixture, not executable")
libraries = f"{worker}:\n\t/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 100.0.0)\n"
libraries += "\t" + (dependency or "/System/Library/Frameworks/Metal.framework/Versions/A/Metal") + " (compatibility version 1.0.0, current version 100.0.0)\n"
loads = "sectname __ggml_metallib\nsegname __DATA\naddr 0x1000\nsize 0x100\n" * sections
with patch.object(macos_runtime.subprocess, "check_output", side_effect=[arches, libraries, loads]):
return macos_runtime.inspect(worker)
def test_static_system_metal_inventory_has_no_packaged_dylibs(self):
result = self.inspect_fixture()
self.assertEqual(result["architectures"], ["arm64"])
self.assertEqual(result["libraries"], [])
self.assertTrue(result["metal_embedded"])
def test_external_library_and_missing_metal_are_rejected(self):
for dependency in ("/private/build path/libggml.dylib", "/usr/lib/libc++.1.dylib"):
with self.subTest(dependency=dependency), self.assertRaises(RuntimeError):
self.inspect_fixture(dependency=dependency)
def test_all_architectures_require_embedded_sources(self):
with self.assertRaisesRegex(RuntimeError, "Each Mach-O architecture"):
self.inspect_fixture(sections=0)
with self.assertRaisesRegex(RuntimeError, "Each Mach-O architecture"):
self.inspect_fixture(sections=1, arches="arm64 x86_64")
self.assertEqual(self.inspect_fixture(sections=2, arches="arm64 x86_64")["architectures"], ["arm64", "x86_64"])
def test_malformed_inventory_and_foreign_artifact_fail(self):
with tempfile.TemporaryDirectory() as directory:
worker = Path(directory) / "worker"
worker.write_bytes(b"\xcf\xfa\xed\xfe")
with self.assertRaises(RuntimeError):
macos_runtime.validate_inventory({"architectures": [["arm64"]]}, worker)
worker.write_bytes(b"MZxx")
with self.assertRaisesRegex(RuntimeError, "Mach-O"):
macos_runtime.validate_inventory({}, worker)
if __name__ == "__main__":
unittest.main()
@@ -13,6 +13,29 @@ import runtime_provenance
class StagingTests(unittest.TestCase):
def test_normal_macos_requires_inventory_and_internal_cpu_remains_optional(self):
self.assertTrue(stage_runtime.inventory_required("auto", False, "darwin"))
self.assertTrue(stage_runtime.inventory_required("metal", False, "darwin"))
self.assertFalse(stage_runtime.inventory_required("cpu", False, "darwin"))
self.assertTrue(stage_runtime.inventory_required("auto", True, "win32"))
self.assertTrue(stage_runtime.inventory_required("auto", False, "linux"))
def test_static_macos_inventory_accepts_no_dynamic_libraries(self):
with tempfile.TemporaryDirectory() as directory:
worker = Path(directory) / "searchi-gemma-worker"
worker.write_bytes(b"\xcf\xfa\xed\xfe" + b"metadata fixture, not executable")
manifest = {"platform": "macos", "layout": "static-metal-embedded",
"architectures": ["arm64"], "metal_embedded": True, "libraries": [],
"system_libraries": ["/usr/lib/libSystem.B.dylib", "/System/Library/Frameworks/Metal.framework/Versions/A/Metal"],
"worker_sha256": hashlib.sha256(worker.read_bytes()).hexdigest(),
"build_provenance": runtime_provenance.fingerprint()}
inventory = worker.parent / "runtime-libraries.json"
inventory.write_text(json.dumps(manifest))
self.assertEqual(stage_runtime.verify_runtime(worker, True), [inventory])
manifest["metal_embedded"] = False
inventory.write_text(json.dumps(manifest))
with self.assertRaises(RuntimeError):
stage_runtime.verify_runtime(worker, True)
def test_linux_inventory_stages_core_and_modules_and_removes_previous_owned_library(self):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)