Skip to content

s390x: IBM Z CPU variants z13 / z15 / z16 (patch 0023), 4-4.5x faster on a z16 - #580

Merged
bernardladenthin merged 2 commits into
mainfrom
feat/s390x-cpu-variants
Oct 27, 2026
Merged

bernardladenthin merged 2 commits into
mainfrom
feat/s390x-cpu-variants

Conversation

@bernardladenthin

@bernardladenthin bernardladenthin commented Oct 27, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • cpu-linux-s390x uses the IBM Z vector unit. Until now the jar was one static, scalar library: GGML_NATIVE=OFF switches VXE off, so no vector code shipped. build-linux-s390x now builds it modular (JLLAMA_BACKEND_DL) with GGML_CPU_ALL_VARIANTS: ggml-cpu-z13 (scalar), -z15 (VXE2) and -z16 (VXE2 + NNPA). ggml loads the best module for the machine. The floor stays z13 and glibc 2.28.
  • Patch 0023, two parts.
    • llamafile/sgemm.h includes <vecintrin.h> a second time after ggml-cpu-impl.h. clang's header has no include guard, so ggml-cpu.c failed with "redefinition of 'vec_extract'"; GCC's guard hid the problem. The include came with llamafile: support s390x SIMD instruction set ggml-org/llama.cpp#14273 and is not needed: sgemm.h declares no vector type, and both of its includers include ggml-cpu-impl.h. Removed.
    • Upstream's s390x variant list starts at z15, so a z13/z14 would get no CPU backend at all. The patch adds a scalar z13 module.
    • Not filed upstream.
  • CI:
    • A modular build cannot link jllama_test, so the C++ suite moves to the new job test-cpp-linux-s390x (static build, same toolchain, still under qemu). It gates package.
    • c_abi now runs under the toolchain's emulator. There ggml loads the z15 module, because qemu's CPU model has VXE2, so CI runs the vector code too.
    • build-linux-s390x checks that all three modules exist; the configure skips a variant the compiler rejects (z17 with clang 18) without reporting it.

Measured on cfarm191 (IBM z16, LinuxONE, Debian 13)

b11901, Qwen3-0.6B Q4_K_M converted to big-endian, llama-bench -t 4 -p 64 -n 16, two interleaved rounds, t/s:

module prompt (pp64) generation (tg16)
z13 (scalar, what 6.0.x shipped) 19.7 – 19.8 13.6 – 13.8
z15 90.0 – 95.5 57.3 – 58.3
z16 82.6 – 88.3 51.9 – 53.9
z16, GCC 14.2 without the patch (comparison) 85.2 – 86.4 44.1 – 53.9
  • Module selection: with all three modules ggml loads z16, without it z15, without both z13.
  • Correctness, measured with llama-perplexity --kl-divergence against a Q8_0 reference computed on z13:
    • Q4_K_M has a mean KLD of 0.0777 on z13 and 0.0746 on z16. Both are equally far from the reference.
    • z16 against z13 directly: KLD 0.0087. That is about a tenth of what the quantization costs.
    • Q8_0, z16 against z13: KLD 0.0012, same top token in 98.5 %.
  • The CI-built 6.1.0-SNAPSHOT jar of run 40400361809 loads on cfarm191 and answers "Paris." with the big-endian model.

Test plan

  • Locally with the job's toolchain (Docker: clang-18, binutils-s390x, the manylinux_2_28 s390x sysroot):
    • the modular build produces all three modules; z17 is skipped;
    • c_abi passes under qemu, with CPU : VXE = 1;
    • verify-native-deps.py: 9 libraries, 0 violations (glibc ≤ 2.27, GLIBCXX_3.4.25, CXXABI_1.3.11, the existing allowlist, typeinfo alignment).
  • NativeLoadSmoke with the built directory in the UBI 8 OpenJDK 21 image on RHEL 8.10 s390x (qemu): z15 module, patches=…0022,0023.
  • check-patches.py (14 patches, 104 hunks, 0 problems; docs/patches.md current), check-natives.py (0 disagreements), buildcheck unit tests 127/127 on Linux, release gate (75 jobs, 0 violations), run scripts parse, publish.yml loads as YAML.
  • CI is green on this branch
  • After merge: the CI-built modular jar on cfarm191 (TODO.md, "Linux s390x")

Related issues / PRs

The open TODO item "s390x runs scalar" is closed by this PR. Follows #573 (glibc floor) and #577 (typeinfo alignment).

Checklist

  • I have read CONTRIBUTING.md and CODE_OF_CONDUCT.md
  • My commits follow Conventional Commits (they follow this repository's own message style)
  • No security-sensitive changes

🤖 Generated with Claude Code

https://claude.ai/code/session_01DuAkLtHrCTx81vP5Mt4jad

Summary by CodeRabbit

  • New Features
    • Linux on IBM Z (s390x) now offers CPU-optimized library variants for z13, z15, and z16. The best available variant is selected automatically at startup, with a scalar baseline available for older systems.
  • Documentation
    • Updated platform information to describe s390x shared-library and CPU-module support, automatic variant selection, and measured performance. The documentation also clarifies that macOS continues to use a static library.

…tch 0023)

cpu-linux-s390x was one static, scalar library: GGML_NATIVE=OFF switches
VXE off, so no IBM Z vector code ever shipped. build-linux-s390x now
builds it modular (JLLAMA_BACKEND_DL) with GGML_CPU_ALL_VARIANTS:
ggml-cpu-z13 (scalar), -z15 (VXE2) and -z16 (VXE2 + NNPA), of which ggml
loads the best for the machine. On cfarm191 (z16, b11901, Qwen3-0.6B
Q4_K_M big-endian, 4 threads) prompt processing goes from 19.7 to
82.6-95.5 t/s and generation from 13.6 to 51.9-58.3; against a Q8_0
reference the Q4_K_M model lands at the same KLD on z13 and z16.

Patch 0023, two parts:
- llamafile/sgemm.h included <vecintrin.h> a second time after
  ggml-cpu-impl.h; clang's header has no include guard, so ggml-cpu.c
  failed with "redefinition of 'vec_extract'". The include is not
  needed (added by ggml-org/llama.cpp#14273; GCC's guard hid it).
- Upstream's s390x variant list starts at z15; a scalar z13 module
  keeps the z13 floor the jar has had.

A modular build cannot link jllama_test, so the C++ suite moves to the
new test-cpp-linux-s390x job (static build, same toolchain, qemu).
c_abi now runs under the toolchain's emulator, where ggml loads the z15
module. build-linux-s390x checks that all three modules were built.

Verified locally with the job's toolchain (clang-18, manylinux_2_28
sysroot): the build, c_abi under qemu, verify-native-deps.py (9
libraries, 0 violations), and a JVM load on RHEL 8.10 s390x.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DuAkLtHrCTx81vP5Mt4jad
@coderabbitai

coderabbitai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 767fc6f5-09c6-4fbc-95b2-643e557eb100
Commits

Reviewing files that changed from the base of the PR and between 6e76156 and 897111c.

Files selected for processing: 2
  • CLAUDE.md
  • llama/CMakeLists.txt
Files skipped from review as they are similar to previous changes: 1
  • CLAUDE.md

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

Walkthrough

Linux s390x now builds modular CPU backends for z13, z15, and z16. The workflow checks for the modules and runs C++ tests in a separate qemu job. CMake, dependency checks, patch inventories, and project documentation reflect the modular build.

Changes: Linux s390x modular CPU build

Layer / File(s) Summary
Add s390x CPU variants
llama/patches/0023-ggml-cpu-s390x-variants-build-with-clang-and-a-z13-baseline.patch, llama/CMakeLists.txt
The patch adds a z13 backend, extends the cross-compilation target range, and removes a conditional vecintrin.h include. CMake enables modular Linux s390x builds and permits the C ABI test under an emulator.
Build and test s390x artifacts
.github/workflows/publish.yml, .github/buildcheck/nativedeps.py
The build job checks for the z13, z15, and z16 modules. A separate job runs the C++ suite under qemu, and package requires that job. The dependency description reflects the modular libraries.
Document modular s390x support
CHANGELOG.md, CLAUDE.md, README.md, TODO.md, docs/patches.md
The documentation and patch inventories describe the CPU modules, build and test setup, and recorded measurements.

Priority: Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant CMake
  participant BuildWorkflow
  participant QemuTestJob
  participant Package
  CMake->>BuildWorkflow: Configure modular CPU backends
  BuildWorkflow->>BuildWorkflow: Check z13, z15, and z16 modules
  QemuTestJob->>Package: Provide required C++ test result
Loading

Possibly related PRs

Suggested reviewers: claude

Merge Risk: Minimal · up to 89711

The modular s390x build, z13 fallback, required artifacts, and qemu-backed tests are wired coherently; no merge-blocking risk is established.

Architecture risk: Low · up to 89711

The change affects 6 systems.

Changed systems: llama, CHANGELOG.md, CLAUDE.md, docs, README.md, TODO.md

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — llama (service) was modified; 2 changed files map to changed impact.
  • observed — CHANGELOG.md (service) was modified; 1 changed file maps to changed impact.
  • observed — CLAUDE.md (service) was modified; 1 changed file maps to changed impact.
  • observed — docs (service) was modified; 1 changed file maps to changed impact.

Before / after behavior

  • observed — Modified behavior in CHANGELOG.md: Adds a changelog entry for modular s390x CPU libraries with z13, z15, and z16 modules and startup selection. It records z16 benchmark results, patch 0023 build and variant-list fixes, and the s390x C++ test job running under qemu.
  • observed — Modified behavior in README.md: The platform description now includes Linux s390x with the shared-library and CPU-module layout; s390x is removed from the platforms described as using one static library, leaving that description for macOS.
  • observed — Modified behavior in README.md: The cpu-linux-s390x entry now specifies three startup-selected CPU modules (z13, z15, z16) and adds a z16 performance comparison against the scalar library of 6.0.x.
  • observed — Modified behavior in TODO.md: The model-backed plain-C smoke note no longer says that s390x remains a static build; it still identifies macOS as static.
Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title names the main change: modular s390x CPU backends (z13, z15, z16) with patch 0023, and the z16 speedup. The raw summary and PR objectives both center on this change, so the title is clearly …
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within survi…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title names the main change: modular s390x CPU backends (z13, z15, z16) with patch 0023, and the z16 speedup. The raw summary and PR objectives both center on this change, so the title is clearly related. It is somewhat long at 78 characters, but it is specific and not vague.

Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 1 files. (2 skipped: 2 unsupported.)

Finishing Touches: 💡 1
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

The dockcross Android images set CMAKE_CROSSCOMPILING_EMULATOR too
(qemu-arm), so "cross-compiling with an emulator" enabled c_abi in the
Android aarch64 job, where qemu-arm cannot run the aarch64 executable
("Invalid ELF image for this architecture", run 40469900299). Only the
s390x toolchain's emulator is meant.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DuAkLtHrCTx81vP5Mt4jad
@sonarqubecloud

Copy link
Copy Markdown

@bernardladenthin
bernardladenthin merged commit 3457f40 into main Oct 27, 2026
95 of 100 checks passed
@bernardladenthin
bernardladenthin deleted the feat/s390x-cpu-variants branch October 27, 2026 21:40

This branch had an error being deployed

1 failed and 2 active deployments
unsigned — 897111c6 Deployed Oct 27, 2026 by bernardladenthin via Sign the Windows DLLs (SSL.com eSigner) #1400
startgate — 897111c6 Deployed Oct 27, 2026 by bernardladenthin via Start gate (abort window) #1400
maven-central — 897111c6 Deployed Oct 27, 2026 by bernardladenthin via Verify GPG signing key (no secrets printed) #1400
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant