From: ochafik Date: Sun, 13 Aug 2023 16:37:03 +0000 (+0100) Subject: Add python example w/ cffi-generated bindings X-Git-Tag: upstream/0.0.1642~1269^2~3 X-Git-Url: https://git.djapps.eu/?a=commitdiff_plain;h=53a0003018828bd4094cd4f67009d9df7bb18669;p=pkg%2Fggml%2Fsources%2Fggml Add python example w/ cffi-generated bindings Add python example w/ cffi-generated bindings Features: - Seamless copies between tensors (ggml & numpy alike) with automatic (de/re)quantization - Access to full C API (incl. CUDA, MPI, OpenCL, Metal, alloc... and any local API changes) - Trivial regeneration with `python regenerate.py` (uses llama.cpp headers by default, README.md for options) --- diff --git a/.gitignore b/.gitignore index 467c19da..d7e11716 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,5 @@ zig-cache/ *.dot *.sw? + +__pycache__/ \ No newline at end of file diff --git a/examples/python/README.md b/examples/python/README.md new file mode 100644 index 00000000..66b91bd4 --- /dev/null +++ b/examples/python/README.md @@ -0,0 +1,107 @@ +# Simple autogenerated Python bindings for ggml + +This folder contains: + +- Scripts to generate full Python bindings from ggml headers. +- Some barebones utils (see [ggml/utils.py](./ggml/utils.py)): + - `ggml.utils.init` builds a context that's freed automatically when the pointer gets GC'd + - `ggml.utils.copy` **copies between same-shaped tensors (numpy or ggml), w/ automatic (de/re)quantization** + - `ggml.utils.numpy` returns a numpy view over a ggml tensor; if it's quantized, it returns a copy (requires `allow_copy=True`) +- Very basic examples (anyone wants to port [llama2.c](https://github.com/karpathy/llama2.c)?) + +Provided you set `GGML_LIBRARY=.../path/to/libggml_shared.so` (see instructions below), it's trivial to do some operations on quantized tensors: + +```python +# Make sure libllama.so is in your [DY]LD_LIBRARY_PATH, or set GGML_LIBRARY=.../libggml_shared.so + +from ggml import lib, ffi +from ggml.utils import init, copy, numpy +import numpy as np + +ctx = init(mem_size=12*1024*1024) +n = 256 +n_threads = 4 + +a = lib.ggml_new_tensor_1d(ctx, lib.GGML_TYPE_Q5_K, n) +b = lib.ggml_new_tensor_1d(ctx, lib.GGML_TYPE_F32, n) # Can't both be quantized +sum = lib.ggml_add(ctx, a, b) # all zeroes for now. Will be quantized too! + +gf = ffi.new('struct ggml_cgraph*') +lib.ggml_build_forward_expand(gf, sum) + +copy(np.array([i for i in range(n)], np.float32), a) +copy(np.array([i*100 for i in range(n)], np.float32), b) + +lib.ggml_graph_compute_with_ctx(ctx, gf, n_threads) + +print(numpy(a, allow_copy=True)) +# 0. 1.0439453 2.0878906 3.131836 4.1757812 5.2197266. ... +print(numpy(b)) +# 0. 100. 200. 300. 400. 500. ... +print(numpy(sum, allow_copy=True)) +# 0. 105.4375 210.875 316.3125 421.75 527.1875 ... +``` + +### Prerequisites + +You'll need a shared library of ggml to use the bindings. + +#### Build libggml_shared.so or libllama.so + +As of this writing the best is to use [ggerganov/llama.cpp](https://github.com/ggerganov/llama.cpp)'s generated `libggml_shared.so` or `libllama.so`, which you can build as follows: + +```bash +git clone https://github.com/ggerganov/llama.cpp +# On a CUDA-enabled system add -DLLAMA_CUBLAS=1 +# On a Mac add -DLLAMA_METAL=1 +cmake llama.cpp \ + -B llama_build \ + -DCMAKE_C_FLAGS=-Ofast \ + -DLLAMA_NATIVE=1 \ + -DLLAMA_LTO=1 \ + -DBUILD_SHARED_LIBS=1 \ + -DLLAMA_MPI=1 \ + -DLLAMA_BUILD_TESTS=0 \ + -DLLAMA_BUILD_EXAMPLES=0 +( cd llama_build && make -j ) + +# On Mac, this will be libggml_shared.dylib instead +export GGML_LIBRARY=$PWD/llama_build/libggml_shared.so +# Alternatively, you can just copy it to your system's lib dir, e.g /usr/local/lib +``` + +#### (Optional) Regenerate the bindings (`ggml/cffi.py`) + +If you added or changed any signatures of the C API, you'll want to regenerate the bindings. + +Luckily it's a one-liner using [regenerate.py](./regenerate.py): + +```bash +pip install -q cffi + +python regenerate.py +``` + +By default it assumes `llama.cpp` was cloned in ../../../llama.cpp (alongside the ggml folder). You can override this with: + +```bash +C_INCLUDE_DIR=$LLAMA_CPP_DIR python regenerate.py +``` + +You can also edit [api.h](./api.h) to control which files should be included in the generated bindings (defaults to `llama.cpp/ggml*.h`) + +In fact, if you wanted to only generate bindings for the current version of the `ggml` repo itself (instead of `llama.cpp`; you'd loose support for k-quants), you could run: + +```bash +API=../../include/ggml/ggml.h python regenerate.py +``` + +### Alternatives + +This example's goal is to showcase [cffi](https://cffi.readthedocs.io/)-generated bindings that are trivial to use and update, but there are already alternatives in the wild: + +- https://github.com/abetlen/ggml-python: these bindings seem to be hand-written and use [ctypes](https://docs.python.org/3/library/ctypes.html). It has [high-quality API reference docs](https://ggml-python.readthedocs.io/en/latest/api-reference/#ggml.ggml) that can be used with these bindings too, but it doesn't expose Metal, CUDA, MPI or OpenCL calls, doesn't support transparent (de/re)quantization like this example does (see [ggml.utils](./ggml/utils.py) module), and won't pick up your local changes. + +- https://github.com/abetlen/llama-cpp-python: these expose the C++ `llama.cpp` interface, which this example cannot easily be extended to support (`cffi` only generates bindings of C libraries) + +- [pybind11](https://github.com/pybind/pybind11) and [nanobind](https://github.com/wjakob/nanobind) are two alternatives to cffi that support binding C++ libraries, but it doesn't seem either of them have an automatic generator (writing bindings is rather time-consuming). diff --git a/examples/python/api.h b/examples/python/api.h new file mode 100644 index 00000000..8d565bd5 --- /dev/null +++ b/examples/python/api.h @@ -0,0 +1,14 @@ +/* + List here all the headers you want to expose in the Python bindings, + then run `python regenerate.py` (see details in README.md) +*/ + +#include "ggml.h" +#include "ggml-metal.h" +#include "ggml-opencl.h" + +// Headers below are currently only present in the llama.cpp repository, comment them out if you don't have them. +#include "k_quants.h" +#include "ggml-alloc.h" +#include "ggml-cuda.h" +#include "ggml-mpi.h" \ No newline at end of file diff --git a/examples/python/example_add_quant.py b/examples/python/example_add_quant.py new file mode 100644 index 00000000..cecb44ec --- /dev/null +++ b/examples/python/example_add_quant.py @@ -0,0 +1,25 @@ +from ggml import lib, ffi +from ggml.utils import init, copy, numpy +import numpy as np + +ctx = init(mem_size=12*1024*1024) # automatically freed when pointer is GC'd +n = 256 +n_threads = 4 + +a = lib.ggml_new_tensor_1d(ctx, lib.GGML_TYPE_Q5_K, n) +b = lib.ggml_new_tensor_1d(ctx, lib.GGML_TYPE_F32, n) # can't both be quantized +sum = lib.ggml_add(ctx, a, b) # all zeroes for now. Will be quantized too! + +# See cffi's doc on how to allocate native memory: it's very simple! +# https://cffi.readthedocs.io/en/latest/ref.html#ffi-interface +gf = ffi.new('struct ggml_cgraph*') +lib.ggml_build_forward_expand(gf, sum) + +copy(np.array([i for i in range(n)], np.float32), a) +copy(np.array([i*100 for i in range(n)], np.float32), b) + +lib.ggml_graph_compute_with_ctx(ctx, gf, n_threads) + +print(numpy(a, allow_copy=True)) +print(numpy(b)) +print(numpy(sum, allow_copy=True)) \ No newline at end of file diff --git a/examples/python/example_test_all_quants.py b/examples/python/example_test_all_quants.py new file mode 100644 index 00000000..8d3c9665 --- /dev/null +++ b/examples/python/example_test_all_quants.py @@ -0,0 +1,68 @@ +from ggml import ffi, lib +from ggml.utils import init, numpy, copy +import numpy as np +from math import pi, cos, sin, ceil + +import matplotlib.pyplot as plt + +ctx = init(mem_size=100*1024*1024) # Will be auto-GC'd +n = 256 + +orig = np.array([ + [ + cos(j * 2 * pi / n) * (sin(i * 2 * pi / n)) + for j in range(n) + ] + for i in range(n) +], np.float32) +orig_tensor = lib.ggml_new_tensor_2d(ctx, lib.GGML_TYPE_F32, n, n) +copy(orig, orig_tensor) + +quants = [ + type for type in range(lib.GGML_TYPE_COUNT) + if lib.ggml_is_quantized(type) and + type not in [lib.GGML_TYPE_Q8_1, lib.GGML_TYPE_Q8_K] # Apparently not supported +] +# quants = [lib.GGML_TYPE_Q2_K] # Test a single one + +def get_name(type): + name = lib.ggml_type_name(type) + return ffi.string(name).decode('utf-8') if name else '?' + +quants.sort(key=get_name) +quants.insert(0, None) +print(quants) + +ncols=4 +nrows = ceil(len(quants) / ncols) + +plt.figure(figsize=(ncols * 5, nrows * 5), layout='tight') + +for i, type in enumerate(quants): + plt.subplot(nrows, ncols, i + 1) + try: + if type == None: + plt.title('Original') + plt.imshow(orig) + else: + quantized_tensor = lib.ggml_new_tensor_2d(ctx, type, n, n) + copy(orig_tensor, quantized_tensor) + quantized = numpy(quantized_tensor, allow_copy=True) + d = quantized - orig + results = { + "l2": np.linalg.norm(d, 2), + "linf": np.linalg.norm(d, np.inf), + "compression": + round(lib.ggml_nbytes(orig_tensor) / + lib.ggml_nbytes(quantized_tensor), 1) + } + name = get_name(type) + print(f'{name}: {results}') + + plt.title(f'{name} ({results["compression"]}x smaller)') + plt.imshow(quantized, interpolation='nearest') + + except Exception as e: + print(f'Error: {e}') + +plt.show() \ No newline at end of file diff --git a/examples/python/ggml/__init__.py b/examples/python/ggml/__init__.py new file mode 100644 index 00000000..31a19102 --- /dev/null +++ b/examples/python/ggml/__init__.py @@ -0,0 +1,58 @@ +""" + Python bindings for the ggml library. + + Usage example: + + from ggml import lib, ffi + from ggml.utils import init, copy, numpy + import numpy as np + + ctx = init(mem_size=10*1024*1024) + n = 1024 + n_threads = 4 + + a = lib.ggml_new_tensor_1d(ctx, lib.GGML_TYPE_Q5_K, n) + b = lib.ggml_new_tensor_1d(ctx, lib.GGML_TYPE_F32, n) + sum = lib.ggml_add(ctx, a, b) + + gf = ffi.new('struct ggml_cgraph*') + lib.ggml_build_forward_expand(gf, sum) + + copy(np.array([i for i in range(n)], np.float32), a) + copy(np.array([i*100 for i in range(n)], np.float32), b) + lib.ggml_graph_compute_with_ctx(ctx, gf, n_threads) + + print(numpy(sum, allow_copy=True)) + + See https://cffi.readthedocs.io/en/latest/cdef.html for more on cffi. +""" + +try: + from ggml.cffi import ffi as ffi +except ImportError as e: + raise ImportError(f"Couldn't find ggml bindings ({e}). Run `python regenerate.py` or check your PYTHONPATH.") + +import os, platform + +__exact_library = os.environ.get("GGML_LIBRARY") +if __exact_library: + __candidates = [__exact_library] +elif platform.system() == "Windows": + __candidates = ["ggml_shared.dll", "llama.dll"] +else: + __candidates = ["libggml_shared.so", "libllama.so"] + if platform.system() == "Darwin": + __candidates += ["libggml_shared.dylib", "libllama.dylib"] + +for i, name in enumerate(__candidates): + try: + # This is where all the functions, enums and constants are defined + lib = ffi.dlopen(name) + except OSError: + if i < len(__candidates) - 1: + continue + raise OSError(f"Couldn't find ggml's shared library (tried names: {__candidates}). Add its directory to DYLD_LIBRARY_PATH (on Mac) or LD_LIBRARY_PATH, or define GGML_LIBRARY.") + +# This contains the cffi helpers such as new, cast, string, etc. +# https://cffi.readthedocs.io/en/latest/ref.html#ffi-interface +ffi = ffi diff --git a/examples/python/ggml/cffi.py b/examples/python/ggml/cffi.py new file mode 100644 index 00000000..97625555 --- /dev/null +++ b/examples/python/ggml/cffi.py @@ -0,0 +1,11 @@ +# auto-generated file +import _cffi_backend + +ffi = _cffi_backend.FFI('ggml.cffi', + _version = 0x2601, + _types = b'\x00\x00\x84\x0D\x00\x00\x09\x0B\x00\x00\x00\x0F\x00\x00\x84\x0D\x00\x03\x7C\x03\x00\x00\x00\x0F\x00\x00\x84\x0D\x00\x03\x7E\x03\x00\x03\x8A\x03\x00\x00\x00\x0F\x00\x00\x84\x0D\x00\x03\x7F\x03\x00\x00\x00\x0F\x00\x00\x84\x0D\x00\x03\x81\x03\x00\x00\x00\x0F\x00\x00\x84\x0D\x00\x00\x0E\x11\x00\x03\x49\x03\x00\x03\xA1\x03\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x84\x0D\x00\x03\x8A\x03\x00\x00\x00\x0F\x00\x00\x84\x0D\x00\x00\x18\x11\x00\x00\x18\x11\x00\x00\x00\x0F\x00\x00\x84\x0D\x00\x00\x18\x11\x00\x00\x18\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x00\x84\x0D\x00\x00\x13\x11\x00\x00\x00\x0F\x00\x00\x84\x0D\x00\x00\x00\x0F\x00\x00\x12\x0D\x00\x00\x04\x0B\x00\x00\x00\x0F\x00\x00\x12\x0D\x00\x00\x01\x11\x00\x00\x00\x0F\x00\x00\x12\x0D\x00\x00\x18\x11\x00\x00\x00\x0F\x00\x03\x61\x0D\x00\x00\x0B\x11\x00\x03\x85\x03\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x03\x61\x0D\x00\x00\x0B\x11\x00\x00\x33\x11\x00\x00\x08\x11\x00\x03\x7D\x03\x00\x00\x3A\x11\x00\x00\x00\x0F\x00\x03\x61\x0D\x00\x00\x0B\x11\x00\x00\x20\x09\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x01\x0B\x00\x00\x00\x0F\x00\x00\xE2\x0D\x00\x00\x18\x11\x00\x00\x00\x0F\x00\x02\x2C\x0D\x00\x00\x18\x11\x00\x00\x00\x0F\x00\x00\xC2\x0D\x00\x00\x01\x11\x00\x00\x00\x0F\x00\x00\xC2\x0D\x00\x00\x18\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\xC2\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x03\x63\x0D\x00\x00\x01\x11\x00\x00\x00\x0F\x00\x00\x50\x0D\x00\x00\x01\x11\x00\x00\x00\x0F\x00\x00\x50\x0D\x00\x00\x3A\x11\x00\x03\x80\x03\x00\x00\x00\x0F\x00\x00\x50\x0D\x00\x03\x82\x03\x00\x00\x00\x0F\x00\x00\x50\x0D\x00\x00\x18\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x50\x0D\x00\x00\x00\x0F\x00\x00\xA9\x0D\x00\x00\x18\x11\x00\x00\x00\x0F\x00\x00\xA9\x0D\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x04\x0D\x00\x00\x13\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x3A\x0D\x00\x00\x0B\x11\x00\x00\x00\x0F\x00\x00\x3A\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x03\x7D\x0D\x00\x00\x12\x11\x00\x00\x0B\x03\x00\x00\x7E\x11\x00\x00\x00\x0F\x00\x03\x7D\x0D\x00\x00\x0B\x11\x00\x00\x3A\x11\x00\x00\x01\x01\x00\x00\x00\x0F\x00\x03\x7D\x0D\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x00\x0B\x0D\x00\x00\x1B\x09\x00\x00\x00\x0F\x00\x03\x80\x0D\x00\x00\x3A\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x0E\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x60\x0D\x00\x00\x00\x0F\x00\x00\x3F\x0D\x00\x00\x07\x0B\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x3A\x11\x00\x00\x12\x11\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x12\x11\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x01\x11\x00\x00\x07\x01\x00\x00\xA9\x03\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x01\x11\x00\x00\x0B\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x01\x11\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x01\x11\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x01\x11\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x0D\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x05\x0B\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\xCF\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x0A\x0B\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x0D\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x0D\x01\x00\x00\x0D\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x0D\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x0D\x01\x00\x00\x0D\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x0B\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x0B\x01\x00\x00\x0B\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x0B\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x01\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x01\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x02\xFB\x03\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x03\x01\x03\x00\x00\x07\x01\x00\x00\x13\x11\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x02\x81\x03\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x02\xEE\x03\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x08\x11\x00\x02\xF3\x03\x00\x00\x07\x01\x00\x00\x13\x11\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x02\x7C\x03\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x02\xE3\x03\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x02\xE7\x03\x00\x00\x07\x01\x00\x00\x13\x11\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x0B\x11\x00\x00\x18\x11\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x08\x11\x00\x00\x12\x11\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x08\x11\x00\x00\x12\x11\x00\x00\x01\x0F\x00\x00\x08\x0D\x00\x00\x08\x11\x00\x00\x0D\x01\x00\x00\x00\x0F\x00\x00\x08\x0D\x00\x00\x08\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x14\x0D\x00\x00\x01\x11\x00\x00\x00\x0F\x00\x00\x14\x0D\x00\x00\x01\x11\x00\x00\xC2\x03\x00\x00\x13\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xA9\x03\x00\x00\x00\x0F\x00\x00\x14\x0D\x00\x01\xF5\x11\x00\x00\x13\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x01\xF9\x11\x00\x00\x00\x0F\x00\x00\x14\x0D\x00\x00\x04\x11\x00\x00\x3A\x11\x00\x00\x00\x0F\x00\x00\x14\x0D\x00\x00\x0B\x11\x00\x00\x21\x09\x00\x00\x00\x0F\x00\x00\x14\x0D\x00\x03\x7F\x03\x00\x00\x00\x0F\x00\x00\x14\x0D\x00\x00\x18\x11\x00\x00\x00\x0F\x00\x00\x14\x0D\x00\x00\x18\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x14\x0D\x00\x00\x18\x11\x00\x00\x18\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x00\x14\x0D\x00\x00\x00\x0F\x00\x00\x53\x0D\x00\x00\x0D\x01\x00\x00\x00\x0F\x00\x00\x13\x0D\x00\x02\x0B\x11\x00\x00\x00\x0F\x00\x00\x13\x0D\x00\x00\x18\x11\x00\x00\x00\x0F\x00\x00\x13\x0D\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x01\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x03\x43\x03\x00\x00\xC2\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x03\x44\x03\x00\x02\x2C\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x03\x45\x03\x00\x02\x2C\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x03\x46\x03\x00\x02\x2C\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x03\x47\x03\x00\x02\x2C\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x03\x48\x03\x00\x02\x2C\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x12\x11\x00\x00\x12\x11\x00\x00\x07\x01\x00\x00\x12\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x01\xF5\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x01\xF5\x11\x00\x03\x43\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x01\xF5\x11\x00\x03\x44\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x01\xF5\x11\x00\x03\x45\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x01\xF5\x11\x00\x03\x46\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x01\xF5\x11\x00\x03\x47\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x01\xF5\x11\x00\x03\x48\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x01\xF5\x11\x00\x00\x53\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x01\xF5\x11\x00\x00\x13\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x07\x01\x00\x02\x2C\x11\x00\x01\xF5\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x07\x01\x00\x02\x2C\x11\x00\x01\xF5\x11\x00\x01\xF5\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x07\x01\x00\x02\x2C\x11\x00\x03\xA1\x03\x00\x02\x8A\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x04\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x04\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x3A\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x3A\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x03\x7D\x03\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x02\x9C\x11\x00\x00\x12\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x02\x9C\x11\x00\x02\x9C\x11\x00\x00\x12\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x0B\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x0B\x11\x00\x00\x01\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x0B\x11\x00\x00\x3A\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x0B\x11\x00\x00\x33\x11\x00\x00\x3F\x11\x00\x00\x0B\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x0B\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x02\x0B\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x0E\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x0E\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x0E\x11\x00\x00\x3A\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x0E\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x60\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x60\x11\x00\x00\x50\x03\x00\x02\xD4\x11\x00\x02\xD4\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x60\x11\x00\x00\x3A\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x03\x84\x03\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x08\x11\x00\x00\x18\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x08\x11\x00\x00\x18\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x13\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x08\x11\x00\x00\x18\x11\x00\x00\x18\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x08\x11\x00\x00\x18\x11\x00\x00\x18\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x13\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x08\x11\x00\x00\x18\x11\x00\x00\x18\x11\x00\x00\x18\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x08\x11\x00\x00\x18\x11\x00\x00\x18\x11\x00\x00\x18\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x13\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x18\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x18\x11\x00\x00\x07\x01\x00\x00\x0D\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x18\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x18\x11\x00\x00\x18\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x18\x11\x00\x00\x18\x11\x00\x00\x08\x11\x00\x00\x13\x11\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x53\x03\x00\x02\x2C\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x13\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x13\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x02\x8A\x11\x00\x02\x2C\x11\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x03\xA1\x0D\x00\x00\x00\x0F\x00\x00\x23\x03\x00\x00\x0D\x09\x00\x00\x0E\x09\x00\x00\x0F\x09\x00\x00\x10\x09\x00\x00\x11\x09\x00\x00\x12\x09\x00\x00\x13\x09\x00\x00\x14\x09\x00\x00\x04\x09\x00\x00\x05\x09\x00\x00\x06\x09\x00\x00\x07\x09\x00\x00\x08\x09\x00\x00\x09\x09\x00\x00\x0A\x09\x00\x00\x02\x01\x00\x03\x49\x05\x00\x00\x00\x80\x00\x03\x49\x05\x00\x00\x00\x10\x00\x03\x49\x05\x00\x00\x00\xC0\x00\x03\x49\x05\x00\x00\x00\x25\x00\x03\x49\x05\x00\x00\x00\x28\x00\x03\x49\x05\x00\x00\x00\x30\x00\x03\x49\x05\x00\x00\x00\x04\x00\x03\x49\x05\x00\x00\x00\x38\x00\x03\x49\x05\x00\x00\x1F\xF0\x00\x03\x49\x05\x00\x00\x00\x08\x00\x00\x00\x0B\x00\x00\x02\x0B\x00\x00\x03\x0B\x00\x00\x06\x0B\x00\x00\x08\x0B\x00\x00\x0B\x09\x00\x00\x50\x05\x00\x00\x10\x00\x00\x00\x50\x05\x00\x00\x00\x08\x00\x00\x0F\x01\x00\x00\xA9\x05\x00\x00\x00\x04\x00\x00\x09\x01\x00\x00\x05\x01\x00\x03\x6C\x05\x00\x00\x00\x10\x00\x00\x03\x01\x00\x03\x6F\x05\x00\x00\x00\x10\x00\x03\x6F\x05\x00\x00\x01\x00\x00\x00\x00\x09\x00\x00\x01\x09\x00\x00\x02\x09\x00\x00\x03\x09\x00\x03\x79\x03\x00\x00\x0C\x09\x00\x03\x7B\x03\x00\x00\x15\x09\x00\x00\x16\x09\x00\x00\x17\x09\x00\x00\x18\x09\x00\x00\x19\x09\x00\x00\x1A\x09\x00\x00\x1C\x09\x00\x00\x1D\x09\x00\x03\x84\x03\x00\x00\x1E\x09\x00\x00\x1F\x09\x00\x00\x08\x05\x00\x00\x10\x00\x00\x00\x08\x05\x00\x00\x00\x06\x00\x00\x22\x09\x00\x03\x8C\x03\x00\x00\x04\x01\x00\x03\x8C\x05\x00\x00\x00\x80\x00\x03\x8C\x05\x00\x00\x00\x0C\x00\x03\x8C\x05\x00\x00\x00\x10\x00\x03\x8C\x05\x00\x00\x00\x20\x00\x03\x8C\x05\x00\x00\x00\x40\x00\x00\x08\x01\x00\x00\x0C\x01\x00\x00\x14\x05\x00\x00\x00\x04\x00\x00\x13\x05\x00\x00\x20\x51\x00\x02\x74\x03\x00\x02\x87\x03\x00\x03\x2B\x03\x00\x03\x32\x03\x00\x00\x00\x01', + _globals = (b'\xFF\xFF\xFF\x0BGGML_BACKEND_CPU',0,b'\xFF\xFF\xFF\x0BGGML_BACKEND_GPU',10,b'\xFF\xFF\xFF\x0BGGML_BACKEND_GPU_SPLIT',20,b'\xFF\xFF\xFF\x0BGGML_FTYPE_ALL_F32',0,b'\xFF\xFF\xFF\x0BGGML_FTYPE_MOSTLY_F16',1,b'\xFF\xFF\xFF\x0BGGML_FTYPE_MOSTLY_Q2_K',10,b'\xFF\xFF\xFF\x0BGGML_FTYPE_MOSTLY_Q3_K',11,b'\xFF\xFF\xFF\x0BGGML_FTYPE_MOSTLY_Q4_0',2,b'\xFF\xFF\xFF\x0BGGML_FTYPE_MOSTLY_Q4_1',3,b'\xFF\xFF\xFF\x0BGGML_FTYPE_MOSTLY_Q4_1_SOME_F16',4,b'\xFF\xFF\xFF\x0BGGML_FTYPE_MOSTLY_Q4_K',12,b'\xFF\xFF\xFF\x0BGGML_FTYPE_MOSTLY_Q5_0',8,b'\xFF\xFF\xFF\x0BGGML_FTYPE_MOSTLY_Q5_1',9,b'\xFF\xFF\xFF\x0BGGML_FTYPE_MOSTLY_Q5_K',13,b'\xFF\xFF\xFF\x0BGGML_FTYPE_MOSTLY_Q6_K',14,b'\xFF\xFF\xFF\x0BGGML_FTYPE_MOSTLY_Q8_0',7,b'\xFF\xFF\xFF\x0BGGML_FTYPE_UNKNOWN',-1,b'\xFF\xFF\xFF\x1FGGML_GRAPH_SIZE',164520,b'\xFF\xFF\xFF\x0BGGML_LINESEARCH_BACKTRACKING_ARMIJO',0,b'\xFF\xFF\xFF\x0BGGML_LINESEARCH_BACKTRACKING_STRONG_WOLFE',2,b'\xFF\xFF\xFF\x0BGGML_LINESEARCH_BACKTRACKING_WOLFE',1,b'\xFF\xFF\xFF\x0BGGML_LINESEARCH_DEFAULT',1,b'\xFF\xFF\xFF\x0BGGML_LINESEARCH_FAIL',-128,b'\xFF\xFF\xFF\x0BGGML_LINESEARCH_INVALID_PARAMETERS',-124,b'\xFF\xFF\xFF\x0BGGML_LINESEARCH_MAXIMUM_ITERATIONS',-125,b'\xFF\xFF\xFF\x0BGGML_LINESEARCH_MAXIMUM_STEP',-126,b'\xFF\xFF\xFF\x0BGGML_LINESEARCH_MINIMUM_STEP',-127,b'\xFF\xFF\xFF\x0BGGML_OBJECT_GRAPH',1,b'\xFF\xFF\xFF\x1FGGML_OBJECT_SIZE',32,b'\xFF\xFF\xFF\x0BGGML_OBJECT_TENSOR',0,b'\xFF\xFF\xFF\x0BGGML_OBJECT_WORK_BUFFER',2,b'\xFF\xFF\xFF\x0BGGML_OPT_ADAM',0,b'\xFF\xFF\xFF\x0BGGML_OPT_DID_NOT_CONVERGE',1,b'\xFF\xFF\xFF\x0BGGML_OPT_FAIL',4,b'\xFF\xFF\xFF\x0BGGML_OPT_INVALID_WOLFE',3,b'\xFF\xFF\xFF\x0BGGML_OPT_LBFGS',1,b'\xFF\xFF\xFF\x0BGGML_OPT_NO_CONTEXT',2,b'\xFF\xFF\xFF\x0BGGML_OPT_OK',0,b'\xFF\xFF\xFF\x0BGGML_OP_ACC',4,b'\xFF\xFF\xFF\x0BGGML_OP_ADD',2,b'\xFF\xFF\xFF\x0BGGML_OP_ADD1',3,b'\xFF\xFF\xFF\x0BGGML_OP_ALIBI',40,b'\xFF\xFF\xFF\x0BGGML_OP_ARGMAX',14,b'\xFF\xFF\xFF\x0BGGML_OP_CLAMP',41,b'\xFF\xFF\xFF\x0BGGML_OP_CONT',26,b'\xFF\xFF\xFF\x0BGGML_OP_CONV_1D',42,b'\xFF\xFF\xFF\x0BGGML_OP_CONV_2D',43,b'\xFF\xFF\xFF\x0BGGML_OP_COUNT',62,b'\xFF\xFF\xFF\x0BGGML_OP_CPY',25,b'\xFF\xFF\xFF\x0BGGML_OP_CROSS_ENTROPY_LOSS',60,b'\xFF\xFF\xFF\x0BGGML_OP_CROSS_ENTROPY_LOSS_BACK',61,b'\xFF\xFF\xFF\x0BGGML_OP_DIAG',33,b'\xFF\xFF\xFF\x0BGGML_OP_DIAG_MASK_INF',34,b'\xFF\xFF\xFF\x0BGGML_OP_DIAG_MASK_ZERO',35,b'\xFF\xFF\xFF\x0BGGML_OP_DIV',7,b'\xFF\xFF\xFF\x0BGGML_OP_DUP',1,b'\xFF\xFF\xFF\x0BGGML_OP_FLASH_ATTN',46,b'\xFF\xFF\xFF\x0BGGML_OP_FLASH_ATTN_BACK',48,b'\xFF\xFF\xFF\x0BGGML_OP_FLASH_FF',47,b'\xFF\xFF\xFF\x0BGGML_OP_GET_ROWS',31,b'\xFF\xFF\xFF\x0BGGML_OP_GET_ROWS_BACK',32,b'\xFF\xFF\xFF\x0BGGML_OP_LOG',10,b'\xFF\xFF\xFF\x0BGGML_OP_MAP_BINARY',53,b'\xFF\xFF\xFF\x0BGGML_OP_MAP_CUSTOM1',57,b'\xFF\xFF\xFF\x0BGGML_OP_MAP_CUSTOM1_F32',54,b'\xFF\xFF\xFF\x0BGGML_OP_MAP_CUSTOM2',58,b'\xFF\xFF\xFF\x0BGGML_OP_MAP_CUSTOM2_F32',55,b'\xFF\xFF\xFF\x0BGGML_OP_MAP_CUSTOM3',59,b'\xFF\xFF\xFF\x0BGGML_OP_MAP_CUSTOM3_F32',56,b'\xFF\xFF\xFF\x0BGGML_OP_MAP_UNARY',52,b'\xFF\xFF\xFF\x0BGGML_OP_MEAN',13,b'\xFF\xFF\xFF\x0BGGML_OP_MUL',6,b'\xFF\xFF\xFF\x0BGGML_OP_MUL_MAT',21,b'\xFF\xFF\xFF\x0BGGML_OP_NONE',0,b'\xFF\xFF\xFF\x0BGGML_OP_NORM',18,b'\xFF\xFF\xFF\x0BGGML_OP_OUT_PROD',22,b'\xFF\xFF\xFF\x0BGGML_OP_PERMUTE',29,b'\xFF\xFF\xFF\x0BGGML_OP_POOL_1D',44,b'\xFF\xFF\xFF\x0BGGML_OP_POOL_2D',45,b'\xFF\xFF\xFF\x0BGGML_OP_POOL_AVG',1,b'\xFF\xFF\xFF\x0BGGML_OP_POOL_COUNT',2,b'\xFF\xFF\xFF\x0BGGML_OP_POOL_MAX',0,b'\xFF\xFF\xFF\x0BGGML_OP_REPEAT',15,b'\xFF\xFF\xFF\x0BGGML_OP_REPEAT_BACK',16,b'\xFF\xFF\xFF\x0BGGML_OP_RESHAPE',27,b'\xFF\xFF\xFF\x0BGGML_OP_RMS_NORM',19,b'\xFF\xFF\xFF\x0BGGML_OP_RMS_NORM_BACK',20,b'\xFF\xFF\xFF\x0BGGML_OP_ROPE',38,b'\xFF\xFF\xFF\x0BGGML_OP_ROPE_BACK',39,b'\xFF\xFF\xFF\x0BGGML_OP_SCALE',23,b'\xFF\xFF\xFF\x0BGGML_OP_SET',24,b'\xFF\xFF\xFF\x0BGGML_OP_SILU_BACK',17,b'\xFF\xFF\xFF\x0BGGML_OP_SOFT_MAX',36,b'\xFF\xFF\xFF\x0BGGML_OP_SOFT_MAX_BACK',37,b'\xFF\xFF\xFF\x0BGGML_OP_SQR',8,b'\xFF\xFF\xFF\x0BGGML_OP_SQRT',9,b'\xFF\xFF\xFF\x0BGGML_OP_SUB',5,b'\xFF\xFF\xFF\x0BGGML_OP_SUM',11,b'\xFF\xFF\xFF\x0BGGML_OP_SUM_ROWS',12,b'\xFF\xFF\xFF\x0BGGML_OP_TRANSPOSE',30,b'\xFF\xFF\xFF\x0BGGML_OP_UNARY',51,b'\xFF\xFF\xFF\x0BGGML_OP_VIEW',28,b'\xFF\xFF\xFF\x0BGGML_OP_WIN_PART',49,b'\xFF\xFF\xFF\x0BGGML_OP_WIN_UNPART',50,b'\xFF\xFF\xFF\x0BGGML_TASK_COMPUTE',1,b'\xFF\xFF\xFF\x0BGGML_TASK_FINALIZE',2,b'\xFF\xFF\xFF\x0BGGML_TASK_INIT',0,b'\xFF\xFF\xFF\x1FGGML_TENSOR_SIZE',272,b'\xFF\xFF\xFF\x0BGGML_TYPE_COUNT',19,b'\xFF\xFF\xFF\x0BGGML_TYPE_F16',1,b'\xFF\xFF\xFF\x0BGGML_TYPE_F32',0,b'\xFF\xFF\xFF\x0BGGML_TYPE_I16',17,b'\xFF\xFF\xFF\x0BGGML_TYPE_I32',18,b'\xFF\xFF\xFF\x0BGGML_TYPE_I8',16,b'\xFF\xFF\xFF\x0BGGML_TYPE_Q2_K',10,b'\xFF\xFF\xFF\x0BGGML_TYPE_Q3_K',11,b'\xFF\xFF\xFF\x0BGGML_TYPE_Q4_0',2,b'\xFF\xFF\xFF\x0BGGML_TYPE_Q4_1',3,b'\xFF\xFF\xFF\x0BGGML_TYPE_Q4_K',12,b'\xFF\xFF\xFF\x0BGGML_TYPE_Q5_0',6,b'\xFF\xFF\xFF\x0BGGML_TYPE_Q5_1',7,b'\xFF\xFF\xFF\x0BGGML_TYPE_Q5_K',13,b'\xFF\xFF\xFF\x0BGGML_TYPE_Q6_K',14,b'\xFF\xFF\xFF\x0BGGML_TYPE_Q8_0',8,b'\xFF\xFF\xFF\x0BGGML_TYPE_Q8_1',9,b'\xFF\xFF\xFF\x0BGGML_TYPE_Q8_K',15,b'\xFF\xFF\xFF\x0BGGML_UNARY_OP_ABS',0,b'\xFF\xFF\xFF\x0BGGML_UNARY_OP_ELU',5,b'\xFF\xFF\xFF\x0BGGML_UNARY_OP_GELU',7,b'\xFF\xFF\xFF\x0BGGML_UNARY_OP_GELU_QUICK',8,b'\xFF\xFF\xFF\x0BGGML_UNARY_OP_NEG',2,b'\xFF\xFF\xFF\x0BGGML_UNARY_OP_RELU',6,b'\xFF\xFF\xFF\x0BGGML_UNARY_OP_SGN',1,b'\xFF\xFF\xFF\x0BGGML_UNARY_OP_SILU',9,b'\xFF\xFF\xFF\x0BGGML_UNARY_OP_STEP',3,b'\xFF\xFF\xFF\x0BGGML_UNARY_OP_TANH',4,b'\x00\x02\x48\x23__assert_rtn',0,b'\x00\x02\x2A\x23dequantize_row_q2_K',0,b'\x00\x02\x2F\x23dequantize_row_q3_K',0,b'\x00\x02\x34\x23dequantize_row_q4_K',0,b'\x00\x02\x39\x23dequantize_row_q5_K',0,b'\x00\x02\x3E\x23dequantize_row_q6_K',0,b'\x00\x02\x43\x23dequantize_row_q8_K',0,b'\x00\x00\xC8\x23ggml_abs',0,b'\x00\x00\xC8\x23ggml_abs_inplace',0,b'\x00\x01\xAB\x23ggml_acc',0,b'\x00\x01\xAB\x23ggml_acc_inplace',0,b'\x00\x01\x52\x23ggml_add',0,b'\x00\x01\x52\x23ggml_add1',0,b'\x00\x01\x52\x23ggml_add1_inplace',0,b'\x00\x01\x52\x23ggml_add_inplace',0,b'\x00\x00\xF4\x23ggml_alibi',0,b'\x00\x02\x90\x23ggml_allocr_alloc',0,b'\x00\x02\x02\x23ggml_allocr_alloc_graph',0,b'\x00\x02\x8D\x23ggml_allocr_free',0,b'\x00\x00\x03\x23ggml_allocr_is_measure',0,b'\x00\x00\x70\x23ggml_allocr_new',0,b'\x00\x00\x6D\x23ggml_allocr_new_measure',0,b'\x00\x02\x8D\x23ggml_allocr_reset',0,b'\x00\x00\x1A\x23ggml_are_same_shape',0,b'\x00\x00\xC8\x23ggml_argmax',0,b'\x00\x00\x58\x23ggml_blck_size',0,b'\x00\x00\x81\x23ggml_build_backward',0,b'\x00\x00\x86\x23ggml_build_forward',0,b'\x00\x00\x78\x23ggml_build_forward_ctx',0,b'\x00\x02\x97\x23ggml_build_forward_expand',0,b'\x00\x00\x1E\x23ggml_cl_can_mul_mat',0,b'\x00\x03\x0A\x23ggml_cl_free_data',0,b'\x00\x03\x2B\x23ggml_cl_host_free',0,b'\x00\x02\x24\x23ggml_cl_host_malloc',0,b'\x00\x03\x37\x23ggml_cl_init',0,b'\x00\x03\x17\x23ggml_cl_mul',0,b'\x00\x03\x1C\x23ggml_cl_mul_mat',0,b'\x00\x02\x14\x23ggml_cl_mul_mat_get_wsize',0,b'\x00\x03\x2E\x23ggml_cl_transform_tensor',0,b'\x00\x00\xE9\x23ggml_clamp',0,b'\x00\x00\xC8\x23ggml_cont',0,b'\x00\x00\xC8\x23ggml_cont_inplace',0,b'\x00\x01\x5E\x23ggml_conv_1d',0,b'\x00\x01\x57\x23ggml_conv_1d_ph',0,b'\x00\x01\x66\x23ggml_conv_2d',0,b'\x00\x00\x66\x23ggml_cpu_has_arm_fma',0,b'\x00\x00\x66\x23ggml_cpu_has_avx',0,b'\x00\x00\x66\x23ggml_cpu_has_avx2',0,b'\x00\x00\x66\x23ggml_cpu_has_avx512',0,b'\x00\x00\x66\x23ggml_cpu_has_avx512_vbmi',0,b'\x00\x00\x66\x23ggml_cpu_has_avx512_vnni',0,b'\x00\x00\x66\x23ggml_cpu_has_blas',0,b'\x00\x00\x66\x23ggml_cpu_has_clblast',0,b'\x00\x00\x66\x23ggml_cpu_has_cublas',0,b'\x00\x00\x66\x23ggml_cpu_has_f16c',0,b'\x00\x00\x66\x23ggml_cpu_has_fma',0,b'\x00\x00\x66\x23ggml_cpu_has_fp16_va',0,b'\x00\x00\x66\x23ggml_cpu_has_gpublas',0,b'\x00\x00\x66\x23ggml_cpu_has_neon',0,b'\x00\x00\x66\x23ggml_cpu_has_sse3',0,b'\x00\x00\x66\x23ggml_cpu_has_vsx',0,b'\x00\x00\x66\x23ggml_cpu_has_wasm_simd',0,b'\x00\x01\x52\x23ggml_cpy',0,b'\x00\x01\x52\x23ggml_cpy_inplace',0,b'\x00\x01\x52\x23ggml_cross_entropy_loss',0,b'\x00\x01\x71\x23ggml_cross_entropy_loss_back',0,b'\x00\x02\xE0\x23ggml_cuda_assign_buffers',0,b'\x00\x02\xE0\x23ggml_cuda_assign_buffers_force_inplace',0,b'\x00\x02\xE0\x23ggml_cuda_assign_buffers_no_scratch',0,b'\x00\x00\x1E\x23ggml_cuda_can_mul_mat',0,b'\x00\x00\x06\x23ggml_cuda_compute_forward',0,b'\x00\x02\xE0\x23ggml_cuda_free_data',0,b'\x00\x03\x37\x23ggml_cuda_free_scratch',0,b'\x00\x03\x2B\x23ggml_cuda_host_free',0,b'\x00\x02\x24\x23ggml_cuda_host_malloc',0,b'\x00\x03\x17\x23ggml_cuda_mul',0,b'\x00\x03\x1C\x23ggml_cuda_mul_mat',0,b'\x00\x02\x14\x23ggml_cuda_mul_mat_get_wsize',0,b'\x00\x02\x79\x23ggml_cuda_set_main_device',0,b'\x00\x02\x27\x23ggml_cuda_set_mul_mat_q',0,b'\x00\x03\x23\x23ggml_cuda_set_scratch_size',0,b'\x00\x02\x4E\x23ggml_cuda_set_tensor_split',0,b'\x00\x03\x2E\x23ggml_cuda_transform_tensor',0,b'\x00\x00\x6B\x23ggml_cycles',0,b'\x00\x00\x6B\x23ggml_cycles_per_ms',0,b'\x00\x00\xC8\x23ggml_diag',0,b'\x00\x00\xEF\x23ggml_diag_mask_inf',0,b'\x00\x00\xEF\x23ggml_diag_mask_inf_inplace',0,b'\x00\x00\xEF\x23ggml_diag_mask_zero',0,b'\x00\x00\xEF\x23ggml_diag_mask_zero_inplace',0,b'\x00\x01\x52\x23ggml_div',0,b'\x00\x01\x52\x23ggml_div_inplace',0,b'\x00\x00\xC8\x23ggml_dup',0,b'\x00\x00\xC8\x23ggml_dup_inplace',0,b'\x00\x01\xD9\x23ggml_dup_tensor',0,b'\x00\x02\x0D\x23ggml_element_size',0,b'\x00\x00\xC8\x23ggml_elu',0,b'\x00\x00\xC8\x23ggml_elu_inplace',0,b'\x00\x01\x77\x23ggml_flash_attn',0,b'\x00\x01\x7E\x23ggml_flash_attn_back',0,b'\x00\x01\x86\x23ggml_flash_ff',0,b'\x00\x01\xE4\x23ggml_format_name',0,b'\x00\x00\x52\x23ggml_fp16_to_fp32',0,b'\x00\x03\x26\x23ggml_fp16_to_fp32_row',0,b'\x00\x02\x1B\x23ggml_fp32_to_fp16',0,b'\x00\x02\x6F\x23ggml_fp32_to_fp16_row',0,b'\x00\x02\xA7\x23ggml_free',0,b'\x00\x00\x42\x23ggml_ftype_to_ggml_type',0,b'\x00\x00\xC8\x23ggml_gelu',0,b'\x00\x00\xC8\x23ggml_gelu_inplace',0,b'\x00\x00\xC8\x23ggml_gelu_quick',0,b'\x00\x00\xC8\x23ggml_gelu_quick_inplace',0,b'\x00\x02\x21\x23ggml_get_data',0,b'\x00\x00\x48\x23ggml_get_data_f32',0,b'\x00\x00\x4E\x23ggml_get_f32_1d',0,b'\x00\x00\x62\x23ggml_get_i32_1d',0,b'\x00\x02\x0A\x23ggml_get_max_tensor_size',0,b'\x00\x02\x1E\x23ggml_get_mem_buffer',0,b'\x00\x02\x0A\x23ggml_get_mem_size',0,b'\x00\x00\x2E\x23ggml_get_name',0,b'\x00\x00\x0A\x23ggml_get_no_alloc',0,b'\x00\x01\x52\x23ggml_get_rows',0,b'\x00\x01\x71\x23ggml_get_rows_back',0,b'\x00\x00\x9C\x23ggml_get_tensor',0,b'\x00\x00\x45\x23ggml_get_unary_op',0,b'\x00\x00\x5B\x23ggml_graph_compute',0,b'\x00\x02\xAE\x23ggml_graph_compute_with_ctx',0,b'\x00\x02\xA2\x23ggml_graph_dump_dot',0,b'\x00\x02\x9E\x23ggml_graph_export',0,b'\x00\x00\x98\x23ggml_graph_get_tensor',0,b'\x00\x00\x7C\x23ggml_graph_import',0,b'\x00\x02\x19\x23ggml_graph_overhead',0,b'\x00\x00\x8C\x23ggml_graph_plan',0,b'\x00\x02\x9B\x23ggml_graph_print',0,b'\x00\x02\x94\x23ggml_graph_reset',0,b'\x00\x00\x89\x23ggml_init',0,b'\x00\x03\x37\x23ggml_init_cublas',0,b'\x00\x00\x55\x23ggml_internal_get_type_traits',0,b'\x00\x00\x17\x23ggml_is_contiguous',0,b'\x00\x00\x26\x23ggml_is_numa',0,b'\x00\x00\x17\x23ggml_is_permuted',0,b'\x00\x00\x00\x23ggml_is_quantized',0,b'\x00\x00\x17\x23ggml_is_transposed',0,b'\x00\x00\xC8\x23ggml_log',0,b'\x00\x00\xC8\x23ggml_log_inplace',0,b'\x00\x01\xB4\x23ggml_map_binary_f32',0,b'\x00\x01\xB4\x23ggml_map_binary_inplace_f32',0,b'\x00\x01\xD2\x23ggml_map_custom1',0,b'\x00\x01\xCD\x23ggml_map_custom1_f32',0,b'\x00\x01\xD2\x23ggml_map_custom1_inplace',0,b'\x00\x01\xCD\x23ggml_map_custom1_inplace_f32',0,b'\x00\x01\xC0\x23ggml_map_custom2',0,b'\x00\x01\xBA\x23ggml_map_custom2_f32',0,b'\x00\x01\xC0\x23ggml_map_custom2_inplace',0,b'\x00\x01\xBA\x23ggml_map_custom2_inplace_f32',0,b'\x00\x01\x95\x23ggml_map_custom3',0,b'\x00\x01\x8E\x23ggml_map_custom3_f32',0,b'\x00\x01\x95\x23ggml_map_custom3_inplace',0,b'\x00\x01\x8E\x23ggml_map_custom3_inplace_f32',0,b'\x00\x01\xC8\x23ggml_map_unary_f32',0,b'\x00\x01\xC8\x23ggml_map_unary_inplace_f32',0,b'\x00\x00\xC8\x23ggml_mean',0,b'\x00\x00\x10\x23ggml_metal_add_buffer',0,b'\x00\x02\xC0\x23ggml_metal_free',0,b'\x00\x02\xCB\x23ggml_metal_get_tensor',0,b'\x00\x02\xC7\x23ggml_metal_graph_compute',0,b'\x00\x02\xC7\x23ggml_metal_graph_find_concurrency',0,b'\x00\x00\x0D\x23ggml_metal_if_optimized',0,b'\x00\x00\x90\x23ggml_metal_init',0,b'\x00\x02\xC3\x23ggml_metal_set_n_cb',0,b'\x00\x02\xCB\x23ggml_metal_set_tensor',0,b'\x00\x03\x37\x23ggml_mpi_backend_free',0,b'\x00\x03\x37\x23ggml_mpi_backend_init',0,b'\x00\x02\xD2\x23ggml_mpi_eval_init',0,b'\x00\x02\xCF\x23ggml_mpi_free',0,b'\x00\x02\xD8\x23ggml_mpi_graph_compute_post',0,b'\x00\x02\xD8\x23ggml_mpi_graph_compute_pre',0,b'\x00\x00\x93\x23ggml_mpi_init',0,b'\x00\x00\x5F\x23ggml_mpi_rank',0,b'\x00\x01\x52\x23ggml_mul',0,b'\x00\x01\x52\x23ggml_mul_inplace',0,b'\x00\x01\x52\x23ggml_mul_mat',0,b'\x00\x02\x0D\x23ggml_nbytes',0,b'\x00\x02\x10\x23ggml_nbytes_split',0,b'\x00\x00\xC8\x23ggml_neg',0,b'\x00\x00\xC8\x23ggml_neg_inplace',0,b'\x00\x00\x68\x23ggml_nelements',0,b'\x00\x00\xC0\x23ggml_new_f32',0,b'\x00\x00\x75\x23ggml_new_graph',0,b'\x00\x00\xC4\x23ggml_new_i32',0,b'\x00\x00\xA0\x23ggml_new_tensor',0,b'\x00\x00\xA6\x23ggml_new_tensor_1d',0,b'\x00\x00\xAB\x23ggml_new_tensor_2d',0,b'\x00\x00\xB1\x23ggml_new_tensor_3d',0,b'\x00\x00\xB8\x23ggml_new_tensor_4d',0,b'\x00\x00\xC8\x23ggml_norm',0,b'\x00\x00\xC8\x23ggml_norm_inplace',0,b'\x00\x00\x68\x23ggml_nrows',0,b'\x00\x03\x37\x23ggml_numa_init',0,b'\x00\x00\x28\x23ggml_op_name',0,b'\x00\x00\x28\x23ggml_op_symbol',0,b'\x00\x00\x3D\x23ggml_opt',0,b'\x00\x00\x95\x23ggml_opt_default_params',0,b'\x00\x02\xB3\x23ggml_opt_init',0,b'\x00\x00\x31\x23ggml_opt_resume',0,b'\x00\x00\x36\x23ggml_opt_resume_g',0,b'\x00\x01\x52\x23ggml_out_prod',0,b'\x00\x01\x02\x23ggml_permute',0,b'\x00\x00\xCC\x23ggml_pool_1d',0,b'\x00\x00\xD4\x23ggml_pool_2d',0,b'\x00\x02\xDD\x23ggml_print_object',0,b'\x00\x02\xBD\x23ggml_print_objects',0,b'\x00\x01\xF3\x23ggml_quantize_chunk',0,b'\x00\x01\xFB\x23ggml_quantize_q2_K',0,b'\x00\x01\xFB\x23ggml_quantize_q3_K',0,b'\x00\x01\xFB\x23ggml_quantize_q4_0',0,b'\x00\x01\xFB\x23ggml_quantize_q4_1',0,b'\x00\x01\xFB\x23ggml_quantize_q4_K',0,b'\x00\x01\xFB\x23ggml_quantize_q5_0',0,b'\x00\x01\xFB\x23ggml_quantize_q5_1',0,b'\x00\x01\xFB\x23ggml_quantize_q5_K',0,b'\x00\x01\xFB\x23ggml_quantize_q6_K',0,b'\x00\x01\xFB\x23ggml_quantize_q8_0',0,b'\x00\x00\xC8\x23ggml_relu',0,b'\x00\x00\xC8\x23ggml_relu_inplace',0,b'\x00\x01\x52\x23ggml_repeat',0,b'\x00\x01\x52\x23ggml_repeat_back',0,b'\x00\x01\x52\x23ggml_reshape',0,b'\x00\x01\x14\x23ggml_reshape_1d',0,b'\x00\x01\x19\x23ggml_reshape_2d',0,b'\x00\x01\x1F\x23ggml_reshape_3d',0,b'\x00\x01\x26\x23ggml_reshape_4d',0,b'\x00\x00\xE4\x23ggml_rms_norm',0,b'\x00\x01\x52\x23ggml_rms_norm_back',0,b'\x00\x00\xE4\x23ggml_rms_norm_inplace',0,b'\x00\x01\x02\x23ggml_rope',0,b'\x00\x01\x02\x23ggml_rope_back',0,b'\x00\x01\x0A\x23ggml_rope_custom',0,b'\x00\x01\x0A\x23ggml_rope_custom_inplace',0,b'\x00\x01\x02\x23ggml_rope_inplace',0,b'\x00\x01\x52\x23ggml_scale',0,b'\x00\x01\x52\x23ggml_scale_inplace',0,b'\x00\x01\xAB\x23ggml_set',0,b'\x00\x01\x9E\x23ggml_set_1d',0,b'\x00\x01\x9E\x23ggml_set_1d_inplace',0,b'\x00\x01\xA4\x23ggml_set_2d',0,b'\x00\x01\xA4\x23ggml_set_2d_inplace',0,b'\x00\x01\xE8\x23ggml_set_f32',0,b'\x00\x03\x0D\x23ggml_set_f32_1d',0,b'\x00\x01\xEC\x23ggml_set_i32',0,b'\x00\x03\x12\x23ggml_set_i32_1d',0,b'\x00\x01\xAB\x23ggml_set_inplace',0,b'\x00\x01\xE0\x23ggml_set_name',0,b'\x00\x02\xAA\x23ggml_set_no_alloc',0,b'\x00\x02\xB9\x23ggml_set_param',0,b'\x00\x02\x06\x23ggml_set_scratch',0,b'\x00\x01\xDD\x23ggml_set_zero',0,b'\x00\x00\xC8\x23ggml_sgn',0,b'\x00\x00\xC8\x23ggml_sgn_inplace',0,b'\x00\x00\xC8\x23ggml_silu',0,b'\x00\x01\x52\x23ggml_silu_back',0,b'\x00\x00\xC8\x23ggml_silu_inplace',0,b'\x00\x00\xC8\x23ggml_soft_max',0,b'\x00\x01\x52\x23ggml_soft_max_back',0,b'\x00\x01\x52\x23ggml_soft_max_back_inplace',0,b'\x00\x00\xC8\x23ggml_soft_max_inplace',0,b'\x00\x00\xC8\x23ggml_sqr',0,b'\x00\x00\xC8\x23ggml_sqr_inplace',0,b'\x00\x00\xC8\x23ggml_sqrt',0,b'\x00\x00\xC8\x23ggml_sqrt_inplace',0,b'\x00\x00\xC8\x23ggml_step',0,b'\x00\x00\xC8\x23ggml_step_inplace',0,b'\x00\x01\x52\x23ggml_sub',0,b'\x00\x01\x52\x23ggml_sub_inplace',0,b'\x00\x00\xC8\x23ggml_sum',0,b'\x00\x00\xC8\x23ggml_sum_rows',0,b'\x00\x00\xC8\x23ggml_tanh',0,b'\x00\x00\xC8\x23ggml_tanh_inplace',0,b'\x00\x02\x19\x23ggml_tensor_overhead',0,b'\x00\x03\x37\x23ggml_time_init',0,b'\x00\x00\x6B\x23ggml_time_ms',0,b'\x00\x00\x6B\x23ggml_time_us',0,b'\x00\x00\xC8\x23ggml_transpose',0,b'\x00\x00\x2B\x23ggml_type_name',0,b'\x00\x01\xF0\x23ggml_type_size',0,b'\x00\x00\x4B\x23ggml_type_sizef',0,b'\x00\x00\xDF\x23ggml_unary',0,b'\x00\x00\xDF\x23ggml_unary_inplace',0,b'\x00\x02\x0A\x23ggml_used_mem',0,b'\x00\x02\x87\x23ggml_vec_dot_q2_K_q8_K',0,b'\x00\x02\x87\x23ggml_vec_dot_q3_K_q8_K',0,b'\x00\x02\x87\x23ggml_vec_dot_q4_K_q8_K',0,b'\x00\x02\x87\x23ggml_vec_dot_q5_K_q8_K',0,b'\x00\x02\x87\x23ggml_vec_dot_q6_K_q8_K',0,b'\x00\x01\x4C\x23ggml_view_1d',0,b'\x00\x01\x44\x23ggml_view_2d',0,b'\x00\x01\x3A\x23ggml_view_3d',0,b'\x00\x01\x2E\x23ggml_view_4d',0,b'\x00\x01\xD9\x23ggml_view_tensor',0,b'\x00\x00\xEF\x23ggml_win_part',0,b'\x00\x00\xFB\x23ggml_win_unpart',0,b'\x00\x02\x74\x23quantize_row_q2_K',0,b'\x00\x02\x51\x23quantize_row_q2_K_reference',0,b'\x00\x02\x74\x23quantize_row_q3_K',0,b'\x00\x02\x56\x23quantize_row_q3_K_reference',0,b'\x00\x02\x74\x23quantize_row_q4_K',0,b'\x00\x02\x5B\x23quantize_row_q4_K_reference',0,b'\x00\x02\x74\x23quantize_row_q5_K',0,b'\x00\x02\x60\x23quantize_row_q5_K_reference',0,b'\x00\x02\x74\x23quantize_row_q6_K',0,b'\x00\x02\x65\x23quantize_row_q6_K_reference',0,b'\x00\x02\x74\x23quantize_row_q8_K',0,b'\x00\x02\x6A\x23quantize_row_q8_K_reference',0), + _struct_unions = ((b'\x00\x00\x03\x74\x00\x00\x00\x02$1',b'\x00\x00\x50\x11n_iter',b'\x00\x00\xC2\x11sched',b'\x00\x00\xC2\x11decay',b'\x00\x00\xC2\x11alpha',b'\x00\x00\xC2\x11beta1',b'\x00\x00\xC2\x11beta2',b'\x00\x00\xC2\x11eps',b'\x00\x00\xC2\x11eps_f',b'\x00\x00\xC2\x11eps_g'),(b'\x00\x00\x03\x75\x00\x00\x00\x02$2',b'\x00\x00\x50\x11m',b'\x00\x00\x50\x11n_iter',b'\x00\x00\x50\x11max_linesearch',b'\x00\x00\xC2\x11eps',b'\x00\x00\xC2\x11ftol',b'\x00\x00\xC2\x11wolfe',b'\x00\x00\xC2\x11min_step',b'\x00\x00\xC2\x11max_step',b'\x00\x03\x5F\x11linesearch'),(b'\x00\x00\x03\x76\x00\x00\x00\x02$3',b'\x00\x00\x08\x11x',b'\x00\x00\x08\x11g1',b'\x00\x00\x08\x11g2',b'\x00\x00\x08\x11m',b'\x00\x00\x08\x11v',b'\x00\x00\x08\x11mh',b'\x00\x00\x08\x11vh',b'\x00\x00\x08\x11pf',b'\x00\x00\xC2\x11fx_best',b'\x00\x00\xC2\x11fx_prev',b'\x00\x00\x50\x11n_no_improvement'),(b'\x00\x00\x03\x77\x00\x00\x00\x02$4',b'\x00\x00\x08\x11x',b'\x00\x00\x08\x11xp',b'\x00\x00\x08\x11g',b'\x00\x00\x08\x11gp',b'\x00\x00\x08\x11d',b'\x00\x00\x08\x11pf',b'\x00\x00\x08\x11lmal',b'\x00\x00\x08\x11lmys',b'\x00\x00\x08\x11lms',b'\x00\x00\x08\x11lmy',b'\x00\x00\xC2\x11fx_best',b'\x00\x00\xC2\x11step',b'\x00\x00\x50\x11j',b'\x00\x00\x50\x11k',b'\x00\x00\x50\x11end',b'\x00\x00\x50\x11n_no_improvement'),(b'\x00\x00\x03\x42\x00\x00\x00\x03$__mbstate_t',b'\x00\x03\x4A\x11__mbstate8',b'\x00\x00\xA9\x11_mbstateL'),(b'\x00\x00\x03\x43\x00\x00\x00\x02$block_q2_K',b'\x00\x03\x91\x11scales',b'\x00\x03\x95\x11qs',b'\x00\x00\x53\x11d',b'\x00\x00\x53\x11dmin'),(b'\x00\x00\x03\x44\x00\x00\x00\x02$block_q3_K',b'\x00\x03\x93\x11hmask',b'\x00\x03\x95\x11qs',b'\x00\x03\x8F\x11scales',b'\x00\x00\x53\x11d'),(b'\x00\x00\x03\x45\x00\x00\x00\x02$block_q4_K',b'\x00\x00\x53\x11d',b'\x00\x00\x53\x11dmin',b'\x00\x03\x8F\x11scales',b'\x00\x03\x8D\x11qs'),(b'\x00\x00\x03\x46\x00\x00\x00\x02$block_q5_K',b'\x00\x00\x53\x11d',b'\x00\x00\x53\x11dmin',b'\x00\x03\x8F\x11scales',b'\x00\x03\x93\x11qh',b'\x00\x03\x8D\x11qs'),(b'\x00\x00\x03\x47\x00\x00\x00\x02$block_q6_K',b'\x00\x03\x8D\x11ql',b'\x00\x03\x95\x11qh',b'\x00\x03\x70\x11scales',b'\x00\x00\x53\x11d'),(b'\x00\x00\x03\x48\x00\x00\x00\x02$block_q8_K',b'\x00\x00\xC2\x11d',b'\x00\x03\x72\x11qs',b'\x00\x03\x6D\x11bsums'),(b'\x00\x00\x03\x63\x00\x00\x00\x02$ggml_type_traits_t',b'\x00\x03\xA0\x11to_float',b'\x00\x03\x9D\x11from_float',b'\x00\x03\x9D\x11from_float_reference',b'\x00\x03\x9E\x11vec_dot',b'\x00\x00\x01\x11vec_dot_type'),(b'\x00\x00\x03\x79\x00\x00\x00\x02__darwin_pthread_handler_rec',b'\x00\x03\x9F\x11__routine',b'\x00\x00\x13\x11__arg',b'\x00\x03\x78\x11__next'),(b'\x00\x00\x03\x3A\x00\x00\x00\x02_opaque_pthread_attr_t',b'\x00\x03\x6B\x11__sig',b'\x00\x03\x58\x11__opaque'),(b'\x00\x00\x03\x3B\x00\x00\x00\x02_opaque_pthread_cond_t',b'\x00\x03\x6B\x11__sig',b'\x00\x03\x52\x11__opaque'),(b'\x00\x00\x03\x3C\x00\x00\x00\x02_opaque_pthread_condattr_t',b'\x00\x03\x6B\x11__sig',b'\x00\x03\x5C\x11__opaque'),(b'\x00\x00\x03\x3D\x00\x00\x00\x02_opaque_pthread_mutex_t',b'\x00\x03\x6B\x11__sig',b'\x00\x03\x58\x11__opaque'),(b'\x00\x00\x03\x3E\x00\x00\x00\x02_opaque_pthread_mutexattr_t',b'\x00\x03\x6B\x11__sig',b'\x00\x03\x5C\x11__opaque'),(b'\x00\x00\x03\x3F\x00\x00\x00\x02_opaque_pthread_once_t',b'\x00\x03\x6B\x11__sig',b'\x00\x03\x5C\x11__opaque'),(b'\x00\x00\x03\x40\x00\x00\x00\x02_opaque_pthread_rwlock_t',b'\x00\x03\x6B\x11__sig',b'\x00\x03\x4E\x11__opaque'),(b'\x00\x00\x03\x41\x00\x00\x00\x02_opaque_pthread_rwlockattr_t',b'\x00\x03\x6B\x11__sig',b'\x00\x03\x4C\x11__opaque'),(b'\x00\x00\x03\x7B\x00\x00\x00\x02_opaque_pthread_t',b'\x00\x03\x6B\x11__sig',b'\x00\x03\x78\x11__cleanup_stack',b'\x00\x03\x5A\x11__opaque'),(b'\x00\x00\x03\x7C\x00\x00\x00\x10ggml_allocr',),(b'\x00\x00\x03\x7D\x00\x00\x00\x02ggml_cgraph',b'\x00\x00\x50\x11n_nodes',b'\x00\x00\x50\x11n_leafs',b'\x00\x03\x86\x11nodes',b'\x00\x03\x86\x11grads',b'\x00\x03\x86\x11leafs',b'\x00\x03\x9B\x11visited_hash_table',b'\x00\x00\x50\x11perf_runs',b'\x00\x00\xA9\x11perf_cycles',b'\x00\x00\xA9\x11perf_time_us'),(b'\x00\x00\x03\x7E\x00\x00\x00\x02ggml_compute_params',b'\x00\x03\x62\x11type',b'\x00\x00\x50\x11ith',b'\x00\x00\x50\x11nth',b'\x00\x00\x14\x11wsize',b'\x00\x00\x13\x11wdata'),(b'\x00\x00\x03\x7F\x00\x00\x00\x10ggml_context',),(b'\x00\x00\x03\x80\x00\x00\x00\x02ggml_cplan',b'\x00\x00\x14\x11work_size',b'\x00\x03\x8B\x11work_data',b'\x00\x00\x50\x11n_threads',b'\x00\x03\x64\x11n_tasks',b'\x00\x03\x39\x11abort_callback',b'\x00\x00\x13\x11abort_callback_data'),(b'\x00\x00\x00\x8A\x00\x00\x00\x02ggml_init_params',b'\x00\x00\x14\x11mem_size',b'\x00\x00\x13\x11mem_buffer',b'\x00\x00\x84\x11no_alloc'),(b'\x00\x00\x03\x81\x00\x00\x00\x10ggml_metal_context',),(b'\x00\x00\x03\x82\x00\x00\x00\x10ggml_mpi_context',),(b'\x00\x00\x03\x84\x00\x00\x00\x02ggml_object',b'\x00\x00\x14\x11offs',b'\x00\x00\x14\x11size',b'\x00\x03\x83\x11next',b'\x00\x03\x60\x11type',b'\x00\x03\x56\x11padding'),(b'\x00\x00\x03\x85\x00\x00\x00\x02ggml_opt_context',b'\x00\x00\x0B\x11ctx',b'\x00\x00\x3F\x11params',b'\x00\x00\x50\x11iter',b'\x00\x00\xA9\x11nx',b'\x00\x00\x84\x11just_initialized',b'\x00\x03\x76\x11adam',b'\x00\x03\x77\x11lbfgs'),(b'\x00\x00\x00\x3F\x00\x00\x00\x02ggml_opt_params',b'\x00\x00\x96\x11type',b'\x00\x00\x50\x11n_threads',b'\x00\x00\x50\x11past',b'\x00\x00\xC2\x11delta',b'\x00\x00\x50\x11max_no_improvement',b'\x00\x00\x84\x11print_forward_graph',b'\x00\x00\x84\x11print_backward_graph',b'\x00\x03\x74\x11adam',b'\x00\x03\x75\x11lbfgs'),(b'\x00\x00\x02\x08\x00\x00\x00\x02ggml_scratch',b'\x00\x00\x14\x11offs',b'\x00\x00\x14\x11size',b'\x00\x00\x13\x11data'),(b'\x00\x00\x03\x8A\x00\x00\x00\x02ggml_tensor',b'\x00\x00\x01\x11type',b'\x00\x03\x5E\x11backend',b'\x00\x00\x50\x11n_dims',b'\x00\x03\x69\x11ne',b'\x00\x03\x99\x11nb',b'\x00\x00\x29\x11op',b'\x00\x03\x66\x11op_params',b'\x00\x00\x84\x11is_param',b'\x00\x00\x08\x11grad',b'\x00\x03\x88\x11src',b'\x00\x00\x50\x11perf_runs',b'\x00\x00\xA9\x11perf_cycles',b'\x00\x00\xA9\x11perf_time_us',b'\x00\x00\x13\x11data',b'\x00\x03\x54\x11name',b'\x00\x00\x13\x11extra',b'\x00\x03\x56\x11padding')), + _enums = (b'\x00\x00\x03\x5E\x00\x00\x00\x16ggml_backend\x00GGML_BACKEND_CPU,GGML_BACKEND_GPU,GGML_BACKEND_GPU_SPLIT',b'\x00\x00\x00\x43\x00\x00\x00\x15ggml_ftype\x00GGML_FTYPE_UNKNOWN,GGML_FTYPE_ALL_F32,GGML_FTYPE_MOSTLY_F16,GGML_FTYPE_MOSTLY_Q4_0,GGML_FTYPE_MOSTLY_Q4_1,GGML_FTYPE_MOSTLY_Q4_1_SOME_F16,GGML_FTYPE_MOSTLY_Q8_0,GGML_FTYPE_MOSTLY_Q5_0,GGML_FTYPE_MOSTLY_Q5_1,GGML_FTYPE_MOSTLY_Q2_K,GGML_FTYPE_MOSTLY_Q3_K,GGML_FTYPE_MOSTLY_Q4_K,GGML_FTYPE_MOSTLY_Q5_K,GGML_FTYPE_MOSTLY_Q6_K',b'\x00\x00\x03\x5F\x00\x00\x00\x16ggml_linesearch\x00GGML_LINESEARCH_DEFAULT,GGML_LINESEARCH_BACKTRACKING_ARMIJO,GGML_LINESEARCH_BACKTRACKING_WOLFE,GGML_LINESEARCH_BACKTRACKING_STRONG_WOLFE',b'\x00\x00\x03\x60\x00\x00\x00\x16ggml_object_type\x00GGML_OBJECT_TENSOR,GGML_OBJECT_GRAPH,GGML_OBJECT_WORK_BUFFER',b'\x00\x00\x00\x29\x00\x00\x00\x16ggml_op\x00GGML_OP_NONE,GGML_OP_DUP,GGML_OP_ADD,GGML_OP_ADD1,GGML_OP_ACC,GGML_OP_SUB,GGML_OP_MUL,GGML_OP_DIV,GGML_OP_SQR,GGML_OP_SQRT,GGML_OP_LOG,GGML_OP_SUM,GGML_OP_SUM_ROWS,GGML_OP_MEAN,GGML_OP_ARGMAX,GGML_OP_REPEAT,GGML_OP_REPEAT_BACK,GGML_OP_SILU_BACK,GGML_OP_NORM,GGML_OP_RMS_NORM,GGML_OP_RMS_NORM_BACK,GGML_OP_MUL_MAT,GGML_OP_OUT_PROD,GGML_OP_SCALE,GGML_OP_SET,GGML_OP_CPY,GGML_OP_CONT,GGML_OP_RESHAPE,GGML_OP_VIEW,GGML_OP_PERMUTE,GGML_OP_TRANSPOSE,GGML_OP_GET_ROWS,GGML_OP_GET_ROWS_BACK,GGML_OP_DIAG,GGML_OP_DIAG_MASK_INF,GGML_OP_DIAG_MASK_ZERO,GGML_OP_SOFT_MAX,GGML_OP_SOFT_MAX_BACK,GGML_OP_ROPE,GGML_OP_ROPE_BACK,GGML_OP_ALIBI,GGML_OP_CLAMP,GGML_OP_CONV_1D,GGML_OP_CONV_2D,GGML_OP_POOL_1D,GGML_OP_POOL_2D,GGML_OP_FLASH_ATTN,GGML_OP_FLASH_FF,GGML_OP_FLASH_ATTN_BACK,GGML_OP_WIN_PART,GGML_OP_WIN_UNPART,GGML_OP_UNARY,GGML_OP_MAP_UNARY,GGML_OP_MAP_BINARY,GGML_OP_MAP_CUSTOM1_F32,GGML_OP_MAP_CUSTOM2_F32,GGML_OP_MAP_CUSTOM3_F32,GGML_OP_MAP_CUSTOM1,GGML_OP_MAP_CUSTOM2,GGML_OP_MAP_CUSTOM3,GGML_OP_CROSS_ENTROPY_LOSS,GGML_OP_CROSS_ENTROPY_LOSS_BACK,GGML_OP_COUNT',b'\x00\x00\x00\xCF\x00\x00\x00\x16ggml_op_pool\x00GGML_OP_POOL_MAX,GGML_OP_POOL_AVG,GGML_OP_POOL_COUNT',b'\x00\x00\x03\x61\x00\x00\x00\x15ggml_opt_result\x00GGML_OPT_OK,GGML_OPT_DID_NOT_CONVERGE,GGML_OPT_NO_CONTEXT,GGML_OPT_INVALID_WOLFE,GGML_OPT_FAIL,GGML_LINESEARCH_FAIL,GGML_LINESEARCH_MINIMUM_STEP,GGML_LINESEARCH_MAXIMUM_STEP,GGML_LINESEARCH_MAXIMUM_ITERATIONS,GGML_LINESEARCH_INVALID_PARAMETERS',b'\x00\x00\x00\x96\x00\x00\x00\x16ggml_opt_type\x00GGML_OPT_ADAM,GGML_OPT_LBFGS',b'\x00\x00\x03\x62\x00\x00\x00\x16ggml_task_type\x00GGML_TASK_INIT,GGML_TASK_COMPUTE,GGML_TASK_FINALIZE',b'\x00\x00\x00\x01\x00\x00\x00\x16ggml_type\x00GGML_TYPE_F32,GGML_TYPE_F16,GGML_TYPE_Q4_0,GGML_TYPE_Q4_1,GGML_TYPE_Q5_0,GGML_TYPE_Q5_1,GGML_TYPE_Q8_0,GGML_TYPE_Q8_1,GGML_TYPE_Q2_K,GGML_TYPE_Q3_K,GGML_TYPE_Q4_K,GGML_TYPE_Q5_K,GGML_TYPE_Q6_K,GGML_TYPE_Q8_K,GGML_TYPE_I8,GGML_TYPE_I16,GGML_TYPE_I32,GGML_TYPE_COUNT',b'\x00\x00\x00\xE2\x00\x00\x00\x16ggml_unary_op\x00GGML_UNARY_OP_ABS,GGML_UNARY_OP_SGN,GGML_UNARY_OP_NEG,GGML_UNARY_OP_STEP,GGML_UNARY_OP_TANH,GGML_UNARY_OP_ELU,GGML_UNARY_OP_RELU,GGML_UNARY_OP_GELU,GGML_UNARY_OP_GELU_QUICK,GGML_UNARY_OP_SILU'), + _typenames = (b'\x00\x00\x00\xA9__darwin_blkcnt_t',b'\x00\x00\x00\x50__darwin_blksize_t',b'\x00\x00\x00\x14__darwin_clock_t',b'\x00\x00\x00\x50__darwin_ct_rune_t',b'\x00\x00\x00\x50__darwin_dev_t',b'\x00\x00\x03\x97__darwin_fsblkcnt_t',b'\x00\x00\x03\x97__darwin_fsfilcnt_t',b'\x00\x00\x03\x97__darwin_gid_t',b'\x00\x00\x03\x97__darwin_id_t',b'\x00\x00\x03\x98__darwin_ino64_t',b'\x00\x00\x03\x98__darwin_ino_t',b'\x00\x00\x03\x6B__darwin_intptr_t',b'\x00\x00\x03\x97__darwin_mach_port_name_t',b'\x00\x00\x03\x97__darwin_mach_port_t',b'\x00\x00\x03\x42__darwin_mbstate_t',b'\x00\x00\x00\x53__darwin_mode_t',b'\x00\x00\x03\x97__darwin_natural_t',b'\x00\x00\x00\xA9__darwin_off_t',b'\x00\x00\x00\x50__darwin_pid_t',b'\x00\x00\x03\x3A__darwin_pthread_attr_t',b'\x00\x00\x03\x3B__darwin_pthread_cond_t',b'\x00\x00\x03\x3C__darwin_pthread_condattr_t',b'\x00\x00\x00\x14__darwin_pthread_key_t',b'\x00\x00\x03\x3D__darwin_pthread_mutex_t',b'\x00\x00\x03\x3E__darwin_pthread_mutexattr_t',b'\x00\x00\x03\x3F__darwin_pthread_once_t',b'\x00\x00\x03\x40__darwin_pthread_rwlock_t',b'\x00\x00\x03\x41__darwin_pthread_rwlockattr_t',b'\x00\x00\x03\x7A__darwin_pthread_t',b'\x00\x00\x03\x6B__darwin_ptrdiff_t',b'\x00\x00\x00\x50__darwin_rune_t',b'\x00\x00\x03\x97__darwin_sigset_t',b'\x00\x00\x00\x14__darwin_size_t',b'\x00\x00\x03\x97__darwin_socklen_t',b'\x00\x00\x03\x6B__darwin_ssize_t',b'\x00\x00\x00\x50__darwin_suseconds_t',b'\x00\x00\x03\x6B__darwin_time_t',b'\x00\x00\x03\x97__darwin_uid_t',b'\x00\x00\x03\x97__darwin_useconds_t',b'\x00\x00\x03\x50__darwin_uuid_string_t',b'\x00\x00\x03\x91__darwin_uuid_t',b'\x00\x00\x00\x50__darwin_wchar_t',b'\x00\x00\x00\x50__darwin_wint_t',b'\x00\x00\x03\x6C__int16_t',b'\x00\x00\x00\x50__int32_t',b'\x00\x00\x00\xA9__int64_t',b'\x00\x00\x03\x6F__int8_t',b'\x00\x00\x03\x42__mbstate_t',b'\x00\x00\x00\x53__uint16_t',b'\x00\x00\x03\x97__uint32_t',b'\x00\x00\x03\x98__uint64_t',b'\x00\x00\x03\x8C__uint8_t',b'\x00\x00\x03\x43block_q2_K',b'\x00\x00\x03\x44block_q3_K',b'\x00\x00\x03\x45block_q4_K',b'\x00\x00\x03\x46block_q5_K',b'\x00\x00\x03\x47block_q6_K',b'\x00\x00\x03\x48block_q8_K',b'\x00\x00\x01\xB8ggml_binary_op_f32_t',b'\x00\x00\x01\xD0ggml_custom1_op_f32_t',b'\x00\x00\x01\xD5ggml_custom1_op_t',b'\x00\x00\x01\xBEggml_custom2_op_f32_t',b'\x00\x00\x01\xC4ggml_custom2_op_t',b'\x00\x00\x01\x93ggml_custom3_op_f32_t',b'\x00\x00\x01\x9Aggml_custom3_op_t',b'\x00\x00\x00\x53ggml_fp16_t',b'\x00\x00\x03\x9Dggml_from_float_t',b'\x00\x00\x03\xA0ggml_to_float_t',b'\x00\x00\x03\x63ggml_type_traits_t',b'\x00\x00\x01\xCBggml_unary_op_f32_t',b'\x00\x00\x03\x9Eggml_vec_dot_t',b'\x00\x00\x03\x6Cint16_t',b'\x00\x00\x00\x50int32_t',b'\x00\x00\x00\xA9int64_t',b'\x00\x00\x03\x6Fint8_t',b'\x00\x00\x03\x6Cint_fast16_t',b'\x00\x00\x00\x50int_fast32_t',b'\x00\x00\x00\xA9int_fast64_t',b'\x00\x00\x03\x6Fint_fast8_t',b'\x00\x00\x03\x6Cint_least16_t',b'\x00\x00\x00\x50int_least32_t',b'\x00\x00\x00\xA9int_least64_t',b'\x00\x00\x03\x6Fint_least8_t',b'\x00\x00\x03\x6Bintmax_t',b'\x00\x00\x03\x6Bintptr_t',b'\x00\x00\x03\x68max_align_t',b'\x00\x00\x03\x6Bptrdiff_t',b'\x00\x00\x00\xA9register_t',b'\x00\x00\x00\x14rsize_t',b'\x00\x00\x00\x14size_t',b'\x00\x00\x03\x98syscall_arg_t',b'\x00\x00\x00\x53u_int16_t',b'\x00\x00\x03\x97u_int32_t',b'\x00\x00\x03\x98u_int64_t',b'\x00\x00\x03\x8Cu_int8_t',b'\x00\x00\x00\x53uint16_t',b'\x00\x00\x03\x97uint32_t',b'\x00\x00\x03\x98uint64_t',b'\x00\x00\x03\x8Cuint8_t',b'\x00\x00\x00\x53uint_fast16_t',b'\x00\x00\x03\x97uint_fast32_t',b'\x00\x00\x03\x98uint_fast64_t',b'\x00\x00\x03\x8Cuint_fast8_t',b'\x00\x00\x00\x53uint_least16_t',b'\x00\x00\x03\x97uint_least32_t',b'\x00\x00\x03\x98uint_least64_t',b'\x00\x00\x03\x8Cuint_least8_t',b'\x00\x00\x00\x14uintmax_t',b'\x00\x00\x00\x14uintptr_t',b'\x00\x00\x03\x98user_addr_t',b'\x00\x00\x00\xA9user_long_t',b'\x00\x00\x00\xA9user_off_t',b'\x00\x00\x03\x98user_size_t',b'\x00\x00\x00\xA9user_ssize_t',b'\x00\x00\x00\xA9user_time_t',b'\x00\x00\x03\x98user_ulong_t',b'\x00\x00\x00\x50wchar_t'), +) diff --git a/examples/python/ggml/utils.py b/examples/python/ggml/utils.py new file mode 100644 index 00000000..2e95798a --- /dev/null +++ b/examples/python/ggml/utils.py @@ -0,0 +1,181 @@ +""" + Common helpers for working with ggml + numpy +""" +from ggml import ffi, lib +from typing import Union, Optional +import numpy as np + +def init(mem_size: int, mem_buffer: ffi.CData = ffi.NULL, no_alloc: bool = False) -> ffi.CData: + """ + Initialize a ggml context, which will be freed automatically when the pointer is garbage collected. + """ + params = ffi.new('struct ggml_init_params*') + params.mem_size = mem_size + params.mem_buffer = mem_buffer + params.no_alloc = no_alloc + return ffi.gc(lib.ggml_init(params[0]), lib.ggml_free) + +TensorLike = Union[ffi.CData, np.ndarray] + +def copy(from_tensor: TensorLike, to_tensor: TensorLike, allow_requantize: bool = True): + """ + Copy the contents of one tensor to another, doing any necessary (de/re)quantization transparently. + Works across numpy & ggml tensors, but they must have the same shape (and be contiguous). + + Parameters + ---------- + from_tensor : TensorLike + The tensor to copy from (a numpy array or possibly-quantized ggml tensor) + to_tensor : TensorLike + The tensor to copy to (a numpy array or possibly-quantized ggml tensor) + allow_requantize : bool + If False, will throw an error if requantization is required (i.e. both from_tensor + and to_tensor are quantized with different quantization types) + """ + if id(from_tensor) == id(to_tensor): + return + + __expect_same_layout("source", from_tensor, "destination", to_tensor) + __check_shape_consistent_with_type(from_tensor) + __check_shape_consistent_with_type(to_tensor) + + from_type = __get_type(from_tensor) + to_type = __get_type(to_tensor) + + if from_type == to_type: + ffi.memmove(__get_data(to_tensor), __get_data(from_tensor), __get_nbytes(from_tensor)) + else: + assert allow_requantize or not lib.ggml_is_quantized(from_type) or not lib.ggml_is_quantized(to_type), \ + f"Requantizing from {__type_name(from_type)} to {__type_name(to_type)} is disabled. Force with allow_requantize=True" + + __set_floats(to_tensor, __get_floats(from_tensor)) + +def numpy(tensor: ffi.CData, allow_copy: Union[bool, np.ndarray] = False, allow_requantize=False) -> np.ndarray: + """ + Convert a ggml tensor to a numpy array. + If the tensor isn't quantized, the returned numpy array will be a view over its data. + + If it is quantized (and allow_copy is True), the copy will involve dequantization and the returned array will + be a copy of the original tensor (any changes to the numpy array won't then be reflected back to the tensor). + + Parameters + ---------- + tensor : ffi.CData + The tensor to convert to a numpy array + allow_copy : bool or np.ndarray + If False, will throw an error if the tensor is quantized (since dequantization requires extra memory). + If True, will dequantize the tensor and return a copy of the data in a new float32 numpy array. + If an np.ndarray, will copy the data into the given array (which must be the same shape as the tensor) when dequantization is needed + allow_requantize : bool + If allow_copy is a tensor with a different quantization type than the source tensor, will throw an error unless allow_requantize is True. + """ + shape = __get_shape(tensor) + + if lib.ggml_is_quantized(tensor.type): + if allow_copy == False: + raise ValueError(f"{__describe(tensor)} is quantized, conversion to numpy requires a copy (pass allow_copy=True; changes to the numpy array won't affect the original).") + elif isinstance(allow_copy, np.ndarray): + __expect_same_layout("source tensor", tensor, "dequantization output tensor", allow_copy) + destination = allow_copy + else: + destination = np.empty(shape, dtype=np.float32) + + copy(tensor, destination, allow_requantize=allow_requantize) + return destination + else: + dtype = __type_to_dtype(tensor.type) + if not dtype: + raise NotImplementedError(f'Cannot convert {__describe(tensor)} to numpy') + + assert __is_contiguous(tensor), f"Cannot convert {__describe(tensor)} to numpy (support contiguous tensors only)" + array = np.frombuffer(ffi.buffer(lib.ggml_get_data(tensor), lib.ggml_nbytes(tensor)), dtype=dtype) + array.shape = shape + return array + +def __type_name(type: int) -> str: + name = lib.ggml_type_name(type) + return ffi.string(name).decode('utf-8') if name else None + +__k_quant_types = set([ + lib.GGML_TYPE_Q2_K, + lib.GGML_TYPE_Q3_K, + lib.GGML_TYPE_Q4_K, + lib.GGML_TYPE_Q5_K, + lib.GGML_TYPE_Q6_K, + lib.GGML_TYPE_Q8_K, +]) + +__type_to_dtype_dict = { + lib.GGML_TYPE_I8: np.int8, + lib.GGML_TYPE_I16: np.int16, + lib.GGML_TYPE_I32: np.int32, + lib.GGML_TYPE_F16: np.float16, + lib.GGML_TYPE_F32: np.float32, +} + +def __type_to_dtype(type: int) -> Optional[np.dtype]: return __type_to_dtype_dict.get(type) +def __dtype_to_type(dtype: np.dtype): + if dtype == np.float32: return lib.GGML_TYPE_F32 + elif dtype == np.float16: return lib.GGML_TYPE_F16 + elif dtype == np.int32: return lib.GGML_TYPE_I32 + elif dtype == np.int16: return lib.GGML_TYPE_I16 + elif dtype == np.int8: return lib.GGML_TYPE_I8 + else: raise ValueError(f"Unsupported dtype: {dtype}") + +def __describe(tensor: ffi.CType): return f'Tensor[{__type_name(tensor.type)}, {__get_shape(tensor)}]' +def __get_type(tensor: TensorLike): return __dtype_to_type(tensor.dtype) if isinstance(tensor, np.ndarray) else tensor.type +def __get_shape(x: TensorLike): return x.shape if isinstance(x, np.ndarray) else tuple([x.ne[i] for i in range(x.n_dims)]) +def __get_strides(x: TensorLike): return x.strides if isinstance(x, np.ndarray) else tuple([x.nb[i] for i in range(x.n_dims)]) +def __get_data(x: TensorLike) -> ffi.CData: return ffi.from_buffer(x) if isinstance(x, np.ndarray) else lib.ggml_get_data(x) +def __get_nbytes(tensor: TensorLike): return tensor.nbytes if isinstance(tensor, np.ndarray) else lib.ggml_nbytes(tensor) +def __get_nelements(tensor: TensorLike): return tensor.size if isinstance(tensor, np.ndarray) else lib.ggml_nelements(tensor) +def __is_contiguous(tensor: TensorLike): return tensor.flags['C_CONTIGUOUS'] if isinstance(tensor, np.ndarray) else lib.ggml_is_contiguous(tensor) + +def __get_floats(tensor: TensorLike) -> ffi.CData: + data, type = __get_data(tensor), __get_type(tensor) + if type == lib.GGML_TYPE_F32: + return ffi.cast('float*', data) + else: + nelements = __get_nelements(tensor) + floats = ffi.new('float[]', nelements) + if type == lib.GGML_TYPE_F16: + lib.ggml_fp16_to_fp32_row(data, floats, nelements) + elif lib.ggml_is_quantized(type): + qtype = lib.ggml_internal_get_type_traits(type) + assert qtype.to_float, f"Type {__type_name(type)} is not supported by ggml" + qtype.to_float(data, floats, nelements) + else: + raise NotImplementedError(f'Cannot read floats from {__describe(tensor)}') + return floats + +def __set_floats(tensor: TensorLike, f32_data: ffi.CData) -> None: + data, type, nbytes = __get_data(tensor), __get_type(tensor), __get_nbytes(tensor) + if type == lib.GGML_TYPE_F32: + ffi.memmove(data, f32_data, nbytes) + else: + nelements = __get_nelements(tensor) + if type == lib.GGML_TYPE_F16: + lib.ggml_fp32_to_fp16_row(f32_data, data, nelements) + elif lib.ggml_is_quantized(type): + qtype = lib.ggml_internal_get_type_traits(type) + assert qtype.from_float, f"Type {__type_name(type)} is not supported by ggml" + qtype.from_float(f32_data, data, nelements) + else: + raise NotImplementedError(f'Cannot write floats to {__describe(tensor)}') + +def __expect_same_layout(name1: str, tensor1: TensorLike, name2: str, tensor2: TensorLike): + shape1, shape2 = __get_shape(tensor1), __get_shape(tensor2) + assert shape1 == shape2, f"Shape mismatch: {name1} has {shape1} but {name2} has {shape2}" + assert __is_contiguous(tensor1) and __is_contiguous(tensor2), f"Only contiguous tensors are supported (got {name1} with strides {__get_strides(tensor1)} and {name2} with strides {__get_strides(tensor2)})" + +def __check_shape_consistent_with_type(tensor: TensorLike): + type = __get_type(tensor) + if not lib.ggml_is_quantized(type): + return + shape = __get_shape(tensor) + + block_size = lib.ggml_blck_size(type) + assert not (block_size == 0 and type in __k_quant_types), f"Can't quantize, native library was not compiled with USE_K_QUANTS!" + assert block_size > 0, f"Invalid block size {block_size} for type {__type_name(type)}" + for i, d in enumerate(shape): + assert d % block_size == 0, f"Dimension {i} of {__describe(tensor)} is not divisible by {block_size}, required for quantization." diff --git a/examples/python/regenerate.py b/examples/python/regenerate.py new file mode 100644 index 00000000..cf61942c --- /dev/null +++ b/examples/python/regenerate.py @@ -0,0 +1,38 @@ +# Generates bindings for the ggml library. +# +# cffi requires prior C preprocessing of the headers, and it uses pycparser which chokes on a couple of things +# so we help it a bit (e.g. replace sizeof expressions with their value, remove exotic syntax found in Darwin headers). +import os, sys, re, subprocess +import cffi + +API = os.environ.get('API', 'api.h') +CC = os.environ.get('CC') or 'gcc' +C_INCLUDE_DIR = os.environ.get('C_INCLUDE_DIR', '../../../llama.cpp') +CPPFLAGS = [ + "-I", C_INCLUDE_DIR, + '-D__fp16=uint16_t', # pycparser doesn't support __fp16 + '-D__attribute__(x)=', + '-D_Static_assert(x, m)=', +] + [x for x in os.environ.get('CPPFLAGS', '').split(' ') if x != ''] + +try: header = subprocess.run([CC, "-E", *CPPFLAGS, API], capture_output=True, text=True, check=True).stdout +except subprocess.CalledProcessError as e: print(f'{e.stderr}\n{e}', file=sys.stderr); raise + +header = '\n'.join([l for l in header.split('\n') if '__darwin_va_list' not in l]) # pycparser hates this + +# Replace constant size expressions w/ their value (compile & run a mini exe for each, because why not). +# First, extract anyting *inside* square brackets and anything that looks like a sizeof call. +for expr in set(re.findall(f'(?<=\\[)[^\\]]+(?=])|sizeof\\s*\\([^()]+\\)', header)): + if re.match(r'^(\d+|\s*)$', expr): continue # skip constants and empty bracket contents + subprocess.run([CC, "-o", "eval_size_expr", *CPPFLAGS, "-x", "c", "-"], text=True, check=True, + input=f'''#include + #include "{API}" + int main() {{ printf("%lu", (size_t)({expr})); }}''') + size = subprocess.run(["./eval_size_expr"], capture_output=True, text=True, check=True).stdout + print(f'Computed constexpr {expr} = {size}') + header = header.replace(expr, size) + +ffibuilder = cffi.FFI() +ffibuilder.cdef(header) +ffibuilder.set_source(f'ggml.cffi', None) # we're not compiling a native extension, as this quickly gets hairy +ffibuilder.compile(verbose=True)