feat(vpto): add sdma_gm_gm with session-template expansion - #1324
feat(vpto): add sdma_gm_gm with session-template expansion#1324kerwinair wants to merge 6 commits into
Conversation
| @@ -0,0 +1,189 @@ | |||
| # 19. Async Communication | |||
| @@ -0,0 +1,40 @@ | |||
| // Copyright (c) 2026 Huawei Technologies Co., Ltd. | |||
There was a problem hiding this comment.
新增ST用例统一使用PTODSL测试框架,参考:test/vpto/cases/micro-op/a5-extra/vmadd.py
Add pto.sdma_gm_gm as a Layer-2 micro-op that copies between GM ranges from an ordinary AICore kernel. The session is a stack-local struct filled by pto.session_init from a host-written GM template; field layout is shared through AsyncSessionABI.h. A2/A3 post SQEs and ring the doorbell through UB with a byte-granular MTE store. Handwritten pto.st_dev is rejected on A2/A3; A5 may use it for the doorbell. A5 uses the engine for local copies and GET. Remote PUT on A5 is expanded to a chunked GM-to-UB-to-GM copy, because that generation cannot write remotely through SDMA. Runtime cases cover local, peer PUT, peer GET, and multicore transfers. Host workspace helpers stay in the test tree. ISA chapter 19 documents the current ops. The broader comm programming model stays in docs/designs/; URMA/RDMA, pointer remote attributes, and fused notify are not in the current IR.
PTODSL built a kernel's shared library from two inputs it generated itself, the launch code and the ptoas-produced kernel object. A kernel whose host side already exists in C++ had no way in, leaving only two bad options: reimplement the C++ in Python, or ship it as a second library the caller loads separately and keeps in step by hand. native_options names host C++ sources to compile and link into the same library, the include directories they need, and the libraries to link against. Host source contents are digested into the build's cache key, so editing one rebuilds rather than silently reusing. Sources are compiled as host code, reusing the host flags that already existed here but were never wired up. compiled.native_library() reaches the result. Library loading moves out of LaunchHandle so one loaded library is shared by every launch handle over a specialization and by callers looking for a host symbol. Paths resolve against the declaring file, as source= already does. Unknown keys, library names that are really paths or flags, and include_dirs without host_sources are all rejected when the decorator runs. Co-authored-by: Cursor <cursoragent@cursor.com>
Review asked that new ST cases use the PTODSL test framework rather than
per-case C++ and shell harnesses. Four directories of kernel.pto, launch.cpp,
main.cpp and run.sh become one Python file.
Only the A5 {soft_put} form of pto.sdma_gm_gm moves, and that is the whole
constraint: it expands to a synchronous GM->UB->GM copy, so the transfer is done
when the kernel returns and the result is an ordinary golden comparison. The
engine form posts SQEs and rings a doorbell, so its destination is polled rather
than read once, which no golden harness expresses. It also only takes effect on
A5; a2/a3 ignore the attribute and post SQEs instead, so these cases are A5-only
by construction rather than by preference.
The four cases share two kernels and differ mostly in the session template the
host writes, which is the point: the transfer is described by session data, not by
the kernel. Multicore needs more than one block, so golden_output_case gains a
grid parameter.
The engine path keeps a spike under test/comm/ rather than a case, because what is
unproven there is not the transfer but whether an async workspace can attach to
the device and context torch_npu set up, whether memory it allocates is
addressable by a harness-launched kernel, and whether an engine-filled destination
is observable. It stays out of test/vpto/cases/ so the validation runner does not
pick up something needing a CANN 9.0 toolkit, and it has no skip path, because a
spike that quietly passes when it could not run answers nothing.
AsyncWorkspaceShim.cpp is what lets Python drive that without a second copy of the
session ABI: every field position and slot width stays in AsyncSessionABI.h, and
the shim takes named values and returns an opaque byte image. It rides into the
kernel's own library through native_options, so there is one build and one
artifact. HcclWindows.h goes away with the C++ cases that were its only caller.
The IR shapes these kernels rely on are pinned in a lit case as well, since the
Python cases only run where a device or simulator is available.
Co-authored-by: Cursor <cursoragent@cursor.com>
8ff7abe to
f6a1f63
Compare
The option and command-line tests do not need MLIR bindings; importing launch/codegen at package load time made collection fail on machines that have not built PTOAS yet. Co-authored-by: Cursor <cursoragent@cursor.com>
from __future__ import annotations turned pto.ptr(...) into strings, so @pto.jit rejected the same entry ABI the soft_put ST already uses. Co-authored-by: Cursor <cursoragent@cursor.com>
bisheng --cce-fatobj-link does not pull the C++ runtime, so a host source that uses std::string failed the kernel .so with undefined cxx11 symbols. Co-authored-by: Cursor <cursoragent@cursor.com>
关于微指令 session / template 建模的设计建议经过讨论,先明确这里存在两个不同层级的概念:
因此不建议直接复用现有 总体结论本 PR 将 session 拆成两部分的方向是合理的:
需要调整的是抽象边界。建议分为三层:
也就是说, 当前公开 struct 形式有几个问题:
|
建议拆分同步
|
其他需要明确的通信 session / SDMA IR 设计问题除同步 1. Session 隐藏了真正的有状态 queue 资源
建议让 session/queue 成为显式的资源句柄,并为通信 queue 定义专门的 side-effect resource。仅把隐藏的 GM 状态表示为对 stack-local struct 的读写,不能准确描述实际 alias 关系。 2. Queue capacity/backpressure 没有 IR contract一个 建议先明确:异步 kick 是否可以为了等待空闲 SQ slot 而阻塞 scalar stream;如果不可以,则需要显式的 reserve/status 机制或可验证的容量前置条件。 3. Host 配置与 kernel/compiler 资源所有权混在同一个 template 中
建议 Host template 只携带通信域/runtime 拥有的信息,而 kernel/compiler 拥有的值作为显式 operand: %s = pto.sdma_session_init %template
channel(%bid)
scratch(%tmp)
sync_id(%event)
: !pto.sdma_session_template -> !pto.comm_session<sdma>4. 本地/远端地址以及 engine 类型没有进入类型系统当前 local copy、remote GET 和 remote PUT 都使用普通 同时 session ABI 有 !pto.comm_session<sdma>
!pto.comm_session<urma>
!pto.comm_session<rdma>5. ABI 中存在未被当前 op 消费的配置字段当前 lowering 没有消费 建议只在当前 engine-specific session 中暴露有明确语义并被验证/消费的配置;future engine 的状态放入对应 session 类型。底层 struct/template layout 可以继续作为 runtime 与 lowering 的内部 ABI,但不应成为用户直接操作的 micro-IR 接口。 总体建议是把以下四类状态分层,而不是压进一个可任意
|
Add pto.sdma_gm_gm as a Layer-2 micro-op that copies between GM ranges from an ordinary AICore kernel. The session is a stack-local struct filled by pto.session_init from a host-written GM template; field layout is shared through AsyncSessionABI.h.
A2/A3 post SQEs and ring the doorbell through UB with a byte-granular MTE store. Handwritten pto.st_dev is rejected on A2/A3; A5 may use it for the doorbell. A5 uses the engine for local copies and GET. Remote PUT on A5 is expanded to a chunked GM-to-UB-to-GM copy, because that generation cannot write remotely through SDMA.
Runtime cases cover local, peer PUT, peer GET, and multicore transfers. Host workspace helpers stay in the test tree.
ISA chapter 19 documents the current ops. The broader comm programming model stays in docs/designs/; URMA/RDMA, pointer remote attributes, and fused notify are not in the current IR.