Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Add unsigned integer (uint) type support to PyTorch operators by updating AT_DISPATCH macros. Use when adding support for uint16, uint32, uint64 types to operators, kernels, or when user mentions enabling unsigned types, barebones unsigned types, or uint support.
.claude/skills/microck-add-uint-support/SKILL.md| Model | Eval pass | Runs |
|---|---|---|
| gemini-3.6-flash | 100% | 13 |
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 84% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 53% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -11% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 23% | 0% |
| case-09 | ✗→✓ | ▲ Improved | -6% | 0% |
This skill helps add support for unsigned integer types (uint16, uint32, uint64) to PyTorch operators by updating their AT_DISPATCH macros.
Use this skill when:
Add unsigned types to existing dispatch:
cpp// 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));
Unsigned type groups:
AT_BAREBONES_UNSIGNED_TYPES: kUInt16, kUInt32, kUInt64AT_INTEGRAL_TYPES_V2: AT_INTEGRAL_TYPES + AT_BAREBONES_UNSIGNED_TYPESRelationship:
cppAT_INTEGRAL_TYPES // kByte, kChar, kInt, kLong, kShort AT_BAREBONES_UNSIGNED_TYPES // kUInt16, kUInt32, kUInt64 AT_INTEGRAL_TYPES_V2 // INTEGRAL_TYPES + BAREBONES_UNSIGNED_TYPES
Check if the file uses AT_DISPATCH_V2:
If using old AT_DISPATCH:
If already using AT_DISPATCH_V2:
Identify what type groups are currently in use:
cppAT_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 typesTwo approaches:
Method 1: Add AT_BAREBONES_UNSIGNED_TYPES explicitly
AT_EXPAND(AT_BAREBONES_UNSIGNED_TYPES) to the type listMethod 2: Substitute AT_INTEGRAL_TYPES with AT_INTEGRAL_TYPES_V2
AT_EXPAND(AT_INTEGRAL_TYPES)Method 1 example:
cpp// 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:
cpp// 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) );
If the dispatch uses AT_EXPAND(AT_ALL_TYPES):
AT_ALL_TYPES = AT_INTEGRAL_TYPES + AT_FLOATING_TYPESAT_EXPAND(AT_BAREBONES_UNSIGNED_TYPES) to the listIf the dispatch separately lists INTEGRAL and FLOATING:
cpp// 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)
Check the file for ALL dispatch macros that need uint support:
Check that:
AT_EXPAND()cpp// 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);
cpp// 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));
cpp// 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);
For a file with multiple functions:
cppvoid 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 }
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 listIf the operator only supports floating point types, don't add uint support:
cpp// Leave as-is - floating point only operator AT_DISPATCH_V2(dtype, "float_op", AT_WRAP([&]() { kernel<scalar_t>(); }), AT_EXPAND(AT_FLOATING_TYPES), kHalf);
Unsigned types work alongside complex types:
cppAT_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);
Check if uint types are already present:
AT_INTEGRAL_TYPES_V2 is used → already has uint supportAT_BAREBONES_UNSIGNED_TYPES is already in list → already has uint supportWhen asked to add uint support:
After adding uint support, the operator should accept uint16, uint32, and uint64 tensors. The user is responsible for functional testing.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 14,564 | 14,806 | +2% | 1 | 1 | 0% | 3,144 | 5,799 | +84% | 0 | 0 | — |
case-06 | pass→fail | 18,683 | 4,520 | -76% | 1 | 1 | 0% | 3,817 | 3,209 | -16% | 0 | 0 | — |
case-02 | fail→pass | 14,519 | 7,762 | -47% | 1 | 1 | 0% | 3,131 | 4,802 | +53% | 0 | 0 | — |
case-03 | fail→pass | 30,504 | 16,375 | -46% | 1 | 1 | 0% | 6,224 | 5,539 | -11% | 0 | 0 | — |
case-04 | pass→pass | 13,647 | 12,567 | -8% | 1 | 1 | 0% | 2,721 | 5,399 | +98% | 0 | 0 | — |
case-05 | pass→pass | 10,547 | 6,707 | -36% | 1 | 1 | 0% | 2,385 | 4,370 | +83% | 0 | 0 | — |
case-07 | fail→pass | 13,824 | 3,955 | -71% | 1 | 1 | 0% | 3,097 | 3,795 | +23% | 0 | 0 | — |
case-08 | pass→pass | 7,820 | 3,880 | -50% | 1 | 1 | 0% | 1,583 | 3,753 | +137% | 0 | 0 | — |
case-09 | fail→pass | 17,870 | 4,073 | -77% | 1 | 1 | 0% | 4,051 | 3,827 | -6% | 0 | 0 | — |
case-10 | fail→pass | 27,116 | 18,166 | -33% | 1 | 1 | 0% | 6,213 | 7,195 | +16% | 0 | 0 | — |
case-11 | fail→pass | 28,244 | 4,323 | -85% | 1 | 1 | 0% | 6,218 | 3,865 | -38% | 0 | 0 | — |
case-12 | fail→fail | 15,241 | 3,073 | -80% | 1 | 1 | 0% | 3,220 | 3,312 | +3% | 0 | 0 | — |
case-13 | fail→fail | 29,036 | 15,812 | -46% | 1 | 1 | 0% | 6,203 | 5,868 | -5% | 0 | 0 | — |
case-14 | fail→pass | 18,600 | 8,230 | -56% | 1 | 1 | 0% | 4,107 | 4,097 | -0% | 0 | 0 | — |
case-15 | fail→pass | 25,637 | 5,546 | -78% | 1 | 1 | 0% | 5,901 | 4,252 | -28% | 0 | 0 | — |
case-16 | fail→pass | 15,320 | 6,466 | -58% | 1 | 1 | 0% | 3,520 | 4,433 | +26% | 0 | 0 | — |
case-17 | fail→pass | 10,491 | 5,052 | -52% | 1 | 1 | 0% | 2,285 | 4,012 | +76% | 0 | 0 | — |
case-18 | fail→pass | 20,543 | 10,927 | -47% | 1 | 1 | 0% | 4,479 | 4,643 | +4% | 0 | 0 | — |
case-19 | fail→pass | 14,213 | 4,896 | -66% | 1 | 1 | 0% | 3,065 | 3,967 | +29% | 0 | 0 | — |
case-20 | pass→pass | 8,493 | 2,916 | -66% | 1 | 1 | 0% | 1,873 | 3,556 | +90% | 0 | 0 | — |
case-21 | fail→fail | 21,623 | 3,251 | -85% | 1 | 1 | 0% | 4,604 | 3,368 | -27% | 0 | 0 | — |
case-22 | fail→fail | 8,177 | 3,253 | -60% | 1 | 1 | 0% | 1,838 | 3,467 | +89% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +55 percentage points is the difference between those two pass rates over the 21 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.