# [furiosa-opt 0.4] Broadcast01과 CustomBroadcast에서 EDF만 생성되고 실행 가능한 NPU 바이너리는 생성되지 않습니다
안녕하세요.
RNGD에서 GEMM 입력을 재사용하려고 Switch Engine을 사용하고 있습니다. 현재 API Book은 `Broadcast01`과 `CustomBroadcast`를 Switch 설정으로 설명하며, `cargo-furiosa-opt` 문서에는 `cargo furiosa-opt compile`이 NPU 커널을 빌드한다고 나와 있습니다.
- Switch Engine: Switch Engine - Programming Tensor Contraction Processors
- Direct/automatic NPU compilation: cargo-furiosa-opt - Programming Tensor Contraction Processors
그런데 제 환경에서는 문서에 나온 두 Switch 경로 모두 실행 가능한 `.bin`을 만들지 못하고 중간 산출물까지만 생성됩니다.
## 환경
```text
Host: Ubuntu, Linux 6.8.0-124-generic, x86_64
Device: RNGD npu5
Device firmware reported by furiosa-smi: 2026.2.0 (a5db283)
Installed furiosa-driver-rngd: 2026.3.0
Installed furiosa-firmware-image-rngd: 2026.3.0
rustc: 1.97.0-nightly (2026-04-30), selected by nightly-2026-05-01
furiosa-opt-std: 0.4.0
## 재현 1. 공식 Broadcast01 topology
현재 upstream의 `switch_assertions::broadcast01::valid_with_time0` 예제 topology를 HBM 입출력이 있는 device kernel로 감쌌습니다. Switch mapping은 변경하지 않았습니다.
사용한 Switch 코드는 다음과 같습니다.
```rust
.switch::<
m![C / 4, D % 4],
m![A / 2, C / 2 % 2, A % 2, C % 2],
>(SwitchConfig::Broadcast01 {
slice1: 2,
slice0: 2,
time0: 2,
})
```
컴파일 명령:
```bash
FURIOSA_OPT_OUT_DIR=/tmp/book-broadcast01 \
RUSTFLAGS=‘–cfg=feature=“communication-probes”’ \
cargo furiosa-opt compile rngd_book_broadcast01_exact \
--exact -p rngd-bf16-matmul \
--dump-visa /tmp/book-broadcast01.visa \
--dump-schedule /tmp/book-broadcast01.schedule.json
```
결과:
```text
Compiling [1/1] kernel::pe_communication_probe::rngd_book_broadcast01_exact
Finished 1 compiled, 12 filtered out
exit status: 0
EDF: 40,102 bytes
vISA: generated; broadcast_kind = Dim0Broadcast
selected BIN: absent
FAIL diagnostic: absent
```
출력 디렉터리에는 필터링된 다른 커널의 0-byte placeholder가 생깁니다. 그러나 선택한 Broadcast01 커널 이름의 `.bin`은 없고 EDF만 생성됩니다.
별도의 Broadcast01 대조군에서는 source 값을 구분할 수 있도록 tag를 넣고 emulation을 실행했습니다. 의도대로 4개 slice에 multicast되는 것을 확인했습니다. front-end와 emulator는 mapping을 해석하지만, 공식 mapping은 실행 가능한 `.bin`이 없어서 물리 NPU에 load할 수 없습니다.
## 재현 2. 공식 CustomBroadcast 예제
현재 upstream의 `switch_engine::custom_broadcast` 예제 mapping도 같은 방식으로 HBM 입출력 커널로 감쌌습니다.
관련 mapping은 다음과 같습니다.
```rust
axes![A = 64, B = 8, V = 16, Y = 4];
type Slice = m![A, 1 # 4];
type OutSlice = m![A, Y];
// Fetch Time=[B], Packet=[V]
.switch::<OutSlice, m![B]>(
SwitchConfig::CustomBroadcast { ring_size: 4 }
)
```
컴파일 명령:
```bash
FURIOSA_OPT_OUT_DIR=/tmp/book-custom \
RUSTFLAGS=‘–cfg=feature=“communication-probes”’ \
cargo furiosa-opt compile rngd_book_custom_broadcast_exact \
--exact -p rngd-bf16-matmul \
--dump-visa /tmp/book-custom.visa \
--dump-schedule /tmp/book-custom.schedule.json
```
결과:
```text
exit status: 0
EDF: 56,951 bytes
vISA: generated
selected BIN: absent
FAIL diagnostic: absent
```
생성된 vISA에는 broadcast shape 정보가 비어 있습니다.
```text
CustomBroadcast {
target_partitioning_shape: [] (0),
in_slice_broadcast_axes: [] (0),
stream_partitioning_shape: None
}
```
## 재현 3. ring_size가 검증되지 않고 산출물에도 반영되지 않음
위 공식 CustomBroadcast mapping에서 예상되는 ring size는 4입니다. 다른 코드는 그대로 두고 `ring_size: 4`만 `ring_size: 8`로 바꿔 다시 컴파일했습니다.
API Book의 **Constraints → Ring size** 항목에는 compiler가 mapping에서 예상 ring size를 계산하고, 입력값이 다르면 컴파일을 거부한다고 나와 있습니다.
실제 결과:
```text
ring_size=4: exit 0, EDF generated, no selected BIN, no FAIL
ring_size=8: exit 0, EDF generated, no selected BIN, no FAIL
EDF SHA-256 for both: ff35061bc17a17faf885df0662425d2aff9045a1564fe16994fdbcfa0ddc07e5
vISA SHA-256 for both: 176d4ddeb1698d209f2942ea1ecd5256af9e4729799fed0bc1686d8d2a596a09
Schedule cycles: identical; only the source-code text in the instruction description changes
```
현재 toolchain에서는 입력한 `ring_size`가 검증되지 않으며 생성 결과에도 반영되지 않습니다.
## 대조 실험
장치 전체나 일반적인 NPU 컴파일 경로가 고장 난 상황은 아닙니다.
- Switch를 사용하지 않는 TDMA 커널은 clean directory에서 33,501-byte `.bin`과 37,916-byte EDF를 정상적으로 생성했습니다.
- 기존 contraction 커널 3개는 clean `CARGO_TARGET_DIR`에서 non-empty `.bin`으로 자동 컴파일됐습니다.
- 세 커널 모두 물리 `npu5`에서 실행됐고 R=1, 8, 32에서 CPU reference와 정확히 일치했습니다.
## pcopy 상태는 Switch 문제와 별개입니다
공개 Rust API에는 `to_dm_pcopy`, `to_dm_pcopy_at`, `to_dm_view_pcopy`도 있습니다. 설치된 compiler에서는 세 API 모두 MIR lowering 단계에서 `Unknown primitive`로 실패합니다.
다만 현재 upstream source에도 `to_dm_pcopy`는 MIR까지만 도달하며 아직 VISA/LIR translation이 없다고 명시돼 있습니다.
그래서 이 현상을 위 Switch 문제와 같은 버그로 묶지는 않았습니다. pcopy API가 0.4에서 의도적으로 emulation 전용인지, 물리 NPU에서 쓸 수 있는 대체 API나 향후 지원 계획이 있는지 확인해 주시면 감사하겠습니다.
## 질문
1. 배포된 0.4 toolchain에서 `Broadcast01`과 `CustomBroadcast`가 물리 RNGD NPU backend에서 지원되는 기능인지, 아니면 현재 emulation/EDF까지만 지원되는 상태인지 확인 부탁드립니다.
2. 물리 NPU에서 지원된다면 함께 사용해야 하는 `cargo-furiosa-opt`, compiler driver, SDK, firmware의 정확한 버전 조합을 알려주시면 감사하겠습니다.
3. 선택한 커널의 `.bin`과 `.fail`이 모두 생성되지 않았는데도 direct compile이 exit status 0을 반환하는 이유를 설명해 주실 수 있을까요?
4. 잘못된 CustomBroadcast `ring_size`는 compiler가 거부하는 것이 맞는지 궁금합니다. 그렇다면 ring size 4와 8의 EDF/vISA가 완전히 같은 현상이 compiler 버그에 해당하는지도 확인해 주시면 감사하겠습니다.
5. vISA의 CustomBroadcast shape 정보가 비어 있는 것이 정상인지, 아니면 bitmap 설정이 lowering되지 않았다는 뜻인지 알려주실 수 있을까요?
6. 물리 NPU에서 GEMM 입력 재사용에 쓸 수 있는 PE-local 또는 cross-slice multicast 공개 API가 있다면 안내해 주시면 감사하겠습니다.
필요하시면 전체 최소 재현 프로젝트와 EDF, vISA, schedule JSON, compile log를 제공하겠습니다.