Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions base-convert/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion base-convert/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ members = [
]

[workspace.package]
version = "0.4.7"
version = "0.5.0"
edition = "2021"
license = "Apache-2.0"
repository = "https://github.com/basecompute/baseRT"
Expand Down
47 changes: 47 additions & 0 deletions base-convert/crates/base-convert/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8333,3 +8333,50 @@ mod tied_head_tests {
);
}
}

#[cfg(test)]
mod row_group_tests {
use super::{pack_for_target_rows, TargetScheme};
use base_format::TensorDtype;

// The runtime's base_qN kernels read K / gs scales per row, so a group may
// never run across a row end. gemma-4-26B-A4B-it's catalog Q8 was packed
// before this choice existed: ffn_down_exps (K = 704) and mlp.down_proj
// (K = 2112) at gs 128, with every row decoding against the wrong scales.
fn pack(k: usize, rows: usize, target: TargetScheme) -> (base_quant::Packed, TensorDtype) {
let w: Vec<f32> = (0..rows * k)
.map(|i| ((i % 97) as f32 - 48.0) / 64.0)
.collect();
pack_for_target_rows(&w, target, Some(k), "layers.0.test.weight").unwrap()
}

#[test]
fn q8_rows_that_split_gs128_pack_at_a_dividing_group() {
for (k, gs) in [(704, 64), (2112, 64), (2816, 128), (1856, 64), (1888, 32)] {
let (p, dt) = pack(k, 3, TargetScheme::BaseQ8);
assert_eq!(dt, TensorDtype::BaseQ8, "K = {k}");
assert_eq!(p.group_size as usize, gs, "K = {k}");
// One f16 scale and one f16 bias per group, groups per row = K / gs.
assert_eq!(p.scales.len(), 3 * (k / gs) * 2, "K = {k}");
assert_eq!(p.biases.len(), 3 * (k / gs) * 2, "K = {k}");
}
}

#[test]
fn rows_no_group_divides_stay_unquantized() {
// gemma-4's vision ffn.down: 4304 = 16 x 269, below the smallest group.
let (p, dt) = pack(4304, 2, TargetScheme::BaseQ8);
assert_eq!(dt, TensorDtype::Bf16);
assert_eq!(p.group_size, 0);
assert!(p.scales.is_empty() && p.biases.is_empty());
assert_eq!(p.packed_weights.len(), 2 * 4304 * 2);
}

#[test]
fn q4_keeps_its_default_group_where_it_divides() {
let (p, dt) = pack(704, 2, TargetScheme::BaseQ4);
assert_eq!((dt, p.group_size), (TensorDtype::BaseQ4, 64));
let (p, _) = pack(1888, 2, TargetScheme::BaseQ4);
assert_eq!(p.group_size, 32);
}
}
52 changes: 51 additions & 1 deletion base-convert/crates/base-convert/src/selfupdate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,9 +625,17 @@ pub fn bundle_dir() -> Result<PathBuf> {
/// The engine bundle name's platform for this machine:
/// `basert-engine-<platform>-<v>.tar.gz`.
pub fn platform() -> Result<&'static str> {
match (std::env::consts::OS, std::env::consts::ARCH) {
platform_for(std::env::consts::OS, std::env::consts::ARCH)
}

/// One engine per OS and CPU: Metal on Apple silicon, CUDA on Linux arm64
/// (GB10), ROCm on Linux x86-64 (AMD Strix Halo and Strix Point; one bundle
/// carries both chips' kernels).
fn platform_for(os: &str, arch: &str) -> Result<&'static str> {
match (os, arch) {
("macos", "aarch64") => Ok("macos-arm64"),
("linux", "aarch64") => Ok("linux-arm64-cuda"),
("linux", "x86_64") => Ok("linux-x64-rocm"),
(os, arch) => bail!("no basert release is published for {os}/{arch}"),
}
}
Expand Down Expand Up @@ -2307,6 +2315,48 @@ mod tests {
assert!(releases_in(&json!([pre]), "macos-arm64").is_empty());
}

#[test]
fn each_os_and_cpu_takes_its_own_engine_bundle() {
assert_eq!(platform_for("macos", "aarch64").unwrap(), "macos-arm64");
assert_eq!(
platform_for("linux", "aarch64").unwrap(),
"linux-arm64-cuda"
);
assert_eq!(platform_for("linux", "x86_64").unwrap(), "linux-x64-rocm");
let err = platform_for("macos", "x86_64").unwrap_err().to_string();
assert!(
err.contains("no basert release is published for macos/x86_64"),
"{err}"
);
assert!(platform_for("windows", "x86_64").is_err());

// A release with all three bundles: Linux x86-64 takes the ROCm one.
let listing = json!([listed(
"v0.5.0",
"2026-12-10T00:00:00Z",
&[
"basert-engine-abi-1.txt",
"basert-engine-macos-arm64-0.5.0.tar.gz",
"basert-engine-macos-arm64-0.5.0.tar.gz.sha256",
"basert-engine-linux-arm64-cuda-0.5.0.tar.gz",
"basert-engine-linux-arm64-cuda-0.5.0.tar.gz.sha256",
"basert-engine-linux-x64-rocm-0.5.0.tar.gz",
"basert-engine-linux-x64-rocm-0.5.0.tar.gz.sha256",
]
)]);
let found = releases_in(&listing, platform_for("linux", "x86_64").unwrap());
assert_eq!(found.len(), 1);
assert_eq!(
found[0].tarball,
"basert-engine-linux-x64-rocm-0.5.0.tar.gz"
);
assert_eq!(
found[0].checksum_url,
"https://x/v0.5.0/basert-engine-linux-x64-rocm-0.5.0.tar.gz.sha256"
);
assert_eq!(found[0].abi, Some(1));
}

#[test]
fn how_a_launcher_was_installed_is_read_from_where_it_is() {
let tmp = TempDir::new().unwrap();
Expand Down
2 changes: 1 addition & 1 deletion bindings/node/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@baseRT/node",
"version": "0.4.7",
"version": "0.5.0",
"private": true,
"description": "Node.js bindings for BaseRT — LLM inference engine for Apple Silicon (Metal)",
"main": "dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion bindings/python/baseRT/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from pathlib import Path
from typing import Any, Callable, Dict, Iterator, List, Optional, Tuple, Union

__version__ = "0.4.7"
__version__ = "0.5.0"

# ---------------------------------------------------------------------------
# Library loading
Expand Down
2 changes: 1 addition & 1 deletion bindings/python/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

setup(
name="baseRT",
version="0.4.7",
version="0.5.0",
description="Python bindings for the BaseRT LLM inference engine (Apple Silicon / Metal)",
long_description=long_description,
long_description_content_type="text/markdown",
Expand Down
2 changes: 1 addition & 1 deletion bindings/rust/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Add the dependency from crates.io (install the engine first, e.g.

```toml
[dependencies]
baseRT = "0.4"
baseRT = "0.5"
```

or from a checkout:
Expand Down
2 changes: 1 addition & 1 deletion bindings/rust/baseRT-sys/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "baseRT-sys"
version = "0.4.7"
version = "0.5.0"
edition = "2021"
description = "Raw FFI bindings for the BaseRT LLM inference engine"
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion bindings/rust/baseRT/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "baseRT"
version = "0.4.7"
version = "0.5.0"
edition = "2021"
description = "Safe Rust bindings for the BaseRT LLM inference engine (Apple Silicon)"
license = "Apache-2.0"
Expand Down
4 changes: 2 additions & 2 deletions bindings/swift/Sources/CBaseRT/include/baseRT.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ extern "C" {
// === Versioning ===

#define BASERT_VERSION_MAJOR 0
#define BASERT_VERSION_MINOR 4
#define BASERT_VERSION_PATCH 7
#define BASERT_VERSION_MINOR 5
#define BASERT_VERSION_PATCH 0

/// Compile-time version, packed as `(MAJOR<<16) | (MINOR<<8) | PATCH`.
/// Useful for `#if BASERT_VERSION >= 0x000200` feature checks.
Expand Down
4 changes: 2 additions & 2 deletions include/baseRT/baseRT.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ extern "C" {
// === Versioning ===

#define BASERT_VERSION_MAJOR 0
#define BASERT_VERSION_MINOR 4
#define BASERT_VERSION_PATCH 7
#define BASERT_VERSION_MINOR 5
#define BASERT_VERSION_PATCH 0

/// Compile-time version, packed as `(MAJOR<<16) | (MINOR<<8) | PATCH`.
/// Useful for `#if BASERT_VERSION >= 0x000200` feature checks.
Expand Down
Loading