[furiosa-opt 0.4] Broadcast01과 CustomBroadcast에서 EDF만 생성되고 실행 가능한 NPU 바이너리는 생성되지 않습니다

# [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를 제공하겠습니다.

질문 주셔서 감사드립니다. 검토 후 답변드리겠습니다.

안녕하세요, furiosa-opt에 관심 가져 주셔서 감사하고 early stage라 불안정한 부분이 다소 있어서 죄송합니다. 하나씩 답변드리면,

  1. 예제로 올라온 Broadcast01과 CustomBroadcast는 물리 NPU에서 지원되고 동작하는 상태입니다. 다만 compiler의 dump 기능에 버그가 있어서 binary가 생성되지 않는 문제가 있었는데요, 이 문제는 수정되었고 다음 릴리즈에 배포될 예정입니다.
  2. 현재 배포된 0.4에서 dump 기능을 제외하고 실행하신다면 동작이 예상됩니다.
  3. 이 부분 또한 1의 버그와 연관된 문제로 dump flag가 주어질 경우 실제로 컴파일 없이 dump가 성공하면 0을 return하도록 되어 있는 부분으로 인한 결과입니다.
  4. 이 부분은 추정하신대로 compiler의 assertion이 미비한 부분으로 동일하게 다음 릴리즈에서는 수정되어 올바르게 동작합니다.
  5. 4와 마찬기로 이 부분도 bitmap 설정이 올바르게 될 예정입니다. 0.4.0에서는 bitmap 설정이 안되어 있긴 하지만 동작자체는 설정된 bitmap 기준으로 되고 있는 상태입니다.
  6. 시도하신 Broadcast01과 CustomBroadcast를 쓰시는게 의도한 API입니다. 그대로 쓰시면 될 거 같습니다.

수정된 다음 릴리즈는 차주내로 배포할 예정입니다.

감사합니다.