| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
feat(dsl): compile class-organized kernels Co-authored-by: yuantao<taoyuan18@huawei.com> # message auto-generated for no-merge-commit merge: !1292 merge design/dsl-kernel-class-org into master feat(dsl): compile class-organized kernels Created-by: yuantao_ Commit-by: yuantao Merged-by: cann-robot Description: ## 描述 让 tla.compile 接受「以类实例组织的 kernel」:编译期配置、kernel 与编译入口封装在同一个类里,实例交给 tla.compile 时,实例作为编译期接收者参与编排,self.attr 折叠为常量。 python class VectorAdd: def __init__(self, vector_ele: int) -> None: self.vector_ele = vector_ele @tla.jit def __call__(self, lhs, rhs, output): self.kernel(lhs, rhs, output) @tla.kernel def kernel(self, lhs, rhs, output): ... # self.vector_ele 作为编译期常量 opts = {"options": "--npu-arch 3510"} # 1. 编译实例:靠 @tla.jit __call__ 的一行纯转发指出要编译的 kernel a = tla.compile(VectorAdd(128), lhs, rhs, output, **opts) # 2. 编译从实例读到的绑定方法:实例随属性读取一并作为 receiver b = tla.compile(VectorAdd(128).kernel, lhs, rhs, output, **opts) # 3. 换一份配置:编译期常量不同,得到新的产物 d = tla.compile(VectorAdd(64), lhs, rhs, output, **opts) a(lhs, rhs, output, block_num=1) 写法 1 与 2 编译出同一份产物,cache_key 相同;启动签名都不含接收者: | 写法 | 编译的 kernel | 启动签名 | |---|---|---| | tla.compile(实例, ...) | @tla.jit __call__ 一行转发指向的 kernel 方法 | lhs, rhs, output | | tla.compile(实例.kernel, ...) | 同一个方法,实例随属性读取作为 receiver | lhs, rhs, output | 换一份编译期配置(写法 3)得到新的 cache_key:以新增样例为例,n_ele=64 为 74035fa27c9e26e8,n_ele=384 为 fb2175bc67b0adb9。 改动涉及的文件: | 文件 | 内容 | |---|---| | catlass/base_dsl/compiler.py | 实例入口解析 _resolve_kernel_target、@tla.jit __call__ 纯转发校验 _check_jit_call_is_pure_forwarding | | catlass/dsl.py | TlaJitFunction 增加 receiver 字段与 __get__,从实例取值时绑定实例 | | catlass/base_dsl/runtime/jit_arg_adapters.py | receiver_argument_name:按位置与名字判定首位接收者 | | catlass/base_dsl/jit_executor.py | ExecutionArgs.filter_runtime_signature 复用同一套静态参数规则,让启动签名与编译计划对齐 | | catlass/execution_lowering.py | 接收者不占运行时 ABI 槽位,self.attr 折叠为常量 | 编译入口的确定规则: | 类里的写法 | 编译的 kernel | |---|---| | 传实例,类声明了 @tla.jit __call__ | __call__ 一行转发指向的方法,方法名不限 | | 传从实例读到的 kernel 方法 实例.kernel | 该方法本身 | | 传实例,类没有 @tla.jit __call__ | 报错,提示补一个 @tla.jit __call__;不做「按方法名 kernel」等回落 | | 传的不是 @tla.kernel 函数、也不是声明了它的类实例 | 报错,提示入口类型 | 接收者规则: - 首位参数名为 self 时视为编译期接收者:不占运行时 ABI 槽位,self.attr 在 kernel 编排时折叠为常量 - receiver_argument_name 以「无宿主」(owning_func=None)调用判定规则,而 cls 需要 classmethod 宿主才成立,因此这条路径实际只把 self 认作接收者;首位 cls 不会成为接收者 - 判定只看位置与参数名,与函数是否定义在类里无关 - 接收者的取值若是运行时取值(设备 tensor、运行时数值),会直接报错并提示改名,避免它被静默丢出运行时 ABI - 绑定方法(实例.kernel)已经带上 receiver,不要再把实例作为实参传一次:tla.compile 会在拼接前检测到重复传入并明确报错 对既有行为的影响:首位 self 不再进入运行时 ABI,仓库内两处按旧语义书写的代码随之调整。 | 文件 | 调整 | |---|---| | examples/end_to_end/structured_arguments/static_tensor_interfaces.py | copy_from_self 改名 copy_from_tensor,首位参数改名 input_tensor | | tests/test_execution_args.py | self 不再出现在启动签名;cls 在没有 classmethod 归属时仍是运行时参数 | ### 检视意见处理(CheaterAbec) | 检视意见 | 处理 | |---|---| | 纯转发校验函数名易误解:它只管 @tla.jit __call__ 是否一行纯转发,与 Host JIT 全路径无关 | 已改名为 _check_jit_call_is_pure_forwarding | | 「编译入口的确定规则」写了「方法名 kernel」「类内唯一 @tla.kernel 方法」两条回落,代码里没有 | 描述已按代码更正:无 @tla.jit __call__ 直接报错,不做回落 | | receiver_argument_name 的 cls 分支是死路径(判定时固定传 owning_func=None) | 描述已更正:该路径只认 self | | 实例.kernel 已带 receiver,再显式传实例会重复传入 | 采纳「检测并明确诊断」:tla.compile 在拼接前对重复 receiver 抛错,并加用例 test_bound_method_rejects_a_duplicated_receiver | | 描述称 @tla.kernel 作用于 staticmethod / classmethod 会在装饰期报错 | 本 PR 未包含该诊断(dsl.py 只新增 receiver 字段与 __get__,测试也无对应用例),描述已删除该条 | ## 关联的Issue https://gitcode.com/cann/catlass/issues/559 ## 原因 issue #559 要求 CATLASS DSL 支持以类实例组织 Kernel,让分块大小、stage 数、dtype 这类编译期配置与 kernel 一起封装,而不是散在 host 侧的调用点。 改动前存在两个障碍: | 现象 | 原因 | |---|---| | 传实例报 TlaUnsupportedAbiError: tla.compile expects a @tla.kernel function, or an instance of a class that declares one. | tla.compile 只接受 @tla.kernel 的返回值 | | 实例形态的 kernel 在 lowering 时实参个数不匹配 | 方法首位 self 被算作运行时参数 | 有意不支持的写法:host 侧没有对应的 pass,因此 @tla.jit __call__ 只能是到 kernel 的纯转发——单条语句、按序传全部参数、不用关键字、不计算实参。其他写法都会报错,这是本次变更的边界;实例若没有 @tla.jit __call__,也直接报错,不做「按方法名或唯一性猜入口」的回落。 ## 测试 单元测试(python/tla_dsl,Python 3.11 venv,python -m pytest tests/): - 新增 tests/frontend/test_kernel_class_organization.py,27 个用例:实例与绑定方法两种写法产物等价(cache_key 相同、启动签名一致)、入口选择(转发指向的方法名不限)、转发形态校验与报错文案、无 @tla.jit __call__ 的实例被拒、接收者不占 ABI 槽位、self.attr(含嵌套普通对象属性)折叠为常量、首位 self 在类外也同样是接收者、运行时取值误当接收者被拒、按配置区分的 cache key - 定向:tests/frontend/test_kernel_class_organization.py + tests/test_execution_args.py 共 83 passed - 全量:2471 passed, 7 skipped;另有 13 failed 全部落在 tests/test_tla_lower_to_hivm.py,是本机 TlaCompile 二进制未随分支重建(缺 tla-vector-region-simd pass)所致,与本改动无关 - lint:按 CI 口径 ruff check --select E4,E7,E9,F --line-length 120 与 format 通过;新增测试文件里 _BareNameCallKernel.__call__ 的裸名调用是刻意用例,已按仓内既有做法在 pyproject.toml 补 per-file-ignores 端到端(Ascend 950,--npu-arch 3510):类版本 vector-add 编译并启动,结果逐元素精确一致,n_ele=64 与 n_ele=384 均 passed=True,cache_key 分别为 74035fa27c9e26e8、fb2175bc67b0adb9。内存 / 性能 / 确定性检测不涉及。 新增样例:examples/end_to_end/kernel_in_class/vector_add_with_static_length.py,类版本 vector-add,编译期配置、kernel 与编译入口封装在同一个类里。 ## 文档更新 | 文件 | 内容 | |---|---| | docs/zh/kernel_development/core_concepts/compile_and_launch.md | 新增「以类实例组织 Kernel」章节,含编译入口写法表与约束 | | docs/zh/api/host_api_reference.md | tla.compile 参数与约束同步 | | docs/en/api/host_api_reference.md | 同步生成结果与源码行号 | | examples/end_to_end/kernel_in_class/README.md | 类版本示例说明 | ## 类型标签 - [x] 新特性 --- ## Description Let tla.compile accept a kernel organized as a class instance: compile-time configuration, the kernel and its compile entry live in one class, and the instance joins compilation as a compile-time receiver, so self.attr folds into constants. python class VectorAdd: def __init__(self, vector_ele: int) -> None: self.vector_ele = vector_ele @tla.jit def __call__(self, lhs, rhs, output): self.kernel(lhs, rhs, output) @tla.kernel def kernel(self, lhs, rhs, output): ... # self.vector_ele as a compile-time constant opts = {"options": "--npu-arch 3510"} # 1. the instance: the one-line @tla.jit __call__ forward names the kernel a = tla.compile(VectorAdd(128), lhs, rhs, output, **opts) # 2. the bound method read off an instance: the instance rides along as the receiver b = tla.compile(VectorAdd(128).kernel, lhs, rhs, output, **opts) # 3. another configuration: different constants, a different binary d = tla.compile(VectorAdd(64), lhs, rhs, output, **opts) a(lhs, rhs, output, block_num=1) Forms 1 and 2 compile to the same artifact and share a cache_key; neither launch signature carries the receiver: | Form | Kernel compiled | Launch signature | |---|---|---| | tla.compile(instance, ...) | the kernel method the one-line @tla.jit __call__ forwards to | lhs, rhs, output | | tla.compile(instance.kernel, ...) | the same method, the instance bound along as the receiver | lhs, rhs, output | Another compile-time configuration (form 3) gets a new cache_key: in the new sample, n_ele=64 gives 74035fa27c9e26e8 and n_ele=384 gives fb2175bc67b0adb9. Files touched: | File | What | |---|---| | catlass/base_dsl/compiler.py | Instance entry resolution _resolve_kernel_target, the @tla.jit __call__ pure-forwarding check _check_jit_call_is_pure_forwarding | | catlass/dsl.py | TlaJitFunction gains a receiver field and __get__, binding the instance when read off it | | catlass/base_dsl/runtime/jit_arg_adapters.py | receiver_argument_name: a leading receiver is decided by position and name | | catlass/base_dsl/jit_executor.py | ExecutionArgs.filter_runtime_signature reuses the same static-parameter rule so the launch signature lines up with the compiled plan | | catlass/execution_lowering.py | The receiver occupies no runtime ABI slot; self.attr folds into constants | How the entry point is picked: | Shape of the class | Kernel compiled | |---|---| | An instance, and the class declares @tla.jit __call__ | The method the one-line forward points to; the name is free | | A kernel method read off an instance (instance.kernel) | That method itself | | An instance whose class has no @tla.jit __call__ | Rejected, asking for a @tla.jit __call__; no "method named kernel" fallback | | Neither a @tla.kernel function nor an instance of a class declaring one | Rejected, naming the expected entry types | Receiver rule: - A leading parameter named self is a compile-time receiver: it takes no runtime ABI slot, and self.attr folds into the kernel as a constant while the body is staged - receiver_argument_name calls the rule with no owner (owning_func=None), and cls only qualifies under a classmethod owner, so on this path only self is ever taken as the receiver; a leading cls is not - The rule keys off position and name only, not on whether the function belongs to a class - A runtime receiver value (a device tensor or a runtime number) is rejected with a rename hint instead of leaving the runtime ABI unannounced - A bound method (instance.kernel) already carries the receiver; passing the instance again is a duplicate that tla.compile rejects with a clear message Impact on existing behaviour: a leading self no longer reaches the runtime ABI, so two places in the tree that relied on the old reading are adjusted. | File | Adjustment | |---|---| | examples/end_to_end/structured_arguments/static_tensor_interfaces.py | copy_from_self becomes copy_from_tensor, its leading parameter becomes input_tensor | | tests/test_execution_args.py | self leaves the launch signature; cls stays a runtime parameter when no classmethod owns it | ### Review follow-up (CheaterAbec) | Comment | Disposition | |---|---| | The pure-forwarding helper's name misleads: it only decides whether @tla.jit __call__ is a one-line forward, unrelated to the full Host JIT path | Renamed to _check_jit_call_is_pure_forwarding | | The entry-selection table claimed two fallbacks ("method named kernel", "the class's only @tla.kernel method") that the code does not have | The description now matches the code: no @tla.jit __call__ is rejected ou See merge request: cann/catlass!1292 | 13 小时前 | |
feat(dsl): compile class-organized kernels Co-authored-by: yuantao<taoyuan18@huawei.com> # message auto-generated for no-merge-commit merge: !1292 merge design/dsl-kernel-class-org into master feat(dsl): compile class-organized kernels Created-by: yuantao_ Commit-by: yuantao Merged-by: cann-robot Description: ## 描述 让 tla.compile 接受「以类实例组织的 kernel」:编译期配置、kernel 与编译入口封装在同一个类里,实例交给 tla.compile 时,实例作为编译期接收者参与编排,self.attr 折叠为常量。 python class VectorAdd: def __init__(self, vector_ele: int) -> None: self.vector_ele = vector_ele @tla.jit def __call__(self, lhs, rhs, output): self.kernel(lhs, rhs, output) @tla.kernel def kernel(self, lhs, rhs, output): ... # self.vector_ele 作为编译期常量 opts = {"options": "--npu-arch 3510"} # 1. 编译实例:靠 @tla.jit __call__ 的一行纯转发指出要编译的 kernel a = tla.compile(VectorAdd(128), lhs, rhs, output, **opts) # 2. 编译从实例读到的绑定方法:实例随属性读取一并作为 receiver b = tla.compile(VectorAdd(128).kernel, lhs, rhs, output, **opts) # 3. 换一份配置:编译期常量不同,得到新的产物 d = tla.compile(VectorAdd(64), lhs, rhs, output, **opts) a(lhs, rhs, output, block_num=1) 写法 1 与 2 编译出同一份产物,cache_key 相同;启动签名都不含接收者: | 写法 | 编译的 kernel | 启动签名 | |---|---|---| | tla.compile(实例, ...) | @tla.jit __call__ 一行转发指向的 kernel 方法 | lhs, rhs, output | | tla.compile(实例.kernel, ...) | 同一个方法,实例随属性读取作为 receiver | lhs, rhs, output | 换一份编译期配置(写法 3)得到新的 cache_key:以新增样例为例,n_ele=64 为 74035fa27c9e26e8,n_ele=384 为 fb2175bc67b0adb9。 改动涉及的文件: | 文件 | 内容 | |---|---| | catlass/base_dsl/compiler.py | 实例入口解析 _resolve_kernel_target、@tla.jit __call__ 纯转发校验 _check_jit_call_is_pure_forwarding | | catlass/dsl.py | TlaJitFunction 增加 receiver 字段与 __get__,从实例取值时绑定实例 | | catlass/base_dsl/runtime/jit_arg_adapters.py | receiver_argument_name:按位置与名字判定首位接收者 | | catlass/base_dsl/jit_executor.py | ExecutionArgs.filter_runtime_signature 复用同一套静态参数规则,让启动签名与编译计划对齐 | | catlass/execution_lowering.py | 接收者不占运行时 ABI 槽位,self.attr 折叠为常量 | 编译入口的确定规则: | 类里的写法 | 编译的 kernel | |---|---| | 传实例,类声明了 @tla.jit __call__ | __call__ 一行转发指向的方法,方法名不限 | | 传从实例读到的 kernel 方法 实例.kernel | 该方法本身 | | 传实例,类没有 @tla.jit __call__ | 报错,提示补一个 @tla.jit __call__;不做「按方法名 kernel」等回落 | | 传的不是 @tla.kernel 函数、也不是声明了它的类实例 | 报错,提示入口类型 | 接收者规则: - 首位参数名为 self 时视为编译期接收者:不占运行时 ABI 槽位,self.attr 在 kernel 编排时折叠为常量 - receiver_argument_name 以「无宿主」(owning_func=None)调用判定规则,而 cls 需要 classmethod 宿主才成立,因此这条路径实际只把 self 认作接收者;首位 cls 不会成为接收者 - 判定只看位置与参数名,与函数是否定义在类里无关 - 接收者的取值若是运行时取值(设备 tensor、运行时数值),会直接报错并提示改名,避免它被静默丢出运行时 ABI - 绑定方法(实例.kernel)已经带上 receiver,不要再把实例作为实参传一次:tla.compile 会在拼接前检测到重复传入并明确报错 对既有行为的影响:首位 self 不再进入运行时 ABI,仓库内两处按旧语义书写的代码随之调整。 | 文件 | 调整 | |---|---| | examples/end_to_end/structured_arguments/static_tensor_interfaces.py | copy_from_self 改名 copy_from_tensor,首位参数改名 input_tensor | | tests/test_execution_args.py | self 不再出现在启动签名;cls 在没有 classmethod 归属时仍是运行时参数 | ### 检视意见处理(CheaterAbec) | 检视意见 | 处理 | |---|---| | 纯转发校验函数名易误解:它只管 @tla.jit __call__ 是否一行纯转发,与 Host JIT 全路径无关 | 已改名为 _check_jit_call_is_pure_forwarding | | 「编译入口的确定规则」写了「方法名 kernel」「类内唯一 @tla.kernel 方法」两条回落,代码里没有 | 描述已按代码更正:无 @tla.jit __call__ 直接报错,不做回落 | | receiver_argument_name 的 cls 分支是死路径(判定时固定传 owning_func=None) | 描述已更正:该路径只认 self | | 实例.kernel 已带 receiver,再显式传实例会重复传入 | 采纳「检测并明确诊断」:tla.compile 在拼接前对重复 receiver 抛错,并加用例 test_bound_method_rejects_a_duplicated_receiver | | 描述称 @tla.kernel 作用于 staticmethod / classmethod 会在装饰期报错 | 本 PR 未包含该诊断(dsl.py 只新增 receiver 字段与 __get__,测试也无对应用例),描述已删除该条 | ## 关联的Issue https://gitcode.com/cann/catlass/issues/559 ## 原因 issue #559 要求 CATLASS DSL 支持以类实例组织 Kernel,让分块大小、stage 数、dtype 这类编译期配置与 kernel 一起封装,而不是散在 host 侧的调用点。 改动前存在两个障碍: | 现象 | 原因 | |---|---| | 传实例报 TlaUnsupportedAbiError: tla.compile expects a @tla.kernel function, or an instance of a class that declares one. | tla.compile 只接受 @tla.kernel 的返回值 | | 实例形态的 kernel 在 lowering 时实参个数不匹配 | 方法首位 self 被算作运行时参数 | 有意不支持的写法:host 侧没有对应的 pass,因此 @tla.jit __call__ 只能是到 kernel 的纯转发——单条语句、按序传全部参数、不用关键字、不计算实参。其他写法都会报错,这是本次变更的边界;实例若没有 @tla.jit __call__,也直接报错,不做「按方法名或唯一性猜入口」的回落。 ## 测试 单元测试(python/tla_dsl,Python 3.11 venv,python -m pytest tests/): - 新增 tests/frontend/test_kernel_class_organization.py,27 个用例:实例与绑定方法两种写法产物等价(cache_key 相同、启动签名一致)、入口选择(转发指向的方法名不限)、转发形态校验与报错文案、无 @tla.jit __call__ 的实例被拒、接收者不占 ABI 槽位、self.attr(含嵌套普通对象属性)折叠为常量、首位 self 在类外也同样是接收者、运行时取值误当接收者被拒、按配置区分的 cache key - 定向:tests/frontend/test_kernel_class_organization.py + tests/test_execution_args.py 共 83 passed - 全量:2471 passed, 7 skipped;另有 13 failed 全部落在 tests/test_tla_lower_to_hivm.py,是本机 TlaCompile 二进制未随分支重建(缺 tla-vector-region-simd pass)所致,与本改动无关 - lint:按 CI 口径 ruff check --select E4,E7,E9,F --line-length 120 与 format 通过;新增测试文件里 _BareNameCallKernel.__call__ 的裸名调用是刻意用例,已按仓内既有做法在 pyproject.toml 补 per-file-ignores 端到端(Ascend 950,--npu-arch 3510):类版本 vector-add 编译并启动,结果逐元素精确一致,n_ele=64 与 n_ele=384 均 passed=True,cache_key 分别为 74035fa27c9e26e8、fb2175bc67b0adb9。内存 / 性能 / 确定性检测不涉及。 新增样例:examples/end_to_end/kernel_in_class/vector_add_with_static_length.py,类版本 vector-add,编译期配置、kernel 与编译入口封装在同一个类里。 ## 文档更新 | 文件 | 内容 | |---|---| | docs/zh/kernel_development/core_concepts/compile_and_launch.md | 新增「以类实例组织 Kernel」章节,含编译入口写法表与约束 | | docs/zh/api/host_api_reference.md | tla.compile 参数与约束同步 | | docs/en/api/host_api_reference.md | 同步生成结果与源码行号 | | examples/end_to_end/kernel_in_class/README.md | 类版本示例说明 | ## 类型标签 - [x] 新特性 --- ## Description Let tla.compile accept a kernel organized as a class instance: compile-time configuration, the kernel and its compile entry live in one class, and the instance joins compilation as a compile-time receiver, so self.attr folds into constants. python class VectorAdd: def __init__(self, vector_ele: int) -> None: self.vector_ele = vector_ele @tla.jit def __call__(self, lhs, rhs, output): self.kernel(lhs, rhs, output) @tla.kernel def kernel(self, lhs, rhs, output): ... # self.vector_ele as a compile-time constant opts = {"options": "--npu-arch 3510"} # 1. the instance: the one-line @tla.jit __call__ forward names the kernel a = tla.compile(VectorAdd(128), lhs, rhs, output, **opts) # 2. the bound method read off an instance: the instance rides along as the receiver b = tla.compile(VectorAdd(128).kernel, lhs, rhs, output, **opts) # 3. another configuration: different constants, a different binary d = tla.compile(VectorAdd(64), lhs, rhs, output, **opts) a(lhs, rhs, output, block_num=1) Forms 1 and 2 compile to the same artifact and share a cache_key; neither launch signature carries the receiver: | Form | Kernel compiled | Launch signature | |---|---|---| | tla.compile(instance, ...) | the kernel method the one-line @tla.jit __call__ forwards to | lhs, rhs, output | | tla.compile(instance.kernel, ...) | the same method, the instance bound along as the receiver | lhs, rhs, output | Another compile-time configuration (form 3) gets a new cache_key: in the new sample, n_ele=64 gives 74035fa27c9e26e8 and n_ele=384 gives fb2175bc67b0adb9. Files touched: | File | What | |---|---| | catlass/base_dsl/compiler.py | Instance entry resolution _resolve_kernel_target, the @tla.jit __call__ pure-forwarding check _check_jit_call_is_pure_forwarding | | catlass/dsl.py | TlaJitFunction gains a receiver field and __get__, binding the instance when read off it | | catlass/base_dsl/runtime/jit_arg_adapters.py | receiver_argument_name: a leading receiver is decided by position and name | | catlass/base_dsl/jit_executor.py | ExecutionArgs.filter_runtime_signature reuses the same static-parameter rule so the launch signature lines up with the compiled plan | | catlass/execution_lowering.py | The receiver occupies no runtime ABI slot; self.attr folds into constants | How the entry point is picked: | Shape of the class | Kernel compiled | |---|---| | An instance, and the class declares @tla.jit __call__ | The method the one-line forward points to; the name is free | | A kernel method read off an instance (instance.kernel) | That method itself | | An instance whose class has no @tla.jit __call__ | Rejected, asking for a @tla.jit __call__; no "method named kernel" fallback | | Neither a @tla.kernel function nor an instance of a class declaring one | Rejected, naming the expected entry types | Receiver rule: - A leading parameter named self is a compile-time receiver: it takes no runtime ABI slot, and self.attr folds into the kernel as a constant while the body is staged - receiver_argument_name calls the rule with no owner (owning_func=None), and cls only qualifies under a classmethod owner, so on this path only self is ever taken as the receiver; a leading cls is not - The rule keys off position and name only, not on whether the function belongs to a class - A runtime receiver value (a device tensor or a runtime number) is rejected with a rename hint instead of leaving the runtime ABI unannounced - A bound method (instance.kernel) already carries the receiver; passing the instance again is a duplicate that tla.compile rejects with a clear message Impact on existing behaviour: a leading self no longer reaches the runtime ABI, so two places in the tree that relied on the old reading are adjusted. | File | Adjustment | |---|---| | examples/end_to_end/structured_arguments/static_tensor_interfaces.py | copy_from_self becomes copy_from_tensor, its leading parameter becomes input_tensor | | tests/test_execution_args.py | self leaves the launch signature; cls stays a runtime parameter when no classmethod owns it | ### Review follow-up (CheaterAbec) | Comment | Disposition | |---|---| | The pure-forwarding helper's name misleads: it only decides whether @tla.jit __call__ is a one-line forward, unrelated to the full Host JIT path | Renamed to _check_jit_call_is_pure_forwarding | | The entry-selection table claimed two fallbacks ("method named kernel", "the class's only @tla.kernel method") that the code does not have | The description now matches the code: no @tla.jit __call__ is rejected ou See merge request: cann/catlass!1292 | 13 小时前 |