已合并
补充hf32模式支持及文档更新 #1133
init__zhb__创建于 22 天前
补充hf32模式支持及文档更新 #1133
已合并
共 36 个文件变更+545-258
| @@ -154,8 +154,8 @@ Kernel 对象(调优与特性查询) | |||
| 154 | 154 | ||
| 155 | 详细参考使用示例和 API 文档请参考下述文档: | 155 | 详细参考使用示例和 API 文档请参考下述文档: |
| 156 | - [Kernel API 基础文档](docs/kernel_api.md) | 156 | - [Kernel API 基础文档](docs/kernel_api.md) |
| 157 | - - OpTensor API 基础文档(文档暂缺) | 157 | + - [`OpTensor` 基础文档](docs/optensor_api.md) |
| 158 | - - [EVG API 基础文档](docs/evg_api.md) | 158 | + - [`EVG` 基础文档](docs/evg_api.md) |
为什么要带上cppgen的修改?缩小PR改动面 ![]() ![]() init__zhb__ 22 天前 评论: 22 天前 评论: | |||
| 159 | 159 | ||
| 160 | ### 4.1 基础 GEMM | 160 | ### 4.1 基础 GEMM |
| 161 | 161 | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | -# EVG API (Python) | 1 | +# `EVG` 基础文档 (Python) |
| 2 | 2 | ||
| 3 | -本节记录了 CATLASS 中 [EVG(Epilogue Visitor Graph)模块](../../../docs/zh/2_Design/03_evg/01_evg_design.md)的 Python API。EVG 将 Python 描述的 epilogue 后处理函数解析为 DAG,并生成对应的 C++ Visitor 代码。 | 3 | +本文档为 `catlass_cppgen` 中 [EVG(Epilogue Visitor Graph)模块](../../../docs/zh/2_Design/03_evg/01_evg_design.md)的使用说明。EVG 将 Python 描述的 epilogue 后处理函数解析为 DAG(Directed Acyclic Graph,有向无环图),并生成对应的 C++ Visitor 代码。 |
| 4 | 4 | ||
| 5 | 核心入口函数定义见 [`evg_extension.py`](../catlass_cppgen/catlass/evg_extension.py),节点与定义见 [`evg/`](../catlass_cppgen/catlass/evg/)。 | 5 | 核心入口函数定义见 [`evg_extension.py`](../catlass_cppgen/catlass/evg_extension.py),节点与定义见 [`evg/`](../catlass_cppgen/catlass/evg/)。 |
| 6 | 6 | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | -# OpTensor 基础 Api (Python) | 1 | +# `OpTensor` 基础文档 (Python) |
| 2 | 2 | ||
| 3 | -本文档详细描述了 `catlass_cppgen` 中所有支持的`OpTensor`创建方式,及关联的基础特性,如数据类型,布局分布等。 | 3 | +本文档为 `catlass_cppgen` 中 `OpTensor` 的使用说明,介绍其创建方法、基础特性(如数据类型,布局分布)等。 |
| 4 | 4 | ||
| 5 | --- | 5 | --- |
| 6 | 6 | ||
| @@ -1830,7 +1830,7 @@ class MmadOp(_ods_ir.OpView): | |||
| 1830 | 1830 | ||
| 1831 | _ODS_REGIONS = (0, True) | 1831 | _ODS_REGIONS = (0, True) |
| 1832 | 1832 | ||
| 1833 | - def __init__(self, acc, lhs, rhs, init_c, unit_flag, compute_order, *, loc=None, ip=None): | 1833 | + def __init__(self, acc, lhs, rhs, init_c, unit_flag, compute_order, hf32_mode, *, loc=None, ip=None): |
| 1834 | operands = [] | 1834 | operands = [] |
| 1835 | results = [] | 1835 | results = [] |
| 1836 | attributes = {} | 1836 | attributes = {} |
| @@ -1845,6 +1845,10 @@ class MmadOp(_ods_ir.OpView): | |||
| 1845 | isinstance(compute_order, _ods_ir.Attribute) or | 1845 | isinstance(compute_order, _ods_ir.Attribute) or |
| 1846 | not _ods_ir.AttrBuilder.contains('Tla_ComputeOrderAttr')) else | 1846 | not _ods_ir.AttrBuilder.contains('Tla_ComputeOrderAttr')) else |
| 1847 | _ods_ir.AttrBuilder.get('Tla_ComputeOrderAttr')(compute_order, context=_ods_context)) | 1847 | _ods_ir.AttrBuilder.get('Tla_ComputeOrderAttr')(compute_order, context=_ods_context)) |
| 1848 | + attributes["hf32_mode"] = (hf32_mode if ( | ||
| 1849 | + isinstance(hf32_mode, _ods_ir.Attribute) or | ||
| 1850 | + not _ods_ir.AttrBuilder.contains('Tla_HF32ModeAttr')) else | ||
| 1851 | + _ods_ir.AttrBuilder.get('Tla_HF32ModeAttr')(hf32_mode, context=_ods_context)) | ||
| 1848 | _ods_successors = None | 1852 | _ods_successors = None |
| 1849 | super().__init__(self.build_generic(attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)) | 1853 | super().__init__(self.build_generic(attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)) |
| 1850 | 1854 | ||
| @@ -1878,8 +1882,18 @@ class MmadOp(_ods_ir.OpView): | |||
| 1878 | raise ValueError("'None' not allowed as value for mandatory attributes") | 1882 | raise ValueError("'None' not allowed as value for mandatory attributes") |
| 1879 | self.operation.attributes["compute_order"] = value | 1883 | self.operation.attributes["compute_order"] = value |
| 1880 | 1884 | ||
| 1881 | -def mmad(acc, lhs, rhs, init_c, unit_flag, compute_order, *, loc=None, ip=None) -> _ods_ir.Operation: | 1885 | + @builtins.property |
| 1882 | - return _get_op_result_or_op_results(MmadOp(acc=acc, lhs=lhs, rhs=rhs, init_c=init_c, unit_flag=unit_flag, compute_order=compute_order, loc=loc, ip=ip)) | 1886 | + def hf32_mode(self): |
| 1887 | + return self.operation.attributes["hf32_mode"] | ||
| 1888 | + | ||
| 1889 | + | ||
| 1890 | + def hf32_mode(self, value): | ||
| 1891 | + if value is None: | ||
| 1892 | + raise ValueError("'None' not allowed as value for mandatory attributes") | ||
| 1893 | + self.operation.attributes["hf32_mode"] = value | ||
| 1894 | + | ||
| 1895 | +def mmad(acc, lhs, rhs, init_c, unit_flag, compute_order, hf32_mode, *, loc=None, ip=None) -> _ods_ir.Operation: | ||
| 1896 | + return _get_op_result_or_op_results(MmadOp(acc=acc, lhs=lhs, rhs=rhs, init_c=init_c, unit_flag=unit_flag, compute_order=compute_order, hf32_mode=hf32_mode, loc=loc, ip=ip)) | ||
| 1883 | 1897 | ||
| 1884 | 1898 | ||
| 1885 | class MulOp(_ods_ir.OpView): | 1899 | class MulOp(_ods_ir.OpView): |
| @@ -61,13 +61,14 @@ from .types import ( | |||
| 61 | _replace_flat_leaves_in_tree, | 61 | _replace_flat_leaves_in_tree, |
| 62 | ) | 62 | ) |
| 63 | from .params import ( | 63 | from .params import ( |
| 64 | - CopyParams, | ||
| 65 | - CopyL0C2DstParams, | ||
| 66 | - QuantMode, | ||
| 67 | - L0C2UBMode, | ||
| 68 | AtomicMode, | 64 | AtomicMode, |
| 65 | + HF32Mode, | ||
| 69 | ComputeOrder, | 66 | ComputeOrder, |
| 67 | + CopyL0C2DstParams, | ||
| 68 | + CopyParams, | ||
| 69 | + L0C2UBMode, | ||
| 70 | MemType, | 70 | MemType, |
| 71 | + QuantMode, | ||
| 71 | ) | 72 | ) |
| 72 | 73 | ||
| 73 | 74 | ||
| @@ -5180,6 +5181,7 @@ def mmad( | |||
| 5180 | init_c: bool | Bool | None = None, | 5181 | init_c: bool | Bool | None = None, |
| 5181 | unit_flag: IndexLike | None = None, | 5182 | unit_flag: IndexLike | None = None, |
| 5182 | compute_order: ComputeOrder = ComputeOrder.M_FIRST, | 5183 | compute_order: ComputeOrder = ComputeOrder.M_FIRST, |
| 5184 | + hf32_mode: HF32Mode = HF32Mode.HF32_DISABLE, | ||
| 5183 | loc: mlir_ir.Location | None = None, | 5185 | loc: mlir_ir.Location | None = None, |
| 5184 | **extra_kwargs: object, | 5186 | **extra_kwargs: object, |
| 5185 | ) -> None: | 5187 | ) -> None: |
| @@ -5196,6 +5198,8 @@ def mmad( | |||
| 5196 | - `unit_flag` (`IndexLike | None`): Unit-flag control bits; defaults to `0` | 5198 | - `unit_flag` (`IndexLike | None`): Unit-flag control bits; defaults to `0` |
| 5197 | when omitted. Optional, default `None`. | 5199 | when omitted. Optional, default `None`. |
| 5198 | - `compute_order` (`ComputeOrder`): M/N compute-direction priority; default `M_FIRST`. | 5200 | - `compute_order` (`ComputeOrder`): M/N compute-direction priority; default `M_FIRST`. |
| 5201 | + - `hf32_mode` (`HF32Mode`): HF32 rounding mode for FP32 operands in L0A/L0B | ||
| 5202 | + before the matrix multiply. Optional, default `HF32_DISABLE`. | ||
| 5199 | 5203 | ||
| 5200 | Constraints: | 5204 | Constraints: |
| 5201 | - Must be called inside a `@tla.kernel`-decorated kernel function. | 5205 | - Must be called inside a `@tla.kernel`-decorated kernel function. |
| @@ -5253,10 +5257,18 @@ def mmad( | |||
| 5253 | "tla.mmad attribute 'compute_order' must be a " | 5257 | "tla.mmad attribute 'compute_order' must be a " |
| 5254 | f"{ComputeOrder}, got {type(compute_order).__name__}" | 5258 | f"{ComputeOrder}, got {type(compute_order).__name__}" |
| 5255 | ) | 5259 | ) |
| 5260 | + if not isinstance(hf32_mode, HF32Mode): | ||
| 5261 | + raise TlaLoweringError( | ||
| 5262 | + "tla.mmad attribute 'hf32_mode' must be a " | ||
| 5263 | + f"{HF32Mode}, got {type(hf32_mode).__name__}" | ||
| 5264 | + ) | ||
| 5256 | ctx = loc.context if loc is not None else mlir_ir.Context.current | 5265 | ctx = loc.context if loc is not None else mlir_ir.Context.current |
| 5257 | compute_order_attr = mlir_ir.Attribute.parse( | 5266 | compute_order_attr = mlir_ir.Attribute.parse( |
| 5258 | f"#tla.compute_order<{str(compute_order)}>", context=ctx | 5267 | f"#tla.compute_order<{str(compute_order)}>", context=ctx |
| 5259 | ) | 5268 | ) |
| 5269 | + hf32_mode_attr = mlir_ir.Attribute.parse( | ||
| 5270 | + f"#tla.hf32_mode<{str(hf32_mode)}>", context=ctx | ||
| 5271 | + ) | ||
| 5260 | 5272 | ||
| 5261 | acc_value = _as_value(acc) | 5273 | acc_value = _as_value(acc) |
| 5262 | lhs_value = _as_value(lhs) | 5274 | lhs_value = _as_value(lhs) |
| @@ -5270,6 +5282,7 @@ def mmad( | |||
| 5270 | unit_flag_value, | 5282 | unit_flag_value, |
| 5271 | loc=loc, | 5283 | loc=loc, |
| 5272 | compute_order=compute_order_attr, | 5284 | compute_order=compute_order_attr, |
| 5285 | + hf32_mode=hf32_mode_attr, | ||
| 5273 | ) | 5286 | ) |
| 5274 | 5287 | ||
| 5275 | 5288 | ||
| @@ -33,6 +33,15 @@ class ComputeOrder(enum.IntEnum): | |||
| 33 | return self.name # "M_FIRST"/"N_FIRST" | 33 | return self.name # "M_FIRST"/"N_FIRST" |
| 34 | 34 | ||
| 35 | 35 | ||
| 36 | +class HF32Mode(enum.IntEnum): | ||
| 37 | + HF32_DISABLE = 0 | ||
| 38 | + HF32_NEAREST_ZERO = 1 | ||
| 39 | + HF32_NEAREST_EVEN = 2 | ||
| 40 | + | ||
| 41 | + def __str__(self): | ||
| 42 | + return self.name # "HF32_DISABLE"/"HF32_NEAREST_ZERO"/"HF32_NEAREST_EVEN" | ||
| 43 | + | ||
| 44 | + | ||
| 36 | class AtomicMode(enum.Enum): | 45 | class AtomicMode(enum.Enum): |
| 37 | """Atomic operation mode""" | 46 | """Atomic operation mode""" |
| 38 | 47 | ||
| @@ -382,6 +382,27 @@ def Tla_ComputeOrderAttr : Tla_EnumAttr<"ComputeOrder", "compute_order"> { | |||
| 382 | }]; | 382 | }]; |
| 383 | } | 383 | } |
| 384 | 384 | ||
| 385 | +// HF32Mode: mmad HF32 rounding mode (CTRL[46] enable, CTRL[47] rounding). | ||
| 386 | +// HF32_DISABLE(0) is the hardware default (no HF32 rounding). | ||
| 387 | +def Tla_HF32Mode_Disable : I32EnumAttrCase<"HF32_DISABLE", 0>; | ||
| 388 | +def Tla_HF32Mode_NearestZero : I32EnumAttrCase<"HF32_NEAREST_ZERO", 1>; | ||
| 389 | +def Tla_HF32Mode_NearestEven : I32EnumAttrCase<"HF32_NEAREST_EVEN", 2>; | ||
| 390 | +def Tla_HF32Mode_Enum : Tla_I32Enum<"HF32Mode", | ||
| 391 | + "mmad HF32 rounding mode", [ | ||
| 392 | + Tla_HF32Mode_Disable, Tla_HF32Mode_NearestZero, Tla_HF32Mode_NearestEven | ||
| 393 | +]>; | ||
| 394 | +def Tla_HF32ModeAttr : Tla_EnumAttr<"HF32Mode", "hf32_mode"> { | ||
| 395 | + let parameters = (ins EnumParameter<Tla_HF32Mode_Enum>:$value); | ||
| 396 | + let assemblyFormat = "`<` params `>`"; | ||
| 397 | + let description = [{ | ||
| 398 | + mmad HF32 rounding mode, lowered to SPR.CTRL[46]/CTRL[47]: | ||
| 399 | + | ||
| 400 | + - HF32_DISABLE (0): HF32 mode disabled (hardware default) | ||
| 401 | + - HF32_NEAREST_ZERO (1): f32 rounded to HF32 towards zero | ||
| 402 | + - HF32_NEAREST_EVEN (2): f32 rounded to HF32 to nearest even | ||
| 403 | + }]; | ||
| 404 | +} | ||
| 405 | + | ||
| 385 | // SatMode: overflow behaviour of the cast (AVE `sat` BoolAttr). | 406 | // SatMode: overflow behaviour of the cast (AVE `sat` BoolAttr). |
| 386 | def Tla_SatMode_Unknown : I32EnumAttrCase<"unknown", 0>; | 407 | def Tla_SatMode_Unknown : I32EnumAttrCase<"unknown", 0>; |
| 387 | def Tla_SatMode_Sat : I32EnumAttrCase<"sat", 1>; | 408 | def Tla_SatMode_Sat : I32EnumAttrCase<"sat", 1>; |
| @@ -857,10 +878,19 @@ def Tla_MmadOp : Tla_Op<"mmad", []> { | |||
| 857 | every mmad in a function agrees on the value it is emitted once at the | 878 | every mmad in a function agrees on the value it is emitted once at the |
| 858 | function entry; if a function mixes values it is emitted ahead of each mmad | 879 | function entry; if a function mixes values it is emitted ahead of each mmad |
| 859 | runtime call instead. | 880 | runtime call instead. |
| 881 | + | ||
| 882 | + ``hf32_mode`` is always supplied by the frontend. The lowering emits | ||
| 883 | + ``hivm.set_ctrl`` on ``CTRL[46]`` (enable HF32 rounding) and ``CTRL[47]`` | ||
| 884 | + (rounding mode, ``HF32_NEAREST_ZERO`` -> 1 / ``HF32_NEAREST_EVEN`` -> 0, | ||
| 885 | + mirroring ``AscendC::SetHF32Mode`` / ``AscendC::SetHF32TransMode``): when | ||
| 886 | + every mmad in a function agrees on the value it is emitted once at the | ||
| 887 | + function entry; if a function mixes values it is emitted ahead of each mmad | ||
| 888 | + runtime call instead. | ||
| 860 | }]; | 889 | }]; |
| 861 | let arguments = (ins Tla_TensorType:$acc, Tla_TensorType:$lhs, Tla_TensorType:$rhs, | 890 | let arguments = (ins Tla_TensorType:$acc, Tla_TensorType:$lhs, Tla_TensorType:$rhs, |
| 862 | I1:$init_c, I64:$unit_flag, | 891 | I1:$init_c, I64:$unit_flag, |
| 863 | - Tla_ComputeOrderAttr:$compute_order); | 892 | + Tla_ComputeOrderAttr:$compute_order, |
| 893 | + Tla_HF32ModeAttr:$hf32_mode); | ||
| 864 | let assemblyFormat = [{ | 894 | let assemblyFormat = [{ |
| 865 | $acc `,` $lhs `,` $rhs `,` $init_c `,` $unit_flag attr-dict `:` | 895 | $acc `,` $lhs `,` $rhs `,` $init_c `,` $unit_flag attr-dict `:` |
| 866 | qualified(type($acc)) `,` qualified(type($lhs)) `,` qualified(type($rhs)) `,` type($init_c) `,` type($unit_flag) | 896 | qualified(type($acc)) `,` qualified(type($lhs)) `,` qualified(type($rhs)) `,` type($init_c) `,` type($unit_flag) |
| @@ -224,6 +224,20 @@ Attribute TlaDialect::parseAttribute(DialectAsmParser& parser, Type type) const | |||
| 224 | return ::tla::ComputeOrderAttr::get(getContext(), *symbolized); | 224 | return ::tla::ComputeOrderAttr::get(getContext(), *symbolized); |
| 225 | } | 225 | } |
| 226 | 226 | ||
| 227 | + if (attrTag == "hf32_mode") { | ||
| 228 | + if (parser.parseLess()) | ||
| 229 | + return {}; | ||
| 230 | + StringRef modeKeyword; | ||
| 231 | + if (parser.parseKeyword(&modeKeyword) || parser.parseGreater()) | ||
| 232 | + return {}; | ||
| 233 | + auto symbolized = ::symbolizeHF32Mode(modeKeyword); | ||
| 234 | + if (!symbolized) { | ||
| 235 | + parser.emitError(parser.getNameLoc()) << "invalid tla.hf32_mode value: " << modeKeyword; | ||
| 236 | + return {}; | ||
| 237 | + } | ||
| 238 | + return ::tla::HF32ModeAttr::get(getContext(), *symbolized); | ||
| 239 | + } | ||
| 240 | + | ||
| 227 | StringRef mnemonic = attrTag; | 241 | StringRef mnemonic = attrTag; |
| 228 | Attribute value; | 242 | Attribute value; |
| 229 | OptionalParseResult parseResult = generatedAttributeParser(parser, &mnemonic, type, value); | 243 | OptionalParseResult parseResult = generatedAttributeParser(parser, &mnemonic, type, value); |
| @@ -279,6 +279,26 @@ mlir::LogicalResult MmadOp::verify() | |||
| 279 | { | 279 | { |
| 280 | if (!hasEnclosingRegion<CubeOp>(getOperation())) | 280 | if (!hasEnclosingRegion<CubeOp>(getOperation())) |
| 281 | return emitOpError("must be nested inside a tla.cube region"); | 281 | return emitOpError("must be nested inside a tla.cube region"); |
| 282 | + | ||
| 283 | + // HF32 rounding only applies to f32 L0A/L0B operands; requesting it for any | ||
| 284 | + // other source element type (f16/bf16/...) is meaningless and must be rejected. | ||
| 285 | + HF32Mode mode = getHf32Mode().getValue(); | ||
| 286 | + if (mode != HF32Mode::HF32_DISABLE) { | ||
| 287 | + auto checkF32SourceOperand = [&](TlaTensorType operandType, | ||
| 288 | + llvm::StringRef operandName) -> mlir::LogicalResult { | ||
| 289 | + mlir::Type elementType = operandType.getPtr().getPointee(); | ||
| 290 | + if (!elementType.isF32()) | ||
| 291 | + return emitOpError() << "hf32_mode " << stringifyHF32Mode(mode) << " requires f32 source operands, but " | ||
| 292 | + << operandName << " operand has element type " << elementType; | ||
| 293 | + return mlir::success(); | ||
| 294 | + }; | ||
| 295 | + | ||
| 296 | + if (failed(checkF32SourceOperand(getLhs().getType(), "lhs"))) | ||
| 297 | + return mlir::failure(); | ||
| 298 | + if (failed(checkF32SourceOperand(getRhs().getType(), "rhs"))) | ||
| 299 | + return mlir::failure(); | ||
| 300 | + } | ||
| 301 | + | ||
| 282 | return mlir::success(); | 302 | return mlir::success(); |
| 283 | } | 303 | } |
| 284 | 304 | ||
| @@ -20,16 +20,24 @@ namespace { | |||
| 20 | // CTRL[51] selects the mmad M/N compute-direction priority | 20 | // CTRL[51] selects the mmad M/N compute-direction priority |
| 21 | static constexpr unsigned int ComputeOrderBit = 51; | 21 | static constexpr unsigned int ComputeOrderBit = 51; |
| 22 | 22 | ||
| 23 | +// CTRL[46] enables the mmad HF32 rounding mode | ||
| 24 | +static constexpr unsigned int HF32ModeBit = 46; | ||
| 25 | + | ||
| 26 | +// CTRL[47] selects the mmad HF32 rounding mode: | ||
| 27 | +// 0 = NEAREST_EVEN (hardware default), 1 = NEAREST_ZERO | ||
| 28 | +static constexpr unsigned int HF32TransModeBit = 47; | ||
| 29 | + | ||
| 23 | struct LowerTlaMmadPattern : public OpRewritePattern<::tla::MmadOp> { | 30 | struct LowerTlaMmadPattern : public OpRewritePattern<::tla::MmadOp> { |
| 24 | LowerTlaMmadPattern( | 31 | LowerTlaMmadPattern( |
| 25 | MLIRContext* ctx, DenseMap<Value, TensorDescriptor>& tensorDescriptorByValue, | 32 | MLIRContext* ctx, DenseMap<Value, TensorDescriptor>& tensorDescriptorByValue, |
| 26 | SmallVectorImpl<Operation*>& toErase, DenseMap<Value, Value>& loweredMemrefByValue, | 33 | SmallVectorImpl<Operation*>& toErase, DenseMap<Value, Value>& loweredMemrefByValue, |
| 27 | - bool funcLevelComputeOrderSet) | 34 | + bool funcLevelComputeOrderSet, bool funcLevelHF32Set) |
| 28 | : OpRewritePattern<::tla::MmadOp>(ctx), | 35 | : OpRewritePattern<::tla::MmadOp>(ctx), |
| 29 | tensorDescriptorByValue(tensorDescriptorByValue), | 36 | tensorDescriptorByValue(tensorDescriptorByValue), |
| 30 | toErase(toErase), | 37 | toErase(toErase), |
| 31 | loweredMemrefByValue(loweredMemrefByValue), | 38 | loweredMemrefByValue(loweredMemrefByValue), |
| 32 | - funcLevelComputeOrderSet(funcLevelComputeOrderSet) | 39 | + funcLevelComputeOrderSet(funcLevelComputeOrderSet), |
| 40 | + funcLevelHF32Set(funcLevelHF32Set) | ||
| 33 | {} | 41 | {} |
| 34 | 42 | ||
| 35 | LogicalResult matchAndRewrite(::tla::MmadOp op, PatternRewriter& rewriter) const override | 43 | LogicalResult matchAndRewrite(::tla::MmadOp op, PatternRewriter& rewriter) const override |
| @@ -188,6 +196,14 @@ struct LowerTlaMmadPattern : public OpRewritePattern<::tla::MmadOp> { | |||
| 188 | bool isNFirst = computeOrderAttr.getValue() == ComputeOrder::N_FIRST; | 196 | bool isNFirst = computeOrderAttr.getValue() == ComputeOrder::N_FIRST; |
| 189 | rewriter.create<hivm::SetCtrlOp>(op.getLoc(), isNFirst, ComputeOrderBit); | 197 | rewriter.create<hivm::SetCtrlOp>(op.getLoc(), isNFirst, ComputeOrderBit); |
| 190 | } | 198 | } |
| 199 | + if (!funcLevelHF32Set) { | ||
| 200 | + auto modeAttr = op->getAttrOfType<::tla::HF32ModeAttr>("hf32_mode"); | ||
| 201 | + HF32Mode mode = modeAttr.getValue(); | ||
| 202 | + bool enableHF32 = mode != HF32Mode::HF32_DISABLE; | ||
| 203 | + bool nearestZero = mode == HF32Mode::HF32_NEAREST_ZERO; | ||
| 204 | + rewriter.create<hivm::SetCtrlOp>(op.getLoc(), enableHF32, HF32ModeBit); | ||
| 205 | + rewriter.create<hivm::SetCtrlOp>(op.getLoc(), nearestZero, HF32TransModeBit); | ||
| 206 | + } | ||
| 191 | rewriter.create<func::CallOp>(op.getLoc(), callee, operands); | 207 | rewriter.create<func::CallOp>(op.getLoc(), callee, operands); |
| 192 | toErase.push_back(op.getOperation()); | 208 | toErase.push_back(op.getOperation()); |
| 193 | return success(); | 209 | return success(); |
| @@ -198,6 +214,7 @@ private: | |||
| 198 | SmallVectorImpl<Operation*>& toErase; | 214 | SmallVectorImpl<Operation*>& toErase; |
| 199 | DenseMap<Value, Value>& loweredMemrefByValue; | 215 | DenseMap<Value, Value>& loweredMemrefByValue; |
| 200 | bool funcLevelComputeOrderSet; | 216 | bool funcLevelComputeOrderSet; |
| 217 | + bool funcLevelHF32Set; | ||
| 201 | }; | 218 | }; |
| 202 | 219 | ||
| 203 | struct LowerTlaCopyPattern : public OpRewritePattern<::tla::CopyOp> { | 220 | struct LowerTlaCopyPattern : public OpRewritePattern<::tla::CopyOp> { |
| @@ -531,8 +548,36 @@ public: | |||
| 531 | builder.create<hivm::SetCtrlOp>(funcOp.getLoc(), isNFirst, ComputeOrderBit); | 548 | builder.create<hivm::SetCtrlOp>(funcOp.getLoc(), isNFirst, ComputeOrderBit); |
| 532 | funcLevelComputeOrderSet = true; | 549 | funcLevelComputeOrderSet = true; |
| 533 | } | 550 | } |
| 551 | + | ||
| 552 | + // CTRL[46]/CTRL[47] (mmad HF32 rounding mode) are global and persist once | ||
| 553 | + // set, so when every mmad in this function agrees on hf32_mode they are set | ||
| 554 | + // once at the function entry. If the function mixes values the per-mmad path | ||
| 555 | + // in LowerTlaMmadPattern is used instead. | ||
| 556 | + std::optional<HF32Mode> funcLevelHF32Mode; | ||
| 557 | + bool HF32Conflict = false; | ||
| 558 | + root->walk([&](::tla::MmadOp op) { | ||
| 559 | + auto attr = op->getAttrOfType<::tla::HF32ModeAttr>("hf32_mode"); | ||
| 560 | + HF32Mode mode = attr.getValue(); | ||
| 561 | + if (funcLevelHF32Mode && *funcLevelHF32Mode != mode) | ||
| 562 | + HF32Conflict = true; | ||
| 563 | + else if (!funcLevelHF32Mode) | ||
| 564 | + funcLevelHF32Mode = mode; | ||
| 565 | + }); | ||
| 566 | + bool funcLevelHF32Set = false; | ||
| 567 | + if (funcLevelHF32Mode && !HF32Conflict) { | ||
| 568 | + Block& entry = funcOp.getBody().front(); | ||
| 569 | + PatternRewriter builder(funcOp.getContext()); | ||
| 570 | + builder.setInsertionPointToStart(&entry); | ||
| 571 | + HF32Mode mode = *funcLevelHF32Mode; | ||
| 572 | + bool enableHF32 = mode != HF32Mode::HF32_DISABLE; | ||
| 573 | + bool nearestZero = mode == HF32Mode::HF32_NEAREST_ZERO; | ||
| 574 | + builder.create<hivm::SetCtrlOp>(funcOp.getLoc(), enableHF32, HF32ModeBit); | ||
| 575 | + builder.create<hivm::SetCtrlOp>(funcOp.getLoc(), nearestZero, HF32TransModeBit); | ||
| 576 | + funcLevelHF32Set = true; | ||
| 577 | + } | ||
| 534 | LowerTlaMmadPattern lowerMmad( | 578 | LowerTlaMmadPattern lowerMmad( |
| 535 | - &getContext(), tensorDescriptorByValue, toErase, lowering.loweredMemrefByValue, funcLevelComputeOrderSet); | 579 | + &getContext(), tensorDescriptorByValue, toErase, lowering.loweredMemrefByValue, funcLevelComputeOrderSet, |
| 580 | + funcLevelHF32Set); | ||
| 536 | SmallVector<Operation*, 16> mmadOps; | 581 | SmallVector<Operation*, 16> mmadOps; |
| 537 | root->walk([&](Operation* op) { | 582 | root->walk([&](Operation* op) { |
| 538 | if (llvm::isa<::tla::MmadOp>(op)) | 583 | if (llvm::isa<::tla::MmadOp>(op)) |
| @@ -17,6 +17,12 @@ static constexpr unsigned int MaskControlBit = 56; | |||
| 17 | // CTRL[51] is the mmad M/N compute-direction priority bit. | 17 | // CTRL[51] is the mmad M/N compute-direction priority bit. |
| 18 | static constexpr unsigned int ComputeOrderBit = 51; | 18 | static constexpr unsigned int ComputeOrderBit = 51; |
| 19 | 19 | ||
| 20 | +// CTRL[46] is the mmad HF32 rounding-mode enable bit. | ||
| 21 | +static constexpr unsigned int HF32ModeBit = 46; | ||
| 22 | + | ||
| 23 | +// CTRL[47] is the mmad HF32 rounding-mode select bit. | ||
| 24 | +static constexpr unsigned int HF32TransModeBit = 47; | ||
| 25 | + | ||
| 20 | class TlaPrologueEpiloguePass : public PassWrapper<TlaPrologueEpiloguePass, OperationPass<ModuleOp>> { | 26 | class TlaPrologueEpiloguePass : public PassWrapper<TlaPrologueEpiloguePass, OperationPass<ModuleOp>> { |
| 21 | public: | 27 | public: |
| 22 | MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TlaPrologueEpiloguePass) | 28 | MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TlaPrologueEpiloguePass) |
| @@ -59,10 +65,12 @@ public: | |||
| 59 | Operation* lastBodyOp = terminator ? terminator->getPrevNode() : nullptr; | 65 | Operation* lastBodyOp = terminator ? terminator->getPrevNode() : nullptr; |
| 60 | if (auto barrier = llvm::dyn_cast_or_null<hivm::PipeBarrierOp>(lastBodyOp)) { | 66 | if (auto barrier = llvm::dyn_cast_or_null<hivm::PipeBarrierOp>(lastBodyOp)) { |
| 61 | if (barrier.getPipe().getPipe() == hivm::PIPE::PIPE_ALL) { | 67 | if (barrier.getPipe().getPipe() == hivm::PIPE::PIPE_ALL) { |
| 62 | - // Already has a trailing PIPE_ALL barrier: restore CTRL[51] to the | 68 | + // Already has a trailing PIPE_ALL barrier: restore CTRL[51] / CTRL[46] / |
| 63 | - // hardware default just before it. | 69 | + // CTRL[47] to the hardware defaults just before it. |
| 64 | builder.setInsertionPoint(barrier); | 70 | builder.setInsertionPoint(barrier); |
| 65 | builder.create<hivm::SetCtrlOp>(loc, /*enable=*/false, ComputeOrderBit); | 71 | builder.create<hivm::SetCtrlOp>(loc, /*enable=*/false, ComputeOrderBit); |
| 72 | + builder.create<hivm::SetCtrlOp>(loc, /*enable=*/false, HF32ModeBit); | ||
| 73 | + builder.create<hivm::SetCtrlOp>(loc, /*enable=*/false, HF32TransModeBit); | ||
| 66 | continue; | 74 | continue; |
| 67 | } | 75 | } |
| 68 | } | 76 | } |
| @@ -71,8 +79,11 @@ public: | |||
| 71 | builder.setInsertionPoint(terminator); | 79 | builder.setInsertionPoint(terminator); |
| 72 | else | 80 | else |
| 73 | builder.setInsertionPointToEnd(&entry); | 81 | builder.setInsertionPointToEnd(&entry); |
| 74 | - // Restore CTRL[51] to the hardware default, then add the trailing barrier. | 82 | + // Restore CTRL[51] / CTRL[46] / CTRL[47] to the hardware defaults, then add |
| 83 | + // the trailing barrier. | ||
| 75 | builder.create<hivm::SetCtrlOp>(loc, /*enable=*/false, ComputeOrderBit); | 84 | builder.create<hivm::SetCtrlOp>(loc, /*enable=*/false, ComputeOrderBit); |
| 85 | + builder.create<hivm::SetCtrlOp>(loc, /*enable=*/false, HF32ModeBit); | ||
| 86 | + builder.create<hivm::SetCtrlOp>(loc, /*enable=*/false, HF32TransModeBit); | ||
| 76 | builder.create<hivm::PipeBarrierOp>(loc, pipeAll); | 87 | builder.create<hivm::PipeBarrierOp>(loc, pipeAll); |
| 77 | } | 88 | } |
| 78 | } | 89 | } |
| @@ -42,7 +42,7 @@ Construction and views for front-end structured values such as Shape / Coord / S | |||
| 42 | 42 | ||
| 43 | ### `make_shape` | 43 | ### `make_shape` |
| 44 | 44 | ||
| 45 | -**Source:** [`catlass.core_api.make_shape`](../../catlass/core_api.py#L3505) | 45 | +**Source:** [`catlass.core_api.make_shape`](../../catlass/core_api.py#L3517) |
| 46 | 46 | ||
| 47 | Description: | 47 | Description: |
| 48 | 48 | ||
| @@ -86,7 +86,7 @@ zn_shape = tla.make_shape((16, 8), (16, 4)) | |||
| 86 | 86 | ||
| 87 | ### `make_coord` | 87 | ### `make_coord` |
| 88 | 88 | ||
| 89 | -**Source:** [`catlass.core_api.make_coord`](../../catlass/core_api.py#L3546) | 89 | +**Source:** [`catlass.core_api.make_coord`](../../catlass/core_api.py#L3558) |
| 90 | 90 | ||
| 91 | Description: | 91 | Description: |
| 92 | 92 | ||
| @@ -117,7 +117,7 @@ coord = tla.make_coord(block_row, 0) | |||
| 117 | 117 | ||
| 118 | ### `make_stride` | 118 | ### `make_stride` |
| 119 | 119 | ||
| 120 | -**Source:** [`catlass.core_api.make_stride`](../../catlass/core_api.py#L3575) | 120 | +**Source:** [`catlass.core_api.make_stride`](../../catlass/core_api.py#L3587) |
| 121 | 121 | ||
| 122 | Description: | 122 | Description: |
| 123 | 123 | ||
| @@ -179,7 +179,7 @@ nz_stride = tla.make_stride((1, 1024), (16, 256)) | |||
| 179 | 179 | ||
| 180 | ### `make_layout` | 180 | ### `make_layout` |
| 181 | 181 | ||
| 182 | -**Source:** [`catlass.core_api.make_layout`](../../catlass/core_api.py#L3635) | 182 | +**Source:** [`catlass.core_api.make_layout`](../../catlass/core_api.py#L3647) |
| 183 | 183 | ||
| 184 | Description: | 184 | Description: |
| 185 | 185 | ||
| @@ -242,7 +242,7 @@ zn = tla.make_layout( | |||
| 242 | 242 | ||
| 243 | ### `tile_view` | 243 | ### `tile_view` |
| 244 | 244 | ||
| 245 | -**Source:** [`catlass.core_api.tile_view`](../../catlass/core_api.py#L3804) | 245 | +**Source:** [`catlass.core_api.tile_view`](../../catlass/core_api.py#L3816) |
| 246 | 246 | ||
| 247 | Description: | 247 | Description: |
| 248 | 248 | ||
| @@ -277,7 +277,7 @@ tile = tla.tile_view( | |||
| 277 | 277 | ||
| 278 | ### `make_tensor` | 278 | ### `make_tensor` |
| 279 | 279 | ||
| 280 | -**Source:** [`catlass.core_api.make_tensor`](../../catlass/core_api.py#L3851) | 280 | +**Source:** [`catlass.core_api.make_tensor`](../../catlass/core_api.py#L3863) |
| 281 | 281 | ||
| 282 | Description: | 282 | Description: |
| 283 | 283 | ||
| @@ -322,7 +322,7 @@ tensor = tla.make_tensor(ptr, layout, coord=tla.make_coord(0, 0)) | |||
| 322 | 322 | ||
| 323 | ### `make_tensor_like` | 323 | ### `make_tensor_like` |
| 324 | 324 | ||
| 325 | -**Source:** [`catlass.core_api.make_tensor_like`](../../catlass/core_api.py#L4046) | 325 | +**Source:** [`catlass.core_api.make_tensor_like`](../../catlass/core_api.py#L4060) |
| 326 | 326 | ||
| 327 | Description: | 327 | Description: |
| 328 | 328 | ||
| @@ -356,7 +356,7 @@ dst = tla.make_tensor_like(ptr, like=src_tile, layoutTag=tla.arch.RowMajor) | |||
| 356 | 356 | ||
| 357 | ### `make_ptr` | 357 | ### `make_ptr` |
| 358 | 358 | ||
| 359 | -**Source:** [`catlass.core_api.make_ptr`](../../catlass/core_api.py#L7032) | 359 | +**Source:** [`catlass.core_api.make_ptr`](../../catlass/core_api.py#L7000) |
| 360 | 360 | ||
| 361 | Description: | 361 | Description: |
| 362 | 362 | ||
| @@ -391,7 +391,7 @@ ptr = tla.make_ptr(tla.Float16, addr, mem_space=tla.AddressSpace.gm) | |||
| 391 | 391 | ||
| 392 | ### `recast_ptr` | 392 | ### `recast_ptr` |
| 393 | 393 | ||
| 394 | -**Source:** [`catlass.core_api.recast_ptr`](../../catlass/core_api.py#L7086) | 394 | +**Source:** [`catlass.core_api.recast_ptr`](../../catlass/core_api.py#L7054) |
| 395 | 395 | ||
| 396 | Description: | 396 | Description: |
| 397 | 397 | ||
| @@ -427,12 +427,12 @@ Tensor copies between on-chip and global memory, and UB register load/store. | |||
| 427 | 427 | ||
| 428 | ### `copy` | 428 | ### `copy` |
| 429 | 429 | ||
| 430 | -**Source:** [`catlass.core_api.copy`](../../catlass/core_api.py#L4240) | 430 | +**Source:** [`catlass.core_api.copy`](../../catlass/core_api.py#L4250) |
| 431 | 431 | ||
| 432 | Description: | 432 | Description: |
| 433 | 433 | ||
| 434 | Copy data between tiles. The hardware path follows `src`/`dst` address spaces | 434 | Copy data between tiles. The hardware path follows `src`/`dst` address spaces |
| 435 | -(vector: GM↔UB, UB→L1; cube: GM→L1, L1→L0A/L0B, L0C→GM|UB, L1→UB). | 435 | +(vector: GM↔UB, UB→L1; cube: GM→L1, L1→L0A/L0B, L0C→GM|UB|L1, L1→UB). |
| 436 | Layout tags on the tiles select format conversion (for example ND→zN). | 436 | Layout tags on the tiles select format conversion (for example ND→zN). |
| 437 | 437 | ||
| 438 | Copy / tiling sizes follow each tile's logical `origin_shape` | 438 | Copy / tiling sizes follow each tile's logical `origin_shape` |
| @@ -592,7 +592,7 @@ Cube-side matrix multiply-accumulate (`tla.mmad`). | |||
| 592 | 592 | ||
| 593 | ### `mmad` | 593 | ### `mmad` |
| 594 | 594 | ||
| 595 | -**Source:** [`catlass.core_api.mmad`](../../catlass/core_api.py#L5176) | 595 | +**Source:** [`catlass.core_api.mmad`](../../catlass/core_api.py#L5134) |
| 596 | 596 | ||
| 597 | Description: | 597 | Description: |
| 598 | 598 | ||
| @@ -601,7 +601,7 @@ Emit matrix-multiply-accumulate on TLA tiles. | |||
| 601 | Prototype: | 601 | Prototype: |
| 602 | 602 | ||
| 603 | ```python | 603 | ```python |
| 604 | -tla.mmad(acc: Tensor, lhs: Tensor, rhs: Tensor, init_c: bool | Bool | None = None, unit_flag: IndexLike | None = None, compute_order: ComputeOrder = ComputeOrder.M_FIRST, **extra_kwargs: object) -> None | 604 | +tla.mmad(acc: Tensor, lhs: Tensor, rhs: Tensor, init_c: bool | Bool | None = None, unit_flag: IndexLike | None = None, compute_order: ComputeOrder = ComputeOrder.M_FIRST, hf32_mode: HF32Mode = HF32Mode.HF32_DISABLE, **extra_kwargs: object) -> None |
| 605 | ``` | 605 | ``` |
| 606 | 606 | ||
| 607 | Parameters: | 607 | Parameters: |
| @@ -614,6 +614,8 @@ Parameters: | |||
| 614 | - `unit_flag` (`IndexLike | None`): Unit-flag control bits; defaults to `0` | 614 | - `unit_flag` (`IndexLike | None`): Unit-flag control bits; defaults to `0` |
| 615 | when omitted. Optional, default `None`. | 615 | when omitted. Optional, default `None`. |
| 616 | - `compute_order` (`ComputeOrder`): M/N compute-direction priority; default `M_FIRST`. | 616 | - `compute_order` (`ComputeOrder`): M/N compute-direction priority; default `M_FIRST`. |
| 617 | +- `hf32_mode` (`HF32Mode`): HF32 rounding mode for FP32 operands in L0A/L0B | ||
中文文档也对应改一下 ![]() ![]() | |||
| 618 | + before the matrix multiply. Optional, default `HF32_DISABLE`. | ||
| 617 | 619 | ||
| 618 | Constraints: | 620 | Constraints: |
| 619 | 621 | ||
| @@ -643,7 +645,7 @@ Mask creation and tail-mask updates. | |||
| 643 | 645 | ||
| 644 | #### `create_mask` | 646 | #### `create_mask` |
| 645 | 647 | ||
| 646 | -**Source:** [`catlass.core_api.create_mask`](../../catlass/core_api.py#L7344) | 648 | +**Source:** [`catlass.core_api.create_mask`](../../catlass/core_api.py#L7312) |
| 647 | 649 | ||
| 648 | Description: | 650 | Description: |
| 649 | 651 | ||
| @@ -699,7 +701,7 @@ with tla.vec.func(mode="simd"): | |||
| 699 | 701 | ||
| 700 | #### `update_mask` | 702 | #### `update_mask` |
| 701 | 703 | ||
| 702 | -**Source:** [`catlass.core_api.update_mask`](../../catlass/core_api.py#L7408) | 704 | +**Source:** [`catlass.core_api.update_mask`](../../catlass/core_api.py#L7378) |
| 703 | 705 | ||
| 704 | Description: | 706 | Description: |
| 705 | 707 | ||
| @@ -736,7 +738,7 @@ Element-wise arithmetic and unary math ops. `VectorSSA` overloads `+` / `-` / `* | |||
| 736 | 738 | ||
| 737 | #### `exp` | 739 | #### `exp` |
| 738 | 740 | ||
| 739 | -**Source:** [`catlass.core_api.exp`](../../catlass/core_api.py#L5768) | 741 | +**Source:** [`catlass.core_api.exp`](../../catlass/core_api.py#L5731) |
| 740 | 742 | ||
| 741 | Description: | 743 | Description: |
| 742 | 744 | ||
| @@ -769,7 +771,7 @@ with tla.vec.func(mode="simd"): | |||
| 769 | 771 | ||
| 770 | #### `log` | 772 | #### `log` |
| 771 | 773 | ||
| 772 | -**Source:** [`catlass.core_api.log`](../../catlass/core_api.py#L5790) | 774 | +**Source:** [`catlass.core_api.log`](../../catlass/core_api.py#L5753) |
| 773 | 775 | ||
| 774 | Description: | 776 | Description: |
| 775 | 777 | ||
| @@ -802,7 +804,7 @@ with tla.vec.func(mode="simd"): | |||
| 802 | 804 | ||
| 803 | #### `sqrt` | 805 | #### `sqrt` |
| 804 | 806 | ||
| 805 | -**Source:** [`catlass.core_api.sqrt`](../../catlass/core_api.py#L5812) | 807 | +**Source:** [`catlass.core_api.sqrt`](../../catlass/core_api.py#L5775) |
| 806 | 808 | ||
| 807 | Description: | 809 | Description: |
| 808 | 810 | ||
| @@ -835,7 +837,7 @@ with tla.vec.func(mode="simd"): | |||
| 835 | 837 | ||
| 836 | #### `abs` | 838 | #### `abs` |
| 837 | 839 | ||
| 838 | -**Source:** [`catlass.core_api.abs`](../../catlass/core_api.py#L5834) | 840 | +**Source:** [`catlass.core_api.abs`](../../catlass/core_api.py#L5797) |
| 839 | 841 | ||
| 840 | Description: | 842 | Description: |
| 841 | 843 | ||
| @@ -868,7 +870,7 @@ with tla.vec.func(mode="simd"): | |||
| 868 | 870 | ||
| 869 | #### `neg` | 871 | #### `neg` |
| 870 | 872 | ||
| 871 | -**Source:** [`catlass.core_api.neg`](../../catlass/core_api.py#L5856) | 873 | +**Source:** [`catlass.core_api.neg`](../../catlass/core_api.py#L5819) |
| 872 | 874 | ||
| 873 | Description: | 875 | Description: |
| 874 | 876 | ||
| @@ -901,7 +903,7 @@ with tla.vec.func(mode="simd"): | |||
| 901 | 903 | ||
| 902 | #### `add` | 904 | #### `add` |
| 903 | 905 | ||
| 904 | -**Source:** [`catlass.core_api.add`](../../catlass/core_api.py#L6035) | 906 | +**Source:** [`catlass.core_api.add`](../../catlass/core_api.py#L5999) |
| 905 | 907 | ||
| 906 | Description: | 908 | Description: |
| 907 | 909 | ||
| @@ -942,7 +944,7 @@ with tla.vec.func(mode="simd"): | |||
| 942 | 944 | ||
| 943 | #### `sub` | 945 | #### `sub` |
| 944 | 946 | ||
| 945 | -**Source:** [`catlass.core_api.sub`](../../catlass/core_api.py#L6081) | 947 | +**Source:** [`catlass.core_api.sub`](../../catlass/core_api.py#L6045) |
| 946 | 948 | ||
| 947 | Description: | 949 | Description: |
| 948 | 950 | ||
| @@ -980,7 +982,7 @@ with tla.vec.func(mode="simd"): | |||
| 980 | 982 | ||
| 981 | #### `mul` | 983 | #### `mul` |
| 982 | 984 | ||
| 983 | -**Source:** [`catlass.core_api.mul`](../../catlass/core_api.py#L6118) | 985 | +**Source:** [`catlass.core_api.mul`](../../catlass/core_api.py#L6082) |
| 984 | 986 | ||
| 985 | Description: | 987 | Description: |
| 986 | 988 | ||
| @@ -1019,7 +1021,7 @@ with tla.vec.func(mode="simd"): | |||
| 1019 | 1021 | ||
| 1020 | #### `max` | 1022 | #### `max` |
| 1021 | 1023 | ||
| 1022 | -**Source:** [`catlass.core_api.max`](../../catlass/core_api.py#L6163) | 1024 | +**Source:** [`catlass.core_api.max`](../../catlass/core_api.py#L6127) |
| 1023 | 1025 | ||
| 1024 | Description: | 1026 | Description: |
| 1025 | 1027 | ||
| @@ -1053,7 +1055,7 @@ with tla.vec.func(mode="simd"): | |||
| 1053 | 1055 | ||
| 1054 | #### `min` | 1056 | #### `min` |
| 1055 | 1057 | ||
| 1056 | -**Source:** [`catlass.core_api.min`](../../catlass/core_api.py#L6203) | 1058 | +**Source:** [`catlass.core_api.min`](../../catlass/core_api.py#L6167) |
| 1057 | 1059 | ||
| 1058 | Description: | 1060 | Description: |
| 1059 | 1061 | ||
| @@ -1087,7 +1089,7 @@ with tla.vec.func(mode="simd"): | |||
| 1087 | 1089 | ||
| 1088 | #### `div` | 1090 | #### `div` |
| 1089 | 1091 | ||
| 1090 | -**Source:** [`catlass.core_api.div`](../../catlass/core_api.py#L6243) | 1092 | +**Source:** [`catlass.core_api.div`](../../catlass/core_api.py#L6207) |
| 1091 | 1093 | ||
| 1092 | Description: | 1094 | Description: |
| 1093 | 1095 | ||
| @@ -1129,7 +1131,7 @@ Bitwise and logical ops on Mask / Vector. | |||
| 1129 | 1131 | ||
| 1130 | #### `bitwise_not` | 1132 | #### `bitwise_not` |
| 1131 | 1133 | ||
| 1132 | -**Source:** [`catlass.core_api.bitwise_not`](../../catlass/core_api.py#L6001) | 1134 | +**Source:** [`catlass.core_api.bitwise_not`](../../catlass/core_api.py#L5965) |
| 1133 | 1135 | ||
| 1134 | Description: | 1136 | Description: |
| 1135 | 1137 | ||
| @@ -1162,7 +1164,7 @@ with tla.vec.func(mode="simd"): | |||
| 1162 | 1164 | ||
| 1163 | #### `bitwise_and` | 1165 | #### `bitwise_and` |
| 1164 | 1166 | ||
| 1165 | -**Source:** [`catlass.core_api.bitwise_and`](../../catlass/core_api.py#L6610) | 1167 | +**Source:** [`catlass.core_api.bitwise_and`](../../catlass/core_api.py#L6576) |
| 1166 | 1168 | ||
| 1167 | Description: | 1169 | Description: |
| 1168 | 1170 | ||
| @@ -1196,7 +1198,7 @@ with tla.vec.func(mode="simd"): | |||
| 1196 | 1198 | ||
| 1197 | #### `bitwise_or` | 1199 | #### `bitwise_or` |
| 1198 | 1200 | ||
| 1199 | -**Source:** [`catlass.core_api.bitwise_or`](../../catlass/core_api.py#L6648) | 1201 | +**Source:** [`catlass.core_api.bitwise_or`](../../catlass/core_api.py#L6614) |
| 1200 | 1202 | ||
| 1201 | Description: | 1203 | Description: |
| 1202 | 1204 | ||
| @@ -1230,7 +1232,7 @@ with tla.vec.func(mode="simd"): | |||
| 1230 | 1232 | ||
| 1231 | #### `bitwise_xor` | 1233 | #### `bitwise_xor` |
| 1232 | 1234 | ||
| 1233 | -**Source:** [`catlass.core_api.bitwise_xor`](../../catlass/core_api.py#L6686) | 1235 | +**Source:** [`catlass.core_api.bitwise_xor`](../../catlass/core_api.py#L6652) |
| 1234 | 1236 | ||
| 1235 | Description: | 1237 | Description: |
| 1236 | 1238 | ||
| @@ -1268,7 +1270,7 @@ Vector compares that produce masks, and masked select. | |||
| 1268 | 1270 | ||
| 1269 | #### `where` | 1271 | #### `where` |
| 1270 | 1272 | ||
| 1271 | -**Source:** [`catlass.core_api.where`](../../catlass/core_api.py#L6327) | 1273 | +**Source:** [`catlass.core_api.where`](../../catlass/core_api.py#L6291) |
| 1272 | 1274 | ||
| 1273 | Description: | 1275 | Description: |
| 1274 | 1276 | ||
| @@ -1302,7 +1304,7 @@ with tla.vec.func(mode="simd"): | |||
| 1302 | 1304 | ||
| 1303 | #### `cmp` | 1305 | #### `cmp` |
| 1304 | 1306 | ||
| 1305 | -**Source:** [`catlass.core_api.cmp`](../../catlass/core_api.py#L6534) | 1307 | +**Source:** [`catlass.core_api.cmp`](../../catlass/core_api.py#L6498) |
| 1306 | 1308 | ||
| 1307 | Description: | 1309 | Description: |
| 1308 | 1310 | ||
| @@ -1341,7 +1343,7 @@ Constant fill and lane-index sequence construction. | |||
| 1341 | 1343 | ||
| 1342 | #### `full` | 1344 | #### `full` |
| 1343 | 1345 | ||
| 1344 | -**Source:** [`catlass.core_api.full`](../../catlass/core_api.py#L5277) | 1346 | +**Source:** [`catlass.core_api.full`](../../catlass/core_api.py#L5243) |
| 1345 | 1347 | ||
| 1346 | Description: | 1348 | Description: |
| 1347 | 1349 | ||
| @@ -1374,7 +1376,7 @@ with tla.vec.func(mode="simd"): | |||
| 1374 | 1376 | ||
| 1375 | #### `arange` | 1377 | #### `arange` |
| 1376 | 1378 | ||
| 1377 | -**Source:** [`catlass.core_api.arange`](../../catlass/core_api.py#L5350) | 1379 | +**Source:** [`catlass.core_api.arange`](../../catlass/core_api.py#L5316) |
| 1378 | 1380 | ||
| 1379 | Description: | 1381 | Description: |
| 1380 | 1382 | ||
| @@ -1412,7 +1414,7 @@ Gather elements from a UB tensor by index. | |||
| 1412 | 1414 | ||
| 1413 | #### `gather` | 1415 | #### `gather` |
| 1414 | 1416 | ||
| 1415 | -**Source:** [`catlass.core_api.gather`](../../catlass/core_api.py#L6724) | 1417 | +**Source:** [`catlass.core_api.gather`](../../catlass/core_api.py#L6690) |
| 1416 | 1418 | ||
| 1417 | Description: | 1419 | Description: |
| 1418 | 1420 | ||
| @@ -1450,7 +1452,7 @@ Interleave / deinterleave and related lane reshuffles. | |||
| 1450 | 1452 | ||
| 1451 | #### `interleave` | 1453 | #### `interleave` |
| 1452 | 1454 | ||
| 1453 | -**Source:** [`catlass.core_api.interleave`](../../catlass/core_api.py#L5894) | 1455 | +**Source:** [`catlass.core_api.interleave`](../../catlass/core_api.py#L5856) |
| 1454 | 1456 | ||
| 1455 | Description: | 1457 | Description: |
| 1456 | 1458 | ||
| @@ -1483,7 +1485,7 @@ with tla.vec.func(mode="simd"): | |||
| 1483 | 1485 | ||
| 1484 | #### `deinterleave` | 1486 | #### `deinterleave` |
| 1485 | 1487 | ||
| 1486 | -**Source:** [`catlass.core_api.deinterleave`](../../catlass/core_api.py#L5947) | 1488 | +**Source:** [`catlass.core_api.deinterleave`](../../catlass/core_api.py#L5910) |
| 1487 | 1489 | ||
| 1488 | Description: | 1490 | Description: |
| 1489 | 1491 | ||
| @@ -1520,7 +1522,7 @@ Compress valid lanes under a mask. | |||
| 1520 | 1522 | ||
| 1521 | #### `squeeze` | 1523 | #### `squeeze` |
| 1522 | 1524 | ||
| 1523 | -**Source:** [`catlass.core_api.squeeze`](../../catlass/core_api.py#L6381) | 1525 | +**Source:** [`catlass.core_api.squeeze`](../../catlass/core_api.py#L6345) |
| 1524 | 1526 | ||
| 1525 | Description: | 1527 | Description: |
| 1526 | 1528 | ||
| @@ -1557,7 +1559,7 @@ In-core / cross-core flags, pipe barriers, mutexes, and local-memory barriers. | |||
| 1557 | 1559 | ||
| 1558 | ### `flag` | 1560 | ### `flag` |
| 1559 | 1561 | ||
| 1560 | -**Source:** [`catlass.core_api.flag`](../../catlass/core_api.py#L4473) | 1562 | +**Source:** [`catlass.core_api.flag`](../../catlass/core_api.py#L4442) |
| 1561 | 1563 | ||
| 1562 | Description: | 1564 | Description: |
| 1563 | 1565 | ||
| @@ -1595,7 +1597,7 @@ with tla.vector(): | |||
| 1595 | 1597 | ||
| 1596 | ### `cross_flag` | 1598 | ### `cross_flag` |
| 1597 | 1599 | ||
| 1598 | -**Source:** [`catlass.core_api.cross_flag`](../../catlass/core_api.py#L4526) | 1600 | +**Source:** [`catlass.core_api.cross_flag`](../../catlass/core_api.py#L4495) |
| 1599 | 1601 | ||
| 1600 | Description: | 1602 | Description: |
| 1601 | 1603 | ||
| @@ -1627,7 +1629,7 @@ cf = tla.cross_flag("aic_aiv", mode=2) | |||
| 1627 | 1629 | ||
| 1628 | ### `cross_core_set_flag` | 1630 | ### `cross_core_set_flag` |
| 1629 | 1631 | ||
| 1630 | -**Source:** [`catlass.core_api.cross_core_set_flag`](../../catlass/core_api.py#L4602) | 1632 | +**Source:** [`catlass.core_api.cross_core_set_flag`](../../catlass/core_api.py#L4567) |
| 1631 | 1633 | ||
| 1632 | Description: | 1634 | Description: |
| 1633 | 1635 | ||
| @@ -1662,7 +1664,7 @@ with tla.cube(): | |||
| 1662 | 1664 | ||
| 1663 | ### `cross_core_wait_flag` | 1665 | ### `cross_core_wait_flag` |
| 1664 | 1666 | ||
| 1665 | -**Source:** [`catlass.core_api.cross_core_wait_flag`](../../catlass/core_api.py#L4646) | 1667 | +**Source:** [`catlass.core_api.cross_core_wait_flag`](../../catlass/core_api.py#L4613) |
| 1666 | 1668 | ||
| 1667 | Description: | 1669 | Description: |
| 1668 | 1670 | ||
| @@ -1696,7 +1698,7 @@ with tla.vector(): | |||
| 1696 | 1698 | ||
| 1697 | ### `set_flag` | 1699 | ### `set_flag` |
| 1698 | 1700 | ||
| 1699 | -**Source:** [`catlass.core_api.set_flag`](../../catlass/core_api.py#L4689) | 1701 | +**Source:** [`catlass.core_api.set_flag`](../../catlass/core_api.py#L4658) |
| 1700 | 1702 | ||
| 1701 | Description: | 1703 | Description: |
| 1702 | 1704 | ||
| @@ -1728,7 +1730,7 @@ with tla.vector(): | |||
| 1728 | 1730 | ||
| 1729 | ### `wait_flag` | 1731 | ### `wait_flag` |
| 1730 | 1732 | ||
| 1731 | -**Source:** [`catlass.core_api.wait_flag`](../../catlass/core_api.py#L4715) | 1733 | +**Source:** [`catlass.core_api.wait_flag`](../../catlass/core_api.py#L4684) |
| 1732 | 1734 | ||
| 1733 | Description: | 1735 | Description: |
| 1734 | 1736 | ||
| @@ -1760,7 +1762,7 @@ with tla.vector(): | |||
| 1760 | 1762 | ||
| 1761 | ### `pipe_barrier` | 1763 | ### `pipe_barrier` |
| 1762 | 1764 | ||
| 1763 | -**Source:** [`catlass.core_api.pipe_barrier`](../../catlass/core_api.py#L4741) | 1765 | +**Source:** [`catlass.core_api.pipe_barrier`](../../catlass/core_api.py#L4710) |
| 1764 | 1766 | ||
| 1765 | Description: | 1767 | Description: |
| 1766 | 1768 | ||
| @@ -1792,7 +1794,7 @@ with tla.vector(): | |||
| 1792 | 1794 | ||
| 1793 | ### `mutex` | 1795 | ### `mutex` |
| 1794 | 1796 | ||
| 1795 | -**Source:** [`catlass.core_api.mutex`](../../catlass/core_api.py#L4784) | 1797 | +**Source:** [`catlass.core_api.mutex`](../../catlass/core_api.py#L4745) |
| 1796 | 1798 | ||
| 1797 | Description: | 1799 | Description: |
| 1798 | 1800 | ||
| @@ -1824,7 +1826,7 @@ mtx = tla.mutex("l1_buf", id=0) | |||
| 1824 | 1826 | ||
| 1825 | ### `mutex_guard` | 1827 | ### `mutex_guard` |
| 1826 | 1828 | ||
| 1827 | -**Source:** [`catlass.core_api.mutex_guard`](../../catlass/core_api.py#L4832) | 1829 | +**Source:** [`catlass.core_api.mutex_guard`](../../catlass/core_api.py#L4793) |
| 1828 | 1830 | ||
| 1829 | Description: | 1831 | Description: |
| 1830 | 1832 | ||
| @@ -1856,7 +1858,7 @@ with tla.mutex_guard(mtx): | |||
| 1856 | 1858 | ||
| 1857 | ### `mutex_lock` | 1859 | ### `mutex_lock` |
| 1858 | 1860 | ||
| 1859 | -**Source:** [`catlass.core_api.mutex_lock`](../../catlass/core_api.py#L4873) | 1861 | +**Source:** [`catlass.core_api.mutex_lock`](../../catlass/core_api.py#L4834) |
| 1860 | 1862 | ||
| 1861 | Description: | 1863 | Description: |
| 1862 | 1864 | ||
| @@ -1888,7 +1890,7 @@ tla.mutex_lock(mtx, pipe=tla.arch.MTE2) | |||
| 1888 | 1890 | ||
| 1889 | ### `mutex_unlock` | 1891 | ### `mutex_unlock` |
| 1890 | 1892 | ||
| 1891 | -**Source:** [`catlass.core_api.mutex_unlock`](../../catlass/core_api.py#L4903) | 1893 | +**Source:** [`catlass.core_api.mutex_unlock`](../../catlass/core_api.py#L4864) |
| 1892 | 1894 | ||
| 1893 | Description: | 1895 | Description: |
| 1894 | 1896 | ||
| @@ -1920,7 +1922,7 @@ tla.mutex_unlock(mtx, pipe=tla.arch.MTE2) | |||
| 1920 | 1922 | ||
| 1921 | ### `local_mem_bar` | 1923 | ### `local_mem_bar` |
| 1922 | 1924 | ||
| 1923 | -**Source:** [`catlass.core_api.local_mem_bar`](../../catlass/core_api.py#L4933) | 1925 | +**Source:** [`catlass.core_api.local_mem_bar`](../../catlass/core_api.py#L4893) |
| 1924 | 1926 | ||
| 1925 | Description: | 1927 | Description: |
| 1926 | 1928 | ||
| @@ -1957,7 +1959,7 @@ Architecture attributes on `tla.arch` (layout tags, pipe identifiers, block help | |||
| 1957 | 1959 | ||
| 1958 | ### `arch` | 1960 | ### `arch` |
| 1959 | 1961 | ||
| 1960 | -**Source:** [`catlass.core_api.arch`](../../catlass/core_api.py#L7202) | 1962 | +**Source:** [`catlass.core_api.arch`](../../catlass/core_api.py#L7170) |
| 1961 | 1963 | ||
| 1962 | Description: | 1964 | Description: |
| 1963 | 1965 | ||
| @@ -2028,7 +2030,7 @@ On-chip scratch allocation via `allocate`. | |||
| 2028 | 2030 | ||
| 2029 | ### `allocate` | 2031 | ### `allocate` |
| 2030 | 2032 | ||
| 2031 | -**Source:** [`catlass.core_api.allocate`](../../catlass/core_api.py#L6972) | 2033 | +**Source:** [`catlass.core_api.allocate`](../../catlass/core_api.py#L6938) |
| 2032 | 2034 | ||
| 2033 | Description: | 2035 | Description: |
| 2034 | 2036 | ||
| @@ -2071,7 +2073,7 @@ In-kernel scalar / tensor debug printing. | |||
| 2071 | 2073 | ||
| 2072 | ### `print` | 2074 | ### `print` |
| 2073 | 2075 | ||
| 2074 | -**Source:** [`catlass.core_api.print`](../../catlass/core_api.py#L3345) | 2076 | +**Source:** [`catlass.core_api.print`](../../catlass/core_api.py#L3355) |
| 2075 | 2077 | ||
| 2076 | Description: | 2078 | Description: |
| 2077 | 2079 | ||
| @@ -2109,7 +2111,7 @@ Cube / Vector / `vec.func` regions and kernel-side loop ranges. | |||
| 2109 | 2111 | ||
| 2110 | ### `range` | 2112 | ### `range` |
| 2111 | 2113 | ||
| 2112 | -**Source:** [`catlass.core_api.range`](../../catlass/core_api.py#L4985) | 2114 | +**Source:** [`catlass.core_api.range`](../../catlass/core_api.py#L4943) |
| 2113 | 2115 | ||
| 2114 | Description: | 2116 | Description: |
| 2115 | 2117 | ||
| @@ -2143,7 +2145,7 @@ for i in tla.range(0, n, 1): | |||
| 2143 | 2145 | ||
| 2144 | ### `range_constexpr` | 2146 | ### `range_constexpr` |
| 2145 | 2147 | ||
| 2146 | -**Source:** [`catlass.core_api.range_constexpr`](../../catlass/core_api.py#L5035) | 2148 | +**Source:** [`catlass.core_api.range_constexpr`](../../catlass/core_api.py#L4993) |
| 2147 | 2149 | ||
| 2148 | Description: | 2150 | Description: |
| 2149 | 2151 | ||
| @@ -2177,7 +2179,7 @@ for k in tla.range_constexpr(0, 4): | |||
| 2177 | 2179 | ||
| 2178 | ### `cube` | 2180 | ### `cube` |
| 2179 | 2181 | ||
| 2180 | -**Source:** [`catlass.core_api.cube`](../../catlass/core_api.py#L5081) | 2182 | +**Source:** [`catlass.core_api.cube`](../../catlass/core_api.py#L5039) |
| 2181 | 2183 | ||
| 2182 | Description: | 2184 | Description: |
| 2183 | 2185 | ||
| @@ -2209,7 +2211,7 @@ with tla.cube(): | |||
| 2209 | 2211 | ||
| 2210 | ### `vector` | 2212 | ### `vector` |
| 2211 | 2213 | ||
| 2212 | -**Source:** [`catlass.core_api.vector`](../../catlass/core_api.py#L5103) | 2214 | +**Source:** [`catlass.core_api.vector`](../../catlass/core_api.py#L5061) |
| 2213 | 2215 | ||
| 2214 | Description: | 2216 | Description: |
| 2215 | 2217 | ||
| @@ -2241,7 +2243,7 @@ with tla.vector(): | |||
| 2241 | 2243 | ||
| 2242 | ### `vec.func` | 2244 | ### `vec.func` |
| 2243 | 2245 | ||
| 2244 | -**Source:** [`catlass.core_api._vec_func`](../../catlass/core_api.py#L5137) | 2246 | +**Source:** [`catlass.core_api._vec_func`](../../catlass/core_api.py#L5095) |
| 2245 | 2247 | ||
| 2246 | Description: | 2248 | Description: |
| 2247 | 2249 | ||
| @@ -46,7 +46,7 @@ Shape / Coord / Stride / Layout / Tensor 等前端结构化值的构造与视图 | |||
| 46 | ### `make_shape` | 46 | ### `make_shape` |
| 47 | 47 | ||
| 48 | 48 | ||
| 49 | -**源码:** [`catlass.core_api.make_shape`](../../catlass/core_api.py#L3516) | 49 | +**源码:** [`catlass.core_api.make_shape`](../../catlass/core_api.py#L3517) |
| 50 | 50 | ||
| 51 | 功能说明: | 51 | 功能说明: |
| 52 | 52 | ||
| @@ -93,7 +93,7 @@ zn_shape = tla.make_shape((16, 8), (16, 4)) | |||
| 93 | ### `make_coord` | 93 | ### `make_coord` |
| 94 | 94 | ||
| 95 | 95 | ||
| 96 | -**源码:** [`catlass.core_api.make_coord`](../../catlass/core_api.py#L3557) | 96 | +**源码:** [`catlass.core_api.make_coord`](../../catlass/core_api.py#L3558) |
| 97 | 97 | ||
| 98 | 功能说明: | 98 | 功能说明: |
| 99 | 99 | ||
| @@ -129,7 +129,7 @@ coord = tla.make_coord(block_row, 0) | |||
| 129 | ### `make_stride` | 129 | ### `make_stride` |
| 130 | 130 | ||
| 131 | 131 | ||
| 132 | -**源码:** [`catlass.core_api.make_stride`](../../catlass/core_api.py#L3586) | 132 | +**源码:** [`catlass.core_api.make_stride`](../../catlass/core_api.py#L3587) |
| 133 | 133 | ||
| 134 | 功能说明: | 134 | 功能说明: |
| 135 | 135 | ||
| @@ -195,7 +195,7 @@ nz_stride = tla.make_stride((1, 1024), (16, 256)) | |||
| 195 | ### `make_layout` | 195 | ### `make_layout` |
| 196 | 196 | ||
| 197 | 197 | ||
| 198 | -**源码:** [`catlass.core_api.make_layout`](../../catlass/core_api.py#L3646) | 198 | +**源码:** [`catlass.core_api.make_layout`](../../catlass/core_api.py#L3647) |
| 199 | 199 | ||
| 200 | 功能说明: | 200 | 功能说明: |
| 201 | 201 | ||
| @@ -260,7 +260,7 @@ zn = tla.make_layout( | |||
| 260 | ### `tile_view` | 260 | ### `tile_view` |
| 261 | 261 | ||
| 262 | 262 | ||
| 263 | -**源码:** [`catlass.core_api.tile_view`](../../catlass/core_api.py#L3815) | 263 | +**源码:** [`catlass.core_api.tile_view`](../../catlass/core_api.py#L3816) |
| 264 | 264 | ||
| 265 | 功能说明: | 265 | 功能说明: |
| 266 | 266 | ||
| @@ -300,7 +300,7 @@ tile = tla.tile_view( | |||
| 300 | ### `make_tensor` | 300 | ### `make_tensor` |
| 301 | 301 | ||
| 302 | 302 | ||
| 303 | -**源码:** [`catlass.core_api.make_tensor`](../../catlass/core_api.py#L3862) | 303 | +**源码:** [`catlass.core_api.make_tensor`](../../catlass/core_api.py#L3863) |
| 304 | 304 | ||
| 305 | 功能说明: | 305 | 功能说明: |
| 306 | 306 | ||
| @@ -344,7 +344,7 @@ tensor = tla.make_tensor(ptr, layout, coord=tla.make_coord(0, 0)) | |||
| 344 | ### `make_tensor_like` | 344 | ### `make_tensor_like` |
| 345 | 345 | ||
| 346 | 346 | ||
| 347 | -**源码:** [`catlass.core_api.make_tensor_like`](../../catlass/core_api.py#L4059) | 347 | +**源码:** [`catlass.core_api.make_tensor_like`](../../catlass/core_api.py#L4060) |
| 348 | 348 | ||
| 349 | 功能说明: | 349 | 功能说明: |
| 350 | 350 | ||
| @@ -383,7 +383,7 @@ dst = tla.make_tensor_like(ptr, like=src_tile, layoutTag=tla.arch.RowMajor) | |||
| 383 | ### `make_ptr` | 383 | ### `make_ptr` |
| 384 | 384 | ||
| 385 | 385 | ||
| 386 | -**源码:** [`catlass.core_api.make_ptr`](../../catlass/core_api.py#L6968) | 386 | +**源码:** [`catlass.core_api.make_ptr`](../../catlass/core_api.py#L7000) |
| 387 | 387 | ||
| 388 | 功能说明: | 388 | 功能说明: |
| 389 | 389 | ||
| @@ -422,7 +422,7 @@ ptr = tla.make_ptr(tla.Float16, addr, mem_space=tla.AddressSpace.gm) | |||
| 422 | ### `recast_ptr` | 422 | ### `recast_ptr` |
| 423 | 423 | ||
| 424 | 424 | ||
| 425 | -**源码:** [`catlass.core_api.recast_ptr`](../../catlass/core_api.py#L7022) | 425 | +**源码:** [`catlass.core_api.recast_ptr`](../../catlass/core_api.py#L7054) |
| 426 | 426 | ||
| 427 | 功能说明: | 427 | 功能说明: |
| 428 | 428 | ||
| @@ -462,7 +462,7 @@ ptr_f32 = tla.recast_ptr(ptr_f16, dtype=tla.Float32) | |||
| 462 | ### `copy` | 462 | ### `copy` |
| 463 | 463 | ||
| 464 | 464 | ||
| 465 | -**源码:** [`catlass.core_api.copy`](../../catlass/core_api.py#L4249) | 465 | +**源码:** [`catlass.core_api.copy`](../../catlass/core_api.py#L4250) |
| 466 | 466 | ||
| 467 | 功能说明: | 467 | 功能说明: |
| 468 | 468 | ||
| @@ -550,7 +550,7 @@ with tla.cube(): | |||
| 550 | ### `Tensor.load` | 550 | ### `Tensor.load` |
| 551 | 551 | ||
| 552 | 552 | ||
| 553 | -**源码:** [`catlass.tla.tensor._Tensor.load`](../../catlass/tla/tensor.py#L211) | 553 | +**源码:** [`catlass.tla.tensor._Tensor.load`](../../catlass/tla/tensor.py#L215) |
| 554 | 554 | ||
| 555 | 功能说明: | 555 | 功能说明: |
| 556 | 556 | ||
| @@ -589,7 +589,7 @@ with tla.vec.func(mode="simd"): | |||
| 589 | ### `Tensor.store` | 589 | ### `Tensor.store` |
| 590 | 590 | ||
| 591 | 591 | ||
| 592 | -**源码:** [`catlass.tla.tensor._Tensor.store`](../../catlass/tla/tensor.py#L382) | 592 | +**源码:** [`catlass.tla.tensor._Tensor.store`](../../catlass/tla/tensor.py#L383) |
| 593 | 593 | ||
| 594 | 功能说明: | 594 | 功能说明: |
| 595 | 595 | ||
| @@ -631,7 +631,7 @@ Cube 侧矩阵乘加(`tla.mmad`)。 | |||
| 631 | ### `mmad` | 631 | ### `mmad` |
| 632 | 632 | ||
| 633 | 633 | ||
| 634 | -**源码:** [`catlass.core_api.mmad`](../../catlass/core_api.py#L5140) | 634 | +**源码:** [`catlass.core_api.mmad`](../../catlass/core_api.py#L5134) |
| 635 | 635 | ||
| 636 | 功能说明: | 636 | 功能说明: |
| 637 | 637 | ||
| @@ -640,7 +640,7 @@ Cube 侧矩阵乘加(`tla.mmad`)。 | |||
| 640 | 函数原型: | 640 | 函数原型: |
| 641 | 641 | ||
| 642 | ```python | 642 | ```python |
| 643 | -tla.mmad(acc: Tensor, lhs: Tensor, rhs: Tensor, init_c: bool | Bool | None = None, unit_flag: IndexLike | None = None, compute_order: ComputeOrder = ComputeOrder.M_FIRST, **extra_kwargs: object) -> None | 643 | +tla.mmad(acc: Tensor, lhs: Tensor, rhs: Tensor, init_c: bool | Bool | None = None, unit_flag: IndexLike | None = None, compute_order: ComputeOrder = ComputeOrder.M_FIRST, hf32_mode: HF32Mode = HF32Mode.HF32_DISABLE, **extra_kwargs: object) -> None |
| 644 | ``` | 644 | ``` |
| 645 | 645 | ||
| 646 | 参数说明: | 646 | 参数说明: |
| @@ -651,6 +651,7 @@ tla.mmad(acc: Tensor, lhs: Tensor, rhs: Tensor, init_c: bool | Bool | None = Non | |||
| 651 | - `init_c`(`bool | Bool | None`):是否先清零累加器;省略时默认为 `False`。可选,默认 `None`。 | 651 | - `init_c`(`bool | Bool | None`):是否先清零累加器;省略时默认为 `False`。可选,默认 `None`。 |
| 652 | - `unit_flag`(`IndexLike | None`):unit flag 控制位;省略时默认为 `0`。可选,默认 `None`。 | 652 | - `unit_flag`(`IndexLike | None`):unit flag 控制位;省略时默认为 `0`。可选,默认 `None`。 |
| 653 | - `compute_order`(`ComputeOrder`):M/N 计算方向优先级;默认 `M_FIRST`。 | 653 | - `compute_order`(`ComputeOrder`):M/N 计算方向优先级;默认 `M_FIRST`。 |
| 654 | +- `hf32_mode`(`HF32Mode`):FP32 操作数在 L0A/L0B 上、矩阵乘之前的 HF32 舍入模式。可选,默认 `HF32_DISABLE`。 | ||
| 654 | 655 | ||
| 655 | 约束说明: | 656 | 约束说明: |
| 656 | 657 | ||
| @@ -683,7 +684,7 @@ Mask 创建与尾块更新。 | |||
| 683 | #### `create_mask` | 684 | #### `create_mask` |
| 684 | 685 | ||
| 685 | 686 | ||
| 686 | -**源码:** [`catlass.core_api.create_mask`](../../catlass/core_api.py#L7280) | 687 | +**源码:** [`catlass.core_api.create_mask`](../../catlass/core_api.py#L7312) |
| 687 | 688 | ||
| 688 | 功能说明: | 689 | 功能说明: |
| 689 | 690 | ||
| @@ -743,7 +744,7 @@ with tla.vec.func(mode="simd"): | |||
| 743 | #### `update_mask` | 744 | #### `update_mask` |
| 744 | 745 | ||
| 745 | 746 | ||
| 746 | -**源码:** [`catlass.core_api.update_mask`](../../catlass/core_api.py#L7346) | 747 | +**源码:** [`catlass.core_api.update_mask`](../../catlass/core_api.py#L7378) |
| 747 | 748 | ||
| 748 | 功能说明: | 749 | 功能说明: |
| 749 | 750 | ||
| @@ -783,7 +784,7 @@ with tla.vec.func(mode="simd"): | |||
| 783 | #### `exp` | 784 | #### `exp` |
| 784 | 785 | ||
| 785 | 786 | ||
| 786 | -**源码:** [`catlass.core_api.exp`](../../catlass/core_api.py#L5723) | 787 | +**源码:** [`catlass.core_api.exp`](../../catlass/core_api.py#L5731) |
| 787 | 788 | ||
| 788 | 功能说明: | 789 | 功能说明: |
| 789 | 790 | ||
| @@ -821,7 +822,7 @@ with tla.vec.func(mode="simd"): | |||
| 821 | #### `log` | 822 | #### `log` |
| 822 | 823 | ||
| 823 | 824 | ||
| 824 | -**源码:** [`catlass.core_api.log`](../../catlass/core_api.py#L5745) | 825 | +**源码:** [`catlass.core_api.log`](../../catlass/core_api.py#L5753) |
| 825 | 826 | ||
| 826 | 功能说明: | 827 | 功能说明: |
| 827 | 828 | ||
| @@ -859,7 +860,7 @@ with tla.vec.func(mode="simd"): | |||
| 859 | #### `sqrt` | 860 | #### `sqrt` |
| 860 | 861 | ||
| 861 | 862 | ||
| 862 | -**源码:** [`catlass.core_api.sqrt`](../../catlass/core_api.py#L5767) | 863 | +**源码:** [`catlass.core_api.sqrt`](../../catlass/core_api.py#L5775) |
| 863 | 864 | ||
| 864 | 功能说明: | 865 | 功能说明: |
| 865 | 866 | ||
| @@ -897,7 +898,7 @@ with tla.vec.func(mode="simd"): | |||
| 897 | #### `abs` | 898 | #### `abs` |
| 898 | 899 | ||
| 899 | 900 | ||
| 900 | -**源码:** [`catlass.core_api.abs`](../../catlass/core_api.py#L5789) | 901 | +**源码:** [`catlass.core_api.abs`](../../catlass/core_api.py#L5797) |
| 901 | 902 | ||
| 902 | 功能说明: | 903 | 功能说明: |
| 903 | 904 | ||
| @@ -935,7 +936,7 @@ with tla.vec.func(mode="simd"): | |||
| 935 | #### `neg` | 936 | #### `neg` |
| 936 | 937 | ||
| 937 | 938 | ||
| 938 | -**源码:** [`catlass.core_api.neg`](../../catlass/core_api.py#L5811) | 939 | +**源码:** [`catlass.core_api.neg`](../../catlass/core_api.py#L5819) |
| 939 | 940 | ||
| 940 | 功能说明: | 941 | 功能说明: |
| 941 | 942 | ||
| @@ -973,7 +974,7 @@ with tla.vec.func(mode="simd"): | |||
| 973 | #### `add` | 974 | #### `add` |
| 974 | 975 | ||
| 975 | 976 | ||
| 976 | -**源码:** [`catlass.core_api.add`](../../catlass/core_api.py#L5991) | 977 | +**源码:** [`catlass.core_api.add`](../../catlass/core_api.py#L5999) |
| 977 | 978 | ||
| 978 | 功能说明: | 979 | 功能说明: |
| 979 | 980 | ||
| @@ -1019,7 +1020,7 @@ with tla.vec.func(mode="simd"): | |||
| 1019 | #### `sub` | 1020 | #### `sub` |
| 1020 | 1021 | ||
| 1021 | 1022 | ||
| 1022 | -**源码:** [`catlass.core_api.sub`](../../catlass/core_api.py#L6037) | 1023 | +**源码:** [`catlass.core_api.sub`](../../catlass/core_api.py#L6045) |
| 1023 | 1024 | ||
| 1024 | 功能说明: | 1025 | 功能说明: |
| 1025 | 1026 | ||
| @@ -1062,7 +1063,7 @@ with tla.vec.func(mode="simd"): | |||
| 1062 | #### `mul` | 1063 | #### `mul` |
| 1063 | 1064 | ||
| 1064 | 1065 | ||
| 1065 | -**源码:** [`catlass.core_api.mul`](../../catlass/core_api.py#L6074) | 1066 | +**源码:** [`catlass.core_api.mul`](../../catlass/core_api.py#L6082) |
| 1066 | 1067 | ||
| 1067 | 功能说明: | 1068 | 功能说明: |
| 1068 | 1069 | ||
| @@ -1106,7 +1107,7 @@ with tla.vec.func(mode="simd"): | |||
| 1106 | #### `max` | 1107 | #### `max` |
| 1107 | 1108 | ||
| 1108 | 1109 | ||
| 1109 | -**源码:** [`catlass.core_api.max`](../../catlass/core_api.py#L6119) | 1110 | +**源码:** [`catlass.core_api.max`](../../catlass/core_api.py#L6127) |
| 1110 | 1111 | ||
| 1111 | 功能说明: | 1112 | 功能说明: |
| 1112 | 1113 | ||
| @@ -1145,7 +1146,7 @@ with tla.vec.func(mode="simd"): | |||
| 1145 | #### `min` | 1146 | #### `min` |
| 1146 | 1147 | ||
| 1147 | 1148 | ||
| 1148 | -**源码:** [`catlass.core_api.min`](../../catlass/core_api.py#L6159) | 1149 | +**源码:** [`catlass.core_api.min`](../../catlass/core_api.py#L6167) |
| 1149 | 1150 | ||
| 1150 | 功能说明: | 1151 | 功能说明: |
| 1151 | 1152 | ||
| @@ -1184,7 +1185,7 @@ with tla.vec.func(mode="simd"): | |||
| 1184 | #### `div` | 1185 | #### `div` |
| 1185 | 1186 | ||
| 1186 | 1187 | ||
| 1187 | -**源码:** [`catlass.core_api.div`](../../catlass/core_api.py#L6199) | 1188 | +**源码:** [`catlass.core_api.div`](../../catlass/core_api.py#L6207) |
| 1188 | 1189 | ||
| 1189 | 功能说明: | 1190 | 功能说明: |
| 1190 | 1191 | ||
| @@ -1229,7 +1230,7 @@ with tla.vec.func(mode="simd"): | |||
| 1229 | #### `bitwise_not` | 1230 | #### `bitwise_not` |
| 1230 | 1231 | ||
| 1231 | 1232 | ||
| 1232 | -**源码:** [`catlass.core_api.bitwise_not`](../../catlass/core_api.py#L5957) | 1233 | +**源码:** [`catlass.core_api.bitwise_not`](../../catlass/core_api.py#L5965) |
| 1233 | 1234 | ||
| 1234 | 功能说明: | 1235 | 功能说明: |
| 1235 | 1236 | ||
| @@ -1267,7 +1268,7 @@ with tla.vec.func(mode="simd"): | |||
| 1267 | #### `bitwise_and` | 1268 | #### `bitwise_and` |
| 1268 | 1269 | ||
| 1269 | 1270 | ||
| 1270 | -**源码:** [`catlass.core_api.bitwise_and`](../../catlass/core_api.py#L6568) | 1271 | +**源码:** [`catlass.core_api.bitwise_and`](../../catlass/core_api.py#L6576) |
| 1271 | 1272 | ||
| 1272 | 功能说明: | 1273 | 功能说明: |
| 1273 | 1274 | ||
| @@ -1306,7 +1307,7 @@ with tla.vec.func(mode="simd"): | |||
| 1306 | #### `bitwise_or` | 1307 | #### `bitwise_or` |
| 1307 | 1308 | ||
| 1308 | 1309 | ||
| 1309 | -**源码:** [`catlass.core_api.bitwise_or`](../../catlass/core_api.py#L6606) | 1310 | +**源码:** [`catlass.core_api.bitwise_or`](../../catlass/core_api.py#L6614) |
| 1310 | 1311 | ||
| 1311 | 功能说明: | 1312 | 功能说明: |
| 1312 | 1313 | ||
| @@ -1345,7 +1346,7 @@ with tla.vec.func(mode="simd"): | |||
| 1345 | #### `bitwise_xor` | 1346 | #### `bitwise_xor` |
| 1346 | 1347 | ||
| 1347 | 1348 | ||
| 1348 | -**源码:** [`catlass.core_api.bitwise_xor`](../../catlass/core_api.py#L6644) | 1349 | +**源码:** [`catlass.core_api.bitwise_xor`](../../catlass/core_api.py#L6652) |
| 1349 | 1350 | ||
| 1350 | 功能说明: | 1351 | 功能说明: |
| 1351 | 1352 | ||
| @@ -1386,7 +1387,7 @@ with tla.vec.func(mode="simd"): | |||
| 1386 | #### `where` | 1387 | #### `where` |
| 1387 | 1388 | ||
| 1388 | 1389 | ||
| 1389 | -**源码:** [`catlass.core_api.where`](../../catlass/core_api.py#L6283) | 1390 | +**源码:** [`catlass.core_api.where`](../../catlass/core_api.py#L6291) |
| 1390 | 1391 | ||
| 1391 | 功能说明: | 1392 | 功能说明: |
| 1392 | 1393 | ||
| @@ -1425,7 +1426,7 @@ with tla.vec.func(mode="simd"): | |||
| 1425 | #### `cmp` | 1426 | #### `cmp` |
| 1426 | 1427 | ||
| 1427 | 1428 | ||
| 1428 | -**源码:** [`catlass.core_api.cmp`](../../catlass/core_api.py#L6490) | 1429 | +**源码:** [`catlass.core_api.cmp`](../../catlass/core_api.py#L6498) |
| 1429 | 1430 | ||
| 1430 | 功能说明: | 1431 | 功能说明: |
| 1431 | 1432 | ||
| @@ -1467,7 +1468,7 @@ with tla.vec.func(mode="simd"): | |||
| 1467 | #### `full` | 1468 | #### `full` |
| 1468 | 1469 | ||
| 1469 | 1470 | ||
| 1470 | -**源码:** [`catlass.core_api.full`](../../catlass/core_api.py#L5235) | 1471 | +**源码:** [`catlass.core_api.full`](../../catlass/core_api.py#L5243) |
| 1471 | 1472 | ||
| 1472 | 功能说明: | 1473 | 功能说明: |
| 1473 | 1474 | ||
| @@ -1505,7 +1506,7 @@ with tla.vec.func(mode="simd"): | |||
| 1505 | #### `arange` | 1506 | #### `arange` |
| 1506 | 1507 | ||
| 1507 | 1508 | ||
| 1508 | -**源码:** [`catlass.core_api.arange`](../../catlass/core_api.py#L5308) | 1509 | +**源码:** [`catlass.core_api.arange`](../../catlass/core_api.py#L5316) |
| 1509 | 1510 | ||
| 1510 | 功能说明: | 1511 | 功能说明: |
| 1511 | 1512 | ||
| @@ -1546,7 +1547,7 @@ with tla.vec.func(mode="simd"): | |||
| 1546 | #### `gather` | 1547 | #### `gather` |
| 1547 | 1548 | ||
| 1548 | 1549 | ||
| 1549 | -**源码:** [`catlass.core_api.gather`](../../catlass/core_api.py#L6682) | 1550 | +**源码:** [`catlass.core_api.gather`](../../catlass/core_api.py#L6690) |
| 1550 | 1551 | ||
| 1551 | 功能说明: | 1552 | 功能说明: |
| 1552 | 1553 | ||
| @@ -1587,7 +1588,7 @@ with tla.vec.func(mode="simd"): | |||
| 1587 | #### `interleave` | 1588 | #### `interleave` |
| 1588 | 1589 | ||
| 1589 | 1590 | ||
| 1590 | -**源码:** [`catlass.core_api.interleave`](../../catlass/core_api.py#L5848) | 1591 | +**源码:** [`catlass.core_api.interleave`](../../catlass/core_api.py#L5856) |
| 1591 | 1592 | ||
| 1592 | 功能说明: | 1593 | 功能说明: |
| 1593 | 1594 | ||
| @@ -1625,7 +1626,7 @@ with tla.vec.func(mode="simd"): | |||
| 1625 | #### `deinterleave` | 1626 | #### `deinterleave` |
| 1626 | 1627 | ||
| 1627 | 1628 | ||
| 1628 | -**源码:** [`catlass.core_api.deinterleave`](../../catlass/core_api.py#L5902) | 1629 | +**源码:** [`catlass.core_api.deinterleave`](../../catlass/core_api.py#L5910) |
| 1629 | 1630 | ||
| 1630 | 功能说明: | 1631 | 功能说明: |
| 1631 | 1632 | ||
| @@ -1665,7 +1666,7 @@ with tla.vec.func(mode="simd"): | |||
| 1665 | #### `squeeze` | 1666 | #### `squeeze` |
| 1666 | 1667 | ||
| 1667 | 1668 | ||
| 1668 | -**源码:** [`catlass.core_api.squeeze`](../../catlass/core_api.py#L6337) | 1669 | +**源码:** [`catlass.core_api.squeeze`](../../catlass/core_api.py#L6345) |
| 1669 | 1670 | ||
| 1670 | 功能说明: | 1671 | 功能说明: |
| 1671 | 1672 | ||
| @@ -1706,7 +1707,7 @@ with tla.vec.func(mode="simd"): | |||
| 1706 | ### `flag` | 1707 | ### `flag` |
| 1707 | 1708 | ||
| 1708 | 1709 | ||
| 1709 | -**源码:** [`catlass.core_api.flag`](../../catlass/core_api.py#L4430) | 1710 | +**源码:** [`catlass.core_api.flag`](../../catlass/core_api.py#L4442) |
| 1710 | 1711 | ||
| 1711 | 功能说明: | 1712 | 功能说明: |
| 1712 | 1713 | ||
| @@ -1749,7 +1750,7 @@ with tla.vector(): | |||
| 1749 | ### `cross_flag` | 1750 | ### `cross_flag` |
| 1750 | 1751 | ||
| 1751 | 1752 | ||
| 1752 | -**源码:** [`catlass.core_api.cross_flag`](../../catlass/core_api.py#L4501) | 1753 | +**源码:** [`catlass.core_api.cross_flag`](../../catlass/core_api.py#L4495) |
| 1753 | 1754 | ||
| 1754 | 功能说明: | 1755 | 功能说明: |
| 1755 | 1756 | ||
| @@ -1786,7 +1787,7 @@ cf = tla.cross_flag("aic_aiv", mode=2) | |||
| 1786 | ### `cross_core_set_flag` | 1787 | ### `cross_core_set_flag` |
| 1787 | 1788 | ||
| 1788 | 1789 | ||
| 1789 | -**源码:** [`catlass.core_api.cross_core_set_flag`](../../catlass/core_api.py#L4573) | 1790 | +**源码:** [`catlass.core_api.cross_core_set_flag`](../../catlass/core_api.py#L4567) |
| 1790 | 1791 | ||
| 1791 | 功能说明: | 1792 | 功能说明: |
| 1792 | 1793 | ||
| @@ -1826,7 +1827,7 @@ with tla.cube(): | |||
| 1826 | ### `cross_core_wait_flag` | 1827 | ### `cross_core_wait_flag` |
| 1827 | 1828 | ||
| 1828 | 1829 | ||
| 1829 | -**源码:** [`catlass.core_api.cross_core_wait_flag`](../../catlass/core_api.py#L4619) | 1830 | +**源码:** [`catlass.core_api.cross_core_wait_flag`](../../catlass/core_api.py#L4613) |
| 1830 | 1831 | ||
| 1831 | 功能说明: | 1832 | 功能说明: |
| 1832 | 1833 | ||
| @@ -1865,7 +1866,7 @@ with tla.vector(): | |||
| 1865 | ### `set_flag` | 1866 | ### `set_flag` |
| 1866 | 1867 | ||
| 1867 | 1868 | ||
| 1868 | -**源码:** [`catlass.core_api.set_flag`](../../catlass/core_api.py#L4664) | 1869 | +**源码:** [`catlass.core_api.set_flag`](../../catlass/core_api.py#L4658) |
| 1869 | 1870 | ||
| 1870 | 功能说明: | 1871 | 功能说明: |
| 1871 | 1872 | ||
| @@ -1902,7 +1903,7 @@ with tla.vector(): | |||
| 1902 | ### `wait_flag` | 1903 | ### `wait_flag` |
| 1903 | 1904 | ||
| 1904 | 1905 | ||
| 1905 | -**源码:** [`catlass.core_api.wait_flag`](../../catlass/core_api.py#L4690) | 1906 | +**源码:** [`catlass.core_api.wait_flag`](../../catlass/core_api.py#L4684) |
| 1906 | 1907 | ||
| 1907 | 功能说明: | 1908 | 功能说明: |
| 1908 | 1909 | ||
| @@ -1939,7 +1940,7 @@ with tla.vector(): | |||
| 1939 | ### `pipe_barrier` | 1940 | ### `pipe_barrier` |
| 1940 | 1941 | ||
| 1941 | 1942 | ||
| 1942 | -**源码:** [`catlass.core_api.pipe_barrier`](../../catlass/core_api.py#L4716) | 1943 | +**源码:** [`catlass.core_api.pipe_barrier`](../../catlass/core_api.py#L4710) |
| 1943 | 1944 | ||
| 1944 | 功能说明: | 1945 | 功能说明: |
| 1945 | 1946 | ||
| @@ -1976,7 +1977,7 @@ with tla.vector(): | |||
| 1976 | ### `mutex` | 1977 | ### `mutex` |
| 1977 | 1978 | ||
| 1978 | 1979 | ||
| 1979 | -**源码:** [`catlass.core_api.mutex`](../../catlass/core_api.py#L4751) | 1980 | +**源码:** [`catlass.core_api.mutex`](../../catlass/core_api.py#L4745) |
| 1980 | 1981 | ||
| 1981 | 功能说明: | 1982 | 功能说明: |
| 1982 | 1983 | ||
| @@ -2013,7 +2014,7 @@ mtx = tla.mutex("l1_buf", id=0) | |||
| 2013 | ### `mutex_guard` | 2014 | ### `mutex_guard` |
| 2014 | 2015 | ||
| 2015 | 2016 | ||
| 2016 | -**源码:** [`catlass.core_api.mutex_guard`](../../catlass/core_api.py#L4799) | 2017 | +**源码:** [`catlass.core_api.mutex_guard`](../../catlass/core_api.py#L4793) |
| 2017 | 2018 | ||
| 2018 | 功能说明: | 2019 | 功能说明: |
| 2019 | 2020 | ||
| @@ -2050,7 +2051,7 @@ with tla.mutex_guard(mtx): | |||
| 2050 | ### `mutex_lock` | 2051 | ### `mutex_lock` |
| 2051 | 2052 | ||
| 2052 | 2053 | ||
| 2053 | -**源码:** [`catlass.core_api.mutex_lock`](../../catlass/core_api.py#L4840) | 2054 | +**源码:** [`catlass.core_api.mutex_lock`](../../catlass/core_api.py#L4834) |
| 2054 | 2055 | ||
| 2055 | 功能说明: | 2056 | 功能说明: |
| 2056 | 2057 | ||
| @@ -2087,7 +2088,7 @@ tla.mutex_lock(mtx, pipe=tla.arch.MTE2) | |||
| 2087 | ### `mutex_unlock` | 2088 | ### `mutex_unlock` |
| 2088 | 2089 | ||
| 2089 | 2090 | ||
| 2090 | -**源码:** [`catlass.core_api.mutex_unlock`](../../catlass/core_api.py#L4870) | 2091 | +**源码:** [`catlass.core_api.mutex_unlock`](../../catlass/core_api.py#L4864) |
| 2091 | 2092 | ||
| 2092 | 功能说明: | 2093 | 功能说明: |
| 2093 | 2094 | ||
| @@ -2124,7 +2125,7 @@ tla.mutex_unlock(mtx, pipe=tla.arch.MTE2) | |||
| 2124 | ### `local_mem_bar` | 2125 | ### `local_mem_bar` |
| 2125 | 2126 | ||
| 2126 | 2127 | ||
| 2127 | -**源码:** [`catlass.core_api.local_mem_bar`](../../catlass/core_api.py#L4899) | 2128 | +**源码:** [`catlass.core_api.local_mem_bar`](../../catlass/core_api.py#L4893) |
| 2128 | 2129 | ||
| 2129 | 功能说明: | 2130 | 功能说明: |
| 2130 | 2131 | ||
| @@ -2165,7 +2166,7 @@ with tla.vec.func(mode="simd"): | |||
| 2165 | ### `arch` | 2166 | ### `arch` |
| 2166 | 2167 | ||
| 2167 | 2168 | ||
| 2168 | -**源码:** [`catlass.core_api.arch`](../../catlass/core_api.py#L7138) | 2169 | +**源码:** [`catlass.core_api.arch`](../../catlass/core_api.py#L7170) |
| 2169 | 2170 | ||
| 2170 | 功能说明: | 2171 | 功能说明: |
| 2171 | 2172 | ||
| @@ -2235,7 +2236,7 @@ ub_bytes = tla.arch.get_capacity_in_bytes(tla.arch.UB) | |||
| 2235 | ### `allocate` | 2236 | ### `allocate` |
| 2236 | 2237 | ||
| 2237 | 2238 | ||
| 2238 | -**源码:** [`catlass.core_api.allocate`](../../catlass/core_api.py#L6906) | 2239 | +**源码:** [`catlass.core_api.allocate`](../../catlass/core_api.py#L6938) |
| 2239 | 2240 | ||
| 2240 | 功能说明: | 2241 | 功能说明: |
| 2241 | 2242 | ||
| @@ -2282,7 +2283,7 @@ kernel 内标量 / tensor 调试打印。 | |||
| 2282 | ### `print` | 2283 | ### `print` |
| 2283 | 2284 | ||
| 2284 | 2285 | ||
| 2285 | -**源码:** [`catlass.core_api.print`](../../catlass/core_api.py#L3354) | 2286 | +**源码:** [`catlass.core_api.print`](../../catlass/core_api.py#L3355) |
| 2286 | 2287 | ||
| 2287 | 功能说明: | 2288 | 功能说明: |
| 2288 | 2289 | ||
| @@ -2325,7 +2326,7 @@ Cube / Vector / `vec.func` 区域以及 kernel 侧循环范围。 | |||
| 2325 | ### `range` | 2326 | ### `range` |
| 2326 | 2327 | ||
| 2327 | 2328 | ||
| 2328 | -**源码:** [`catlass.core_api.range`](../../catlass/core_api.py#L4949) | 2329 | +**源码:** [`catlass.core_api.range`](../../catlass/core_api.py#L4943) |
| 2329 | 2330 | ||
| 2330 | 功能说明: | 2331 | 功能说明: |
| 2331 | 2332 | ||
| @@ -2366,7 +2367,7 @@ for i in tla.range(0, n, 1): | |||
| 2366 | ### `range_constexpr` | 2367 | ### `range_constexpr` |
| 2367 | 2368 | ||
| 2368 | 2369 | ||
| 2369 | -**源码:** [`catlass.core_api.range_constexpr`](../../catlass/core_api.py#L4999) | 2370 | +**源码:** [`catlass.core_api.range_constexpr`](../../catlass/core_api.py#L4993) |
| 2370 | 2371 | ||
| 2371 | 功能说明: | 2372 | 功能说明: |
| 2372 | 2373 | ||
| @@ -2407,7 +2408,7 @@ for k in tla.range_constexpr(0, 4): | |||
| 2407 | ### `cube` | 2408 | ### `cube` |
| 2408 | 2409 | ||
| 2409 | 2410 | ||
| 2410 | -**源码:** [`catlass.core_api.cube`](../../catlass/core_api.py#L5045) | 2411 | +**源码:** [`catlass.core_api.cube`](../../catlass/core_api.py#L5039) |
| 2411 | 2412 | ||
| 2412 | 功能说明: | 2413 | 功能说明: |
| 2413 | 2414 | ||
| @@ -2446,7 +2447,7 @@ with tla.cube(): | |||
| 2446 | ### `vector` | 2447 | ### `vector` |
| 2447 | 2448 | ||
| 2448 | 2449 | ||
| 2449 | -**源码:** [`catlass.core_api.vector`](../../catlass/core_api.py#L5067) | 2450 | +**源码:** [`catlass.core_api.vector`](../../catlass/core_api.py#L5061) |
| 2450 | 2451 | ||
| 2451 | 功能说明: | 2452 | 功能说明: |
| 2452 | 2453 | ||
| @@ -2485,7 +2486,7 @@ with tla.vector(): | |||
| 2485 | ### `vec.func` | 2486 | ### `vec.func` |
| 2486 | 2487 | ||
| 2487 | 2488 | ||
| 2488 | -**源码:** [`catlass.core_api._vec_func`](../../catlass/core_api.py#L5101) | 2489 | +**源码:** [`catlass.core_api._vec_func`](../../catlass/core_api.py#L5095) |
| 2489 | 2490 | ||
| 2490 | 功能说明: | 2491 | 功能说明: |
| 2491 | 2492 | ||
| @@ -70,8 +70,8 @@ basic_mixed.py [-h] [--device DEVICE] [--m M] [--n N] [--k K] | |||
| 70 | | `--device` | `0` | 上板执行使用的 NPU 设备号。 | | 70 | | `--device` | `0` | 上板执行使用的 NPU 设备号。 | |
| 71 | | `--m` / `--n` / `--k` | `32`, `32`, `32` | 矩阵乘加的问题大小 | | 71 | | `--m` / `--n` / `--k` | `32`, `32`, `32` | 矩阵乘加的问题大小 | |
| 72 | | `--layout-a` / `--layout-b` | `"row"` / `"row"` | 左、右矩阵 A、B 的数据排布格式,可选`"row"` 或 `"col"`,表示行优先或列优先布局。 | | 72 | | `--layout-a` / `--layout-b` | `"row"` / `"row"` | 左、右矩阵 A、B 的数据排布格式,可选`"row"` 或 `"col"`,表示行优先或列优先布局。 | |
| 73 | -| `--block-num` | `-1`(依据所使用的 NPU 设备采集其满核值) | 所启用的 AI Core 核数 | | 73 | +| `--block-num` | `-1` | 启用的核数,`-1` 表示自动探测可用核数(满核)。 | |
| 74 | -| `--sentinel` | `-9.0` | Kernel 启动前写入结果 C 的哨兵值。 | | 74 | +| `--sentinel` | `-9.0` | Kernel 启动前预先填入结果矩阵的值。 | |
| 75 | 75 | ||
| 76 | ### 执行示例 | 76 | ### 执行示例 |
| 77 | 77 | ||
| @@ -74,7 +74,7 @@ basic_matmul.py [-h] [--device DEVICE] [--m M] [--n N] [--k K] | |||
| 74 | | `--k` | `1024` | 矩阵乘累加轴的大小 | | 74 | | `--k` | `1024` | 矩阵乘累加轴的大小 | |
| 75 | | `--layout-a` / `--layout-b` | `"row"` / `"row"` | 左、右矩阵 A、B 的数据排布格式,可选`"row"` 或 `"col"`,表示行优先或列优先布局。 | | 75 | | `--layout-a` / `--layout-b` | `"row"` / `"row"` | 左、右矩阵 A、B 的数据排布格式,可选`"row"` 或 `"col"`,表示行优先或列优先布局。 | |
| 76 | | `--dtype-a` / `--dtype-b` / `--dtype-c` | `"f16"` / `"f16"` / `"f32"` | 左、右矩阵 A、B 和结果矩阵 C 的数据类型,可选范围包括`"f16"`, `"bf16"` 和 `"f32"` 。 | | 76 | | `--dtype-a` / `--dtype-b` / `--dtype-c` | `"f16"` / `"f16"` / `"f32"` | 左、右矩阵 A、B 和结果矩阵 C 的数据类型,可选范围包括`"f16"`, `"bf16"` 和 `"f32"` 。 | |
| 77 | -| `--block-num` | `-1`(依据所使用的 NPU 设备采集其满核值) | 所启用的 AI Core 核数 | | 77 | +| `--block-num` | `-1` | 启用的核数,`-1` 表示自动探测可用核数(满核)。 | |
| 78 | 78 | ||
| 79 | ### 执行示例 | 79 | ### 执行示例 |
| 80 | 80 | ||
| @@ -39,6 +39,7 @@ def basic_mmad_kernel( | |||
| 39 | gm_b: tla.Tensor, | 39 | gm_b: tla.Tensor, |
| 40 | gm_c: tla.Tensor, | 40 | gm_c: tla.Tensor, |
| 41 | _tiling: TilingParams, | 41 | _tiling: TilingParams, |
| 42 | + hf32_mode: tla.Constexpr[tla.params.HF32Mode], | ||
| 42 | ) -> None: | 43 | ) -> None: |
| 43 | c0 = 0 | 44 | c0 = 0 |
| 44 | c1 = 1 | 45 | c1 = 1 |
| @@ -239,7 +240,21 @@ def basic_mmad_kernel( | |||
| 239 | else 0b10 | 240 | else 0b10 |
| 240 | ) | 241 | ) |
| 241 | init_c = True if k_l1 == 0 and k_l0 == 0 else False | 242 | init_c = True if k_l1 == 0 and k_l0 == 0 else False |
| 242 | - tla.mmad(l0_c, l0_a, l0_b, init_c=init_c, unit_flag=unit_flag) | 243 | + if tla.const_expr( |
| 244 | + hf32_mode != tla.params.HF32Mode.HF32_DISABLE | ||
| 245 | + and dtype_a == tla.Float32 | ||
| 246 | + and dtype_b == tla.Float32 | ||
| 247 | + ): | ||
| 248 | + tla.mmad( | ||
| 249 | + l0_c, | ||
| 250 | + l0_a, | ||
| 251 | + l0_b, | ||
| 252 | + init_c=init_c, | ||
| 253 | + unit_flag=unit_flag, | ||
| 254 | + hf32_mode=hf32_mode, | ||
| 255 | + ) | ||
| 256 | + else: | ||
| 257 | + tla.mmad(l0_c, l0_a, l0_b, init_c=init_c, unit_flag=unit_flag) | ||
| 243 | if l0_buf_idx == c0: | 258 | if l0_buf_idx == c0: |
| 244 | tla.set_flag(l0a0_available) | 259 | tla.set_flag(l0a0_available) |
| 245 | tla.set_flag(l0b0_available) | 260 | tla.set_flag(l0b0_available) |
| @@ -271,6 +286,7 @@ def run(args: argparse.Namespace) -> int: | |||
| 271 | get_block_num, | 286 | get_block_num, |
| 272 | create_tla_tensor, | 287 | create_tla_tensor, |
| 273 | compare, | 288 | compare, |
| 289 | + to_hf32, | ||
| 274 | ) | 290 | ) |
| 275 | 291 | ||
| 276 | torch.npu.set_device(args.device) | 292 | torch.npu.set_device(args.device) |
| @@ -284,12 +300,23 @@ def run(args: argparse.Namespace) -> int: | |||
| 284 | dtype_a = dtypes[args.dtype_a] | 300 | dtype_a = dtypes[args.dtype_a] |
| 285 | dtype_b = dtypes[args.dtype_b] | 301 | dtype_b = dtypes[args.dtype_b] |
| 286 | dtype_c = dtypes[args.dtype_c] | 302 | dtype_c = dtypes[args.dtype_c] |
| 303 | + | ||
| 287 | a = torch.rand(args.m, args.k, dtype=dtype_a, device="cpu") * 10.0 - 5.0 | 304 | a = torch.rand(args.m, args.k, dtype=dtype_a, device="cpu") * 10.0 - 5.0 |
| 288 | b = torch.rand(args.k, args.n, dtype=dtype_b, device="cpu") * 10.0 - 5.0 | 305 | b = torch.rand(args.k, args.n, dtype=dtype_b, device="cpu") * 10.0 - 5.0 |
| 289 | c = torch.rand(args.m, args.n, dtype=dtype_c, device="cpu") * 10.0 - 5.0 | 306 | c = torch.rand(args.m, args.n, dtype=dtype_c, device="cpu") * 10.0 - 5.0 |
| 290 | - ref = a.float() @ b.float() | 307 | + |
| 291 | - if dtype_c in (torch.float16, torch.bfloat16): | 308 | + hf32_mode = tla.params.HF32Mode.HF32_NEAREST_EVEN |
| 292 | - ref = ref.to(dtype_c).float() | 309 | + enable_hf32 = ( |
| 310 | + hf32_mode != tla.params.HF32Mode.HF32_DISABLE | ||
| 311 | + and dtype_a == torch.float32 | ||
| 312 | + and dtype_b == torch.float32 | ||
| 313 | + ) | ||
| 314 | + if enable_hf32: | ||
| 315 | + ref = to_hf32(a, hf32_mode) @ to_hf32(b, hf32_mode) | ||
| 316 | + else: | ||
| 317 | + ref = a.float() @ b.float() | ||
| 318 | + if dtype_c in (torch.float16, torch.bfloat16): | ||
| 319 | + ref = ref.to(dtype_c).float() | ||
| 293 | 320 | ||
| 294 | a = ( | 321 | a = ( |
| 295 | a.contiguous() if args.layout_a == "row" else a.permute(1, 0).contiguous() | 322 | a.contiguous() if args.layout_a == "row" else a.permute(1, 0).contiguous() |
| @@ -308,13 +335,18 @@ def run(args: argparse.Namespace) -> int: | |||
| 308 | b_tensor, | 335 | b_tensor, |
| 309 | c_tensor, | 336 | c_tensor, |
| 310 | TilingParams(), # default tiling: L1: (256, 256, 128); L0: (256, 256, 32) | 337 | TilingParams(), # default tiling: L1: (256, 256, 128); L0: (256, 256, 32) |
| 338 | + hf32_mode, | ||
| 311 | options="--npu-arch 3510", | 339 | options="--npu-arch 3510", |
| 312 | ) | 340 | ) |
| 313 | block_num = get_block_num(args.block_num, args.device, kind="cube") | 341 | block_num = get_block_num(args.block_num, args.device, kind="cube") |
| 314 | artifact(a_tensor, b_tensor, c_tensor, block_num=block_num) | 342 | artifact(a_tensor, b_tensor, c_tensor, block_num=block_num) |
| 315 | torch.npu.synchronize() | 343 | torch.npu.synchronize() |
| 316 | 344 | ||
| 317 | - passed = compare(c.detach().cpu(), ref, args.k) | 345 | + result = c.detach().cpu() |
| 346 | + if enable_hf32: | ||
| 347 | + passed = compare(result, ref, enable_hf32=True) | ||
| 348 | + else: | ||
| 349 | + passed = compare(result, ref, args.k) | ||
| 318 | print(f"passed={passed} cache_key={artifact.cache_key}") | 350 | print(f"passed={passed} cache_key={artifact.cache_key}") |
| 319 | print(f"kernel.o={artifact.kernel_binary_path}") | 351 | print(f"kernel.o={artifact.kernel_binary_path}") |
| 320 | return 0 if passed else 1 | 352 | return 0 if passed else 1 |
Rpython/tla_dsl/examples/end_to_end/basic_mmad_evg/README.md→python/tla_dsl/examples/end_to_end/basic_mmad_epilogue/README.md+30-17
| @@ -1,24 +1,24 @@ | |||
| 1 | -# Matmul EVG 端到端示例 | 1 | +# CV (Cube + Vector) 融合后处理类 端到端示例 |
| 2 | 2 | ||
I basic_mmad_evg更名为_epilogue后,需要更新相关测试件中命名 ![]() ![]() | |||
| 3 | -本目录下提供的系列样例演示 **CATLASS DSL** 下 基于 Ascend950 的 GEMM + EVG(Epilogue Visitor Graph)尾处理,对齐 C++ 参考实现 `examples/64_ascend950_matmul_evg_*`。 | 3 | +本目录下提供的系列样例演示 **CATLASS DSL** 下系列后处理类CV(Cube + Vector)融合算子的计算过程。 |
| 4 | 4 | ||
| 5 | ## 功能说明 | 5 | ## 功能说明 |
| 6 | 6 | ||
| 7 | -基础矩阵乘算子实现形如 `(m, k)` 和 `(k, n)` 两矩阵的乘法,输出形如 `(m, n)`: | 7 | +后处理类算子实现基础矩阵乘并复合后续计算步骤。 |
| 8 | 8 | ||
| 9 | $$ | 9 | $$ |
| 10 | \begin{aligned} | 10 | \begin{aligned} |
| 11 | -D &= A \times B \oplus \text{Epilogue} | 11 | +D &= f(A \times B) |
| 12 | \end{aligned} | 12 | \end{aligned} |
| 13 | $$ | 13 | $$ |
| 14 | 14 | ||
| 15 | -各变体在 GEMM 之后接入不同的 EVG 尾处理算子(Add、Bias、LeakyRelu、Sigmoid、Silu、Tanh 等),由 AIV 融合完成。 | 15 | +本目录下样例包含的后处理操作见后续介绍。 |
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | ## 代码组织 | 18 | ## 代码组织 |
| 19 | 19 | ||
| 20 | ```plain | 20 | ```plain |
| 21 | -./basic_mmad_evg | 21 | +./basic_mmad_epilogue |
| 22 | ├── matmul_add.py | 22 | ├── matmul_add.py |
| 23 | ├── matmul_add_ub.py | 23 | ├── matmul_add_ub.py |
| 24 | ├── matmul_bias.py | 24 | ├── matmul_bias.py |
| @@ -31,16 +31,18 @@ $$ | |||
| 31 | 31 | ||
| 32 | | 文件 | 概述 | | 32 | | 文件 | 概述 | |
| 33 | |------|------| | 33 | |------|------| |
| 34 | -| [**`matmul_add.py`**](matmul_add.py) | D = A×B + X;L0C→GM + AIV。 | | 34 | +| [**`matmul_add.py`**](matmul_add.py) | 实现 `D = A@B + X` 计算功能。 | |
| 35 | -| [**`matmul_add_ub.py`**](matmul_add_ub.py) | D = A×B + X;L0C→UB + AIV。 | | 35 | +| [**`matmul_add_ub.py`**](matmul_add_ub.py) | 实现 `D = A@B + X` 计算功能,启用L0C -> UB通路将矩阵乘结果搬出到 UB。 | |
| 36 | -| [**`matmul_bias.py`**](matmul_bias.py) | D = A×B + bias(1×N);L0C→GM + RowBroadcast。 | | 36 | +| [**`matmul_bias.py`**](matmul_bias.py) | 实现 `D = A@B + bias` 计算功能,其中 `bias` 为一维 `(n,)` 的广播向量。 | |
| 37 | -| [**`matmul_leaky_relu.py`**](matmul_leaky_relu.py) | D = LeakyRelu(A×B),α=0.1;L0C→GM + AIV。 | | 37 | +| [**`matmul_leaky_relu.py`**](matmul_leaky_relu.py) | 实现 `D = LeakyRelu(A@B)` 计算功能,其中`α` 默认为 `0.1`。 | |
| 38 | -| [**`matmul_sigmoid.py`**](matmul_sigmoid.py) | D = Sigmoid(A×B);L0C→GM + AIV。 | | 38 | +| [**`matmul_sigmoid.py`**](matmul_sigmoid.py) | 实现 `D = Sigmoid(A@B)` 计算功能。 | |
| 39 | -| [**`matmul_silu.py`**](matmul_silu.py) | D = Silu(A×B);L0C→GM + AIV。 | | 39 | +| [**`matmul_silu.py`**](matmul_silu.py) | 实现 `D = Silu(A@B)` 计算功能。 | |
| 40 | -| [**`matmul_tanh.py`**](matmul_tanh.py) | D = Tanh(A×B);L0C→GM + AIV。 | | 40 | +| [**`matmul_tanh.py`**](matmul_tanh.py) | 实现 `D = Tanh(A@B)` 计算功能。 | |
| 41 | 41 | ||
| 42 | ## 约束说明 | 42 | ## 约束说明 |
| 43 | 43 | ||
| 44 | + - 左、右矩阵及结果矩阵所支持的数据组合类型如下。 | ||
| 45 | + | ||
| 44 | | 算子 | `DTYPE_A` / `DTYPE_B` | `DTYPE_C` | | 46 | | 算子 | `DTYPE_A` / `DTYPE_B` | `DTYPE_C` | |
| 45 | |------|-------------------|---------| | 47 | |------|-------------------|---------| |
| 46 | | add, bias, leaky_relu, sigmoid, silu | f16 / bf16 / f32 | f16 或 f32 | | 48 | | add, bias, leaky_relu, sigmoid, silu | f16 / bf16 / f32 | f16 或 f32 | |
| @@ -61,8 +63,10 @@ $$ | |||
| 61 | | `--m` | `256` | 矩阵乘左矩阵 A 的行数 | | 63 | | `--m` | `256` | 矩阵乘左矩阵 A 的行数 | |
| 62 | | `--n` | `256` | 矩阵乘右矩阵 B 的列数 | | 64 | | `--n` | `256` | 矩阵乘右矩阵 B 的列数 | |
| 63 | | `--k` | `256` | 矩阵乘累加轴的大小 | | 65 | | `--k` | `256` | 矩阵乘累加轴的大小 | |
| 64 | -| `--layout-a` / `--layout-b` | `row` / `row` | 左、右矩阵 A、B 的数据排布格式,可选 `"row"` 或 `"col"`,表示行优先或列优先布局。 | | 66 | +| `--layout-a` / `--layout-b` | `"row"` / `"row"` | 左、右矩阵 A、B 的数据排布格式,可选 `"row"` 或 `"col"`,表示行优先或列优先布局。 | |
| 65 | -| `--dtype-a` / `--dtype-b` / `--dtype-c` | `f32` / `f32` / `f32` | 左、右矩阵 A、B 和结果矩阵 C 的数据类型,可选范围参考约束说明。 | | 67 | +| `--dtype-a` / `--dtype-b` | `"f32"` / `"f32"` | 左、右矩阵 A、B 的数据类型,可选范围参考约束说明。 | |
| 68 | +| `--dtype-c` | `"f32"` | 结果矩阵 C 的数据类型,可选范围参考约束说明(`add_ub` / `tanh` 仅支持 f32)。 | | ||
| 69 | +| `--block-num` | `-1` | 启用的 AIC 核数,`-1` 表示自动探测可用核数(满核)。 | | ||
| 66 | 70 | ||
| 67 | 71 | ||
| 68 | ### 执行示例 | 72 | ### 执行示例 |
| @@ -73,9 +77,18 @@ $$ | |||
| 73 | cd python/tla_dsl | 77 | cd python/tla_dsl |
| 74 | 78 | ||
| 75 | # 其余变体替换文件名即可 | 79 | # 其余变体替换文件名即可 |
| 76 | -python examples/end_to_end/basic_mmad_evg/matmul_add.py --device 0 \ | 80 | +python examples/end_to_end/basic_mmad_epilogue/matmul_add.py --device 0 \ |
| 77 | --m 256 --n 256 --k 256 \ | 81 | --m 256 --n 256 --k 256 \ |
| 78 | --layout-a row --layout-b row \ | 82 | --layout-a row --layout-b row \ |
| 79 | --dtype-a f16 --dtype-b f16 --dtype-c f32 | 83 | --dtype-a f16 --dtype-b f16 --dtype-c f32 |
| 80 | - | ||
| 81 | ``` | 84 | ``` |
| 85 | + | ||
| 86 | +默认测试条件下,预期输出: | ||
| 87 | + | ||
| 88 | +```text | ||
| 89 | +--- mnk=(256,256,256) layout=row/row dtype=f16/f16/f32 --- | ||
| 90 | +passed=True cache_key=<cache_key> | ||
| 91 | +kernel.o=<cache_dir>/<cache_key>/kernel.o | ||
| 92 | +``` | ||
| 93 | + | ||
| 94 | +其中 `passed`结果为`True`或`False` 表明 NPU 计算结果与golden参考值精度校验是否通过;`cache_dir` 是指定的缓存目录, `cache_key` 是编译缓存的哈希值。 | ||
Rpython/tla_dsl/examples/end_to_end/basic_mmad_evg/matmul_add.py→python/tla_dsl/examples/end_to_end/basic_mmad_epilogue/matmul_add.py+0-0
文件重命名但无更改。
Rpython/tla_dsl/examples/end_to_end/basic_mmad_evg/matmul_add_ub.py→python/tla_dsl/examples/end_to_end/basic_mmad_epilogue/matmul_add_ub.py+0-0
文件重命名但无更改。
Rpython/tla_dsl/examples/end_to_end/basic_mmad_evg/matmul_bias.py→python/tla_dsl/examples/end_to_end/basic_mmad_epilogue/matmul_bias.py+0-0
文件重命名但无更改。
Rpython/tla_dsl/examples/end_to_end/basic_mmad_evg/matmul_leaky_relu.py→python/tla_dsl/examples/end_to_end/basic_mmad_epilogue/matmul_leaky_relu.py+0-0
文件重命名但无更改。
Rpython/tla_dsl/examples/end_to_end/basic_mmad_evg/matmul_sigmoid.py→python/tla_dsl/examples/end_to_end/basic_mmad_epilogue/matmul_sigmoid.py+0-0
文件重命名但无更改。
Rpython/tla_dsl/examples/end_to_end/basic_mmad_evg/matmul_silu.py→python/tla_dsl/examples/end_to_end/basic_mmad_epilogue/matmul_silu.py+0-0
文件重命名但无更改。
Rpython/tla_dsl/examples/end_to_end/basic_mmad_evg/matmul_tanh.py→python/tla_dsl/examples/end_to_end/basic_mmad_epilogue/matmul_tanh.py+0-0
文件重命名但无更改。
| @@ -1,6 +1,6 @@ | |||
| 1 | # StreamK MMAD 端到端示例 | 1 | # StreamK MMAD 端到端示例 |
| 2 | 2 | ||
| 3 | -本目录下的样例演示 **CATLASS DSL** 下 StreamK MatMul 的实现,对齐 C++ 参考实现`examples/66_ascend950_streamk_matmul`。 | 3 | +本目录下的样例演示 **CATLASS DSL** 下 StreamK MatMul 的实现。 |
| 4 | 4 | ||
| 5 | ## 功能说明 | 5 | ## 功能说明 |
| 6 | 6 | ||
| @@ -53,15 +53,13 @@ StreamK 通过将 K 维度的计算分摊到多个核上以均衡负载:normal | |||
| 53 | | 参数 | 默认值 | 说明 | | 53 | | 参数 | 默认值 | 说明 | |
| 54 | |------|--------|------| | 54 | |------|--------|------| |
| 55 | | `--device` | `0` | 上板执行使用的 NPU 设备号。 | | 55 | | `--device` | `0` | 上板执行使用的 NPU 设备号。 | |
| 56 | -| `--run` | 默认开启 | 上板并校验精度。 | | ||
| 57 | | `--m` | `256` | 矩阵乘左矩阵 A 的行数 | | 56 | | `--m` | `256` | 矩阵乘左矩阵 A 的行数 | |
| 58 | | `--n` | `256` | 矩阵乘右矩阵 B 的列数 | | 57 | | `--n` | `256` | 矩阵乘右矩阵 B 的列数 | |
| 59 | | `--k` | `512` | 矩阵乘累加轴的大小 | | 58 | | `--k` | `512` | 矩阵乘累加轴的大小 | |
| 60 | | `--layout-a` / `--layout-b` | `"row"` / `"row"` | 左、右矩阵 A、B 的数据排布格式,可选 `"row"` 或 `"col"`,表示行优先或列优先布局。 | | 59 | | `--layout-a` / `--layout-b` | `"row"` / `"row"` | 左、右矩阵 A、B 的数据排布格式,可选 `"row"` 或 `"col"`,表示行优先或列优先布局。 | |
| 61 | | `--dtype-a` / `--dtype-b` / `--dtype-c` | `"f16"` / `"f16"` / `"f32"` | 左、右矩阵 A、B 和结果矩阵 C 的数据类型,可选范围参考约束说明。 | | 60 | | `--dtype-a` / `--dtype-b` / `--dtype-c` | `"f16"` / `"f16"` / `"f32"` | 左、右矩阵 A、B 和结果矩阵 C 的数据类型,可选范围参考约束说明。 | |
| 62 | -| `--block` | `None` | 启用的 AIC 核数。 | | 61 | +| `--block-num` | `-1` | 启用的 AIC 核数,`-1` 表示自动探测可用核数(满核)。 | |
| 63 | - | 62 | +| `--atol` | `1e-3` | 精度比对时的绝对容差。 | |
| 64 | -其余参数(`--sentinel`、`--atol`、`--cache-dir`、`--force-recompile`、`--no-cache` 等)详见 `--help`。 | ||
| 65 | 63 | ||
| 66 | ### 执行示例 | 64 | ### 执行示例 |
| 67 | 65 | ||
| @@ -70,18 +68,18 @@ StreamK 通过将 K 维度的计算分摊到多个核上以均衡负载:normal | |||
| 70 | ```bash | 68 | ```bash |
| 71 | cd python/tla_dsl | 69 | cd python/tla_dsl |
| 72 | 70 | ||
| 73 | -# 上板并校验(默认即 --run,精度校验默认开启) | 71 | +# 上板并校验精度 |
| 74 | -python examples/end_to_end/basic_mmad_streamk/basic_mmad_streamk.py --run --device 0 \ | 72 | +python examples/end_to_end/basic_mmad_streamk/basic_mmad_streamk.py --device 0 \ |
| 75 | --layout-a row --layout-b col \ | 73 | --layout-a row --layout-b col \ |
| 76 | --dtype-a f16 --dtype-b f16 --dtype-c f32 | 74 | --dtype-a f16 --dtype-b f16 --dtype-c f32 |
| 77 | ``` | 75 | ``` |
| 78 | 76 | ||
| 77 | +默认测试条件下,预期输出: | ||
| 79 | 78 | ||
| 80 | - | 79 | +```text |
| 81 | -```bash | 80 | +--- mnk=(256,256,512) layout=row/col dtype=f16/f16/f32 --- |
| 82 | -python examples/end_to_end/basic_mmad_streamk/basic_mmad_streamk.py --help | 81 | +passed=True cache_key=<cache_key> |
| 82 | +kernel.o=<cache_dir>/<cache_key>/kernel.o | ||
| 83 | ``` | 83 | ``` |
| 84 | 84 | ||
| 85 | -执行测试后,预期输出: | 85 | +其中 `passed`结果为`True`或`False` 表明 NPU 计算结果与golden参考值精度校验是否通过;`cache_dir` 是指定的缓存目录, `cache_key` 是编译缓存的哈希值。 |
| 86 | - | ||
| 87 | -默认运行会打印 `compile_ok=True`、`host=torch_npu`、`launch_ok=True`、`kernel.o` 路径,以及 `C unchanged?` / `C equals expected matmul?` / `first mismatch=...` 等(与 `m×n×k`、block、`--sentinel`、dtype 有关;golden 为 **Torch** 在 NPU 上的 matmul)。 | ||
| @@ -60,7 +60,7 @@ basic_vadd.py [-h] [--device DEVICE] [--n N] | |||
| 60 | |------|--------|------| | 60 | |------|--------|------| |
| 61 | | `--device` | `0` | 上板执行使用的 NPU 设备号。 | | 61 | | `--device` | `0` | 上板执行使用的 NPU 设备号。 | |
| 62 | | `--n` | `400` | 向量长度。 | | 62 | | `--n` | `400` | 向量长度。 | |
| 63 | -| `--block-num` | `-1`(依据所使用的 NPU 设备采集其满核值) | 所启用的 AI Vector 核数 | | 63 | +| `--block-num` | `-1` | 启用的核数,`-1` 表示自动探测可用核数(满核)。 | |
| 64 | | `--dtype` | `"f32"` | 数据类型,可选 `"f32"`、`"f16"`、`"i8"`、`"i16"`、`"i32"`。 | | 64 | | `--dtype` | `"f32"` | 数据类型,可选 `"f32"`、`"f16"`、`"i8"`、`"i16"`、`"i32"`。 | |
| 65 | | `--use-mutex` | `False` | 切换到显式 Mutex `lock` / `unlock` 同步(执行 `basic_vadd_mutex`)。 | | 65 | | `--use-mutex` | `False` | 切换到显式 Mutex `lock` / `unlock` 同步(执行 `basic_vadd_mutex`)。 | |
| 66 | | `--use-mutex-with` | `False` | 切换到 `with tla.mutex_guard(...)` 同步(执行 `basic_vadd_mutex_with`)。 | | 66 | | `--use-mutex-with` | `False` | 切换到 `with tla.mutex_guard(...)` 同步(执行 `basic_vadd_mutex_with`)。 | |
| @@ -125,7 +125,7 @@ tla.copy(ub_a, gm_a) | |||
| 125 | mutex_ub_a.unlock(pipe=tla.arch.MTE2) | 125 | mutex_ub_a.unlock(pipe=tla.arch.MTE2) |
| 126 | ``` | 126 | ``` |
| 127 | 127 | ||
| 128 | -## basic_vadd_mutex_with | 128 | +### basic_vadd_mutex_with |
| 129 | 129 | ||
| 130 | **文件**:[`basic_vadd.py`](basic_vadd.py#L127) | 130 | **文件**:[`basic_vadd.py`](basic_vadd.py#L127) |
| 131 | 131 | ||
| @@ -139,7 +139,7 @@ with tla.mutex_guard(mutex_ub_a): | |||
| 139 | tla.copy(ub_a, gm_a) | 139 | tla.copy(ub_a, gm_a) |
| 140 | ``` | 140 | ``` |
| 141 | 141 | ||
| 142 | -## basic_vadd_atomic_add | 142 | +### basic_vadd_atomic_add |
| 143 | 143 | ||
| 144 | **文件**:[`basic_vadd.py`](basic_vadd.py#L175) | 144 | **文件**:[`basic_vadd.py`](basic_vadd.py#L175) |
| 145 | 145 | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | # Batched Matmul 端到端示例 | 1 | # Batched Matmul 端到端示例 |
| 2 | 2 | ||
| 3 | -本目录下的样例演示 **CATLASS DSL** 下的批量矩阵乘,对齐 C++ 参考实现 `examples/67_ascend950_batched_matmul*`。 | 3 | +本目录下的样例演示 **CATLASS DSL** 下的批量矩阵乘。 |
| 4 | 4 | ||
| 5 | ## 功能说明 | 5 | ## 功能说明 |
| 6 | 6 | ||
| @@ -12,8 +12,6 @@ $$ | |||
| 12 | 12 | ||
| 13 | 各 batch 的 `(M, N, K)` 相同。 | 13 | 各 batch 的 `(M, N, K)` 相同。 |
| 14 | 14 | ||
| 15 | - | ||
| 16 | - | ||
| 17 | ## 代码组织 | 15 | ## 代码组织 |
| 18 | 16 | ||
| 19 | ```plain | 17 | ```plain |
| @@ -22,21 +20,21 @@ $$ | |||
| 22 | └── README.md | 20 | └── README.md |
| 23 | ``` | 21 | ``` |
| 24 | 22 | ||
| 25 | -| 文件 | 概述 | | 23 | +| 文件 | 概述 | |
| 26 | -|------|------| | 24 | +| --------------------------------------------------- | --------------------------------------------------------------------------------------------------- | |
| 27 | -| [**`batched_matmul.py`**](batched_matmul.py) | 设备侧 `@tla.kernel` 与 host 侧运行/校验逻辑同文件。执行数据生成、compile/launch、以及golden比对。 | | 25 | +| [**`batched_matmul.py`**](batched_matmul.py) | 设备侧`@tla.kernel` 与 host 侧运行/校验逻辑同文件。执行数据生成、compile/launch、以及golden比对。 | |
| 28 | 26 | ||
| 29 | ## 约束说明 | 27 | ## 约束说明 |
| 30 | 28 | ||
| 31 | - - 左、右矩阵及结果矩阵所支持的数据组合类型如下。 | 29 | +- 左、右矩阵及结果矩阵所支持的数据组合类型如下。 |
| 32 | 30 | ||
| 33 | | `DTYPE_A` | `DTYPE_B` | `DTYPE_C` | | 31 | | `DTYPE_A` | `DTYPE_B` | `DTYPE_C` | |
| 34 | -|---------|---------|------------------| | 32 | +| ----------- | ----------- | ----------- | |
| 35 | -| f16 | f16 | f32 | | 33 | +| f16 | f16 | f32 | |
| 36 | -| f16 | f16 | f16 | | 34 | +| f16 | f16 | f16 | |
| 37 | -| bf16 | bf16 | f32 | | 35 | +| bf16 | bf16 | f32 | |
| 38 | -| bf16 | bf16 | bf16 | | 36 | +| bf16 | bf16 | bf16 | |
| 39 | -| f32 | f32 | f32 | | 37 | +| f32 | f32 | f32 | |
| 40 | 38 | ||
| 41 | ## 使用示例 | 39 | ## 使用示例 |
| 42 | 40 | ||
| @@ -44,33 +42,34 @@ $$ | |||
| 44 | 42 | ||
| 45 | ### 命令行参数 | 43 | ### 命令行参数 |
| 46 | 44 | ||
| 47 | -| 参数 | 默认值 | 说明 | | 45 | +| 参数 | 默认值 | 说明 | |
| 48 | -|------|--------|------| | 46 | +| --------------------------------------------- | --------------------------------- | ------------------------------------------------------------------------------------ | |
| 49 | -| `--device` | `0` | 上板执行使用的 NPU 设备号。 | | 47 | +| `--device` | `0` | 上板执行使用的 NPU 设备号。 | |
| 50 | -| `--batch` | `5` | batch 数 B。 | | 48 | +| `--batch` | `5` | batch 数 B。 | |
| 51 | -| `--m` | `256` | 矩阵乘左矩阵 A 的行数 | | 49 | +| `--m` | `256` | 矩阵乘左矩阵 A 的行数 | |
| 52 | -| `--n` | `512` | 矩阵乘右矩阵 B 的列数 | | 50 | +| `--n` | `512` | 矩阵乘右矩阵 B 的列数 | |
| 53 | -| `--k` | `1024` | 矩阵乘累加轴的大小 | | 51 | +| `--k` | `1024` | 矩阵乘累加轴的大小 | |
| 54 | -| `--layout-a` / `--layout-b` | `"row"` / `"row"` | 左、右矩阵 A、B 的数据排布格式,可选 `"row"` 或 `"col"`,表示行优先或列优先布局。 | | 52 | +| `--layout-a` / `--layout-b` | `"row"` / `"row"` | 左、右矩阵 A、B 的数据排布格式,可选`"row"` 或 `"col"`,表示行优先或列优先布局。 | |
| 55 | -| `--dtype-a` / `--dtype-b` / `--dtype-c` | `f16` / `f16` / `f16` | 左、右矩阵 A、B 和结果矩阵 C 的数据类型,可选范围参考约束说明。 | | 53 | +| `--dtype-a` / `--dtype-b` / `--dtype-c` | `"f16"` / `"f16"` / `"f32"` | 左、右矩阵 A、B 和结果矩阵 C 的数据类型,可选范围参考约束说明。 | |
| 56 | -| `--block` | `8` | 启用的核数。 | | 54 | +| `--block-num` | `-1` | 启用的核数,`-1` 表示自动探测可用核数(满核)。 | |
| 57 | 55 | ||
| 58 | ### 执行示例 | 56 | ### 执行示例 |
| 59 | 57 | ||
| 60 | 在 `python/tla_dsl` 目录下执行: | 58 | 在 `python/tla_dsl` 目录下执行: |
| 61 | 59 | ||
| 62 | ```bash | 60 | ```bash |
| 63 | -cd "${CATLASS_ROOT}/python/tla_dsl/examples/end_to_end/batched_matmul" | 61 | +cd python/tla_dsl |
| 64 | - | ||
| 65 | -python batched_matmul.py --run --device 0 --batch 4 --m 256 --n 256 --k 256 --block 8 | ||
| 66 | 62 | ||
| 63 | +python examples/end_to_end/batched_matmul/batched_matmul.py --device 0 \ | ||
| 64 | + --batch 4 --m 256 --n 256 --k 256 | ||
| 67 | ``` | 65 | ``` |
| 68 | 66 | ||
| 69 | -执行测试后,预期输出: | 67 | +默认测试条件下,预期输出: |
| 70 | 68 | ||
| 71 | ```text | 69 | ```text |
| 72 | -compile_ok=True ... | 70 | +--- batch=(4) mnk=(256,256,256) layout=row/row dtype=f16/f16/f32 --- |
| 73 | -launch_ok=True | 71 | +passed=True cache_key=<cache_key> |
| 74 | -C equals batched golden? True | 72 | +kernel.o=<cache_dir>/<cache_key>/kernel.o |
| 75 | -first mismatch=None | ||
| 76 | ``` | 73 | ``` |
| 74 | + | ||
| 75 | +其中 `passed`结果为`True`或`False` 表明 NPU 计算结果与golden参考值精度校验是否通过;`cache_dir` 是指定的缓存目录, `cache_key` 是编译缓存的哈希值。 | ||
| @@ -10,7 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | from .golden import compare, tolerance | 11 | from .golden import compare, tolerance |
| 12 | from .params import TilingParams, SwizzleParams | 12 | from .params import TilingParams, SwizzleParams |
| 13 | -from .utils import create_tla_tensor, get_block_num | 13 | +from .utils import create_tla_tensor, get_block_num, to_hf32 |
| 14 | 14 | ||
| 15 | __all__ = [ | 15 | __all__ = [ |
| 16 | # struct-like params | 16 | # struct-like params |
| @@ -19,6 +19,7 @@ __all__ = [ | |||
| 19 | # helper function | 19 | # helper function |
| 20 | "create_tla_tensor", | 20 | "create_tla_tensor", |
| 21 | "get_block_num", | 21 | "get_block_num", |
| 22 | + "to_hf32", | ||
| 22 | # golden compare | 23 | # golden compare |
| 23 | "compare", | 24 | "compare", |
| 24 | "tolerance", | 25 | "tolerance", |
| @@ -12,6 +12,12 @@ from typing import overload | |||
| 12 | 12 | ||
| 13 | import torch | 13 | import torch |
| 14 | 14 | ||
| 15 | +# HF32 mixed tolerance thresholds. | ||
| 16 | +_HF32_RTOL = 2.0**-9 | ||
| 17 | +_HF32_ATOL = 2.0**-10 | ||
| 18 | +_HF32_REQUIRED_MATCHED_RATIO = 0.99 | ||
| 19 | +_HF32_MAX_ABS_ERROR_LIMIT = 1e-1 | ||
| 20 | + | ||
| 15 | 21 | ||
| 16 | def tolerance( | 22 | def tolerance( |
| 17 | expected: torch.Tensor, | 23 | expected: torch.Tensor, |
| @@ -32,6 +38,27 @@ def tolerance( | |||
| 32 | return rtol * torch.maximum(torch.full_like(expected, floor), expected.abs()) | 38 | return rtol * torch.maximum(torch.full_like(expected, floor), expected.abs()) |
| 33 | 39 | ||
| 34 | 40 | ||
| 41 | +def _compare_hf32( | ||
| 42 | + result: torch.Tensor, | ||
| 43 | + expected: torch.Tensor, | ||
| 44 | +) -> bool: | ||
| 45 | + """Compare result against an HF32-semantic golden.""" | ||
| 46 | + result = result.float() | ||
| 47 | + expected = expected.float() | ||
| 48 | + diff = (result - expected).abs() | ||
| 49 | + matched = diff <= _HF32_ATOL + _HF32_RTOL * expected.abs() | ||
| 50 | + matched_ratio = matched.float().mean().item() | ||
| 51 | + max_abs_error = diff.max().item() | ||
| 52 | + ulp = torch.finfo(expected.dtype).eps * ( | ||
| 53 | + 2.0 ** torch.floor(torch.log2(expected.abs().max())) | ||
| 54 | + ) | ||
| 55 | + max_abs_error_limit = max(_HF32_MAX_ABS_ERROR_LIMIT, 32.0 * ulp.item()) | ||
| 56 | + return bool( | ||
| 57 | + matched_ratio >= _HF32_REQUIRED_MATCHED_RATIO | ||
| 58 | + and max_abs_error <= max_abs_error_limit | ||
| 59 | + ) | ||
| 60 | + | ||
| 61 | + | ||
| 35 | 62 | ||
| 36 | def compare( | 63 | def compare( |
| 37 | result: torch.Tensor, | 64 | result: torch.Tensor, |
| @@ -48,6 +75,7 @@ def compare( | |||
| 48 | result: torch.Tensor, | 75 | result: torch.Tensor, |
| 49 | expected: torch.Tensor, | 76 | expected: torch.Tensor, |
| 50 | *, | 77 | *, |
| 78 | + enable_hf32: bool = False, | ||
| 51 | rtol: float = 0.0, | 79 | rtol: float = 0.0, |
| 52 | atol: float = 0.0, | 80 | atol: float = 0.0, |
| 53 | ) -> bool: ... | 81 | ) -> bool: ... |
| @@ -61,15 +89,21 @@ def compare( | |||
| 61 | rtol: float | None = None, | 89 | rtol: float | None = None, |
| 62 | floor: float | None = None, | 90 | floor: float | None = None, |
| 63 | atol: float = 0.0, | 91 | atol: float = 0.0, |
| 92 | + enable_hf32: bool = False, | ||
| 64 | ) -> bool: | 93 | ) -> bool: |
| 65 | """Compare ``result`` against ``expected`` with given threshold. | 94 | """Compare ``result`` against ``expected`` with given threshold. |
| 66 | 95 | ||
| 67 | - Two call forms are supported: | 96 | + Three call forms are supported: |
| 68 | 97 | ||
| 69 | 1. Accumulative precision standard (``k`` given), for matmul-like operators. | 98 | 1. Accumulative precision standard (``k`` given), for matmul-like operators. |
| 70 | 2. Generic element-wise check. | 99 | 2. Generic element-wise check. |
| 100 | + 3. HF32 mixed tolerance (``enable_hf32=True``). | ||
| 71 | """ | 101 | """ |
| 102 | + if enable_hf32: | ||
| 103 | + # Use mixed tolerance for HF32. | ||
| 104 | + return _compare_hf32(result, expected) | ||
| 72 | if k is not None and isinstance(k, int): | 105 | if k is not None and isinstance(k, int): |
| 106 | + # Single precision standard. | ||
| 73 | is_bf16 = result.dtype == torch.bfloat16 | 107 | is_bf16 = result.dtype == torch.bfloat16 |
| 74 | result, expected = result.float(), expected.float() | 108 | result, expected = result.float(), expected.float() |
| 75 | return bool( | 109 | return bool( |
| @@ -81,6 +115,7 @@ def compare( | |||
| 81 | if result.dtype != expected.dtype: | 115 | if result.dtype != expected.dtype: |
| 82 | raise TypeError("the data type between the golden and the result do not match") | 116 | raise TypeError("the data type between the golden and the result do not match") |
| 83 | if result.dtype in (torch.float32, torch.float16, torch.bfloat16): | 117 | if result.dtype in (torch.float32, torch.float16, torch.bfloat16): |
| 118 | + # Generic element-wise precision check. | ||
| 84 | return bool( | 119 | return bool( |
| 85 | torch.isclose( | 120 | torch.isclose( |
| 86 | result, expected, rtol=0.0 if rtol is None else rtol, atol=atol | 121 | result, expected, rtol=0.0 if rtol is None else rtol, atol=atol |
| @@ -38,3 +38,35 @@ def get_block_num(block_num: int, device: int = 0, *, kind: str = "vector") -> i | |||
| 38 | def create_tla_tensor(buf, layout: str): | 38 | def create_tla_tensor(buf, layout: str): |
| 39 | tag = tla.arch.RowMajor if layout == "row" else tla.arch.ColumnMajor | 39 | tag = tla.arch.RowMajor if layout == "row" else tla.arch.ColumnMajor |
| 40 | return from_dlpack(buf.contiguous(), layout_tag=tag).mark_layout_dynamic() | 40 | return from_dlpack(buf.contiguous(), layout_tag=tag).mark_layout_dynamic() |
| 41 | + | ||
| 42 | + | ||
| 43 | +def to_hf32( | ||
| 44 | + x: torch.Tensor, | ||
| 45 | + hf32_mode: tla.params.HF32Mode, | ||
| 46 | +) -> torch.Tensor: | ||
| 47 | + """Simulate HF32 rounding mode on f32 values. | ||
| 48 | + | ||
| 49 | + HF32 keeps the FP32 sign and 8-bit exponent, and reduces the mantissa to | ||
| 50 | + 11 significant bits (10 explicit mantissa bits, close to FP16): | ||
| 51 | + | ||
| 52 | + - ``HF32_NEAREST_ZERO`` rounds to nearest, ties toward zero. | ||
| 53 | + - ``HF32_NEAREST_EVEN`` rounds them to nearest-even. | ||
| 54 | + """ | ||
| 55 | + if not isinstance(hf32_mode, tla.params.HF32Mode): | ||
| 56 | + raise TypeError( | ||
| 57 | + f"hf32_mode must be a tla.params.HF32Mode, got {type(hf32_mode).__name__}" | ||
| 58 | + ) | ||
| 59 | + x = x.float() | ||
| 60 | + if hf32_mode == tla.params.HF32Mode.HF32_DISABLE: | ||
| 61 | + return x | ||
| 62 | + | ||
| 63 | + bits = x.contiguous().view(torch.int32) | ||
| 64 | + if hf32_mode == tla.params.HF32Mode.HF32_NEAREST_ZERO: | ||
| 65 | + rounded_bits = (bits + 0x0FFF) & ~0x1FFF | ||
| 66 | + elif hf32_mode == tla.params.HF32Mode.HF32_NEAREST_EVEN: | ||
| 67 | + lsb = (bits >> 13) & 1 | ||
| 68 | + rounded_bits = (bits + 0x0FFF + lsb) & ~0x1FFF | ||
| 69 | + else: | ||
| 70 | + raise ValueError(f"Unsupported HF32 mode: {hf32_mode!r}") | ||
| 71 | + | ||
| 72 | + return rounded_bits.view(torch.float32) | ||
| @@ -95,7 +95,7 @@ flash_attention_infer.py [-h] [--device DEVICE] [--dtype {f16,bf16}] | |||
| 95 | | `--kvheadnum` | `1` | KV 头数,覆盖 `KV_HEAD_NUM`。 | | 95 | | `--kvheadnum` | `1` | KV 头数,覆盖 `KV_HEAD_NUM`。 | |
| 96 | | `--qseqlen` | `117` | Q 序列长度,覆盖 `Q_SEQ`。 | | 96 | | `--qseqlen` | `117` | Q 序列长度,覆盖 `Q_SEQ`。 | |
| 97 | | `--kvseqlen` | `512` | KV 序列长度,覆盖 `KV_SEQ`。 | | 97 | | `--kvseqlen` | `512` | KV 序列长度,覆盖 `KV_SEQ`。 | |
| 98 | -| `--block-num` | `-1` | 所启用的 AI Core 核数;`-1` 表示满 AIC(`cube_core_num`)。 | | 98 | +| `--block-num` | `-1` | 启用的核数,`-1` 表示自动探测可用核数(满核)。 | |
| 99 | | `--sentinel` | `-7.0` | O 的初始值,用于对比检测 kernel 是否真正写入。 | | 99 | | `--sentinel` | `-7.0` | O 的初始值,用于对比检测 kernel 是否真正写入。 | |
| 100 | 100 | ||
| 101 | ### 执行示例 | 101 | ### 执行示例 |
| @@ -1,6 +1,6 @@ | |||
| 1 | # Grouped Matmul Slice-M 端到端示例 | 1 | # Grouped Matmul Slice-M 端到端示例 |
| 2 | 2 | ||
| 3 | -本目录下的样例演示 **CATLASS DSL** 下按 M 切分的分组矩阵乘,对齐 C++ 参考实现`examples/60_ascend950_grouped_matmul_slice_m`。 | 3 | +本目录下的样例演示 **CATLASS DSL** 下按 M 切分的分组矩阵乘。 |
| 4 | 4 | ||
| 5 | ## 功能说明 | 5 | ## 功能说明 |
| 6 | 6 | ||
| @@ -49,22 +49,29 @@ $$ | |||
| 49 | | `--k` | `256` | 矩阵乘累加轴的大小 | | 49 | | `--k` | `256` | 矩阵乘累加轴的大小 | |
| 50 | | `--groups` | `4` | 分组数 G。 | | 50 | | `--groups` | `4` | 分组数 G。 | |
| 51 | | `--group-mode` | `random` | 组切分模式,可选 `average` 或 `random`。 | | 51 | | `--group-mode` | `random` | 组切分模式,可选 `average` 或 `random`。 | |
| 52 | -| `--layout-a` / `--layout-b` | `row` / `row` | 左、右矩阵 A、B 的数据排布格式,可选 `"row"` 或 `"col"`,表示行优先或列优先布局。 | | 52 | +| `--layout-a` / `--layout-b` | `"row"` / `"row"` | 左、右矩阵 A、B 的数据排布格式,可选 `"row"` 或 `"col"`,表示行优先或列优先布局。 | |
| 53 | -| `--dtype-a` / `--dtype-b` / `--dtype-c` | `f16` / `f16` / `f16` | 左、右矩阵 A、B 和结果矩阵 C 的数据类型,可选范围参考约束说明。 | | 53 | +| `--dtype-a` / `--dtype-b` / `--dtype-c` | `"f16"` / `"f16"` / `"f16"` | 左、右矩阵 A、B 和结果矩阵 C 的数据类型,可选范围参考约束说明。 | |
| 54 | -| `--block` | `8` | 启用的核数。 | | 54 | +| `--block-num` | `-1` | 启用的核数,`-1` 表示自动探测可用核数(满核)。 | |
| 55 | 55 | ||
| 56 | ### 执行示例 | 56 | ### 执行示例 |
| 57 | 57 | ||
| 58 | 在 `python/tla_dsl` 目录下执行: | 58 | 在 `python/tla_dsl` 目录下执行: |
| 59 | 59 | ||
| 60 | ```bash | 60 | ```bash |
| 61 | -cd "${CATLASS_ROOT}/python/tla_dsl" | 61 | +cd python/tla_dsl |
| 62 | - | ||
| 63 | -python examples/end_to_end/grouped_matmul_slice_m/grouped_matmul_slice_m.py \ | ||
| 64 | - --run --device 4 --m 1024 --n 256 --k 256 --groups 4 --group-mode average --block 8 | ||
| 65 | 62 | ||
| 63 | +python examples/end_to_end/grouped_matmul_slice_m/grouped_matmul_slice_m.py --device 0 \ | ||
| 64 | + --m 1024 --n 256 --k 256 --groups 4 --group-mode average | ||
| 66 | ``` | 65 | ``` |
| 67 | 66 | ||
| 68 | -执行测试后,预期输出: | 67 | +默认测试条件下,预期输出: |
| 69 | 68 | ||
| 70 | -成功时可见 `compile_ok` / `launch_ok` 与 golden 比对结果。 | 69 | +```text |
| 70 | +--- groups=(4) mnk=(1024,256,256) layout=row/row dtype=f16/f16/f16 group_mode=average --- | ||
| 71 | +GROUP_CURRENT_M=(256, 256, 256, 256) | ||
| 72 | +GROUP_LIST_PREFIX=(0, 256, 512, 768, 1024) | ||
| 73 | +passed=True cache_key=<cache_key> | ||
| 74 | +kernel.o=<cache_dir>/<cache_key>/kernel.o | ||
| 75 | +``` | ||
| 76 | + | ||
| 77 | +其中 `passed`结果为`True`或`False` 表明 NPU 计算结果与golden参考值精度校验是否通过;`cache_dir` 是指定的缓存目录, `cache_key` 是编译缓存的哈希值。 | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | # 多核切 K Matmul 端到端示例 | 1 | # 多核切 K Matmul 端到端示例 |
| 2 | 2 | ||
| 3 | -本目录下提供的样例演示 **CATLASS DSL** 下多核切 K 矩阵乘的两种实现,对齐 C++ 参考实现 `examples/68_ascend950_multi_core_splitk_matmul` 和 `examples/69_ascend950_tail_multi_core_splitk_matmul` 。 | 3 | +本目录下提供的样例演示 **CATLASS DSL** 下多核切 K 矩阵乘的两种实现。 |
| 4 | 4 | ||
| 5 | ## 功能说明 | 5 | ## 功能说明 |
| 6 | 6 | ||
| @@ -12,7 +12,7 @@ C_{i,j} &= \Sigma_{k} A_{i,k}B_{k,j} | |||
| 12 | \end{aligned} | 12 | \end{aligned} |
| 13 | $$ | 13 | $$ |
| 14 | 14 | ||
| 15 | -Split-K 将 K 维度的计算切分到多个核上并行执行,各核的部分积累入 workspace,再由 AIV 做 ReduceAdd 归约得到最终结果 C。 | 15 | +Split-K 将 K 维度的计算切分到多个核上并行执行,各核的计算结果写回 GM,再由 AIV 做 ReduceAdd 归约计算。 |
| 16 | 16 | ||
| 17 | ## 代码组织 | 17 | ## 代码组织 |
| 18 | 18 | ||
| @@ -25,8 +25,8 @@ Split-K 将 K 维度的计算切分到多个核上并行执行,各核的部分 | |||
| 25 | 25 | ||
| 26 | | 文件 | 概述 | | 26 | | 文件 | 概述 | |
| 27 | |------|------| | 27 | |------|------| |
| 28 | -| [**`multi_core_splitk_matmul.py`**](multi_core_splitk_matmul.py) | 设备侧 `@tla.kernel` 与 host 侧运行/校验逻辑同文件。全部 M×N tile 做 K 维 split-K 写入 workspace,AIV 做 ReduceAdd 写回 GM C。 | | 28 | +| [**`multi_core_splitk_matmul.py`**](multi_core_splitk_matmul.py) | 全部 Tile 块在累加轴 K方向上做切分,并在 AIV 核进行规约(ReduceAdd)写回 GM。 | |
| 29 | -| [**`tail_multi_core_splitk_matmul.py`**](tail_multi_core_splitk_matmul.py) | 设备侧 `@tla.kernel` 与 host 侧运行/校验逻辑同文件。normal tile full-K 直接写回 gmC;tail tile 再做 split-K + ReduceAdd。 | | 29 | +| [**`tail_multi_core_splitk_matmul.py`**](tail_multi_core_splitk_matmul.py) | 针对尾轮采取上述多核切K优化,以达成负载均衡。 | |
| 30 | 30 | ||
| 31 | ## 约束说明 | 31 | ## 约束说明 |
| 32 | 32 | ||
| @@ -45,7 +45,7 @@ Split-K 将 K 维度的计算切分到多个核上并行执行,各核的部分 | |||
| 45 | 45 | ||
| 46 | ### 命令行参数 | 46 | ### 命令行参数 |
| 47 | 47 | ||
| 48 | -CLI 与 basic 同形,主要参数如下: | 48 | +接收命令行参数如下: |
| 49 | 49 | ||
| 50 | | 参数 | 默认值 | 说明 | | 50 | | 参数 | 默认值 | 说明 | |
| 51 | |------|--------|------| | 51 | |------|--------|------| |
| @@ -53,21 +53,32 @@ CLI 与 basic 同形,主要参数如下: | |||
| 53 | | `--m` | `256` | 矩阵乘左矩阵 A 的行数 | | 53 | | `--m` | `256` | 矩阵乘左矩阵 A 的行数 | |
| 54 | | `--n` | `512` | 矩阵乘右矩阵 B 的列数 | | 54 | | `--n` | `512` | 矩阵乘右矩阵 B 的列数 | |
| 55 | | `--k` | `1024` | 矩阵乘累加轴的大小 | | 55 | | `--k` | `1024` | 矩阵乘累加轴的大小 | |
| 56 | -| `--layout-a` / `--layout-b` | `row` / `row` | 左、右矩阵 A、B 的数据排布格式,可选 `"row"` 或 `"col"`,表示行优先或列优先布局。 | | 56 | +| `--layout-a` / `--layout-b` | `"row"` / `"row"` | 左、右矩阵 A、B 的数据排布格式,可选 `"row"` 或 `"col"`,表示行优先或列优先布局。 | |
| 57 | | `--dtype-a` / `--dtype-b` / `--dtype-c` | `"f16"` / `"f16"` / `"f16"` | 左、右矩阵 A、B 和结果矩阵 C 的数据类型,可选范围参考约束说明。 | | 57 | | `--dtype-a` / `--dtype-b` / `--dtype-c` | `"f16"` / `"f16"` / `"f16"` | 左、右矩阵 A、B 和结果矩阵 C 的数据类型,可选范围参考约束说明。 | |
| 58 | +| `--block-num` | `-1` | 启用的 AIC 核数,`-1` 表示自动探测可用核数(满核)。 | | ||
| 58 | 59 | ||
| 59 | ### 执行示例 | 60 | ### 执行示例 |
| 60 | 61 | ||
| 61 | 在 `python/tla_dsl` 目录下执行: | 62 | 在 `python/tla_dsl` 目录下执行: |
| 62 | 63 | ||
| 63 | ```bash | 64 | ```bash |
| 64 | -export PYTHONPATH="$(pwd):${PYTHONPATH:-}" | 65 | +cd python/tla_dsl |
| 65 | 66 | ||
| 66 | -# multi_core_splitk | 67 | +# multi_core_splitk (指定 NPU 设备ID, m/n/k 的值) |
| 67 | python examples/end_to_end/multi_core_splitk_matmul/multi_core_splitk_matmul.py \ | 68 | python examples/end_to_end/multi_core_splitk_matmul/multi_core_splitk_matmul.py \ |
| 68 | --device 0 --m 256 --n 512 --k 1024 | 69 | --device 0 --m 256 --n 512 --k 1024 |
| 69 | 70 | ||
| 70 | -# tail_multi_core_splitk | 71 | +# tail_multi_core_splitk (指定 NPU 设备ID, m/n/k 的值) |
| 71 | python examples/end_to_end/multi_core_splitk_matmul/tail_multi_core_splitk_matmul.py \ | 72 | python examples/end_to_end/multi_core_splitk_matmul/tail_multi_core_splitk_matmul.py \ |
| 72 | --device 0 --m 2048 --n 1024 --k 2048 | 73 | --device 0 --m 2048 --n 1024 --k 2048 |
| 73 | ``` | 74 | ``` |
| 75 | + | ||
| 76 | +默认测试条件下,预期输出: | ||
| 77 | + | ||
| 78 | +```text | ||
| 79 | +--- mnk=(256,512,1024) layout=row/row dtype=f16/f16/f16 --- | ||
| 80 | +passed=True mismatch=0.0000% (budget=0.1000%) cache_key=<cache_key> | ||
| 81 | +kernel.o=<cache_dir>/<cache_key>/kernel.o | ||
| 82 | +``` | ||
| 83 | + | ||
| 84 | +其中 `passed`结果为`True`或`False` 表明 NPU 计算结果与golden参考值精度校验是否通过;`mismatch`为超容差元素占比,不高于 `budget` 即判定通过;`cache_dir` 是指定的缓存目录, `cache_key` 是编译缓存的哈希值。 | ||
| @@ -8,7 +8,7 @@ | |||
| 8 | 向量运算是 NPU 上基础的计算原语,在 AIV 物理核上执行,整体执行流程包括: | 8 | 向量运算是 NPU 上基础的计算原语,在 AIV 物理核上执行,整体执行流程包括: |
| 9 | 1. 构造 GM (Global memory)上的输入/输出 `tla.Tensor`; | 9 | 1. 构造 GM (Global memory)上的输入/输出 `tla.Tensor`; |
| 10 | 2. 启动MTE2,将数据搬运至 UB (Unified Buffer); | 10 | 2. 启动MTE2,将数据搬运至 UB (Unified Buffer); |
| 11 | -3. 加载至寄存器上,以 `VL`(向量寄存器位宽)为粒度分块执行各类向量指令; | 11 | +3. 加载至寄存器上,以 `VL`(向量寄存器位宽, 256 字节)为粒度分块执行各类向量指令; |
| 12 | 4. 输出回 UB,然后启动 MTE3,将数据搬运回 GM。 | 12 | 4. 输出回 UB,然后启动 MTE3,将数据搬运回 GM。 |
| 13 | 13 | ||
| 14 | 14 | ||
| @@ -191,7 +191,7 @@ def _cases(device: int) -> Iterator[tuple[str, list[list[str]]]]: | |||
| 191 | "--groups", "3", "--m", "768", "--n", "333", "--k", "333", *dev]] | 191 | "--groups", "3", "--m", "768", "--n", "333", "--k", "333", *dev]] |
| 192 | ) | 192 | ) |
| 193 | 193 | ||
| 194 | - # --- basic_mmad_evg: multiple epilogue examples --- | 194 | + # --- basic_mmad_epilogue: multiple epilogue examples --- |
| 195 | for op in EVG_OPS: | 195 | for op in EVG_OPS: |
| 196 | if op in ("add_ub", "tanh"): | 196 | if op in ("add_ub", "tanh"): |
| 197 | # f32 (dtype-c) only examples | 197 | # f32 (dtype-c) only examples |
| @@ -209,9 +209,9 @@ def _cases(device: int) -> Iterator[tuple[str, list[list[str]]]]: | |||
| 209 | for m, n, k in MMAD_SHAPES: | 209 | for m, n, k in MMAD_SHAPES: |
| 210 | for dab, dc in triples: | 210 | for dab, dc in triples: |
| 211 | yield ( | 211 | yield ( |
| 212 | - f"mmad-evg-{op.replace('_', '-')}-{m}x{n}x{k}-{dab}-{dc}", | 212 | + f"mmad-epilogue-{op.replace('_', '-')}-{m}x{n}x{k}-{dab}-{dc}", |
| 213 | [[ | 213 | [[ |
| 214 | - f"basic_mmad_evg/matmul_{op}.py", | 214 | + f"basic_mmad_epilogue/matmul_{op}.py", |
| 215 | "--m", m, "--n", n, "--k", k, | 215 | "--m", m, "--n", n, "--k", k, |
| 216 | "--dtype-a", dab, "--dtype-b", dab, "--dtype-c", dc, | 216 | "--dtype-a", dab, "--dtype-b", dab, "--dtype-c", dc, |
| 217 | *dev | 217 | *dev |
| @@ -19,7 +19,7 @@ | |||
| 19 | # interleave_op.py, load_dintlv_op.py, load_store_mask.py, squeeze_op.py, | 19 | # interleave_op.py, load_dintlv_op.py, load_store_mask.py, squeeze_op.py, |
| 20 | # register_control_flow.py, load_and_store_scalar_after_reduction.py, load_us_b8_op.py, | 20 | # register_control_flow.py, load_and_store_scalar_after_reduction.py, load_us_b8_op.py, |
| 21 | # cast_multi.py, gather_op.py). | 21 | # cast_multi.py, gather_op.py). |
| 22 | -# python/tla_dsl/examples/end_to_end/basic_mmad_evg (matmul_add.py, matmul_add_ub.py, | 22 | +# python/tla_dsl/examples/end_to_end/basic_mmad_epilogue (matmul_add.py, matmul_add_ub.py, |
| 23 | # matmul_bias.py, matmul_leaky_relu.py, matmul_sigmoid.py, matmul_silu.py, matmul_tanh.py). | 23 | # matmul_bias.py, matmul_leaky_relu.py, matmul_sigmoid.py, matmul_silu.py, matmul_tanh.py). |
| 24 | # python/tla_dsl/examples/end_to_end/flash_attention_infer (flash_attention_infer.py). | 24 | # python/tla_dsl/examples/end_to_end/flash_attention_infer (flash_attention_infer.py). |
| 25 | # python/tla_dsl/examples/end_to_end/multi_core_splitk_matmul (multi_core_splitk_matmul.py, | 25 | # python/tla_dsl/examples/end_to_end/multi_core_splitk_matmul (multi_core_splitk_matmul.py, |
| @@ -118,13 +118,13 @@ BATCHED_MATMUL_REL="examples/end_to_end/batched_matmul/batched_matmul.py" | |||
| 118 | FLASH_ATTENTION_INFER_REL="examples/end_to_end/flash_attention_infer/flash_attention_infer.py" | 118 | FLASH_ATTENTION_INFER_REL="examples/end_to_end/flash_attention_infer/flash_attention_infer.py" |
| 119 | MULTI_CORE_SPLITK_REL="examples/end_to_end/multi_core_splitk_matmul/multi_core_splitk_matmul.py" | 119 | MULTI_CORE_SPLITK_REL="examples/end_to_end/multi_core_splitk_matmul/multi_core_splitk_matmul.py" |
| 120 | TAIL_MULTI_CORE_SPLITK_REL="examples/end_to_end/multi_core_splitk_matmul/tail_multi_core_splitk_matmul.py" | 120 | TAIL_MULTI_CORE_SPLITK_REL="examples/end_to_end/multi_core_splitk_matmul/tail_multi_core_splitk_matmul.py" |
| 121 | -BASIC_MMAD_EVG_ADD_REL="examples/end_to_end/basic_mmad_evg/matmul_add.py" | 121 | +BASIC_MMAD_EPILOGUE_ADD_REL="examples/end_to_end/basic_mmad_epilogue/matmul_add.py" |
| 122 | -BASIC_MMAD_EVG_ADD_UB_REL="examples/end_to_end/basic_mmad_evg/matmul_add_ub.py" | 122 | +BASIC_MMAD_EPILOGUE_ADD_UB_REL="examples/end_to_end/basic_mmad_epilogue/matmul_add_ub.py" |
| 123 | -BASIC_MMAD_EVG_BIAS_REL="examples/end_to_end/basic_mmad_evg/matmul_bias.py" | 123 | +BASIC_MMAD_EPILOGUE_BIAS_REL="examples/end_to_end/basic_mmad_epilogue/matmul_bias.py" |
| 124 | -BASIC_MMAD_EVG_LEAKY_RELU_REL="examples/end_to_end/basic_mmad_evg/matmul_leaky_relu.py" | 124 | +BASIC_MMAD_EPILOGUE_LEAKY_RELU_REL="examples/end_to_end/basic_mmad_epilogue/matmul_leaky_relu.py" |
| 125 | -BASIC_MMAD_EVG_SIGMOID_REL="examples/end_to_end/basic_mmad_evg/matmul_sigmoid.py" | 125 | +BASIC_MMAD_EPILOGUE_SIGMOID_REL="examples/end_to_end/basic_mmad_epilogue/matmul_sigmoid.py" |
| 126 | -BASIC_MMAD_EVG_SILU_REL="examples/end_to_end/basic_mmad_evg/matmul_silu.py" | 126 | +BASIC_MMAD_EPILOGUE_SILU_REL="examples/end_to_end/basic_mmad_epilogue/matmul_silu.py" |
| 127 | -BASIC_MMAD_EVG_TANH_REL="examples/end_to_end/basic_mmad_evg/matmul_tanh.py" | 127 | +BASIC_MMAD_EPILOGUE_TANH_REL="examples/end_to_end/basic_mmad_epilogue/matmul_tanh.py" |
| 128 | CAST_MULTI_REL="examples/end_to_end/vector_ops/cast_multi.py" | 128 | CAST_MULTI_REL="examples/end_to_end/vector_ops/cast_multi.py" |
| 129 | GATHER_OP_REL="examples/end_to_end/vector_ops/gather_op.py" | 129 | GATHER_OP_REL="examples/end_to_end/vector_ops/gather_op.py" |
| 130 | 130 | ||
| @@ -166,7 +166,7 @@ Run end-to-end validation for: | |||
| 166 | - squeeze_op (squeeze_op.py squeeze --all-dtypes) | 166 | - squeeze_op (squeeze_op.py squeeze --all-dtypes) |
| 167 | - register_control_flow (register_control_flow.py register_carriers: | 167 | - register_control_flow (register_control_flow.py register_carriers: |
| 168 | mixed VectorSSA/MaskSSA scf.for carriers and masked store) | 168 | mixed VectorSSA/MaskSSA scf.for carriers and masked store) |
| 169 | - - basic_mmad_evg (matmul_add.py, ...: CV fused examples) | 169 | + - basic_mmad_epilogue (matmul_add.py, ...: CV fused examples) |
| 170 | - flash_attention_infer (flash_attention_infer.py) | 170 | - flash_attention_infer (flash_attention_infer.py) |
| 171 | - multi_core_splitk_matmul (multi_core_splitk_matmul.py: using split-k strategy for workload balancing) | 171 | - multi_core_splitk_matmul (multi_core_splitk_matmul.py: using split-k strategy for workload balancing) |
| 172 | - basic_mmad_streamk (basic_mmad_streamk.py: streamK workload balancing) | 172 | - basic_mmad_streamk (basic_mmad_streamk.py: streamK workload balancing) |
| @@ -459,32 +459,32 @@ if [[ ! -f "${CATLASS_DSL_DIR}/${GROUPED_MATMUL_SLICEM_REL}" ]]; then | |||
| 459 | echo "error: missing ${GROUPED_MATMUL_SLICEM_REL} under ${CATLASS_DSL_DIR}" >&2 | 459 | echo "error: missing ${GROUPED_MATMUL_SLICEM_REL} under ${CATLASS_DSL_DIR}" >&2 |
| 460 | exit 1 | 460 | exit 1 |
| 461 | fi | 461 | fi |
| 462 | -if [[ ! -f "${CATLASS_DSL_DIR}/${BASIC_MMAD_EVG_ADD_REL}" ]]; then | 462 | +if [[ ! -f "${CATLASS_DSL_DIR}/${BASIC_MMAD_EPILOGUE_ADD_REL}" ]]; then |
| 463 | - echo "error: missing ${BASIC_MMAD_EVG_ADD_REL} under ${CATLASS_DSL_DIR}" >&2 | 463 | + echo "error: missing ${BASIC_MMAD_EPILOGUE_ADD_REL} under ${CATLASS_DSL_DIR}" >&2 |
| 464 | exit 1 | 464 | exit 1 |
| 465 | fi | 465 | fi |
| 466 | -if [[ ! -f "${CATLASS_DSL_DIR}/${BASIC_MMAD_EVG_ADD_UB_REL}" ]]; then | 466 | +if [[ ! -f "${CATLASS_DSL_DIR}/${BASIC_MMAD_EPILOGUE_ADD_UB_REL}" ]]; then |
| 467 | - echo "error: missing ${BASIC_MMAD_EVG_ADD_UB_REL} under ${CATLASS_DSL_DIR}" >&2 | 467 | + echo "error: missing ${BASIC_MMAD_EPILOGUE_ADD_UB_REL} under ${CATLASS_DSL_DIR}" >&2 |
| 468 | exit 1 | 468 | exit 1 |
| 469 | fi | 469 | fi |
| 470 | -if [[ ! -f "${CATLASS_DSL_DIR}/${BASIC_MMAD_EVG_BIAS_REL}" ]]; then | 470 | +if [[ ! -f "${CATLASS_DSL_DIR}/${BASIC_MMAD_EPILOGUE_BIAS_REL}" ]]; then |
| 471 | - echo "error: missing ${BASIC_MMAD_EVG_BIAS_REL} under ${CATLASS_DSL_DIR}" >&2 | 471 | + echo "error: missing ${BASIC_MMAD_EPILOGUE_BIAS_REL} under ${CATLASS_DSL_DIR}" >&2 |
| 472 | exit 1 | 472 | exit 1 |
| 473 | fi | 473 | fi |
| 474 | -if [[ ! -f "${CATLASS_DSL_DIR}/${BASIC_MMAD_EVG_LEAKY_RELU_REL}" ]]; then | 474 | +if [[ ! -f "${CATLASS_DSL_DIR}/${BASIC_MMAD_EPILOGUE_LEAKY_RELU_REL}" ]]; then |
| 475 | - echo "error: missing ${BASIC_MMAD_EVG_LEAKY_RELU_REL} under ${CATLASS_DSL_DIR}" >&2 | 475 | + echo "error: missing ${BASIC_MMAD_EPILOGUE_LEAKY_RELU_REL} under ${CATLASS_DSL_DIR}" >&2 |
| 476 | exit 1 | 476 | exit 1 |
| 477 | fi | 477 | fi |
| 478 | -if [[ ! -f "${CATLASS_DSL_DIR}/${BASIC_MMAD_EVG_SIGMOID_REL}" ]]; then | 478 | +if [[ ! -f "${CATLASS_DSL_DIR}/${BASIC_MMAD_EPILOGUE_SIGMOID_REL}" ]]; then |
| 479 | - echo "error: missing ${BASIC_MMAD_EVG_SIGMOID_REL} under ${CATLASS_DSL_DIR}" >&2 | 479 | + echo "error: missing ${BASIC_MMAD_EPILOGUE_SIGMOID_REL} under ${CATLASS_DSL_DIR}" >&2 |
| 480 | exit 1 | 480 | exit 1 |
| 481 | fi | 481 | fi |
| 482 | -if [[ ! -f "${CATLASS_DSL_DIR}/${BASIC_MMAD_EVG_SILU_REL}" ]]; then | 482 | +if [[ ! -f "${CATLASS_DSL_DIR}/${BASIC_MMAD_EPILOGUE_SILU_REL}" ]]; then |
| 483 | - echo "error: missing ${BASIC_MMAD_EVG_SILU_REL} under ${CATLASS_DSL_DIR}" >&2 | 483 | + echo "error: missing ${BASIC_MMAD_EPILOGUE_SILU_REL} under ${CATLASS_DSL_DIR}" >&2 |
| 484 | exit 1 | 484 | exit 1 |
| 485 | fi | 485 | fi |
| 486 | -if [[ ! -f "${CATLASS_DSL_DIR}/${BASIC_MMAD_EVG_TANH_REL}" ]]; then | 486 | +if [[ ! -f "${CATLASS_DSL_DIR}/${BASIC_MMAD_EPILOGUE_TANH_REL}" ]]; then |
| 487 | - echo "error: missing ${BASIC_MMAD_EVG_TANH_REL} under ${CATLASS_DSL_DIR}" >&2 | 487 | + echo "error: missing ${BASIC_MMAD_EPILOGUE_TANH_REL} under ${CATLASS_DSL_DIR}" >&2 |
| 488 | exit 1 | 488 | exit 1 |
| 489 | fi | 489 | fi |
| 490 | if [[ ! -f "${CATLASS_DSL_DIR}/${CAST_MULTI_REL}" ]]; then | 490 | if [[ ! -f "${CATLASS_DSL_DIR}/${CAST_MULTI_REL}" ]]; then |


关联一下issue