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
7 changes: 7 additions & 0 deletions .github/workflows/pr-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,13 @@ jobs:
LINX_SYSROOT: ${{ env.TOOLCHAIN_INSTALL_DIR }}/sysroot
run: python3 test/test_llvm138_narrow_tcmp.py -v

- name: Check typed PredicateCell producer and consumers
working-directory: tileop-api
env:
LINX_CXX: ${{ env.TOOLCHAIN_INSTALL_DIR }}/bin/clang++
LINX_SYSROOT: ${{ env.TOOLCHAIN_INSTALL_DIR }}/sysroot
run: python3 test/test_predicate_adapters.py -v

- name: Run DType macro regression with associated APIs
working-directory: tileop-api
env:
Expand Down
3 changes: 3 additions & 0 deletions docs/tileop-usage/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ clang++ --target=linx64v5-unknown-linux-musl -mlxbc -fenable-matrix \
- 需要从 GM 传输数据时,阅读 [TLSU load/store/move](tlsu/load-store-move/TLOAD.md)。
其中卷积权重 GM 到 Shared NK 的 `OHWI2NK`/`OIHW2NK` 专用 `TLOAD` overload
也在该页面说明。
- 需要将 CUBE comparison predicate 交给 scatter 或 masked atomic-add 时,阅读
[实验性 PredicateCell adapters](predicate-adapters.md)。该接口仍在开发分支,
需要配套 compiler builtin,不代表当前发布工具链已经支持。
- 常规逐元素算子从 [TADD](elementwise-tile-tile/arithmetic/TADD.md) 开始;按目录选择
算术、逻辑、转换、归约、布局和不规则操作。
- PTO ISA v0.58.7 的 CUBE layout 重排操作从
Expand Down
31 changes: 31 additions & 0 deletions docs/tileop-usage/element-if.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,37 @@ void scalar_style(tile &out, const tile &lhs, const tile &rhs) {
if (ready) { } // 错误:下一条语句不是 for
```

### 1.3 与显式 PredicateCell API 的区别

Element-if 是编译器驱动的路径:开发者在 pragma 循环内写普通条件表达式,
由编译器构造、组合 predicate 并选择受支持的 masked 指令。通常不需要手工
创建或传递 predicate carrier。

开发分支另有独立的、尚未发布的
[PredicateCell adapters](predicate-adapters.md),供显式 TileOP 数据流使用:

```cpp
auto active = predicate::compare_scalar<CmpMode::GE>(values, threshold);
predicate::scatter(destination, byte_offsets, values, active);
predicate::atomic_add(destination, byte_offsets, values, active);
```

这条路径不要求 `#pragma pto element for`、`#pragma linx elementwise` 或
`TPARTELEMENT`,也不是供 pragma loop body 调用的入口。目前没有将
`Predicate<Basis>` 导入/导出 element-if 隐式 mask 的桥接接口,不能假设
把这些调用放进循环就能编译。

两条路径使用相同架构中的 predicate/ExecutionMask 概念,但公开支持边界
不同。显式 adapters 首版只覆盖 Local VEC CUBE_M32、静态有效区域和
FP32/S32/U32,尚无 predicate 逻辑组合;本页 element-if 已支持的组合条件
不能据此推广到 `Predicate<Basis>`。显式 `atomic_add` 使用 MSCATTER_ADD
ExecutionMask,本页 histogram 示例的已验收 profile 则使用 MGATHER.ADD,
不能互相替代其 dtype、memory-order、返回值或验证结论。

写普通逐元素条件时优先使用本页的 element-if;已有显式 Tile comparison、
需要把结果直接交给 scatter/atomic consumer 时,再选择实验性 adapters,
并满足其配套 compiler builtin 和独立类型约束。

## 2. 基本语法规则

推荐使用编译器容易证明的 canonical loop:
Expand Down
8 changes: 8 additions & 0 deletions docs/tileop-usage/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@
的 packed / one-column source 不能混用,编译期诊断见
[TCMP 约束](elementwise-tile-tile/logical/TCMP.md)。

## 实验性 PredicateCell adapters

`predicate::compare_scalar` 的强类型结果可以直接供给
`predicate::scatter`,或作为 `predicate::atomic_add<Invert>` 的
ExecutionMask。`Invert` 是编译期布尔参数,默认 false,不属于
`fixp::Options`。当前支持边界、byte-offset 单位和未支持的逻辑组合见
[PredicateCell adapters](predicate-adapters.md)。

## 1. 快速开始

普通计算直接使用基础重载;需要后处理时,在对应的 `TMATMUL*` 或 `TGEMV*` 调用中传入
Expand Down
97 changes: 97 additions & 0 deletions docs/tileop-usage/predicate-adapters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Typed PredicateCell adapters (experimental)

## Availability

This is an explicit TileOP API, **not an element-if-only interface**. It does
not require a pragma loop or `TPARTELEMENT`. For scalar-style conditionals in
element loops, use the [Element-if guide](element-if.md); that path constructs
predicates internally. There is currently no public bridge between its implicit
masks and `Predicate<Basis>`, and these adapter calls are not supported loop-body
operations. Sharing ISA predicate concepts does not make the two APIs or their
supported profiles interchangeable.

This is an **unreleased development-branch interface**, not a claim about an
installed SDK. It requires the matching LLVM compiler changes that introduce
`ew_mscatter_add_predicate`; existing MC ExecutionMask support alone is not
sufficient. Keep the new TileOP headers and matching compiler together. Do not
replace headers in an older installed SDK before that compiler dependency is
available.

Include `common/pto_tileop.hpp` when targeting Linx. The experimental
`pto::predicate` API keeps a comparison result distinct from ordinary numeric
Tiles and packed GPR predicates:

```cpp
auto active = pto::predicate::compare_scalar<pto::CmpMode::GE>(values, threshold);
pto::predicate::scatter(destination, byte_offsets, values, active);
pto::predicate::atomic_add(destination, byte_offsets, values, active);
pto::predicate::atomic_add<true>(destination, byte_offsets, values, active);
```

## Complete compile-only example

```cpp
#include <common/pto_tileop.hpp>

using namespace pto;
using Values = VecTileM32<uint32_t, 32, 4>;
using Offsets = VecTileM32<uint64_t, 32, 4>;
using Global = global_tensor<uint32_t, RowMajor<32, 4>>;

void predicate_consumers(Values &values, Offsets &byte_offsets,
Global &destination, uint32_t threshold) {
auto active = predicate::compare_scalar<CmpMode::GE>(values, threshold);
predicate::scatter(destination, byte_offsets, values, active);
predicate::atomic_add(destination, byte_offsets, values, active);
predicate::atomic_add<true>(destination, byte_offsets, values, active);
}
```

The caller must supply initialized Numeric CUBE operands. Offsets are already
byte displacements, not element indices; this API does not scale them by the
value element size. This example demonstrates compilation only, not a complete
kernel initialization sequence or a model execution test.

With the matching compiler, use the usual Linx target options and your SDK
sysroot/resource configuration:

```bash
clang++ --target=linx64v5-unknown-linux-musl -mlxbc -fenable-matrix \
-O2 -std=c++20 -D__linx -DENABLE_TENSOR_INSTR \
--sysroot="$LINX_SYSROOT" -I"$TILEOP_ROOT/include" \
-c predicate_consumers.cpp -o predicate_consumers.o
```

Ensure the compiler resource directory does not contain a stale TileOP include
tree that takes precedence over the selected headers.

## Carrier and consumer contract

The first implementation admits static valid shapes, Local VEC CUBE_M32,
FP32/S32/U32 comparison and value operands, and S64/U64 **byte displacements**.
The value type, valid region and layout must match the comparison basis.
Offsets may have a different physical capacity, but must cover that valid
region. `destination` must have the same element type as `values`.

`scatter` binds the PredicateCell directly to the explicit MSCATTER_MASK
operand. It does not convert it with TCVT or reinterpret it as an ordinary
numeric U8 Tile. This follows the executable
`IndexedTLSUPredicateDescriptorLegal` helper; the instruction-page wording
discrepancy is tracked in PTO-ISA/pto-spec #349.

`atomic_add` requires the compiler builtin `ew_mscatter_add_predicate` and
emits MSCATTER_ADD with a PredicateCell ExecutionMask. `true` inverts the
execution mask; this is not a new operation-owned atomic mask operand.
According to `GM_RED_VALUE`, inactive coordinates do not calculate indexed
addresses, probe memory or enqueue atomic RMWs. Structural legality checks
still apply. Replacing inactive addends with zero is not equivalent.

`Predicate<Basis>` cannot be default-constructed by callers or imported from
an arbitrary U8 Tile. Its carrier is intentionally private. Ordinary TAND is
not a PredicateCell logical operator. Predicate composition, GPR selection,
first-set-bit operations, dynamic valid shapes, M16 and cross-call predicate
ABI/spill support are not provided by this experimental interface. Keep
producer and consumers together in an optimized, inlined region.

Object/assembly compilation checks are not model execution or TopK numerical
validation. No ISA or model legality checks are relaxed by this interface.
15 changes: 14 additions & 1 deletion docs/tileop-usage/support-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,19 @@ rollback、definedness 或 memory-order 语义。

## 版本边界

### 开发分支中的 PredicateCell adapters(未发布)

`predicate::compare_scalar`、`predicate::scatter` 和
`predicate::atomic_add<Invert>` 的首版封装仅覆盖 Local VEC CUBE_M32、
静态有效区域、FP32/S32/U32 和 S64/U64 byte offsets。
atomic-add 依赖配套 LLVM 的 `ew_mscatter_add_predicate` builtin;
不能由 MC 已支持 ExecutionMask 推断已安装 compiler 也支持该 API。
目前验证包含对象生成、汇编 roundtrip 与负例,不包含完整 TopK 模型数值验收。
Predicate 逻辑组合、GPR 自动适配、M16 和跨调用/spill 不在首版支持范围。
示例、语义及依赖见 [PredicateCell adapters](predicate-adapters.md)。

### 已发布基线

- 当前 API/spec 基线:PTO ISA `0.58.7`,publication `0.58.7.0`,ABI
`pto-isa-0.58.7-mode-function-v1`。
- backend 能力必须分别判断:CPU simulator/JCORE wrapper、LLVM MC
Expand All @@ -39,4 +52,4 @@ rollback、definedness 或 memory-order 语义。
0.58.3 compiler、ELF identity 和旧 engine projection 不表示当前实现基线。
- 需要核对精确 fault ordering、completion、rollback、memory ordering 或编码位域时,
必须回到 `PTO-ISA/pto-spec` 对应 ASL/NDF owner;Markdown wrapper 文档不构成完整
规范镜像。
规范镜像。
8 changes: 8 additions & 0 deletions docs/tileop-usage/tile-scalar-and-immediate/logical/TCMPS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

`TCMPS` 按照 CMode 将每个有效 Tile 元素与每 PE 标量比较,并将谓词结果编码为 0 或 1。

### 实验性强类型生产者

开发分支新增 `predicate::compare_scalar<Mode>(source, scalar)`,返回私有
carrier 的 `Predicate<Basis>`,避免将 CUBE PredicateCell、普通 Numeric U8
和 packed GPR 混为同一类型。它是独立封装,不改变本页既有 `TCMPS` 重载。
直接 scatter、ExecutionMask atomic-add 及当前支持边界见
[PredicateCell adapters](../../predicate-adapters.md)。该接口尚未发布。

## C++ 接口

当前 API 中可用的调用形式:
Expand Down
9 changes: 9 additions & 0 deletions docs/tileop-usage/tlsu/memory/MSCATTER_ADD.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

## C++ 接口

### 实验性 ExecutionMask 消费者

开发分支提供 `predicate::atomic_add<Invert>(destination, byte_offsets, values, active)`。
它通过配套 compiler builtin 生成 PredicateCell ExecutionMask,而非为原始
MSCATTER_ADD 增加普通 source 操作数。`Invert` 默认为 false;inactive lane
不计算索引地址、不 probe、不发起 atomic RMW,结构合法性检查仍保留。
零 addend 不等价于屏蔽。该接口尚未发布,不改变下列既有重载;详见
[PredicateCell adapters](../../predicate-adapters.md)。

当前 API 中可用的调用形式:

```cpp
Expand Down
11 changes: 10 additions & 1 deletion docs/tileop-usage/tlsu/memory/MSCATTER_MASK.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

## C++ 接口

### 实验性 PredicateCell 消费者

开发分支提供 `predicate::scatter(destination, byte_offsets, values, active)`,
可直接消费 `predicate::compare_scalar` 返回的强类型 CUBE PredicateCell,
不插入 TCVT。它不是把普通 U8 Tile 强制转换成 PredicateCell,也不改变
下列既有重载。当前 executable ASL helper 接受这一 carrier,但指令页文字
仍有待 owner 对齐的差异;支持边界与说明见
[PredicateCell adapters](../../predicate-adapters.md)。该接口尚未发布。

当前 API 中可用的调用形式:

```cpp
Expand Down Expand Up @@ -125,4 +134,4 @@ void scatter_masked(float *base, const float *input, const uint32_t *offsets,
}
```

涉及标量、索引、scale 或 bias 的操作,请按上方实际重载替换示例参数。
涉及标量、索引、scale 或 bias 的操作,请按上方实际重载替换示例参数。
Loading
Loading