[furiosa-opt v0.6.0]같은 slice의 DM 텐서를 다른 축 조합으로 commit_view할 때 StreamUnmatchedSegment가 발생합니다

안녕하세요.

Opt 0.6.0에서 같은 physical slice에 있는 DM 텐서를 다른 축 조합의 DM view로 저장하던 중 TensorUnit lowering 오류를 확인했습니다. Source와 destination의 원소 수는 같은데, destination의 축을 나누어 표현하면 컴파일이 실패합니다.

재현 환경은 `furiosa-opt-std = “=0.6.0”`, `nightly-2026-05-01`입니다.

## 확인하려는 데이터 이동

두 커널 모두 HBM의 `i32` 입력을 slice-local DM으로 읽습니다. 각 slice의 `32×32` 타일에서 7-bit 값을 추출해 `i8`로 바꾼 후, 마지막에 이 값을 다른 DM tensor의 view로 `commit_view`합니다.

```text

HBM i32

→ slice-local DM 32×32 i32

→ 7-bit 값 추출

→ i8 cast

→ destination DM view에 commit_view

```

성공 대조군인 `dm_repack_control`은 source와 destination에서 같은 `32×32` 축을 사용합니다.

```text

source: [ROWS % 32, COLUMNS % 32]

destination: [ROWS % 32, COLUMNS % 32]

```

Direct compile 결과 이 커널은 성공했고, 43,755-byte NPU binary와 schedule JSON도 생성됐습니다.

반면 `dm_repack_split_axis_failure`는 목적지의 축 구성을 바꾸면 실패합니다. 저장하는 값은 앞선 대조군과 같은 `32×32 i8` 데이터입니다. 전체 목적 tensor에 8개의 slot을 두고, `tile`로 하나를 선택해 `commit_view`했습니다. 이때 선택된 destination view와 source의 원소 수는 각각 1,024개로 같습니다.

```text

source element axes:

[ROWS % 32, COLUMNS % 32]

selected destination view axes:

[ROWS % 32, COLUMNS % 16 % 2, DIGIT_SLOT = 1, COLUMNS / 16]

```

두 tensor는 cluster와 physical slice mapping도 같습니다. Switch와 ring broadcast는 사용하지 않았으며, cross-slice 복사도 없습니다. 두 커널의 차이는 `commit_view`에 넘기는 destination 축 구성 하나뿐입니다.

오류가 발생한 부분은 아래 `commit_view`입니다.

```rust

ctx.main

.begin(digit.view())

.fetch::<m!\[ROWS % 32\], m!\[COLUMNS % 32\]>()

.collect::<m!\[ROWS % 32\], m!\[COLUMNS % 32\]>()

.commit_trim::<m!\[COLUMNS % 32\]>()

.commit_view(destination);

```

Opt 0.6.0에서 direct compile하면 아래 오류가 발생합니다.

```text

Compiling [1/1] dm_repack_split_axis_failure

error: furiosa-opt: dm_repack_split_axis_failure: visa: while lowering TensorUnit

   caused by: CommitArgs::commit_projection() failed:

   Commit: cannot write an input axis into DM (StreamUnmatchedSegment)

```

## 확인 부탁드리는 내용

1. 같은 physical slice 안에서 source와 원소 수가 같은 destination view로 축 구성을 바꾸어 `commit_view`하는 동작을 Opt 0.6.0에서 지원하는지 궁금합니다.

2. `StreamUnmatchedSegment`가 위 mapping을 `commit_view`로 표현할 수 없다는 뜻인지, 현재 compiler lowering에서 아직 지원하지 않는 경로인지 확인 부탁드립니다.

3. 이와 같은 DM-to-DM 축 재배치에는 `commit_view` 대신 사용해야 하는 공식 API나 권장 mapping이 있을까요?

4. 중간 tensor를 HBM에 썼다가 다시 읽지 않고 같은 변환을 수행할 방법이 있다면 안내 부탁드립니다.

첨부 프로젝트에서 `./reproduce.sh`를 실행하면 두 커널을 차례로 컴파일합니다. 이후 성공 대조군의 새 binary와 실패 커널의 오류 메시지를 자동으로 확인합니다. 전체 소스와 성공 대조군 schedule, 두 커널의 compile log도 함께 넣었습니다.

안녕하세요, commit engine의 경우에, commit_trim으로 생성된 stream mapping과, write 대상의 Element mapping을 비교했을 때:

stream Packet과 Element의 innermost Packet::SIZE 만큼이 완전히 동일해야합니다.

해당 예제에서,

commit_trim의 output Packet: m![COLUMNS % 32],

Element: m![ROWS % 32, COLUMNS % 16 % 2, DIGIT_SLOT = 1 #{!} 8, COLUMNS / 16]

에서, Element % Packet::SIZE(=32) 는 [DIGIT_SLOT = 1 #{!} 2, COLUMNS / 16] 인데, 이것이 commit_trim의 output Packet과 다르기 때문에 commit engine에서 받아들일 수 없는 형태에 해당합니다.

이러한 형태를 컴파일 하기 위해서는, transpose engine을 이용하여 Element innermost와 commit_trim output Packet을 맞추는 방향으로 커널을 작성해야 합니다.

관련하여 commit engine의 에러 메세지를 더 친절하게 수정해두겠습니다.