]> git.djapps.eu Git - pkg/ggml/sources/ggml/commitdiff
Add python example w/ cffi-generated bindings
authorochafik <redacted>
Sun, 13 Aug 2023 16:37:03 +0000 (17:37 +0100)
committerochafik <redacted>
Sun, 13 Aug 2023 19:05:13 +0000 (20:05 +0100)
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)

.gitignore
examples/python/README.md [new file with mode: 0644]
examples/python/api.h [new file with mode: 0644]
examples/python/example_add_quant.py [new file with mode: 0644]
examples/python/example_test_all_quants.py [new file with mode: 0644]
examples/python/ggml/__init__.py [new file with mode: 0644]
examples/python/ggml/cffi.py [new file with mode: 0644]
examples/python/ggml/utils.py [new file with mode: 0644]
examples/python/regenerate.py [new file with mode: 0644]

index 467c19dafba4048a13c6180ac003876a772989dd..d7e11716a810fd39ffe8131448e347d381f65cc0 100644 (file)
@@ -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 (file)
index 0000000..66b91bd
--- /dev/null
@@ -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 (file)
index 0000000..8d565bd
--- /dev/null
@@ -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 (file)
index 0000000..cecb44e
--- /dev/null
@@ -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 (file)
index 0000000..8d3c966
--- /dev/null
@@ -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 (file)
index 0000000..31a1910
--- /dev/null
@@ -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 (file)
index 0000000..9762555
--- /dev/null
@@ -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 (file)
index 0000000..2e95798
--- /dev/null
@@ -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 (file)
index 0000000..cf61942
--- /dev/null
@@ -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 <stdio.h>
+                             #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)