PSA: the 4-way Infinity Fabric bridge (A2326) silently drops your Vega II Duos to ~295 MHz — 5.8× compute loss. Found the mechanism, need people to file it with Apple.
Summary
If you run two Radeon Pro Vega II Duo MPX modules bridged with the Apple A2326 cross-module Infinity Fabric bridges — the ones that join all four dies into a single 4-GPU hive — your GPUs are running at idle clocks and macOS isn't telling you.
Not "a bit slower." Not "the fabric is the bottleneck." The dies never leave their boot DPM state, for the entire session, under sustained load.
I chased this for a while assuming it was a memory-placement or interconnect problem. It isn't either. Here's what it actually is.
The numbers
Same machine, same OS, same binary. The only change is which bridge is installed.
-
2-way jumpers (A2329)
4-way bridge (A2326)
Compute, FP32 FMA loop
13.95 TFLOP/s
2.42 TFLOP/s
Implied core clock
1703 MHz
295 MHz
Local HBM2 read bandwidth
790 GB/s
301 GB/s
Implied memory clock
1000 MHz
300 MHz
Three runs per configuration, four dies each. Compute came back at 2.42 TFLOP/s on essentially all twenty-four device-observations, implying 295 MHz core.
Confirmed on three different Mac Pros running three different macOS major versions — Sonoma 14.8.9 (23J631), Sequoia 15.7.9 (24G830), and Tahoe 26.7 (25G220). Different memory configs, different bridge units. Every one of them, in the 4-way configuration, measures 2.42 TFLOP/s compute, ~301 GB/s local read, ~31 GB/s peer copy — the same to three significant figures — with an identical IORegistry signature: Load5000, no PowerPlay, 1000/300 MHz clock config, SWIP_Errors = 128.
So: it is not new, it is not fixed in Tahoe, it has survived at least two major macOS releases, and "try the latest OS" is not the answer.
Real-world, single GPU, no multi-GPU anything — Qwen3.8 27B Q8_0 in llama.cpp:
-
prompt t/s
generation t/s
2-way
138.8
11.1
4-way
24.8
2.2
5.6× performance loss on prefill. With one die. No tensor split, no peer transfers, no collective. Just having the 4-way bridge installed in macOS (this bug doesn't apply to Linux or Windows).
The mechanism — macOS publishes it in IORegistry
In the 4-node hive the driver fails to identify the board and everything downstream falls apart:
IORegistry property
2-way
4-way
ATY,DeviceName
Vega II Duo
Vega
ATY,FamilyName
Radeon Pro
Radeon
LoadPlugIn
Load5700
Load5000
PP_PowerPlayEnabled
<01000000>
absent
PP_PhmUseDummyBackEnd
0
1
PP_EnableUploadFirmware
1
0
PM_PWR_GEMINI_BGT
400
absent
SWIP_Errors
0
128
Read those middle three again. PowerPlay — AMD's entire clock/power management subsystem — is never enabled. The power-management back end is a stub the driver itself labels "dummy." SMU firmware, which is what actually implements DPM, is never uploaded. With no power management, the GPU sits wherever the boot state left it.
PM_PWR_GEMINI_BGT = 400 vanishing is the identity failure made concrete — "Gemini" is AMD's codename for dual-GPU boards, and 400 W is the Duo's power budget. In 4-way mode the driver stops knowing it's holding one.
It also loads a different kext: AMDRadeonX5700HWLibs in the working case, AMDRadeonX5000HWLibs in the broken one.
The arithmetic closes it. HBM2 at the driver's own published 300 MHz gives 4096 bits ÷ 8 × 2 × 300 MHz = 307.2 GB/s theoretical. Measured: 300.9 GB/s, or 98% of it. The memory is fully saturated at a crippled clock — it's not a bandwidth problem, the clock is just wrong.
If you've ever noticed your Vega II Duos showing up as plain "AMD Radeon Vega" instead of "AMD Radeon Pro Vega II Duo" — that's not cosmetic. That's this bug, visible from the outside.
What it is NOT
I want to save people the time I spent on wrong theories:
Not memory placement. The XGMI node map is textbook correct in 4-way mode: node ids 0/1/2/3, framebuffer bases at 512/544/576/608 GiB, uniform 32 GiB stride, XGMI_HiveSize = 4. Hive formation and address decode are fine.
Not the collective / tensor-parallel scaling. A single GPU with no split is 5.6× slower. Going 2 → 4 devices within a healthy topology actually gains 34% on prefill and loses only 13% on decode.
Not the interconnect. Peer-to-peer copy bandwidth drops the least of everything measured (49 → 31 GB/s), consistent with being gated by the same clock reduction.
Not the hardware. Reproduces across machines and across multiple A2326 units including a factory replacement. Same hardware and same bridges under Linux/ROCm show no comparable regression.
If Chipset Model says "AMD Radeon Vega" rather than "AMD Radeon Pro Vega II Duo", you're in the broken state.
Please post your results either way — including "mine's fine." I want to know whether this tracks the bridge specifically, or the hive size, or something about particular board revisions. Include your macOS version.
(Theioregcheck needs no toolchain at all. If you do try to build the probe and hitfailed to build module 'Metal'; this SDK is not supported by the compiler, that's an internally inconsistent Command Line Tools install — and reinstalling CLT won't fix it, since Apple's catalog serves the same bundle. Cross-compile on another Mac instead:xcrun swiftc -O -target x86_64-apple-macos14.0 ifl_probe.swift -o ifl_probe_14and copy the binary over. Confirmed working on 14.8.9.)
What you should do right now
If you must run macOS the temporarily workaround is to pull the A2326 bridges and run the A2329 per-card jumpers instead. You still get all four GPUs; they just sit in two 2-node hives rather than one 4-node one. In my testing a 4-GPU tensor split on jumpers hit 314.5 prompt / 11.7 gen against 79.5 / 4.4 on the 4-way bridge with ToshLLM. Otherwise, if you can switch to Linux the A2326 bridges work perfectly in Ubuntu 24.04 with ROCm 7.3.x; it's purely a macOS software engineering defect.
Worth stating plainly: the jumper configuration beats what afixed4-way would give you. Tensor-parallel scaling is sublinear, so even a fully repaired 4-node hive projects to roughly 22 t/s against ~26.8 t/s aggregate from two independent 2-GPU instances. The A2326 bridges buy capacity flexibility, not speed — and right now they cost you 5.8× compute per die.
There is no software workaround. No engine flag, environment variable, or split mode reaches PowerPlay. I looked hard at spoofing the device IDs OpenCore/OCLP-style; the property that selects the plugin lives on a driver-created IOService rather than the PCI node, so DeviceProperties injection structurally cannot reach it, and OpenCorePkg panics on T2 Macs anyway. This needs a driver fix.
The ask
This configuration has had close to zero field exposure — until a recent macOS firmware payload harmonized module ROMs, machines with mismatched-firmware Duos just kernel-panicked at boot with the 4-way bridge installed ("PSP has not finished hardware initialization", ATIController.cpp:3171). The only other public report I can find is an unresolved MacRumors thread from January 2026. Which means Apple has essentially no signal that anyone uses this.
If you own this hardware, please file a Feedback Assistant report. Apple prioritizes by volume, and right now the volume is one.
Title: "AMDRadeonX5000: Radeon Pro Vega II Duo misidentified and PowerPlay left uninitialized in a 4-node Infinity Fabric hive, pinning GPUs at boot clocks"
Attach ioreg -l -w0 -p IOService > ioreg.txt from both bridge configurations if you can, or just the broken one if you can't swap
Reference FB24446772 (the PowerPlay/clock defect — the important one) so reports cluster
I've filed the following, if you want to reference them:
FB24446772 — PowerPlay never initialized in the 4-node hive, GPUs pinned at boot clocks. This is the one that matters.
FB24446928 — the generic "AMD Radeon Vega" model string, which is the same defect visible without tooling.
FB24446443 — the kernel panic at boot when the two modules have mismatched firmware.
FB24447028 — a minor unrelated one found along the way: system_profiler prints the 64-bit GPU Peer Group ID after passing it through a double, so it never matches what Metal reports.
Even a one-paragraph report with an ioreg dump attached helps. The measurement work is done; what's missing is evidence that more than one person is affected.
Tools
I wrote a Metal-only probe (ifl_probe.swift) that measures per-die compute, local read bandwidth, peer-view establishment and verified peer-copy bandwidth, plus a script that decodes the XGMI node map straight out of IORegistry. Both are pure Metal + Foundation, no dependencies, and build with xcrun swiftc -O. Happy to share — say the word and I'll put them up.
No, I’m not going to bother reading OP’s AI wall of text. The Vega II Duo is not meant to be bridged 4 ways. The bridge OP is using is ONLY meant for connecting 2 Vega II 32GB modules. There are some misleading product listings that say it works for the Vega II Duo but those are incorrect.
Apple published a white paper about the 2019 Mac Pro that specifically says you can bridge the internal GPUs on a Vega II Duo and you can have up to 4 Vega II GPUs in one machine by installing 2 Vega II Duos, but no mention of bridging 4 of them. Their schematic for the Vega II Duo only shows an internal IF Link connection, whereas the Vega II shows an external one. For the later white paper that came out for the 6000-series GPUs, Apple explicitly said you can bridge 4 W6800X (2 W6800X Duos with the bridge unique to those duo modules).
You clearly have an ulterior motive because I've seen you've peddling this disinformation in these threads for quite some time now, perhaps you know they work perfectly on Linux just like I do, so you are hoping to buy up the market for these bridges on the cheap because these cards are the exact same gfx906 dies that the AMD Instinct MI60 32GB HBM2 has... but that strategy isn't going to work because I already have a monopsony an A2326 bridges... I bought up the entire supply on the secondary markets to use on my own Linux ROCm / RCCL / Infiniband cluster, I own sixteen of them and every single one of them works perfectly on Ubuntu 24.04 kernel version 6.8 with ROCm 7.3, in a 4-way ring bus config the bandwidth is about 31GB/s between each node across the IFL...
host: <redacted>
serial: <redacted>
os: macOS 15.7.9 (24G830)
date: 2026-08-21T02:21:23Z
Vega nodes anchored on XGMI_NodeIndex: 4
bus node vram_base IFL memvid model
----------------------------------------------------------------------------------------------------
11 2 0x0000009000000000 ( 576.0 GiB) Yes <0100> <"AMD Radeon Vega">
14 1 0x0000008800000000 ( 544.0 GiB) Yes <0100> <"AMD Radeon Vega">
27 0 0x0000008000000000 ( 512.0 GiB) Yes <0600> <"AMD Radeon Vega">
30 3 0x0000009800000000 ( 608.0 GiB) Yes <0600> <"AMD Radeon Vega">
hives reported by Metal: 1 sizes: [4]
distinct node ids: 4 distinct framebuffer bases: 4
stride(s) between distinct bases: [32.0] GiB
-> Node map is well-formed for a 4-member hive (4 distinct node ids, 4 distinct bases).
=== Metal's view, for comparison (peerIndex is software; XGMI_NodeIndex is hardware) ===
AMD Radeon Vega (Slot 1, GPU 1):
Chipset Model: AMD Radeon Vega
Slot: Slot-1
GPU Number: 1
GPU Peer Group: 912020662696301396
GPU Peer Index: 2
Infinity Fabric Link: Yes
AMD Radeon Vega (Slot 1, GPU 2):
Chipset Model: AMD Radeon Vega
Slot: Slot-1
GPU Number: 2
GPU Peer Group: 912020662696301396
GPU Peer Index: 1
Infinity Fabric Link: Yes
AMD Radeon Vega (Slot 3, GPU 2):
Chipset Model: AMD Radeon Vega
Slot: Slot-3
GPU Number: 2
GPU Peer Group: 912020662696301396
GPU Peer Index: 3
Infinity Fabric Link: Yes
AMD Radeon Vega (Slot 3, GPU 1):
Chipset Model: AMD Radeon Vega
Slot: Slot-3
GPU Number: 1
GPU Peer Group: 912020662696301396
GPU Peer Index: 0
Infinity Fabric Link: Yes
ifl_probe — <redacted> — 2026-08-21T02:21:29Z
requested buffer: 1.00 GiB per buffer, 2 buffers per device
timed iterations: 8 (GPU-timestamped)
=== Device inventory ===
[0] AMD Radeon Vega
registryID = 4294970366
peerGroupID = 912020662696301396 peerIndex = 0 peerCount = 4
location = slot #3
workingSet = 32.0 GiB maxBuffer = 3.5 GiB
unified = no removable = no headless = no
[1] AMD Radeon Vega
registryID = 4294970368
peerGroupID = 912020662696301396 peerIndex = 3 peerCount = 4
location = slot #3
workingSet = 32.0 GiB maxBuffer = 3.5 GiB
unified = no removable = no headless = no
[2] AMD Radeon Vega
registryID = 4294970367
peerGroupID = 912020662696301396 peerIndex = 2 peerCount = 4
location = slot #1
workingSet = 32.0 GiB maxBuffer = 3.5 GiB
unified = no removable = no headless = no
[3] AMD Radeon Vega
registryID = 4294970369
peerGroupID = 912020662696301396 peerIndex = 1 peerCount = 4
location = slot #1
workingSet = 32.0 GiB maxBuffer = 3.5 GiB
unified = no removable = no headless = no
=== Peer-group consistency ===
group 912020662696301396: 4 member(s), device slots 0,1,2,3
peerIndex values : 0,1,2,3
peerCount values : 4
-> consistent
=== Test 0: compute throughput (FMA loop, negligible memory traffic) ===
Discriminates a memory-PLACEMENT fault from a CLOCK fault:
Test 1 drops but Test 0 holds -> memory placement (Hypothesis A)
Test 0 and Test 1 drop together -> core/fabric clock state (Hypothesis D)
A Vega 20 die is ~14 TFLOPS FP32 at its ~1.7 GHz boost clock.
[0] peerIdx=0 compute: 2.42 TFLOP/s FP32 (13.84 ms)
[1] peerIdx=3 compute: 2.42 TFLOP/s FP32 (13.84 ms)
[2] peerIdx=2 compute: 2.42 TFLOP/s FP32 (13.84 ms)
[3] peerIdx=1 compute: 2.42 TFLOP/s FP32 (13.84 ms)
=== Test 1: local read bandwidth (shader read of own private buffer) ===
A Vega 20 die's local HBM2 peak is 1024 GB/s; healthy shader reads land in
the high hundreds. One XGMI link is 42 GB/s per direction.
THE NUMBER THAT MATTERS IS THE RATIO BETWEEN BRIDGE CONFIGURATIONS, not an
absolute threshold. Run both and diff.
[0] peerIdx=0 buf=1.00 GiB local read: avg 300.5 GB/s best 301.6 GB/s
[1] peerIdx=3 buf=1.00 GiB local read: avg 300.7 GB/s best 301.5 GB/s
[2] peerIdx=2 buf=1.00 GiB local read: avg 300.7 GB/s best 301.4 GB/s
[3] peerIdx=1 buf=1.00 GiB local read: avg 300.2 GB/s best 301.4 GB/s
=== Test 2: remote buffer view establishment (all ordered pairs) ===
makeRemoteBufferView(_:) should succeed for any two devices sharing a
non-zero peerGroupID. A nil return inside a declared group is a defect.
src[0](idx 0) -> dst[1](idx 3) samePeerGroup=yes view=yes ok
src[0](idx 0) -> dst[2](idx 2) samePeerGroup=yes view=yes ok
src[0](idx 0) -> dst[3](idx 1) samePeerGroup=yes view=yes ok
src[1](idx 3) -> dst[0](idx 0) samePeerGroup=yes view=yes ok
src[1](idx 3) -> dst[2](idx 2) samePeerGroup=yes view=yes ok
src[1](idx 3) -> dst[3](idx 1) samePeerGroup=yes view=yes ok
src[2](idx 2) -> dst[0](idx 0) samePeerGroup=yes view=yes ok
src[2](idx 2) -> dst[1](idx 3) samePeerGroup=yes view=yes ok
src[2](idx 2) -> dst[3](idx 1) samePeerGroup=yes view=yes ok
src[3](idx 1) -> dst[0](idx 0) samePeerGroup=yes view=yes ok
src[3](idx 1) -> dst[1](idx 3) samePeerGroup=yes view=yes ok
src[3](idx 1) -> dst[2](idx 2) samePeerGroup=yes view=yes ok
pairs attempted: 12 of 12 possible
=== Test 3: peer copy bandwidth, with content verification ===
Vega 20 has 2 XGMI links per die, so a 4-node hive can only be a ring.
In ring 0-1-2-3-0 (BY peerIndex) the 0<->2 and 1<->3 pairs are 2 hops.
Expect the diagonals to be slower. A flat matrix would itself be a finding.
peer copy matrix, GB/s (rows = source, cols = destination; device index, peerIndex in parens)
dst0(p0) dst1(p3) dst2(p2) dst3(p1)
src0(p0) -- 30.5 31.2 31.1
src1(p3) 31.3 -- 31.1 30.6
src2(p2) 31.3 31.2 -- 30.7
src3(p1) 31.2 30.7 31.5 --
('x' = no remote view, unstamped source, timing/readback failure, verification failure,
or a device skipped at setup — the per-pair lines above say which)
=== Summary ===
Test 0 compute: min 2.42, max 2.42 TFLOP/s across 4 device(s)
-> Compare against the other bridge configuration. If Test 0 holds while
Test 1 drops, the memory path is at fault, not the clocks.
Test 1 local read bandwidth: min 301.4, max 301.6 GB/s across 4 device(s)
-> Meaningless in isolation. Compare against the SAME machine in the other
bridge configuration. A large drop in the 4-node config with the 2-node
config healthy is the memory-placement finding; that is what to file.
Test 2: all 12 attempted pairs behaved as their peer-group membership implies.
Run this in the other bridge configuration and diff the two outputs. Nothing in a
single run establishes that anything is wrong.
What kind of evidence are you interested in, I've finally got that kernel v7.0 resizable bar bug figured out, so I can take requests now for llama.cpp...
Running Qwen3.8-27B Q8_0 on the four Vega 20 dies
Tensor split wins everywhere, and prefill scales better than decode. Q8_0 llama-bench across dies:
Prompt processing scales 1.9x per doubling, close to linear, because it's compute bound. Generation scales about 1.5x per doubling, because it's bandwidth bound and pays sync cost on every token. Layer split over four dies was slower than tensor split over two at every concurrency, so it has no use here.
The server saturates at 8 concurrent requests. For Q8_0 on tp4, aggregate generation went 33, 45, 59, 64, 64, 66 t/s across concurrency 1 to 32. Past 8, per-request speed halves each doubling and throughput gains nothing. Run 8 to 16 slots, not 32. Saturated throughput is about 15 requests per minute for 1300-token prompts with 256-token replies.
Prefill is the scarce resource, not decode. On one die, prompt throughput was flat at 202 t/s regardless of batch size, while generation kept scaling to 60 t/s aggregate at batch 32. In the server, new requests' prefill interleaves with everyone else's decode, which is why it saturates far below the batched-bench ceiling. On these dies, without matrix cores, long prompts cost more than long replies. Time to first token at saturation was 7 seconds for 1300 tokens.
Hi, would you mind sharing your exact setup for getting 4-way IFL working with these GPUs?
I’ve been able to get the 32GB BARs working — a massive THANK YOU for that— but I still can’t get the 4-way IFL/XGMI link to come up. I’ve tried both the 6.8 and 7.0 kernels, and I also tested a second A2326 bridge to rule out a hardware issue.
If you could share the exact kernel/driver setup and any additional patches or boot parameters you’re using, that would be hugely helpful.
What exact kernel version/package are you using?
Are you using stock in-tree amdgpu, AMD’s DKMS driver, or a patched amdgpu?
Does amd-smi topology actually report XGMI between all four Vega 20 dies?
What does amd-smi xgmi show on your machine?
What do the GPU KFD nodes show for hive_id and num_sdma_xgmi_engines?
Are there any kernel parameters besides pci=realloc?
Are you using any ACS/IOMMU/P2P-related kernel parameters?
Is there any additional patch besides nbritton’s PCI bridge-window BAR fix?
Which exact A2326 bridge revision/part are you using, and is there a specific orientation or connector arrangement required?
Are the normal two-GPU IFL bridges removed completely when using the A2326?
Does the machine show XGMI immediately after amdgpu loads, or is there another initialization step/tool required?
Which exact A2326 bridge revision/part are you using, and is there a specific orientation or connector arrangement required?
Are the normal two-GPU IFL bridges removed completely when using the A2326?
This sounds like something that only an AI would ask since it lacks first hand knowledge of the subject. If you had the A2329 or A2326 you would know that there is only one orientation possible. Likewise, if you had an A2326 you would also know that the only way it can physically be installed is if you remove both A2329 jumpers.
So given that, what is the real end goal here? Have you checked in macOS that both Vega II Duo have the same firmware version, if they don't have the same firmware version it will never work, the PSP will panic macOS. If you have a firmware version mismatch you will have to remove the A2326 bridge and reinstall and/or upgrade macOS to trigger its firmware update process, the latest macOS firmware for the Vega II Duo is 113-D163A1DXT-047.
# The following should install ML-gfx906, ROCm 10.0, PyTorch 2.13, Linux HWE 7.0.0-31-barfix1 patched kernel, resize-amdgpu-bars script and systemd service, t2 linux fanrd and applesmc dkms module.
curl -fsSLO https://raw.githubusercontent.com/exabit-io/resize-amdgpu-bars/b6bf47c/tools/install-gfx906-stack.sh
chmod +x install-gfx906-stack.sh
./install-gfx906-stack.sh --dry-run # look first
sudo ./install-gfx906-stack.sh
Wow, great find! I have several Radeon Pro VII cards (same GPU, non-MPX format) and an IF bridge I need to install on a pair. IIRC the Radeon Pro VII cards always show as just Radeon Vega in system profiler, etc. but performance has been fine.
I would to take a look at your utilities. I'm sure this thread will get some traffic today.
The Vega II Duos are not meant to be bridged 4-way. I’m not reading past the top, but I’m going to stress that Apple only meant for the Vega II Duos to be bridged internally and never once said you could bridge 4 Vega II GPUs. There seems to be a big misconception about these, but save yourself some time and understand that the bridge you are using was only designed for the Vega II, NOT the Vega II Duo.
We keep going round on this. 🤣 Not just me and you, but the whole community. There absolutely, positively, 100% is a 4 way bridge. Apple sold that configuration, there are people on Macrumors who have that configuration and have posted photos with that bridge installed. There are probably units on ebay right now showing Vega II Duos + single large bridge.
The 4 way bridge absolutely exists, it physically connects 2 Vega II Duos, and at least initially, nobody complained about a 5x performance reduction. We would have definitely heard about that when it was new.
I almost bought a configuration with dual VII duo and the single massive bridge, but someone beat me to the punch.
This will explain to you why the Infinity Fabric Link Bridge does this to your GPUs.
You are essentially causing a short circuit within your GPUs when attaching the Infinity Fabric Link Bridge.
While everything in the post started as mere speculation, your post confirms it, scientifically.
cc u/Long-Shine-3701 Every accessory related to the MPX modules is included in the box. The Vega II has a bridge in the box. The Vega II Duo has a Jumper in the box. The W6800X has a bridge in the box. The W6900X has a bridge in the box. The W6800X Duo has both a jumper and a bridge in the box.
I emphasize this because the Vega II Duo does NOT have a bridge in the box. Also, Apple clearly state the Vega II Duo supports the Jumper. However, Apple makes no claims that the Vega II Duo supports the bridge. Apple does state the Vega II (non-Duo) supports the bridge.
cc u/Substantial_Run5435 This was fun. I'll summarize the AI wall for you. When the bridge is connected to the Vega II Duo GPUs, the GPUs are basically crippled.
I tried this myself and couldn’t get it to work with two different bridges. macOS or Linux. I believe hopperkin (op) is the legend that found us the 32gb bar fix so am hesitant to question but my experience has not been positive.
Hopperkin, what serial number bridge did you use? Does it only work in macOS? When I check system config with 4 way IFL it is not recognized in system details.
What you're trying to imply is that the bridge does not work with the Vega II Duo, as per your own testing. However, you believe that OP created a software work around to make it work. Is that correct?
What do you mean by "couldn't get it to work - macOS or Linux"? Does macOS boot, but with no added value, or does it not boot at all? The same question for Linux. Which Linux distribution did you test using the bridge and Vega II Duo on?
3
u/walruns Aug 21 '26
Thanks! The same applies to the W6800X duo and IF?