From e8844be3e6683df1a72e414e9ecb8eb76b893591 Mon Sep 17 00:00:00 2001 From: IsuraManchanayake Date: Fri, 13 Nov 2026 04:39:35 +1100 Subject: [PATCH] sync: open-core source for 0.5.0 --- base-convert/Cargo.lock | 16 +++--- base-convert/Cargo.toml | 2 +- base-convert/crates/base-convert/src/main.rs | 47 +++++++++++++++++ .../crates/base-convert/src/selfupdate.rs | 52 ++++++++++++++++++- bindings/node/package.json | 2 +- bindings/python/baseRT/__init__.py | 2 +- bindings/python/setup.py | 2 +- bindings/rust/README.md | 2 +- bindings/rust/baseRT-sys/Cargo.toml | 2 +- bindings/rust/baseRT/Cargo.toml | 2 +- .../swift/Sources/CBaseRT/include/baseRT.h | 4 +- include/baseRT/baseRT.h | 4 +- 12 files changed, 117 insertions(+), 20 deletions(-) diff --git a/base-convert/Cargo.lock b/base-convert/Cargo.lock index 4c88c50..a71bd02 100644 --- a/base-convert/Cargo.lock +++ b/base-convert/Cargo.lock @@ -151,7 +151,7 @@ dependencies = [ [[package]] name = "base-arch" -version = "0.4.7" +version = "0.5.0" dependencies = [ "anyhow", "base-format", @@ -162,7 +162,7 @@ dependencies = [ [[package]] name = "base-awq" -version = "0.4.7" +version = "0.5.0" dependencies = [ "anyhow", "base-format", @@ -176,7 +176,7 @@ dependencies = [ [[package]] name = "base-convert" -version = "0.4.7" +version = "0.5.0" dependencies = [ "anyhow", "base-arch", @@ -202,7 +202,7 @@ dependencies = [ [[package]] name = "base-format" -version = "0.4.7" +version = "0.5.0" dependencies = [ "anyhow", "bitflags", @@ -218,7 +218,7 @@ dependencies = [ [[package]] name = "base-hub" -version = "0.4.7" +version = "0.5.0" dependencies = [ "anyhow", "base-format", @@ -237,7 +237,7 @@ dependencies = [ [[package]] name = "base-quant" -version = "0.4.7" +version = "0.5.0" dependencies = [ "anyhow", "base-format", @@ -249,7 +249,7 @@ dependencies = [ [[package]] name = "base-readers" -version = "0.4.7" +version = "0.5.0" dependencies = [ "anyhow", "base-format", @@ -263,7 +263,7 @@ dependencies = [ [[package]] name = "base-sign" -version = "0.4.7" +version = "0.5.0" dependencies = [ "anyhow", "base-format", diff --git a/base-convert/Cargo.toml b/base-convert/Cargo.toml index 1dd9f5b..408a3de 100644 --- a/base-convert/Cargo.toml +++ b/base-convert/Cargo.toml @@ -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" diff --git a/base-convert/crates/base-convert/src/main.rs b/base-convert/crates/base-convert/src/main.rs index 9644e8b..0269d4f 100644 --- a/base-convert/crates/base-convert/src/main.rs +++ b/base-convert/crates/base-convert/src/main.rs @@ -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 = (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); + } +} diff --git a/base-convert/crates/base-convert/src/selfupdate.rs b/base-convert/crates/base-convert/src/selfupdate.rs index eda6d86..b855cab 100644 --- a/base-convert/crates/base-convert/src/selfupdate.rs +++ b/base-convert/crates/base-convert/src/selfupdate.rs @@ -625,9 +625,17 @@ pub fn bundle_dir() -> Result { /// The engine bundle name's platform for this machine: /// `basert-engine--.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}"), } } @@ -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(); diff --git a/bindings/node/package.json b/bindings/node/package.json index 1b53b17..a3e45f2 100644 --- a/bindings/node/package.json +++ b/bindings/node/package.json @@ -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", diff --git a/bindings/python/baseRT/__init__.py b/bindings/python/baseRT/__init__.py index 4e9664c..da7b85a 100644 --- a/bindings/python/baseRT/__init__.py +++ b/bindings/python/baseRT/__init__.py @@ -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 diff --git a/bindings/python/setup.py b/bindings/python/setup.py index 2b5264f..a455a6d 100644 --- a/bindings/python/setup.py +++ b/bindings/python/setup.py @@ -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", diff --git a/bindings/rust/README.md b/bindings/rust/README.md index 408ab89..abc72c9 100644 --- a/bindings/rust/README.md +++ b/bindings/rust/README.md @@ -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: diff --git a/bindings/rust/baseRT-sys/Cargo.toml b/bindings/rust/baseRT-sys/Cargo.toml index d5c5b2f..e976b8f 100644 --- a/bindings/rust/baseRT-sys/Cargo.toml +++ b/bindings/rust/baseRT-sys/Cargo.toml @@ -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" diff --git a/bindings/rust/baseRT/Cargo.toml b/bindings/rust/baseRT/Cargo.toml index c1c6658..03f2335 100644 --- a/bindings/rust/baseRT/Cargo.toml +++ b/bindings/rust/baseRT/Cargo.toml @@ -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" diff --git a/bindings/swift/Sources/CBaseRT/include/baseRT.h b/bindings/swift/Sources/CBaseRT/include/baseRT.h index ec18d9d..2214f89 100644 --- a/bindings/swift/Sources/CBaseRT/include/baseRT.h +++ b/bindings/swift/Sources/CBaseRT/include/baseRT.h @@ -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. diff --git a/include/baseRT/baseRT.h b/include/baseRT/baseRT.h index ec18d9d..2214f89 100644 --- a/include/baseRT/baseRT.h +++ b/include/baseRT/baseRT.h @@ -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.