mirror of
https://github.com/HeyPuter/firefox.git
synced 2026-11-13 20:14:57 -10:00
This is the result of running `./mach vendor third_party/llama.cpp/moz.yaml --patch none && ./mach vendor third_party/llama.cpp/moz.yaml --patch only`. This vendors the CMakeLists.txt files, and parses them, generating sources.mozbuild. Some custom code runs after that, but things have been stable for 3 or 4 updates in the last few weeks. This runs in a separate process (Inference) that has a similar sandbox to a content process. Only CPU inference is enabled, hardware acceleration will come at a later stage, and after sandboxing work. A few patches were needed, most notably to work around the lack of exceptions in Firefox, and to not use functions from libstdc++ that are too recent. Differential Revision: https://phabricator.services.mozilla.com/D253058
138 lines
4.7 KiB
Python
Executable File
138 lines
4.7 KiB
Python
Executable File
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
import cmakeparser as cp
|
|
|
|
import copy
|
|
import datetime
|
|
import os
|
|
import re
|
|
import subprocess
|
|
|
|
LLAMA_DIR = '.'
|
|
|
|
# This program runs after pulling a new version of the llama.cpp library,
|
|
# including all its CMakeLists.txt files, and runs the a cmake file parser, to
|
|
# generate a source file list.
|
|
|
|
def deduplicate_into(input_dict, common_key):
|
|
sets = [set(input_dict[key]) for key in input_dict]
|
|
common_values = set.intersection(*sets)
|
|
input_dict[common_key] = list(common_values)
|
|
for key in input_dict:
|
|
if key != common_key:
|
|
input_dict[key] = [item for item in input_dict[key] if item not in common_values]
|
|
|
|
return input_dict
|
|
|
|
if __name__ == '__main__':
|
|
shared_variables = {
|
|
'CMAKE_CURRENT_SOURCE_DIR': LLAMA_DIR,
|
|
'CMAKE_CURRENT_BINARY_DIR': 'OBJDIR',
|
|
'CMAKE_INSTALL_PREFIX': 'INSTALLDIR',
|
|
'CMAKE_SYSTEM_NAME': 'Linux',
|
|
'CMAKE_SYSTEM_PROCESSOR': 'x86_64',
|
|
'LLAMA_USE_SYSTEM_GGML': 0,
|
|
'TARGET': 'llama',
|
|
'ENABLE_EXAMPLES': 0,
|
|
'ENABLE_TESTS': 0,
|
|
'ENABLE_TOOLS': 0,
|
|
'ENABLE_DOCS': 0,
|
|
'ENABLE_NEON': 1,
|
|
'MOZ_GGML_BACKENDS': "cpu"
|
|
}
|
|
|
|
platforms = [
|
|
('armv7', 'linux', 'arm', True),
|
|
('arm64', 'mac', 'arm64', True),
|
|
('generic', '', 'generic', True),
|
|
('x86', 'linux', 'ia32', True),
|
|
('x86', 'win', 'ia32', False),
|
|
('x86_64', 'linux', 'x64', True),
|
|
('x86_64', 'mac', 'x64', False),
|
|
('x86_64', 'win', 'x64', False),
|
|
]
|
|
all_sources = dict()
|
|
# exports aren't platform specific
|
|
all_exports = []
|
|
for cpu, system, arch, generate_sources in platforms:
|
|
print('Running CMake for %s (%s)' % (cpu, system))
|
|
variables = shared_variables.copy()
|
|
|
|
# llama.cpp only cares about x86 and arm
|
|
if "arm" in cpu:
|
|
variables["GGML_SYSTEM_ARCH"] = "ARM"
|
|
elif "x86" in cpu:
|
|
variables["GGML_SYSTEM_ARCH"] = "x86"
|
|
else:
|
|
print("CPU not x86 or arm, falling back on C paths")
|
|
|
|
if system == "mac":
|
|
variables["APPLE"] = 1
|
|
variables["GGML_ACCELERATE"] = 1
|
|
|
|
cache_variables = []
|
|
pwd = [LLAMA_DIR]
|
|
sources = cp.parse(variables, cache_variables, pwd,
|
|
os.path.join(LLAMA_DIR, 'CMakeLists.txt'))
|
|
|
|
if generate_sources:
|
|
sources = list(set(sources))
|
|
sources = list(filter(lambda x: x.startswith(LLAMA_DIR), sources))
|
|
sources = list(filter(lambda x: not x.endswith('/'), sources))
|
|
|
|
headers = list(filter(lambda x: x.endswith(".h"), sources))
|
|
headers = list(filter(lambda x: "include" in x , headers))
|
|
sources = list(filter(lambda x: not x.endswith(".h"), sources))
|
|
sources = list(filter(lambda x: "//" not in x, sources))
|
|
|
|
all_exports.extend(headers)
|
|
all_sources["{}".format(arch.upper())] = sources
|
|
|
|
all_sources = deduplicate_into(all_sources, "COMMON")
|
|
rename_rules = [
|
|
("ggml.c", "ggml-c.c"),
|
|
("ggml-cpu.c", "ggml-cpu-c.c"),
|
|
("x86/quants.c", "x86/quants-x86.c"),
|
|
("arm/quants.c", "arm/quants-arm.c"),
|
|
("x86/repack.cpp", "x86/repack-x86.cpp"),
|
|
("arm/repack.cpp", "arm/repack-arm.cpp"),
|
|
("x86/cpu-feats.c", "x86/cpu-feats-x86.c"),
|
|
("arm/cpu-feats.c", "arm/cpu-feats-x86.c"),
|
|
]
|
|
for old, new in rename_rules:
|
|
for source_class in all_sources:
|
|
for file in all_sources[source_class]:
|
|
if file.endswith(old):
|
|
# rename the file in the dict, and move on disk if not already done
|
|
renamed_path = file[:-len(old)] + new
|
|
all_sources[source_class].remove(file)
|
|
all_sources[source_class].append(renamed_path)
|
|
if not os.path.exists(renamed_path):
|
|
os.rename(file, renamed_path)
|
|
|
|
# dedup
|
|
all_exports = list(set(all_exports))
|
|
# normalize paths, removing `/../`
|
|
all_exports = list(map(os.path.normpath, all_exports))
|
|
|
|
f = open('sources.mozbuild', 'w')
|
|
f.write('# This file is generated. Do not edit.\n\n')
|
|
f.write('files = {\n')
|
|
|
|
f.write(' \'EXPORTS\': [\n')
|
|
for header in sorted(all_exports):
|
|
f.write(' \'{}\',\n'.format(header))
|
|
f.write(' ],\n')
|
|
for (arch, sources) in all_sources.items():
|
|
if len(sources) == 0:
|
|
continue
|
|
f.write(' \'%s_SOURCES\': [\n' % arch.upper())
|
|
for source in sorted(sources):
|
|
f.write(' \'%s\',\n' % source)
|
|
f.write(' ],\n')
|
|
|
|
print('\n')
|
|
f.write('}\n')
|
|
f.close()
|