텐서 계산
텐서 계산에서는 유효한 Tensor Unit 스트림이 Vector Engine 또는 Contraction Engine에 도달하는 방식을 설명합니다. 한 피연산자는 Register File에 고정되어 머무르고, 다른 피연산자는 엔진을 통해 스트리밍됩니다. Tensor Register File(TRF)은 축약 피연산자를 저장하고, Vector Register File(VRF)은 벡터 피연산자를 저장합니다. 이 장에서는 피연산자를 배치하고 스트림 차원을 보존하는 엔진 동작을 설명합니다.
계산 경로 선택
| 커널 요구 사항 | 선택 | 다음에 읽을 동작 |
|---|---|---|
| 요소별 연산 또는 리덕션 | Vector Engine | 벡터 스트림 및 리덕션 계약 |
| matmul 또는 합성곱과 같은 축약 | Tensor Register File(TRF)과 Contraction Engine | TRF 레이아웃 및 축약 매핑 |
| Slice 간 재분배 또는 리덕션 | Switch Engine 또는 Inter-Slice Reducer | Slice 이동 및 리듀서 계약 |
| 레이아웃 또는 정밀도 변경 | Fetch/Commit Adapter, Cast Engine 또는 Transpose Engine | Adapter 단계와 출력 매핑 계약 |
Tensor Unit
Tensor Unit은 Chip 내부의 연산 파이프라인입니다. Tensor Unit은 DM에서 텐서 데이터를 읽고, 10개의 엔진을 거쳐 변환한 뒤, 결과를 다시 DM에 씁니다.
각 텐서는 사이클당 하나의 패킷씩, 패킷 스트림 형태로 파이프라인을 통과합니다. 엔진들은 이러한 스트림을 소비하고 생성하며, 그 과정에서 사이클별 레이아웃과 반복 순서를 재구성합니다. Collect Engine은 들어오는 패킷을 32바이트 플릿(flit)으로 정규화합니다. 모든 다운스트림 엔진은 이 플릿을 대상으로 동작합니다. 파이프라인에는 Contraction, Vector, Cast, Transpose, Commit Adapter, Commit이 포함됩니다. 링크된 엔진 페이지 Contraction, Vector, Cast, Transpose, Commit Adapter, Commit을 참조하십시오.
flowchart TB
subgraph SRAM
DM[(DM)] & TRF[(TRF)] & VRF[(VRF)]
end
subgraph TU[Tensor Unit]
direction LR
FE[Fetch] --> FA[Fetch Adapter] --> SW[Switching] --> CO[Collect] --> CE[Contraction] --> VE[Vector] --> CA[Cast] --> TR[Transpose] --> CMA[Commit Adapter] --> CM[Commit]
end
DM --> FE
CM --> DM
CO --> TRF --> CE
CO --> VRF --> VE
click FE "../moving-tensors/fetch-engine.html" "Fetch Engine"
click FA "./fetch-adapter.html" "Fetch Adapter"
click SW "./switch-engine.html" "Switch Engine"
click CO "./collect-engine.html" "Collect Engine"
click CE "./contraction-engine/index.html" "Contraction Engine"
click VE "./vector-engine/index.html" "Vector Engine"
click CA "./cast-engine.html" "Cast Engine"
click TR "./transpose-engine.html" "Transpose Engine"
click CMA "./commit-adapter.html" "Commit Adapter"
click CM "../moving-tensors/commit-engine.html" "Commit Engine"
| 엔진 | 기능 | 핵심 제약 조건 |
|---|---|---|
| Fetch | DM에서 파이프라인으로 데이터를 로드합니다 | 패킷은 8바이트 단위로 정렬되어야 합니다. 축 리프팅이 브로드캐스트를 Time의 축으로 대체하지 않는 한 Slice는 유지됩니다 |
| Fetch Adapter | 페치 후 요소별 변환(테이블 룩업, 캐스팅) | 선택 사항입니다. 생략하면 항등 변환입니다 |
| Switching | Slice 간에 데이터를 이동합니다 | 링 네트워크이며, Slice가 바뀔 수 있습니다 |
| Collect | 패킷을 32바이트 플릿으로 정규화 | 출력 = 정확히 하나의 플릿 |
| Contraction | Einsum: matmul, 합성곱, 어텐션 | 한 피연산자는 TRF에 상주합니다. 다른 피연산자는 스트리밍됩니다 |
| Vector | 요소별 연산, 이항 연산, 리덕션 연산 | i32/f32 입력만 가능합니다 |
| Cast | 배칭을 통한 정밀도 낮춤 | 출력 = 정확히 하나의 플릿 |
| Transpose | 플릿 내 요소 재정렬 | 플릿 내부 한정 |
| Commit Adapter | commit 이전 요소별 변환(캐스트, ReLU, trim) | 선택 사항입니다. .commit() 앞에 체이닝됩니다 |
| Commit | 결과를 DM에 다시 씁니다 | 플릿 정렬 쓰기 |
Tensor Unit 내부의 각 텐서 스트림은 [Chip, Cluster, Slice, Time, Packet]의 다섯 차원을 가지며, 이 차원은 두 그룹으로 나뉩니다. Chip, Cluster, Slice는 공간 차원입니다. 각 Slice는 자체 파이프라인 인스턴스를 실행하며, Slice는 Cluster 단위로, Cluster는 Chip 단위로 묶입니다. Time과 Packet은 Slice별 스트림을 나타냅니다(정의는 공간 차원과 시간 차원을 참조하십시오). 위의 엔진들은 파이프라인을 따라 Time / Packet의 형태를 바꿉니다. 대부분의 엔진은 공간 차원을 유지합니다. Switch는 Slice 간에 데이터를 이동합니다. Fetch의 축 리프팅은 Chip, Cluster 또는 Slice를 따라 서로 다른 DM 읽기 오프셋을 할당하여 축을 Time 밖으로 옮깁니다. Vector Inter-Slice Reducer는 Cluster 내의 256개 Slice를 결합합니다.
Contraction Engine과 Vector Engine은 각각 한 피연산자를 파이프라인 스트림에서, 다른 피연산자를 Slice별 전용 Register File에서 가져옵니다. TRF(Tensor Register File)는 Contraction Engine에 데이터를 공급하고, VRF(Vector Register File)는 Vector Engine에 데이터를 공급합니다. Collect Engine은 .to_trf()를 통해 TRF에, .to_vrf()를 통해 VRF에 씁니다. 두 Register File을 모두 사용하는 엔드투엔드 예제는 빠른 시작을 참조하십시오.
Fetch는 DM에서 읽고 Commit은 DM에 다시 씁니다. 이들의 상세한 Sequencer 동작은 여기가 아닌 텐서 이동에서 설명합니다.
실행 컨텍스트
스케줄러는 각 실행 컨텍스트를 독립적인 연산 스트림으로 취급합니다. 하드웨어는 다음 세 가지 실행 컨텍스트를 제공합니다:
- Main은 커널의 주요 연산을 위해 Tensor Unit 파이프라인을 구동합니다.
- Sub는 같은 파이프라인의 일부를 구동하며, 일반적으로 Main이 연산하는 동안 피연산자를 TRF / VRF로 미리 가져옵니다.
- DMA는 Tensor Unit 외부에서 DMA Engine만 단독으로 구동합니다.
Main 컨텍스트는 모든 Tensor Unit 엔진을 구동할 수 있습니다. Sub 컨텍스트에서는 Contraction Engine과 몇 가지 다른 기능을 사용할 수 없습니다. 그 외의 모든 것은 Main과 동일하게 적용됩니다.
컨텍스트 순서, 중첩, 리소스 충돌, 메모리 규칙 스케줄링은 스케줄에서 정의합니다.