Skip to content
This repository was archived by the owner on Nov 12, 2026. It is now read-only.
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
5 changes: 4 additions & 1 deletion .github/workflows/aurora-enhancements.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@ on:
- "mseries/aurora/release.json"
- "mseries/aurora/enhancements/**"
- "mseries/aurora/unified72/series.json"
- "mseries/aurora/unified72/egpu-series.json"
- "mseries/aurora/unified72/connectx-series.json"
- "mseries/aurora/unified72/combined-series.json"
- "mseries/aurora/unified72/patches/**"
- ".github/workflows/aurora-enhancements.yml"
workflow_dispatch:
inputs:
profile:
description: Kernel profile (eGPU remains an unqualified experiment)
type: choice
options: [candidate, egpu, unified72]
options: [candidate, egpu, unified72, unified72-egpu, unified72-connectx, unified72-combined]
default: candidate

permissions:
Expand Down
36 changes: 36 additions & 0 deletions mseries/OS9-HANDOFF.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
## Warren local AI and eGPU updates — 2026-10-30

Added `unified72-combined`, a distinct downstream kernel profile carrying #188 plus both AMDGPU and ConnectX Ethernet modules so one kernel can provide both. Source preparation, 12 PMP host tests, 88 Aurora tests and GCC olddefconfig passed. Native build pending. Existing eGPU trial remains staged; `/boot` has about 45 MiB free, insufficient for another Image plus initramfs without a storage plan. [Details](aurora/unified72/README.md#combined-egpu-and-connectx-package--october-30-2026).

Owner clarified that upstream acceptance is not ours to duplicate; downstream regression testing and packaging are requested. Deployed official MLX v0.7.35 wheel (`39671c8a...19fba82`) to the live venv with the previous venv retained at `~/.local/share/mlx-omarchy/venv.before-v0.7.35-20261030`. Qwen 2B baseline/work120k gate passed; Granite 1B short text matched earlier baseline; reply service restarted and returned `ready`, expected private ICD and server patches checked. Installer/source pins now target `42b30a2d`. [Receipt](local-ai/receipts/2026-10-30-mlx-v0735-deploy/README.md).

Installed the eGPU kernel package and Ubuntu AMD graphics firmware; staged `elementary-aurora72-egpu-test-trial` with 91-module audited wip5-derived initramfs. GRUB syntax passes, one-shot is empty, current wip5 remains running; shared boot.bin remains unchanged and its old PCI ranges still apply to tunnels 1–3. No eGPU is attached. [Deployment details](aurora/unified72/README.md#separate-egpu-candidate--october-30-2026).

Long Qwen 2B divergence investigated with the exact 256-token installed-MLX sequence, a CPU float32 teacher-forced forward and two TensorFold probe runs. One TensorFold selection differs at zero-based row 167; its ` This` instead of MLX incremental ` Red` aligns with the 880-character common prefix. CPU prefers ` Red` by 0.08872; TensorFold BF16 ties at 20.125 and picks ` This`, as does a separate MLX full-pass teacher-forced forward. TF/CPU RMSE 0.02758, MLX/CPU 0.02963; each has only this near-tie CPU argmax difference. Strict exact-ID probe fails; this supports but does not prove the numerical cause. [Receipt](local-ai/receipts/2026-10-30-tensorfold-b3ab9ba/README.md).

Aurora eGPU CI run 41048473839 passed. The downloaded ZIP matched GitHub digest and all payload checksums passed; package `e15886c7...8923763` contains AMDGPU with matching vermagic and expected J314S DTB, no /boot payload. No installation or boot; firmware and shared-DTB fallback compatibility remain open. [Receipt](aurora/unified72/egpu-ci-2026-10-30.json).

Extended TensorFold #1544 `b3ab9ba` CPU-float32 teacher-forced comparison to all six cached 32-step cases. Pooled RMSE ratio to installed MLX 0.967 (1.05 bound); max case ratio 1.049 (1.15 bound); all finite and no argmax flips outside 0.5-margin near ties. The stricter TensorFold probe **failed exact IDs** on `single` row 24 (CPU margin 0.0041) and `code` row 16 (0.10039); other four passed. Each repeat matched its own logits. These are numerical checks, not complete free-running, long-context or FP64 qualification. [Receipt](local-ai/receipts/2026-10-30-tensorfold-b3ab9ba/README.md).

TensorFold #1544 `b3ab9ba` teacher-forced short rainbow case: two runs matched all 32 CPU-reference IDs and repeated logits byte-for-byte; BF16 logits versus the cached float32 CPU rows had RMSE 0.02884 versus installed MLX 0.03183 (ratio 0.906, within 1.15 case bound), with 6,437,111 unequal BF16 elements against rounded CPU logits. One case only, not the FP64 gate or an explanation of long divergence. [Receipt](local-ai/receipts/2026-10-30-tensorfold-b3ab9ba/README.md).

TensorFold #1544 head `b3ab9ba` long Qwen 2B follow-up: one guarded 256-token pair completed, but its text diverged from installed MLX after 880 common characters, matching the earlier trial's divergence position. This is a text comparison, not a logits diagnosis; teacher-forced fidelity and batching remain open. [Receipt](local-ai/receipts/2026-10-30-tensorfold-b3ab9ba/README.md).

Tested TensorFold draft #1544 head `b3ab9ba` privately: host tests, all five M1 Pro GPU stages and six contract groups pass (pointwise records known fp32 denormal flush). Qwen 2B 32-token, three rotated rounds matched installed MLX's response text; TensorFold loopback median 2.89 decode tokens/s versus MLX in-process 54.51, with different timing boundaries. Long-output fidelity, desktop pacing and submit-batching remain unqualified; no service changed. [Receipt](local-ai/receipts/2026-10-30-tensorfold-b3ab9ba/README.md).

The installed system has no `/usr/lib/firmware/amdgpu` and no Ubuntu `linux-firmware` package; identify and verify matching card firmware before any AMD eGPU trial. The local ConnectX module compile required `rustup component add rust-src --toolchain 1.93.1`; this adds build-tool source only and does not alter the running kernel.

Local GCC compilation of ConnectX `mlx5_core` and `mlxfw` completed with `KBUILD_MODPOST_WARN=1` and no kernel `Module.symvers`: unresolved-symbol warnings and missing BTF mean compile-only evidence, not loadable artifacts. The diagnostic build changed the private prepared source tree; prepare a fresh tree for its digest gate. The separate ConnectX CI build remains in progress.

Added an isolated `unified72-connectx` kernel profile on wip5 source with Mellanox support and Ethernet enabled (`MLX5_CORE=m`, `MLX5_CORE_EN=y`, `MLXFW=m`); AMDGPU and RDMA remain off. Source preparation, the 12 PMP tests, GCC olddefconfig and 87 Aurora tests pass. No ConnectX adapter is present, and build/boot/link/throughput are unqualified. [Details](aurora/unified72/README.md#separate-connectx-candidate--october-30-2026).

Compiled the #188 J314S DTB locally and compared its decompiled contents with wip5: only the three expected PCI ranges differ. Added `prepare-egpu-boot-candidate.py` to create an uninstalled image from the existing shared boot payload by changing only those three DTB bytes, checking the exact input hash and preserving all other boot bytes. The private candidate is `fe7ad1e9...8539913`; 86 Aurora tests pass. This does not establish compatibility with fallback kernels or any eGPU boot, and no boot file was changed. [Details](aurora/unified72/README.md#separate-egpu-candidate--october-30-2026).

Follow-up: a real-device QMV toggle probe mapped candidate dispatch ID 547 to the batch route, and the separate candidate batch-4 model trace contains 3,366 such dispatches; the installed baseline probe and batch-4 trace show the same route and dispatch count. Live J314S DTB still has the pre-#188 non-identity PCI windows on tunnels 1–3, and shared `boot.bin` matches the retained fallback hash. The package DTB alone does not alter that boot tree; preserve fallback compatibility before staging a trial.

Built MLX #303 merge `42b30a2` in an isolated venv; installed v0.7.34 and candidate both passed the Qwen 2B single-stream gate. Three alternating batch pairs per size produced matching token hashes, median paired reductions 8.7% (batch 2), -3.1% (batch 3) and 8.0% (batch 4). This is a short smoke; serving fidelity and desktop pacing remain unqualified. No live runtime replaced. [Receipt](local-ai/receipts/2026-10-30-qmv-batch/README.md).

Added a separate `unified72-egpu` build profile at Aurora #188 merge `c506e1c3` with wip5's five display patches and AMDGPU=m. Archive verification, patch preparation, 12 PMP host tests and GCC olddefconfig passed; local LLVM configuration lacked lld. The profile is experimental and unbuilt/unbooted, with no attached eGPU. See [candidate details](aurora/unified72/README.md#separate-egpu-candidate--october-30-2026).

Audited the linked announcement against the running wip5 host and current dev pins. TensorFold's merged Vulkan base is not yet a model engine; MLX #303 needs M1 Pro batch qualification; Aurora #188 merged after our source pin and changes shared PCI/DTB behavior. No external GPU or ConnectX appeared in the PCI inventory. No runtime, kernel or boot changes were made. See [the source and qualification notes](local-ai/WARREN-UPSTREAM-2026-10-30.md).

## Rust compositor: frames for X11 windows — 2026-10-29

Owner report: the WiFiman Desktop window (Electron, X11, `_MOTIF_WM_HINTS 0x2, 0x0, 0x1`, min 420x460) could not be moved or resized. The Rust compositor drew no server-side decorations at all, so X11 apps that rely on the window manager's title bar had nothing to grab. New `rust/pantheon-compositor/src/decorations.rs`: X11 windows that ask for a frame (no Motif hints, or hints with a title; normal/dialog/utility types) get a 34 px title bar above the client, an invisible 8 px resize band, and the `org.gnome.desktop.wm.preferences button-layout` buttons (close, minimize, maximize; the owner's `close,minimize,maximize:`), drawn with pango/cairo and rounded with the window corners. Drag moves, edges resize within the size hints, double-click and the maximize button toggle maximize, close sends WM_DELETE_WINDOW. Snapped/maximized framed windows are configured below the title bar; work-area fitting counts the title bar. Fixes on the way: X11 resize ignored WM_NORMAL_HINTS min/max; moving an X11 window (title bar or Super-drag) never told the client its new position. `_NET_WM_MOVERESIZE` was already routed by smithay and is now covered by the probe. Wayland windows, header-bar (CSD) X11 windows and fullscreen windows are unchanged. Verified: `mseries/pantheon-rust-compositor/ssd-probe/run.sh` (nested, 11/11 pass with a window carrying WiFiman's exact hints), 184 unit tests, activation probe 7/7. Not verified: the real WiFiman window on the M1 Pro (needs the owner's install + re-login); the real app was not started nested because its root daemon carries the owner's live VPN. Not done: `_NET_FRAME_EXTENTS`, a window shadow, frames during gesture animations.
Expand Down
7 changes: 7 additions & 0 deletions mseries/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -5640,3 +5640,10 @@ remains open. The current live site byte-matches `dev` `7053069f` from Pages run
## T3 launcher and panel decision (2026-10-27)

Keep the unified T3 Wingpanel menu and use the Dock launcher to open the T3 window. Validate the combined experience on the target desktop before claiming acceptance.
# 2026-10-30 eGPU candidate

The separate Aurora `unified72-egpu` profile carries upstream #188 with AMDGPU enabled. Its CI-built package and AMD firmware are installed, and a non-default trial entry is staged; running wip5 and shared boot DTB remain in place. J314S dock, recovery, matched-DTB and actual eGPU testing remain. See [candidate status](aurora/unified72/README.md#separate-egpu-candidate--october-30-2026).

The separate `unified72-connectx` profile enables the Mellanox Ethernet module on wip5 source; it requires a native build and real-adapter link and throughput qualification. [Status](aurora/unified72/README.md#separate-connectx-candidate--october-30-2026).

The `unified72-combined` profile packages both driver sets in one kernel; native build, boot-space planning and device regression tests remain. [Status](aurora/unified72/README.md#combined-egpu-and-connectx-package--october-30-2026).
13 changes: 9 additions & 4 deletions mseries/aurora/candidate.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,10 @@ def tree_digest(root):


def manifest(profile):
return HERE / "unified72/series.json" if profile == "unified72" else MANIFEST
return (HERE / "unified72" / {"unified72": "series.json",
"unified72-egpu": "egpu-series.json", "unified72-connectx": "connectx-series.json",
"unified72-combined": "combined-series.json"}[profile]
if profile in ("unified72", "unified72-egpu", "unified72-connectx", "unified72-combined") else MANIFEST)


def series(profile="candidate"):
Expand All @@ -163,8 +166,10 @@ def settings(data, profile):
result = dict(data["config"]["candidate"])
# Explicitly retain the release's disabled eGPU drivers in the normal candidate.
result.update(DRM_AMDGPU="n", DRM_NOUVEAU="n")
if profile == "egpu":
if profile in ("egpu", "unified72-egpu", "unified72-combined"):
result.update(data["config"]["egpu"])
if profile == "unified72-connectx":
result.update(data["config"]["connectx"])
result.update(LOCALVERSION='""', LOCALVERSION_AUTO="n")
return result

Expand Down Expand Up @@ -304,7 +309,7 @@ def check(root):
binary = Path(temporary) / f"production-tests-{index}"
run("rustc", "--edition=2021", "--test", "-D", "warnings", source / test, "-o", binary, cwd=root)
run(binary)
if receipt["profile"] != "unified72":
if receipt["profile"] not in ("unified72", "unified72-egpu", "unified72-connectx", "unified72-combined"):
run("python3", ENHANCEMENTS / "check-macsmc.py", source)


Expand Down Expand Up @@ -400,7 +405,7 @@ def main():
prep = commands.add_parser("prepare")
prep.add_argument("--cache", type=Path, required=True)
prep.add_argument("--output", type=Path, required=True)
prep.add_argument("--profile", choices=("candidate", "egpu", "unified72"), default="candidate")
prep.add_argument("--profile", choices=("candidate", "egpu", "unified72", "unified72-egpu", "unified72-connectx", "unified72-combined"), default="candidate")
prep.add_argument("--offline", action="store_true")
for command in ("check", "build"):
sub = commands.add_parser(command)
Expand Down
43 changes: 43 additions & 0 deletions mseries/aurora/test_egpu_boot_candidate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""Safety checks for the uninstalled eGPU boot payload builder."""
import importlib.util
from pathlib import Path
import struct
import unittest

path = Path(__file__).parent / 'unified72/prepare-egpu-boot-candidate.py'
spec = importlib.util.spec_from_file_location('egpu_boot', path)
egpu = importlib.util.module_from_spec(spec)
spec.loader.exec_module(egpu)


def tree(payload):
size = 40 + len(payload)
return b'\xd0\x0d\xfe\xed' + struct.pack('>I', size) + bytes(32) + payload


def fixture():
ranges = b''.join(struct.pack('>7I', 0x43000000, 8, 0, h, 0, 2, 0)
for h in (12, 16, 20))
return b'loader' + tree(b'apple,j314s\0' + ranges) + b''.join(tree(bytes([i])) for i in range(8)) + b'payload'


class CandidateTest(unittest.TestCase):
def test_only_three_expected_bytes_change(self):
data = fixture()
new, receipt = egpu.compose(data)
self.assertEqual(len(data), len(new))
self.assertEqual(sum(a != b for a, b in zip(data, new)), 3)
self.assertEqual(receipt['dtb_count'], 9)
self.assertTrue(new.endswith(b'payload'))

def test_missing_or_duplicate_ranges_are_refused(self):
data = fixture()
needle = struct.pack('>7I', 0x43000000, 8, 0, 12, 0, 2, 0)
with self.assertRaisesRegex(ValueError, 'unexpected or ambiguous'):
egpu.compose(data.replace(needle, bytes(len(needle))))
with self.assertRaisesRegex(ValueError, 'unexpected or ambiguous'):
egpu.compose(data.replace(bytes(32), needle + bytes(4), 1))


if __name__ == '__main__':
unittest.main()
39 changes: 39 additions & 0 deletions mseries/aurora/test_qualification.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,45 @@ def test_journal_from_a_different_boot_is_refused(self):
with self.assertRaisesRegex(ValueError, "exactly the observed boot"):
self.collect_fixture(["PMP started"], "other-boot")

def test_unified72_combines_egpu_and_connectx_without_overwriting_either(self):
data = candidate.series("unified72-combined")
egpu = candidate.series("unified72-egpu")
connectx = candidate.series("unified72-connectx")
self.assertEqual(data["source"]["commit"], egpu["source"]["commit"])
self.assertNotIn(data["debian_package"], (egpu["debian_package"], connectx["debian_package"]))
config = candidate.settings(data, "unified72-combined")
self.assertEqual(config["DRM_AMDGPU"], "m")
self.assertEqual(config["MLX5_CORE"], "m")
self.assertEqual(config["MLX5_CORE_EN"], "y")
self.assertEqual(config["MLXFW"], "m")
self.assertEqual(config["DRM_NOUVEAU"], "n")
self.assertEqual([p["sha256"] for p in data["patches"]],
[p["sha256"] for p in egpu["patches"]])

def test_unified72_connectx_is_separate_and_enables_ethernet(self):
normal = candidate.series("unified72")
connectx = candidate.series("unified72-connectx")
self.assertNotEqual(normal["debian_package"], connectx["debian_package"])
self.assertEqual(normal["source"]["commit"], connectx["source"]["commit"])
self.assertEqual(candidate.settings(connectx, "unified72-connectx")["MLX5_CORE"], "m")
self.assertEqual(candidate.settings(connectx, "unified72-connectx")["MLX5_CORE_EN"], "y")
self.assertEqual(candidate.settings(connectx, "unified72-connectx")["MLXFW"], "m")
self.assertEqual(candidate.settings(connectx, "unified72-connectx")["DRM_AMDGPU"], "n")
self.assertNotIn("MLX5_CORE", candidate.settings(normal, "unified72"))

def test_unified72_egpu_is_separate_and_enables_amd_only_in_its_profile(self):
normal = candidate.series("unified72")
egpu = candidate.series("unified72-egpu")
self.assertNotEqual(normal["debian_package"], egpu["debian_package"])
self.assertNotEqual(normal["kernel_release"]["unified72"],
egpu["kernel_release"]["unified72-egpu"])
self.assertEqual(candidate.settings(normal, "unified72")["DRM_AMDGPU"], "n")
self.assertEqual(candidate.settings(egpu, "unified72-egpu")["DRM_AMDGPU"], "m")
self.assertEqual(candidate.settings(egpu, "unified72-egpu")["DRM_NOUVEAU"], "n")
self.assertIn(egpu["source"]["commit"], egpu["source"]["url"])
self.assertEqual([p["sha256"] for p in normal["patches"]],
[p["sha256"] for p in egpu["patches"]])

def test_unified72_snapshot_has_separate_identity_and_no_moving_branch_url(self):
data = candidate.series("unified72")
self.assertIn(data["source"]["commit"], data["source"]["url"])
Expand Down
Loading
Loading