Skip to content
Open
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
12 changes: 12 additions & 0 deletions .github/workflows/pr-gate.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -185,6 +185,18 @@ jobs:
toolchain/output/linx_blockisa_llvm_musl
key: llvm-${{ runner.os }}-tileop-required-gate-v2-${{ steps.llvm-source.outputs.sha }}

- name: Install candidate TileOP headers into the cached toolchain
run: |
set -euo pipefail
RESOURCE_DIR="$(${TOOLCHAIN_INSTALL_DIR}/bin/clang -print-resource-dir)"
mkdir -p "${RESOURCE_DIR}/include/tileop-api"
rsync -a --delete \
toolchain/src/Linx-TileOP-API/include/ \
"${RESOURCE_DIR}/include/tileop-api/"
cmp \
toolchain/src/Linx-TileOP-API/include/common/pto_tile.hpp \
"${RESOURCE_DIR}/include/tileop-api/common/pto_tile.hpp"

- name: Run TileOP contract checks
working-directory: toolchain/src/Linx-TileOP-API
env:
Expand Down
5 changes: 5 additions & 0 deletions docs/tileop-usage/tlsu/load-store-move/TLOAD.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,11 @@ PTO_SHARED_INLINE void TLOAD(SharedTile<shp> &dst, const gm_shape &src);

除通用 Tile 约束外,必须满足 PTO-SPEC 对本操作规定的操作数角色、数据类型组合、形状、布局、有效区域、容量、存储位置、PE mask 以及 alias 规则。对于需要 Shared Tile、标量、索引、scale、bias 或选项对象的重载,只能使用接口声明的参数形式;不能通过省略参数来伪造另一种操作数组合。

`B.IOR.RegSrc1` carries the GM row stride in **bytes**, not elements. The
ordinary, Shared, and CUBE transport overloads therefore derive the encoded
stride with `GetStrideBytes`; callers must not pre-scale or reinterpret that
value in element units.

## 默认值

未显式传入的可选参数使用该 C++ 重载和 PTO-SPEC contract 规定的默认值。默认选项、维度、布局、padding、scale mask 和属性字段可能与显式编码的零值不同;调用者不得把“省略”与“传入零值”自动等同。
Expand Down
35 changes: 20 additions & 15 deletions include/jcore/template_asm.hpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -6945,24 +6945,29 @@ void TPRELU(tile_shape &dst, tile_shape &src0, tile_shape &src1) {
}


// TSEL: select between two tiles using mask
// TSEL: select true_src where mask is set, otherwise preserve the prior dst.
// PTO requires the false source to be bound explicitly. Model the public
// in-place API as two B.IOT bindings and keep dst read/write so the second
// binding snapshots its old value before publishing the new destination.
template <is_tile_data_v tile_shape>
void TSEL(tile_shape &dst, tile_shape &src0, tile_shape &src1) {
void TSEL(tile_shape &dst, tile_shape &mask, tile_shape &true_src) {
asm volatile(
"BSTART.TEPL 26, %D1\n"
"B.DIM %2, 0, ->lb0\n"
"B.DIM %3, 0, ->lb1\n"
"B.DIM zero, %c4, ->lb2\n"
"B.IOT %5, %6, mask=1111, last, ->%0<%Z7>\n"
"BSTART.TEPL 26, %D[DataType]\n"
"B.DIM %[ValidCol], 0, ->lb0\n"
"B.DIM %[ValidRow], 0, ->lb1\n"
"B.DIM zero, %c[Cols], ->lb2\n"
"B.IOT %[Mask], %[True], mask=1111\n"
"B.IOT %[Prior], mask=1111, last, ->%[Dst]<%Z[TileSize]>\n"
""
: "=Tr"(dst.data())
: "i"(type_traits<typename tile_shape::DType>::TypeCode),
"r"(src0.GetValidCol()),
"r"(src0.GetValidRow()),
"i"(tile_shape::Cols),
"Tr"(src0.data()),
"Tr"(src1.data()),
"i"(tile_type_traits<typename tile_shape::TileDType>::TilesizeCode)
: [Dst] "=Tr"(dst.data())
: [Prior] "0"(dst.data()),
[DataType] "i"(type_traits<typename tile_shape::DType>::TypeCode),
[ValidCol] "r"(mask.GetValidCol()),
[ValidRow] "r"(mask.GetValidRow()),
[Cols] "i"(tile_shape::Cols),
[Mask] "Tr"(mask.data()),
[True] "Tr"(true_src.data()),
[TileSize] "i"(tile_type_traits<typename tile_shape::TileDType>::TilesizeCode)
);
}

Expand Down
15 changes: 15 additions & 0 deletions test/test_v058_engine_contract.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -200,6 +200,21 @@ def test_tlsu_load_store_stride_is_expressed_in_bytes(self) -> None:
tlsu_doc = (ROOT / "docs" / "tileop-usage" / "tlsu" / "load-store-move" / "TLOAD.md").read_text(encoding="utf-8")
self.assertIn("row stride in **bytes**", tlsu_doc)

def test_tsel_binds_the_prior_destination_as_explicit_false_source(self) -> None:
start = self.header.index("void TSEL(")
end = self.header.index("// TABS:", start)
tsel = self.header[start:end]
self.assertIn('"B.IOT %[Mask], %[True], mask=1111\\n"', tsel)
self.assertIn(
'"B.IOT %[Prior], mask=1111, last, ->%[Dst]<%Z[TileSize]>\\n"',
tsel,
)
self.assertIn(': [Dst] "=Tr"(dst.data())', tsel)
self.assertIn('[Prior] "0"(dst.data())', tsel)
self.assertNotIn(
'"B.IOT %5, %6, mask=1111, last, ->%0<%Z7>\\n"', tsel
)

def test_fpatr_carries_shared_transpose_controls(self) -> None:
tile = PTO_TILE.read_text(encoding="utf-8")
self.assertIn("bool TransA = false", tile)
Expand Down
11 changes: 11 additions & 0 deletions test/tileop_api/src/TSELCanonical.cpp
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
#include <common/pto_tileop.hpp>

using namespace pto;

using SelectTile = Tile<Location::Vec, uint16_t, 16, 16,
BLayout::RowMajor>;

void tsel_canonical(SelectTile &dst, SelectTile &mask,
SelectTile &true_src) {
TSEL(dst, mask, true_src);
}
33 changes: 32 additions & 1 deletion test/tileop_api/verify_target_cxx_frontend.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,9 +8,26 @@ ROOT=$(cd "$(dirname "$0")/../.." && pwd)
OUT=$(mktemp -d "${TMPDIR:-/tmp}/tileop-target-cxx.XXXXXX")
trap 'rm -rf "$OUT"' EXIT

# -mlxbc injects the TileOP headers installed in Clang's resource directory
# ahead of ordinary -I paths. Build a temporary resource overlay that keeps
# the toolchain's builtin headers but replaces only tileop-api with this
# checkout, otherwise this gate silently validates the packaged API instead of
# the proposed source tree.
CLANG_RESOURCE_DIR=$("$TC_DIR/clang++" -print-resource-dir)
CLANG_RESOURCE_OVERLAY="$OUT/clang-resource"
mkdir -p "$CLANG_RESOURCE_OVERLAY/include"
for resource_path in "$CLANG_RESOURCE_DIR"/include/*; do
resource_name=${resource_path##*/}
if [[ "$resource_name" != tileop-api ]]; then
ln -s "$resource_path" "$CLANG_RESOURCE_OVERLAY/include/$resource_name"
fi
done
ln -s "$ROOT/include" "$CLANG_RESOURCE_OVERLAY/include/tileop-api"

FLAGS=(
--target="$LINX_TARGET"
-mlxbc
-resource-dir="$CLANG_RESOURCE_OVERLAY"
--sysroot="$LINX_SYSROOT"
-nostdinc++
-isystem "$LINX_SYSROOT/include/c++/v1"
Expand All@@ -22,7 +39,7 @@ FLAGS=(
-I"$ROOT/include"
)

for source in MXScaleVariants.cpp SharedTransposeNonSquare.cpp; do
for source in MXScaleVariants.cpp SharedTransposeNonSquare.cpp TSELCanonical.cpp; do
"$TC_DIR/clang++" "${FLAGS[@]}" -fsyntax-only \
"$ROOT/test/tileop_api/src/$source"
done
Expand All@@ -33,7 +50,10 @@ done
"$ROOT/test/tileop_api/src/MXScaleVariants.cpp" -o "$OUT/MXScaleVariants.ll"
"$TC_DIR/clang++" "${FLAGS[@]}" -c \
"$ROOT/test/tileop_api/src/MXScaleVariants.cpp" -o "$OUT/MXScaleVariants.o"
"$TC_DIR/clang++" "${FLAGS[@]}" -c \
"$ROOT/test/tileop_api/src/TSELCanonical.cpp" -o "$OUT/TSELCanonical.o"
"$TC_DIR/llvm-objdump" -d "$OUT/MXScaleVariants.o" > "$OUT/MXScaleVariants.dis"
"$TC_DIR/llvm-objdump" -d "$OUT/TSELCanonical.o" > "$OUT/TSELCanonical.dis"
grep -q '<1024 x i32> asm sideeffect' "$OUT/SharedTLoad.ll"
grep -q 'i64 asm sideeffect.*=@2Sr' "$OUT/SharedTLoad.ll"
grep -q '<1024 x i32> asm sideeffect.*@2Sr' "$OUT/SharedTLoad.ll"
Expand DownExpand Up@@ -93,4 +113,15 @@ grep -Eiq 'BSTART\.CUBE[[:space:]]+TMATMULMX\.ACC,[[:space:]]+E4M3' "$OUT/MXScal
grep -Eiq 'BSTART\.CUBE[[:space:]]+TGEMVMX\.BIAS,[[:space:]]+BF16' "$OUT/MXScaleVariants.dis"
grep -Eq 'B\.IOT[[:space:]]+t#[1-8], t#[1-8], mask=1111' "$OUT/MXScaleVariants.dis"

grep -Eq 'B\.IOT[[:space:]]+[tumn]#[1-8], [tumn]#[1-8], mask=1111[[:space:]]*$' \
"$OUT/TSELCanonical.dis"
grep -Eq 'B\.IOT[[:space:]]+[tumn]#[1-8], mask=1111, last,.*->[tumn]<[0-9]+(B|KB)>' \
"$OUT/TSELCanonical.dis"
if grep -Eq 'B\.IOT[[:space:]]+[tumn]#[1-8], [tumn]#[1-8], mask=1111, last,.*->' \
"$OUT/TSELCanonical.dis"; then
echo "FAIL: TSEL collapsed to the forbidden single-B.IOT in-place form" >&2
sed -n '1,120p' "$OUT/TSELCanonical.dis" >&2
exit 1
fi

echo "Linx target C++ frontend MX/effective-shape contract: PASS"
19 changes: 19 additions & 0 deletions tools/generate_engine_docs.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -84,6 +84,25 @@ def render() -> str:
"The `BSTART.VEC` / `BSTART.SFU` spellings are canonical aliases of",
"the unique `BSTART.TEPL` compiled carrier (ADR 0057).",
"",
"## 使用要求",
"",
"优先根据操作页面中的 C++ API 调用 TileOP;本页仅用于按执行引擎查找操作。不要仅凭分类名称推断执行引擎,具体 engine 和支持的 Tile location 以操作页面为准。",
"",
"## 约束、默认值、异常和边界行为",
"",
"每个 engine 都有自己的 Tile、PE participation、容量和 bundle 约束。省略的 bundle 字段采用具体操作 contract 的默认值;非法 engine、binder、Tile location、mask 或属性组合会在执行前被拒绝。操作的边界、padding、异常和结果语义不由本索引页定义。",
"",
"## 使用示例",
"",
"```cpp",
"// 例如从 VEC 操作页面调用 C++ wrapper。",
"TADD(dst, lhs, rhs);",
"```",
"",
"## 完整语义",
"",
"各操作的完整语义请参阅其操作页面末尾的 PTO-SPEC 链接,规范总目录见 [PTO-SPEC tile 文档](https://github.com/PTO-ISA/pto-spec/tree/v0.58.4.1/docs/tile)。",
"",
]
)

Expand Down
Loading