关于 add-uint-support
面向 PyTorch 贡献者的编码技能,指导为算子分派宏添加 uint16、uint32 和 uint64 支持,并涵盖转换、逐处更新与验证。
主要功能
- 01添加无符号整数分派类型
- 02说明 AT_DISPATCH_V2 转换
- 03覆盖多个分派位置
- 04提供验证清单
适用场景
- 01为算子扩展 uint16、uint32 和 uint64
- 02检查内核分派位置的类型覆盖
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ pytorch/ pytorch --skill add-uint-support安装后在 Claude Code 中输入/add-uint-support确认已加载。
详细介绍
为运算符添加无符号整数(uint)支持
此技能可帮助通过更新 AT_DISPATCH 宏,为 PyTorch 运算符添加对无符号整数类型(uint16、uint32、uint64)的支持。
何时使用此技能
在以下情况下使用此技能:
- 为运算符添加对 uint16、uint32 或 uint64 的支持
- 用户提到“无符号类型”“uint 支持”或“基础无符号类型”
- 在内核中启用对 kUInt16、kUInt32、kUInt64 的支持
- 处理需要扩大类型覆盖范围的运算符实现
快速参考
为现有的分派添加无符号类型:
// Before
AT_DISPATCH_V2(dtype, "op", AT_WRAP([&]() {
kernel<scalar_t>();
}), AT_EXPAND(AT_ALL_TYPES));
// After (method 1: add unsigned types explicitly)
AT_DISPATCH_V2(dtype, "op", AT_WRAP([&]() {
kernel<scalar_t>();
}), AT_EXPAND(AT_ALL_TYPES), AT_EXPAND(AT_BAREBONES_UNSIGNED_TYPES));
// After (method 2: use V2 integral types if AT_INTEGRAL_TYPES present)
AT_DISPATCH_V2(dtype, "op", AT_WRAP([&]() {
kernel<scalar_t>();
}), AT_EXPAND(AT_INTEGRAL_TYPES_V2), AT_EXPAND(AT_FLOATING_TYPES));
类型组参考
无符号类型组:
AT_BAREBONES_UNSIGNED_TYPES:kUInt16、kUInt32、kUInt64AT_INTEGRAL_TYPES_V2:AT_INTEGRAL_TYPES + AT_BAREBONES_UNSIGNED_TYPES
关系:
AT_INTEGRAL_TYPES // kByte, kChar, kInt, kLong, kShort
AT_BAREBONES_UNSIGNED_TYPES // kUInt16, kUInt32, kUInt64
AT_INTEGRAL_TYPES_V2 // INTEGRAL_TYPES + BAREBONES_UNSIGNED_TYPES
说明
步骤 1:确定是否需要转换为 V2
检查文件是否使用 AT_DISPATCH_V2:
如果使用旧版 AT_DISPATCH:
- 先使用 at-dispatch-v2 技能转换为 AT_DISPATCH_V2
- 然后继续添加 uint 支持
如果已使用 AT_DISPATCH_V2:
- 直接继续步骤 2
步骤 2:分析当前的分派宏
识别当前使用的类型组:
AT_DISPATCH_V2(dtype, "op", AT_WRAP([&]() {
// body
}), AT_EXPAND(AT_ALL_TYPES), kHalf, kBFloat16);
^^^^^^^^^^^^^^^^^^^^^^^^^
Current type coverage
常见模式:
AT_EXPAND(AT_ALL_TYPES)→ 包含 AT_INTEGRAL_TYPES + AT_FLOATING_TYPESAT_EXPAND(AT_INTEGRAL_TYPES)→ 仅有符号整数AT_EXPAND(AT_FLOATING_TYPES)→ 浮点类型
步骤 3:选择添加 uint 的方法
有两种方法:
方法 1:显式添加 AT_BAREBONES_UNSIGNED_TYPES
- 适用情况:希望明确添加 uint 支持
- 将
AT_EXPAND(AT_BAREBONES_UNSIGNED_TYPES)添加到类型列表
方法 2:将 AT_INTEGRAL_TYPES 替换为 AT_INTEGRAL_TYPES_V2
- 适用情况:分派已使用
AT_EXPAND(AT_INTEGRAL_TYPES) - 更简洁:用其超集替换一个类型组
- 仅适用于存在 AT_INTEGRAL_TYPES 的情况
步骤 4:应用转换
方法 1 示例:
// Before
AT_DISPATCH_V2(
dtype,
"min_values_cuda",
AT_WRAP([&]() {
kernel_impl<scalar_t>(iter);
}),
AT_EXPAND(AT_ALL_TYPES),
kBFloat16, kHalf, kBool
);
// After (add unsigned types)
AT_DISPATCH_V2(
dtype,
"min_values_cuda",
AT_WRAP([&]() {
kernel_impl<scalar_t>(iter);
}),
AT_EXPAND(AT_ALL_TYPES),
AT_EXPAND(AT_BAREBONES_UNSIGNED_TYPES),
kBFloat16, kHalf, kBool
);
方法 2 示例:
// Before
AT_DISPATCH_V2(
dtype,
"integral_op",
AT_WRAP([&]() {
kernel<scalar_t>();
}),
AT_EXPAND(AT_INTEGRAL_TYPES)
);
// After (substitute with V2)
AT_DISPATCH_V2(
dtype,
"integral_op",
AT_WRAP([&]() {
kernel<scalar_t>();
}),
AT_EXPAND(AT_INTEGRAL_TYPES_V2)
);
步骤 5:处理 AT_ALL_TYPES 与单独的类型组
如果分派使用 AT_EXPAND(AT_ALL_TYPES):
AT_ALL_TYPES=AT_INTEGRAL_TYPES+AT_FLOATING_TYPES- 添加 uint:将
AT_EXPAND(AT_BAREBONES_UNSIGNED_TYPES)添加到列表
如果分派分别列出 INTEGRAL 和 FLOATING:
// Before
AT_EXPAND(AT_INTEGRAL_TYPES), AT_EXPAND(AT_FLOATING_TYPES)
// After (Method 2 preferred)
AT_EXPAND(AT_INTEGRAL_TYPES_V2), AT_EXPAND(AT_FLOATING_TYPES)
步骤 6:验证所有分派位置
检查文件中所有需要 uint 支持的分派宏:
- 某些运算符有多个分派位置(CPU、CUDA、不同函数)
- 在所有位置一致地应用转换
- 确保每处都更新为相同的类型覆盖范围
步骤 7:验证更改
检查以下各项:
- 使用 AT_DISPATCH_V2 格式(而非旧版 AT_DISPATCH)
- 通过两种方法之一添加无符号类型
- 更新文件中所有相关的分派位置
- 类型组使用
AT_EXPAND() - 参数格式正确,并以逗号分隔
常见模式
模式 1:AT_ALL_TYPES + 额外类型
// Before
AT_DISPATCH_V2(dtype, "op", AT_WRAP([&]() {
kernel<scalar_t>();
}), AT_EXPAND(AT_ALL_TYPES), kHalf, kBFloat16);
// After
AT_DISPATCH_V2(dtype, "op", AT_WRAP([&]() {
kernel<scalar_t>();
}), AT_EXPAND(AT_ALL_TYPES), AT_EXPAND(AT_BAREBONES_UNSIGNED_TYPES), kHalf, kBFloat16);
模式 2:分别列出 INTEGRAL + FLOATING
// Before
AT_DISPATCH_V2(dtype, "op", AT_WRAP([&]() {
kernel<scalar_t>();
}), AT_EXPAND(AT_INTEGRAL_TYPES), AT_EXPAND(AT_FLOATING_TYPES));
// After
AT_DISPATCH_V2(dtype, "op", AT_WRAP([&]() {
kernel<scalar_t>();
}), AT_EXPAND(AT_INTEGRAL_TYPES_V2), AT_EXPAND(AT_FLOATING_TYPES));
模式 3:先转换旧版分派
// Before (needs v2 conversion first)
AT_DISPATCH_ALL_TYPES_AND2(kHalf, kBFloat16, dtype, "op", [&]() {
kernel<scalar_t>();
});
// After v2 conversion
AT_DISPATCH_V2(dtype, "op", AT_WRAP([&]() {
kernel<scalar_t>();
}), AT_EXPAND(AT_ALL_TYPES), kHalf, kBFloat16);
// After adding uint support
AT_DISPATCH_V2(dtype, "op", AT_WRAP([&]() {
kernel<scalar_t>();
}), AT_EXPAND(AT_ALL_TYPES), AT_EXPAND(AT_BAREBONES_UNSIGNED_TYPES), kHalf, kBFloat16);
多个分派位置示例
对于包含多个函数的文件:
void min_values_kernel_cuda(TensorIterator& iter) {
AT_DISPATCH_V2(iter.dtype(), "min_values_cuda", AT_WRAP([&]() {
impl<scalar_t>(iter);
}), AT_EXPAND(AT_ALL_TYPES), AT_EXPAND(AT_BAREBONES_UNSIGNED_TYPES), kBFloat16, kHalf);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Added uint support
}
void min_launch_kernel(TensorIterator &iter) {
AT_DISPATCH_V2(iter.input_dtype(), "min_cuda", AT_WRAP([&]() {
gpu_reduce_kernel<scalar_t>(iter);
}), AT_EXPAND(AT_ALL_TYPES), AT_EXPAND(AT_BAREBONES_UNSIGNED_TYPES), kBFloat16, kHalf);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Added uint support here too
}
决策树
使用此决策树确定处理方法:
Is the file using AT_DISPATCH_V2?
├─ No → Use at-dispatch-v2 skill first, then continue
└─ Yes
└─ Does it use AT_EXPAND(AT_INTEGRAL_TYPES)?
├─ Yes → Replace with AT_EXPAND(AT_INTEGRAL_TYPES_V2)
└─ No → Add AT_EXPAND(AT_BAREBONES_UNSIGNED_TYPES) to type list
边缘情况
情况 1:分派仅包含浮点类型
如果运算符仅支持浮点类型,则不要添加 uint 支持:
// Leave as-is - floating point only operator
AT_DISPATCH_V2(dtype, "float_op", AT_WRAP([&]() {
kernel<scalar_t>();
}), AT_EXPAND(AT_FLOATING_TYPES), kHalf);
情况 2:存在复数类型
无符号类型可以与复数类型一起使用:
AT_DISPATCH_V2(dtype, "op", AT_WRAP([&]() {
kernel<scalar_t>();
}), AT_EXPAND(AT_ALL_TYPES),
AT_EXPAND(AT_BAREBONES_UNSIGNED_TYPES),
AT_EXPAND(AT_COMPLEX_TYPES),
kHalf, kBFloat16);
情况 3:已支持 uint
检查是否已包含 uint 类型:
- 如果使用
AT_INTEGRAL_TYPES_V2→ 已支持 uint - 如果列表中已包含
AT_BAREBONES_UNSIGNED_TYPES→ 已支持 uint - 如果已支持 uint,则跳过该文件
工作流
当被要求添加 uint 支持时:
- 读取目标文件
- 检查是否使用 AT_DISPATCH_V2:
- 如果没有 → 先使用 at-dispatch-v2 技能
- 找出所有分发宏位置
- 对每个分发:
- 分析当前类型组
- 选择方法(添加 BAREBONES_UNSIGNED 或升级到 V2)
- 使用 Edit 工具应用转换
- 向用户展示更改
- 说明修改内容
重要说明
- 始终先检查是否需要转换为 v2
- 在文件的所有分发位置一致地应用更改
- 方法 2(AT_INTEGRAL_TYPES_V2)在适用时更简洁
- 方法 1(显式 AT_BAREBONES_UNSIGNED_TYPES)更明确
- 无符号类型包括:kUInt16、kUInt32、kUInt64(不包括 kByte,后者是 uint8)
- 某些运算符在语义上可能不支持无符号类型,请酌情判断
测试
添加 uint 支持后,该运算符应能接受 uint16、uint32 和 uint64 张量。功能测试由用户负责。
评论
支持 Markdown