
Add Unsigned Integer Support
FreeIntegrate unsigned integer types in PyTorch operators.
Free · Opens the source repo
What Add Unsigned Integer Support does
The Add Unsigned Integer Support skill facilitates the inclusion of unsigned integer types (uint16, uint32, uint64) in PyTorch operators by modifying the AT_DISPATCH macros. This skill is essential for developers who need to extend the type coverage of PyTorch's computational capabilities, particularly when dealing with unsigned integer data types in their machine learning models or custom operations.
When you are working on PyTorch extensions or custom kernels, you may encounter scenarios where unsigned integer support is necessary. This skill provides a structured approach to update existing operator implementations, ensuring that they can handle uint types effectively. By following the provided instructions, developers can seamlessly integrate uint support into their code, enhancing the versatility and performance of their applications.
The skill outlines a step-by-step process for identifying whether the existing code uses the older AT_DISPATCH macros or the newer AT_DISPATCH_V2. It then guides users through analyzing the current dispatch macros and selecting the appropriate method to add uint support. This ensures that all relevant dispatch sites are updated consistently, maintaining the integrity of the codebase while expanding its functionality.
This skill is particularly beneficial for developers working on numerical computations, image processing, or any domain where unsigned integers are relevant. It empowers them to leverage the full potential of PyTorch by enabling support for additional data types, thus broadening the scope of operations that can be performed efficiently.
When to use it
Use this skill when adding support for uint16, uint32, or uint64 types to PyTorch operators and kernels.
When not to use it
This skill is not suitable for scenarios where unsigned integer support is not required or when working with older versions of PyTorch that do not utilize AT_DISPATCH_V2.
What you can build with it
Adding uint support to a custom operator
When implementing a new operator that requires unsigned integer types, this skill guides you through the necessary macro updates.
Updating existing kernels for expanded type coverage
If you have existing kernels that need to handle unsigned integers, this skill provides the steps to modify them appropriately.
Enhancing data handling in machine learning models
For machine learning applications that utilize unsigned integers, this skill enables the necessary support in PyTorch operations.
How to install Add Unsigned Integer Support
View source1. Install with the skills CLI
npx skills add pytorch/pytorch/add-uint-support --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by pytorchAdd Unsigned Integer (uint) Support to Operators
This skill helps add support for unsigned integer types (uint16, uint32, uint64) to PyTorch operators by updating their AT_DISPATCH macros.
When to use this skill
Use this skill when:
- Adding uint16, uint32, or uint64 support to an operator
- User mentions "unsigned types", "uint support", "barebones unsigned types"
- Enabling support for kUInt16, kUInt32, kUInt64 in kernels
- Working with operator implementations that need expanded type coverage
Quick reference
Add unsigned types to existing dispatch:
// 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));
Type group reference
Unsigned type groups:
AT_BAREBONES_UNSIGNED_TYPES: kUInt16, kUInt32, kUInt64AT_INTEGRAL_TYPES_V2: AT_INTEGRAL_TYPES + AT_BAREBONES_UNSIGNED_TYPES
Relationship:
AT_INTEGRAL_TYPES // kByte, kChar, kInt, kLong, kShort
AT_BAREBONES_UNSIGNED_TYPES // kUInt16, kUInt32, kUInt64
AT_INTEGRAL_TYPES_V2 // INTEGRAL_TYPES + BAREBONES_UNSIGNED_TYPES
Instructions
Step 1: Determine if conversion to V2 is needed
Check if the file uses AT_DISPATCH_V2:
If using old AT_DISPATCH:
- First convert to AT_DISPATCH_V2 using the at-dispatch-v2 skill
- Then proceed with adding uint support
If already using AT_DISPATCH_V2:
- Proceed directly to Step 2
Step 2: Analyze the current dispatch macro
Identify what type groups are currently in use:
AT_DISPATCH_V2(dtype, "op", AT_WRAP([&]() {
// body
}), AT_EXPAND(AT_ALL_TYPES), kHalf, kBFloat16);
^^^^^^^^^^^^^^^^^^^^^^^^^
Current type coverage
Common patterns:
AT_EXPAND(AT_ALL_TYPES)→ includes AT_INTEGRAL_TYPES + AT_FLOATING_TYPESAT_EXPAND(AT_INTEGRAL_TYPES)→ signed integers onlyAT_EXPAND(AT_FLOATING_TYPES)→ floating point types
Step 3: Choose the uint addition method
Two approaches:
Method 1: Add AT_BAREBONES_UNSIGNED_TYPES explicitly
- Use when: You want to be explicit about adding uint support
- Add
AT_EXPAND(AT_BAREBONES_UNSIGNED_TYPES)to the type list
Method 2: Substitute AT_INTEGRAL_TYPES with AT_INTEGRAL_TYPES_V2
- Use when: The dispatch already uses
AT_EXPAND(AT_INTEGRAL_TYPES) - More concise: replaces one type group with its superset
- Only applicable if AT_INTEGRAL_TYPES is present
Step 4: Apply the transformation
Method 1 example:
// 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
);
Method 2 example:
// 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)
);
Step 5: Handle AT_ALL_TYPES vs individual type groups
If the dispatch uses AT_EXPAND(AT_ALL_TYPES):
AT_ALL_TYPES=AT_INTEGRAL_TYPES+AT_FLOATING_TYPES- To add uint: add
AT_EXPAND(AT_BAREBONES_UNSIGNED_TYPES)to the list
If the dispatch separately lists INTEGRAL and 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)
Step 6: Verify all dispatch sites
Check the file for ALL dispatch macros that need uint support:
- Some operators have multiple dispatch sites (CPU, CUDA, different functions)
- Apply the transformation consistently across all sites
- Ensure each gets the same type coverage updates
Step 7: Validate the changes
Check that:
- AT_DISPATCH_V2 format is used (not old AT_DISPATCH)
- Unsigned types are added via one of the two methods
- All relevant dispatch sites in the file are updated
- Type groups use
AT_EXPAND() - Arguments are properly formatted and comma-separated
Common patterns
Pattern 1: AT_ALL_TYPES + extras
// 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);
Pattern 2: Separate 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));
Pattern 3: Old dispatch needs conversion first
// 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);
Multiple dispatch sites example
For a file with multiple functions:
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
}
Decision tree
Use this decision tree to determine the approach:
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
Edge cases
Case 1: Dispatch with only floating types
If the operator only supports floating point types, don't add uint support:
// Leave as-is - floating point only operator
AT_DISPATCH_V2(dtype, "float_op", AT_WRAP([&]() {
kernel<scalar_t>();
}), AT_EXPAND(AT_FLOATING_TYPES), kHalf);
Case 2: Complex types present
Unsigned types work alongside complex types:
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);
Case 3: Already has uint support
Check if uint types are already present:
- If
AT_INTEGRAL_TYPES_V2is used → already has uint support - If
AT_BAREBONES_UNSIGNED_TYPESis already in list → already has uint support - Skip the file if uint support is already present
Workflow
When asked to add uint support:
- Read the target file
- Check if using AT_DISPATCH_V2:
- If not → use at-dispatch-v2 skill first
- Identify all dispatch macro sites
- For each dispatch:
- Analyze current type groups
- Choose method (add BAREBONES_UNSIGNED or upgrade to V2)
- Apply transformation with Edit tool
- Show the user the changes
- Explain what was modified
Important notes
- Always check if v2 conversion is needed first
- Apply changes consistently across all dispatch sites in the file
- Method 2 (AT_INTEGRAL_TYPES_V2) is cleaner when applicable
- Method 1 (explicit AT_BAREBONES_UNSIGNED_TYPES) is more explicit
- Unsigned types are: kUInt16, kUInt32, kUInt64 (not kByte which is uint8)
- Some operators may not semantically support unsigned types - use judgment
Testing
After adding uint support, the operator should accept uint16, uint32, and uint64 tensors. The user is responsible for functional testing.
Frequently asked questions about Add Unsigned Integer Support
Similar skills
Python PyPI Package Builder
Streamline the process of creating and publishing Python packages.
Minecraft Plugin Development
Streamline your Minecraft server plugin creation.
MCP Server Builder
Easily build .NET MCP servers with the latest standards.
CommunityToolkit.Mvvm Messenger
Decoupled communication for ViewModels in .NET applications.
MVVM Toolkit DI
Streamline ViewModel integration with Dependency Injection in .NET.
MCP Apps Builder
Essential guidelines for MCP server development.
