Conversation
Register deep_gemm::tf32_hc_prenorm_gemm as a torch dispatcher op (torch.ops.deep_gemm.tf32_hc_prenorm_gemm) so external C++/Python callers can invoke it without including DeepGEMM headers or linking DeepGEMM. The schema is compiled into the _C extension next to the pybind bindings, so the op is available once import deep_gemm loads _C. The op forwards to deep_gemm::hyperconnection::tf32_hc_prenorm_gemm; d and sqr_sum are marked mutable (in-place) and num_splits is optional, matching the existing pybind signature.
|
|
||
| // NOTE: use the handle name `lib` (not `m`) so the .pyi stub generator, which | ||
| // scans csrc for pybind-style `m.def(...)`, skips these dispatcher schemas. | ||
| TORCH_LIBRARY(deep_gemm, lib) { |
There was a problem hiding this comment.
🟡 warning: TORCH_LIBRARY / TORCH_LIBRARY_IMPL 会在每个包含该头文件的翻译单元中生成静态注册对象,#pragma once 无法跨 TU 保护。当前 setup.py 只编译 csrc/python_api.cpp 单个 TU,因此是安全的;但若将来 sources 增加第二个 .cpp 并 include 此头,会在加载时触发 'Only a single TORCH_LIBRARY can be used to register the namespace deep_gemm' 错误。建议在头文件顶部注释中明确“本头文件只能被恰好一个 TU 包含”,或将注册块移入独立的 torch_ops.cpp 并加入 setup.py 的 sources。
🤖 v5
|
|
||
| // Thin forwarder matching a torch-op-friendly signature: `d` and `sqr_sum` are | ||
| // written in place, `num_splits` is optional. | ||
| inline void tf32_hc_prenorm_gemm(const at::Tensor& a, const at::Tensor& b, |
There was a problem hiding this comment.
🔵 suggestion: 转发函数使用 std::optional / int64_t,但未显式 #include 与 ,目前依赖 torch/library.h 的传递包含。建议显式包含以增强健壮性。另外该文件使用 at::Tensor,而仓库其余 API 统一使用 torch::Tensor,可考虑保持一致(二者为同一类型,仅为风格问题)。
🤖 v5
|
|
||
| // NOTE: use the handle name `lib` (not `m`) so the .pyi stub generator, which | ||
| // scans csrc for pybind-style `m.def(...)`, skips these dispatcher schemas. | ||
| TORCH_LIBRARY(deep_gemm, lib) { |
There was a problem hiding this comment.
🔵 suggestion: TORCH_LIBRARY(deep_gemm, lib) cannot be used more than once per translation unit: it expands to a static TORCH_LIBRARY_init_deep_gemm and TORCH_LIBRARY_static_init_deep_gemm. Since the header is included from python_api.cpp and the description states more host APIs will be exposed "the same way later", a second header using TORCH_LIBRARY(deep_gemm, ...) in the same TU will fail to compile with a redefinition error. Consider using TORCH_LIBRARY_FRAGMENT(deep_gemm, lib) here (the documented mechanism for splitting schema registration across files), or centralizing all deep_gemm schemas in a single registration block.
🤖 v4
| at::Tensor& d, at::Tensor& sqr_sum, | ||
| std::optional<int64_t> num_splits) { | ||
| std::optional<int> ns = num_splits.has_value() | ||
| ? std::optional<int>(static_cast<int>(num_splits.value())) |
There was a problem hiding this comment.
🔵 suggestion: The schema exposes num_splits as int? (64-bit) but the forwarder narrows it with static_cast<int>. A value larger than INT_MAX would silently truncate/overflow before reaching the kernel. num_splits is realistically small, but a checked conversion (or asserting num_splits <= INT_MAX) would avoid a silent wraparound.
🤖 v4
🤖 ds-review-bot Code Reviewv6新增 dispatcher 入口绕过了共享 JIT 状态原有的 GIL 保护,引入并发调用时的数据竞争。当前环境缺少 PyTorch 和 CUDA 编译工具,未运行构建或 GPU 测试。 v5本 MR 新增 csrc/apis/torch_ops.hpp,将 deep_gemm::hyperconnection::tf32_hc_prenorm_gemm 通过 TORCH_LIBRARY / TORCH_LIBRARY_IMPL 注册为 torch dispatcher op(torch.ops.deep_gemm.tf32_hc_prenorm_gemm),并在 csrc/python_api.cpp 中 include 该头文件使 schema 编译进 _C。静态审查结论:实现正确、与描述一致。(1) 转发函数签名与 pybind 目标兼容:at::Tensor& 可绑定 const torch::Tensor&,int? 正确映射为 std::optional<int64_t> 并转换为 std::optional<int>;(2) Tensor(d!)/Tensor(s!) 可变标注与 kernel 就地写入语义一致,num_splits=None 与 pybind 默认值 std::nullopt 对齐;(3) TORCH_LIBRARY 放在头文件中在当前构建下是安全的——setup.py 只编译单个 TU(csrc/python_api.cpp),且仓库中不存在其他 TORCH_LIBRARY(deep_gemm, ...),不会出现重复注册;(4) scripts/generate_pyi.py 以字面量 'm.def(' 匹配,lib.def( 不会被误采集,头文件注释中的 m.def(...) 以 // 开头也会被生成器跳过;(5) csrc/python_api.cpp 中的 include 位置合理,注册随 _C 加载完成,符合“import deep_gemm 即可用”的预期。未做编译/运行验证(环境仅允许 git 命令)。整体建议:可合并,附带若干非阻塞建议。 v4This change registers the existing Files reviewed: 2 📍 未定位到 diff 的评论🔵 suggestion |
- Use TORCH_LIBRARY_FRAGMENT so future headers can register more deep_gemm ops in the same translation unit without a duplicate-namespace error. - Validate num_splits range before narrowing int64_t -> int to avoid silent overflow; reject values < 1. - Add explicit <cstdint>/<limits>/<optional> includes; use torch::Tensor to match the rest of the APIs. - Document the eager-only (no Meta kernel) limitation and the GIL/JIT threading contract in header comments. - Add a dispatcher-level test comparing torch.ops.deep_gemm.tf32_hc_prenorm_gemm against the pybind path for num_splits None and an explicit split.
|
Thanks for the detailed review. Pushed a follow-up commit (9f07225) addressing most of the comments:
Update: verified locally on an SM90 GPU (CUDA 13.2, PyTorch 2.11, Python 3.12, cxx11abi).
|
What
Registers
deep_gemm::tf32_hc_prenorm_gemmas a torch dispatcher op (torch.ops.deep_gemm.tf32_hc_prenorm_gemm) in addition to the existing pybind binding.Why
External C++ (and Python) callers can then invoke this kernel through the PyTorch dispatcher without including DeepGEMM headers or linking against DeepGEMM — e.g. a host-side C++ extension can resolve it via
c10::Dispatcher::singleton().findSchemaOrThrow("deep_gemm::tf32_hc_prenorm_gemm", ""). The schema is compiled into the_Cextension alongside the pybind bindings, so the op is available as soon asimport deep_gemmloads_C.Details
csrc/apis/torch_ops.hpp:deep_gemm::hyperconnection::tf32_hc_prenorm_gemm, convertingstd::optional<int64_t>→std::optional<int>.TORCH_LIBRARY(deep_gemm)schema:tf32_hc_prenorm_gemm(Tensor a, Tensor b, Tensor(d!) d, Tensor(s!) sqr_sum, int? num_splits=None) -> ()—dandsqr_sumare marked mutable (written in place),num_splitsdefaults toNoneto match the pybind signature.TORCH_LIBRARY_IMPL(deep_gemm, CUDA)registering the CUDA implementation.csrc/python_api.cpp: include the new header so the schema is compiled into_C.Notes
TORCH_LIBRARYhandle is namedlib(notm) so the.pyistub generator, which scans csrc for pybind-stylem.def(...), skips these dispatcher schemas.torch.compile.