Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,30 @@ void TCVT(DstTile &dst, SrcTile &src);

对于 `RowMajor`、`ColMajor` 等普通布局,源 Tile 和目标 Tile 必须满足以下条件:

- 物理 `Rows` 和 `Cols` 相同;
- **容量推导的物理行相同**(PTO ISA `PTO-TILE-TCVT` legality:"Source and
destination have equal Row, Col, ValidRow, and ValidCol. Their capacities
and packing independently match their own DataTypes.",其中 Row/Col 是
`DerivedTileRows = capacity × 8 / (物理Col × 元素位宽)` 的容量推导值,不是
C++ Tile 类型声明的逻辑 `Rows`/`Cols`);
- `ValidRow` 和 `ValidCol` 相同;
- 有效区域均包含在对应的物理 Tile 中;
- 源/目标 dtype 组合以及 Tile location 合法;
- 目标容量足以容纳转换结果。除适用的 Tile 容量和 shape 规则外,普通布局没有额外的固定字节数限制。

**窄化 dtype(如 bf16/fp32 → e8m0)注意**:B.IOT 目的 TSize 最小 128B,1 字节
窄类型的 `[Rows,1]` 列向量会被 `round_capacity` 抬到 128B 档,容量推导行数随之
翻倍(如 `[64,1]` e8m0 推导为 128 行),与 2 字节源(64 行)不再相等——这是 ISA
层面的非法编码(issue #42)。合法写法是把**两侧**的物理列声明为更大的 2 的幂
(如 `[64,2]`,`ValidCol` 保持 1):

```cpp
using SrcBf = Tile<Location::Vec, __bf16, 64, 2, BLayout::RowMajor, 64, 1>;
using DstE8 = Tile<Location::Vec, __fp8_e8m0, 64, 2, BLayout::RowMajor, 64, 1>;
// bf16 256B → DerivedTileRows = 256*8/(2*16) = 64
// e8m0 128B → DerivedTileRows = 128*8/(2*8) = 64 ✓ 相等,ISA 合法
TCVT(dst_e8, src_bf);
```

示例:

```cpp
Expand Down
31 changes: 27 additions & 4 deletions include/jcore/template_asm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,33 @@ asm volatile(
} else {
static_assert(!tile_shape_out::IsCubeLayout,
"TCVT to a CUBE layout requires a CUBE_M16/M32 source");
static_assert(tile_shape_out::Rows == tile_shape_in::Rows &&
tile_shape_out::Cols == tile_shape_in::Cols,
"ordinary TCVT source and destination must have identical "
"physical Rows/Cols");
// PTO ISA (PTO-TILE-TCVT legality): "Source and destination have equal
// Row, Col, ValidRow, and ValidCol. Their capacities and packing
// independently match their own DataTypes." Row/Col are the
// capacity-derived physical dimensions
// (DerivedTileRows = capacity*8 / (Col * elementBits),
// asl/tile/model/shape/rows-columns.asl), NOT the C++ logical Rows/Cols
// of the Tile type. A narrowing conversion (e.g. bf16 -> e8m0 [Rows,1])
// pads the destination to the 128B minimum TSize, which doubles its
// capacity-derived rows; the ISA-legal encoding declares a wider
// physical column on both sides (Col=2 keeps the derived rows equal
// while ValidCol stays 1). Enforce the ISA condition directly instead
// of requiring bitwise-identical C++ Rows/Cols (issue #42).
constexpr int SrcDerivedRows =
(tile_shape_in::StorageBytes * 8) /
(tile_shape_in::Cols *
type_traits<typename tile_shape_in::DType>::bits);
constexpr int DstDerivedRows =
(tile_shape_out::StorageBytes * 8) /
(tile_shape_out::Cols *
type_traits<typename tile_shape_out::DType>::bits);
static_assert(SrcDerivedRows == DstDerivedRows,
"ordinary TCVT source and destination must have equal "
"capacity-derived physical Rows (ISA PTO-TILE-TCVT: "
"DerivedTileRows(capacity, Col, dtype) must match; for a "
"narrowing dtype, declare a wider physical Col on both "
"sides, e.g. [Rows,2] with ValidCol=1, so the 128B "
"minimum TSize does not double the destination rows)");
static_assert(tile_shape_out::ValidRow == tile_shape_in::ValidRow &&
tile_shape_out::ValidCol == tile_shape_in::ValidCol,
"ordinary TCVT source and destination must have identical "
Expand Down
Loading