Skip to content

CPU bundles: runtime-selected ggml CPU variants and repacked quantized weights (1.3x to 3x faster on CPU) - #28

Merged
danielhanchen merged 23 commits into
masterfrom
perf/cpu-isa
Oct 12, 2026
Merged

danielhanchen merged 23 commits into
masterfrom
perf/cpu-isa

Conversation

@danielhanchen

@danielhanchen danielhanchen commented Oct 11, 2026 •

Copy link
Copy Markdown
Member

Problem

Every CPU path in the prebuilt bundles ran a fraction of the CPU it was on.

  • One instruction set level for every host. The Linux x64, Linux arm64, macOS x86_64 and Windows CPU bundles are static -DGGML_NATIVE=OFF builds. On x86 that is ggml's fixed AVX/AVX2/FMA/F16C/BMI2 baseline: no AVX512, AVX512-VNNI or AMX on the CPUs that have them, and SIGILL on any CPU without AVX2. On Linux arm64 no -march is passed at all, so the build is plain Armv8.0 (System Info: NEON = 1 | ARM_FMA = 1): no dotprod, no fp16 arithmetic, no i8mm, which are the instructions every quantized and f16 matmul uses on Arm.
  • ggml's CPU weight repacking never ran. ggml's CPU backend converts Q4_0 / Q4_K / Q2_K / Q5_K / Q6_K / IQ4_NL weights into interleaved layouts (and, on AMX CPUs, Q4_0 / Q4_K / Q8_0 and others into AMX tiles) when they are uploaded into its "extra" buffer types, so each matmul reading them runs a wider GEMM kernel. sd.cpp put every weight in the plain CPU buffer, so none of these kernels were reachable. A diffusion transformer is almost entirely such matmuls.

Change

Four commits.

  1. Ship every ggml CPU variant in the CPU bundles (unsloth-sd-prebuilt.yml). The Linux x64, Linux arm64, macOS x86_64 and win-cpu-x64 legs build with GGML_BACKEND_DL=ON GGML_CPU_ALL_VARIANTS=ON (shared ggml), so ggml scores each libggml-cpu-<variant> against the host at startup and loads the best: x86-64 baseline, SSE4.2, AVX, AVX2 (haswell), AVX-VNNI, AVX512 / VNNI / BF16 and AMX on x86 (MSVC builds the 9 variants it can compile), Armv8.0 up to Armv8.6 i8mm, SVE2 and SME on Linux arm64 (built with GCC 14, since GCC 13 rejects +sme). sd.cpp already creates its CPU backend through the ggml registry, so no source change was needed for this.
    • Linux libraries get DT_RPATH=$ORIGIN exactly like the CUDA bundles; macOS libraries get @loader_path only.
    • New scripts/unsloth/cpu_variants_gate.sh runs on every finished CPU zip (a PowerShell twin on Windows): the floor variant (x64 / armv8.0_1) must be present, no file may point back at the build tree, and sd-cli started from the unzipped copy in an empty cwd must load a variant from that copy.
    • The Metal (macOS arm64), Vulkan and CUDA legs are unchanged.
    • Bundle size, Linux x64: 31.6 MiB to 36.9 MiB.
  2. Repack quantized matmul weights for the CPU backend. Linear tags its quantized weight as matmul-only (a slot in the leaf tensor's unused op_params, so the tag lives and dies with the tensor). When the compute backend is the CPU, the model manager places a tagged weight in the first CPU extra buffer type whose supports_op accepts that weight's MUL_MAT (AMX first, then the generic repack), and logs it once: cpu weight repack: quantized matmul weights use CPU_REPACK. Everything else, and every GPU path, is untouched.
    • A LoRA on such a weight is added to the output (x W^T + x dW^T, add_lora_to_output) instead of being folded into a copy of W, since a repacked weight can only feed MUL_MAT. Weights that are not repacked keep the existing path bit for bit.
    • --lora-apply-mode immediately (which rewrites weights in place) turns repacking off.
    • A 4D activation is flattened to 3D before such a matmul (the repacked kernel takes at most three activation dims).
    • Kill switch: SD_CPU_REPACK=0.
    • --mmap keeps weights in the file mapping, which the repacked layout cannot use, so mmapped weights are not repacked; the log says so once (cpu weight repack: skipped for mmapped weights). Studio does not pass --mmap.
    • A model whose LoRAs are merged in place (immediately) opts out of repacking for that context only; on CPU, AUTO picks at_runtime whenever --type or --tensor-type-rules quantizes while loading and the diffusion model, text encoder or VAE runs on the CPU.
  3. On CPU, pick at_runtime LoRA when the weights end up quantized. auto looked only at the file's types, so an f16 file loaded with --type q4_0 chose immediately. That turned repacking off for every such run, LoRA or not. The conversion target now counts as quantized when the diffusion model runs on the CPU. (On the base, that same immediately path aborts with GGML_ASSERT(*cur_backend_id != -1) for an f16 SD1.5 file + --type q4_0 + a LoRA on CPU; with this change the run completes.)
  4. AVX512 variants only on CPUs that also have AVX-VNNI (ggml-patches/0008). On GitHub's Azure EPYC 9V74 (Zen 4: AVX512 without AVX-VNNI) the AVX512 variants ran 15 to 50% slower than the AVX2 one, with MSVC and with clang. On Zen 5 (Strix Halo) and Emerald Rapids, both with AVX-VNNI, they are the fastest by a wide margin. Without AVX-VNNI an AVX512 variant now scores 0, so those hosts load the AVX2 variant, as the static build ran.

Results

Base = fork master afac7a7c built with the workflow's flags; head = this branch built with the new flags. Same host, same job, arms interleaved ABBA, one fresh sd-cli process per measurement, 3 repeats, median [min, max]. Seconds. Prompt "a photo of a red fox sitting in fresh snow, golden hour, detailed fur", seed 42, cfg 1. "Sampling" is sd-cli's sampling completed, "generate" its generate_image completed (text encoder + sampling + VAE).

AMD Ryzen AI MAX+ 395 (Strix Halo, Zen 5, 16C/32T, AVX512 + AVX-VNNI), Linux, 16 threads, exclusive box

Head loads libggml-cpu-zen4.so.

model, 512x512 steps sampling base sampling head generate base generate head
FLUX.1-schnell Q4_0, T5 Q4_K_M 4 89.56 [88.92, 89.96] 32.90 [32.89, 33.01] 98.68 41.61
Z-Image-Turbo Q4_K_M, Qwen3-4B Q4_K_M 4 49.36 [49.35, 49.46] 35.11 [34.93, 35.12] 56.54 42.41
Qwen-Image-2.1-Turbo Q2_K, Qwen3-VL-8B Q4_K_M 4 42.40 [42.32, 42.40] 29.33 [29.28, 29.52] 52.97 41.01
Z-Image-Turbo Q4_K_M + distill-patch LoRA (n=1) 4 54.74 44.99 61.84 52.35
SD-Turbo q4_0 2 3.64 [3.62, 3.66] 3.04 [3.03, 3.06] 10.96 9.73
SD-Turbo q4_K 2 3.59 [3.55, 3.59] 3.16 [3.14, 3.20] 12.10 11.18
SD-Turbo q8_0 2 3.60 [3.58, 3.62] 3.29 [3.28, 3.32] 10.61 9.91
SD-Turbo f16 2 3.60 [3.58, 3.60] 3.32 [3.23, 3.38] 10.63 9.88

Where it comes from (same box, sampling):

FLUX.1-schnell Z-Image-Turbo Qwen-Image-2.1-Turbo
base (static AVX2) 89.56 49.36 42.40
zen4 variant, SD_CPU_REPACK=0 89.48 43.26 40.70
AVX2 variant forced, repack on 55.02 45.98 -
head (zen4 variant + repack) 32.90 35.11 29.33

Threads: head at 32 threads (SMT) instead of 16 gave the same sampling time (44.13 vs 43.83 s, Z-Image) and a slower VAE decode (9.12 vs 6.24 s), so Studio's physical-core default stays.

GitHub ubuntu-24.04-arm (Neoverse-N2, 4 cores, SVE2 + i8mm), 4 threads

Base System Info: NEON = 1 | ARM_FMA = 1; head loads libggml-cpu-armv8.6_2.so (FP16_VA | MATMUL_INT8 | SVE | DOTPROD).

model res, steps sampling base sampling head VAE decode base VAE decode head generate base generate head
SD-Turbo q8_0 512, 2 45.45 [45.41, 45.55] 15.63 [15.61, 15.97] 101.61 28.99 148.05 45.36
SD-Turbo q4_K 512, 2 50.84 [50.72, 50.86] 16.37 [16.26, 16.42] 101.56 29.02 161.07 53.78
SD-Turbo q4_0 512, 2 46.15 [46.11, 46.17] 16.20 [16.12, 16.27] 101.55 29.01 150.62 47.84
SD-Turbo f16 512, 2 56.87 [56.86, 56.98] 16.62 [16.59, 16.79] 101.71 29.02 160.49 46.15
Z-Image-Turbo Q4_K_M, Qwen3-4B Q4_K_M 256, 2 159.00 [158.38, 165.03] 93.83 [91.87, 95.07] 25.57 7.32 192.26 105.19

Z-Image with SD_CPU_REPACK=0: 116.16 s sampling.

GitHub ubuntu-latest (AMD EPYC 7763, Zen 3, AVX2 only, 4 vCPU), 4 threads

Head loads libggml-cpu-haswell.so: the same instruction set as the static build, and with SD_CPU_REPACK=0 its images are bit-identical to base and its times equal (SD-Turbo q8_0 / q4_K / q4_0 / f16 sampling 23.89 / 23.79 / 25.35 / 24.33 s base, 23.86 / 23.69 / 25.27 / 24.31 s head). The gain is the repack:

model res, steps sampling base sampling head generate base generate head
Z-Image-Turbo Q4_K_M, Qwen3-4B Q4_K_M 256, 2 75.47 [74.86, 77.81] 65.13 [64.16, 66.93] 91.77 81.66
SD-Turbo q4_0 (first run) 512, 2 25.52 [25.43, 25.56] 21.42 [21.38, 21.51] 69.75 65.52
SD-Turbo q4_K (first run) 512, 2 23.85 [23.81, 23.91] 22.90 [22.84, 22.94] 80.96 80.02

Intel Xeon Platinum 8559C (Emerald Rapids, AVX512 + AVX-VNNI + AMX), Linux, 16 threads pinned to 16 physical cores

A shared host (load average 57 to 73 on 192 threads during the run), so ratios only. Head loads libggml-cpu-sapphirerapids.so and puts Q4_K / Q4_0 / Q8_0 weights in AMX tiles.

model, 512x512 steps sampling base sampling head generate base generate head
Z-Image-Turbo Q4_K_M, Qwen3-4B Q4_K_M 4 74.74 [70.87, 75.25] 33.46 [31.18, 37.14] 85.10 44.97
SD-Turbo q4_0 2 5.05 [4.97, 7.05] 4.07 [3.99, 4.34] 15.47 14.20

Z-Image with the AVX2 variant forced and repack on: 68.56 s; AMX variant with SD_CPU_REPACK=0: 65.88 s.

GitHub windows-latest (MSVC, as the release leg builds it), 4 threads

This branch, with the fork's full ggml patch set applied to both arms, on an AMD EPYC 7763 (Zen 3, AVX2 only). Head loads ggml-cpu-haswell.dll.

model res, steps sampling base sampling head generate base generate head
SD-Turbo q4_0 512, 2 27.14 [27.14, 28.47] 23.24 [23.20, 24.72] 79.59 75.39
SD-Turbo f16 512, 2 26.09 [26.00, 26.10] 26.23 [26.04, 26.45] 73.52 73.53
Z-Image-Turbo Q4_K_M, Qwen3-4B Q4_K_M 256, 2 235.92 [235.63, 282.73] 234.06 [226.14, 234.73] 336.92 335.93

SD-Turbo f16 head images are bit-identical to base. Z-Image's repack gain on this MSVC build is inside the noise (the same arm under another name ran 227.09 s).

Why commit 4 exists, from two earlier Windows runs without it (SD-Turbo, 512, 2 steps, sampling, SD_CPU_REPACK=0):

runner CPU arm q4_0 f16 VAE decode
EPYC 9V74 (Zen 4, AVX512, no AVX-VNNI) base 22.53 22.32 39.0
MSVC, cascadelake loaded 30.79 33.12 50.8
clang, zen4 loaded 25.71 27.35 49.6
MSVC or clang, haswell forced 22.47 / 22.26 22.36 / 22.07 39.0
EPYC 9V45 (AVX512, no AVX-VNNI) base 17.09 17.76 30.0
MSVC, cascadelake loaded 20.06 20.85 27.1

With commit 4 both CPUs load haswell, which matches base.

GitHub macos-15-intel (Core i7-8700B, AVX2 only, 4 vCPU)

Head loads libggml-cpu-haswell.so; SD-Turbo images are bit-identical to base at all four types. This runner's timings swung up to 2.5x within one arm (SD-Turbo q8_0 base sampling 23.13 to 66.35 s), so it gives no speed verdict either way; every head run completed.

Accuracy

An instruction set change legitimately moves low bits; the check is that head is no further from a high-precision reference than base.

case base head
Z-Image-Turbo Q4_K_M (Strix), PSNR vs a bf16 DiT + bf16 Qwen3-4B render, same seed 25.85 dB 26.15 dB
SD-Turbo q8_0 / q4_K / q4_0 (Strix), PSNR vs base f16 37.95 / 24.20 / 21.21 dB 39.13 / 24.81 / 21.19 dB
SD-Turbo q8_0 / q4_K / q4_0 (Neoverse-N2), PSNR vs base f16 38.59 / 24.91 / 21.07 dB 35.15 / 24.81 / 21.01 dB
SD-Turbo f16, head vs base 57.2 to 59.2 dB
  • Where head runs the same variant as base with SD_CPU_REPACK=0 (Zen 3 above; AVX2 variant forced on this host with the full ggml patch set), images are bit-identical to base.
  • LoRA through repacked weights, SD1.5 Q8_0 loaded as q4_0 + LCM LoRA, 4 steps, 512: repack on vs SD_CPU_REPACK=0 39.9 dB (AVX2 repack) and 42.6 dB (AMX); the same seed without the LoRA is 13.3 dB away, so the LoRA is applied. With the AVX2 variant and Q8_0 (no repack for that type on x86) head is bit-identical to base with the LoRA.

Tests

  • This workflow, run on a staging fork at this branch's tree (CUDA legs and publishing off): the Linux x64, Linux arm64, macOS x86_64 and win-cpu-x64 legs all pass the new CPU variants gate. Each lists its variants (14 on Linux / macOS x64, 9 with MSVC, 8 on arm64) and sd-cli from the unzipped bundle loads haswell / armv8.6_2 / haswell / ggml-cpu-haswell.dll from it (an earlier Linux x64 runner loaded sapphirerapids). The gate caught two real problems on the way, both fixed in commit 1: build-tree LC_RPATHs in the macOS libraries, and the Windows step ending on sd-cli's own exit code.
  • On the staging fork, win-cpu-x64 (and the unchanged win-vulkan-x64) fail the existing "every PE is signed" check, since a fork has no signing secrets; the signing step itself signs every PE in build/bin, which now includes the ggml-cpu-*.dll files.
  • Bench workflows on GitHub ubuntu-latest, ubuntu-24.04-arm, macos-15, macos-15-intel, windows-latest and on the gfx1151 CI box: every head run exits 0.
  • Local: base vs head with the AVX2 variant and SD_CPU_REPACK=0 bit-identical (SD-Turbo q4_0 / q8_0 / q4_K / f16, SD1.5 + LoRA); repack engagement in every DiT run (cpu weight repack: ... use CPU_REPACK / AMX, 324 to 449 tensors).

Not covered

  • macOS arm64 (Metal bundle) is unchanged. GGML_CPU_ALL_VARIANTS' apple_m1 variant drops the fp16 arithmetic Apple clang's default target already has, and was 40% slower than base on GitHub's M1 runner, so it is not used there.
  • AVX512 on Intel CPUs without AVX-VNNI (Skylake-X, Cascade Lake, Ice Lake, Tiger Lake, Rocket Lake) is now gated off and was not measured either way; they run the AVX2 variant as before.
  • No Zen 4 machine measured AVX512 with repack on; the gate sends Zen 4 to the AVX2 variant (+ repack).
  • Seen but not changed here: on the same EPYC 7763 class, the MSVC Windows build runs Z-Image Q4_K_M about 3x slower than the GCC Linux build (sampling 235.9 s vs 75.5 s at 256, 2 steps), while SD-Turbo q4_0 is close (27.1 vs 25.4 s). That points at MSVC code generation for the k-quant kernels; a clang Windows CPU build is the follow-up to measure.
  • MiniMax-H3 and SDXL were not benchmarked on CPU. Windows on ARM and Windows on gfx1151 were not run.
  • The bench builds apply the fork's ggml patch set only in the Windows and local runs; the Linux/macOS/Strix bench builds used the bare submodule for both arms.

The Linux x64, Linux arm64, macOS x86_64 and Windows CPU bundles were static
-DGGML_NATIVE=OFF builds: AVX2/FMA on x86 (no AVX512, VNNI or AMX, and SIGILL
on pre-AVX2 CPUs) and plain Armv8.0 on Linux arm64 (no dotprod or i8mm).
Build them with GGML_BACKEND_DL + GGML_CPU_ALL_VARIANTS so ggml loads the best
libggml-cpu-<variant> for the host at startup (Linux arm64 with GCC 14, which
accepts +sme). Linux libraries get DT_RPATH $ORIGIN like the CUDA bundles,
macOS ones @loader_path only. A gate checks every finished zip ships the
floor variant, keeps no build-tree paths, and loads a variant from itself.
ggml's CPU backend converts Q4_0 / Q4_K / Q2_K / Q5_K / Q6_K / IQ4_NL weights to
interleaved layouts (and Q4_0 / Q4_K / Q8_0 ... to AMX tiles on AMX hosts) when
they are uploaded into its extra buffer types, so every matmul reading them runs
a wider GEMM kernel. sd.cpp put all weights in the plain CPU buffer, so these
kernels never ran. Linear tags its quantized weight as matmul-only, and the
model manager places tagged weights in the first extra buffer type whose
supports_op accepts the matmul. LoRA on such a weight is added to the output
instead of folded into the weight; 'immediately' LoRA mode turns repacking off.
SD_CPU_REPACK=0 disables it.
The auto LoRA mode looked only at the file's weight types, so an f16 file
converted with --type q4_0 chose 'immediately', which turned CPU repacking off
for every such run even with no LoRA. On CPU, count the conversion target as
quantized and apply LoRAs at runtime, which works on repacked weights.
Measured on GitHub's Azure EPYC 9V74 (Zen 4: AVX512 without AVX-VNNI), the
AVX512 variants ran sd.cpp 15 to 50% slower than the AVX2 one (MSVC and
clang alike), while on Zen 5 (Strix Halo) and Emerald Rapids (AVX512 + AMX),
both with AVX-VNNI, they were the fastest. Score an AVX512 variant 0 without
AVX-VNNI so those hosts load the AVX2 variant, as the static build ran.
@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

@danielhanchen

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-12T04:34:26.691424Z 8684583 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Something went wrong. Try again later by commenting “@codex review”.

Unknown error
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 89efda16df

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


void sd_tag_matmul_only_weight(ggml_tensor* weight) {
if (weight != nullptr && weight->op == GGML_OP_NONE) {
weight->op_params[SD_MATMUL_ONLY_TAG_SLOT] = SD_MATMUL_ONLY_TAG;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Write the tag as a 32-bit op parameter

ggml_tensor::op_params is a byte array, so this stores only the low byte (0x4d) at byte offset 15, while sd_is_matmul_only_weight() compares that byte with the full 0x53444d4d value. The predicate therefore never recognizes tagged weights, sd_cpu_repack_buffer_type_for() always rejects them, and the CPU repacking optimization introduced by this commit is never used. Store and retrieve the tag with the 32-bit op-parameter helpers or an equivalent memcpy at the intended slot.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

op_params is declared as int32_t op_params[GGML_MAX_OP_PARAMS / sizeof(int32_t)] in this ggml (include/ggml.h:707), so SD_MATMUL_ONLY_TAG_SLOT indexes the last 32-bit slot and the whole tag is stored and compared. Engagement confirmed on d8008ba: SD1.5 with --type q4_0 on an AMX host logs 'cpu weight repack: quantized matmul weights use AMX' and ggml reports 'amx repack tensor ...' for each tagged weight.

@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Oct 11, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Oct 11, 2026
chatgpt-codex-connector[bot]

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Oct 11, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Oct 11, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Oct 11, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Oct 11, 2026
chatgpt-codex-connector[bot]

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Oct 11, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Oct 11, 2026
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: 2ec6fe2d04

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

AMX steps the shared 2D weight per activation batch (wrong batches, out-of-bounds writes) and
both AMX and CPU_REPACK read strided views as contiguous rows. Make the activation contiguous and
flatten every batch dim into rows before the matmul on a possibly repacked weight.
…uffer

A repack buffer has no read path and holds the repacked layout, so a destination sharing its source
with a repacked first destination is read from the file in its own batch.
ggml_backend_load_best opens every matching libggml-<name>-*.so before scoring it, so the current
directory search ran any such library placed where sd-cli or sd-server is launched. Keep
GGML_BACKEND_DIR, the executable directory and explicit search paths.
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

Reviewed commit: 5897deb44d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…indows path buffer

On Linux/FreeBSD get_executable_path() fell back to "." when readlink failed, which
put the current directory back on the backend search list. Return an empty path
instead and only search the executable directory when it is known. On Windows,
GetModuleFileNameW truncates at MAX_PATH and the helper then returned an ancestor
directory; retry with a larger buffer.
AMX and CPU_REPACK extra buffers only implement MUL_MAT with F32 activations (the
type the buffer selection probes with). A non-F32 activation produced NaN on AMX
and aborted on CPU_REPACK.
chatgpt-codex-connector[bot]

This comment was marked as resolved.

…the CPU

A weight's buffer is not allocated until its first segment loads, so the first
graph asked the process-wide repack switch instead of the weight's placement, and
quantized GPU linears took the repacked-CPU matmul path (2D flatten) on that graph.
The model manager now keeps the tag only while the weight's compute backend is the
CPU, at registration and when the compute backend changes.
chatgpt-codex-connector[bot]

This comment was marked as resolved.

@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Oct 12, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Oct 12, 2026
chatgpt-codex-connector[bot]

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Oct 12, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Oct 12, 2026
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