Skip to content

Shrink-wrap block-level GPU register allocations - #9343

Open
abadams wants to merge 3 commits into
abadams/gpu_register_crosstalk_checkfrom
abadams/gpu_register_sgemm
Open

Shrink-wrap block-level GPU register allocations#9343
abadams wants to merge 3 commits into
abadams/gpu_register_crosstalk_checkfrom
abadams/gpu_register_sgemm

Conversation

@abadams

@abadams abadams commented Aug 14, 2026

Copy link
Copy Markdown
Member

#9325 checks that block-level register storage is safe, but it still duplicates that storage per-thread. This new pass, which runs later, decomposes that into a set of actual ptx registers for each thread to use by identifying which subtiles of the block-level allocation are actually used by each thread. Without this, each thread writes to a dynamic thread-id-dependent index into the allocation, resulting in it spilling to local instead of truly being a register. There doesn't seem to be a good way to merge this with the earlier PR's pass, unfortunately. That one checks legality, and then this one is an optimization that exploits the legality. The need to run at different times.

This is the missing ingredient required to hit >90% of cublas performance in the cuda mat mul app for float32 (i.e. cuda cores, not tensor cores). #9283 hits similar performance levels for narrower float mat muls.

@alexreinking alexreinking left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's see if we can get Claude to lean more on the lambda mutators

Comment on lines +22 to +47
class FindAccesses : public IRVisitor {
using IRVisitor::visit;

void visit(const Store *op) override {
if (op->name == alloc) {
indices.push_back(op->index);
}
IRVisitor::visit(op);
}

void visit(const Load *op) override {
if (op->name == alloc) {
indices.push_back(op->index);
}
IRVisitor::visit(op);
}

const string &alloc;

public:
vector<Expr> indices;

FindAccesses(const string &alloc)
: alloc(alloc) {
}
};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be a ~5 line visit_with

Comment on lines +105 to +110
public:
using IRMutator::mutate;

private:
using IRMutator::visit;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? Shouldn't these both be protected, anyway?

@codecov

codecov Bot commented Aug 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.89189% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.06%. Comparing base (74fa54b) to head (8861d3b).

Files with missing lines Patch % Lines
src/PromoteGPURegisters.cpp 92.95% 0 Missing and 5 partials ⚠️
src/Lower.cpp 66.66% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@                           Coverage Diff                            @@
##           abadams/gpu_register_crosstalk_check    #9343      +/-   ##
========================================================================
- Coverage                                 70.13%   70.06%   -0.08%     
========================================================================
  Files                                       260      261       +1     
  Lines                                     79264    79338      +74     
  Branches                                  19320    19337      +17     
========================================================================
- Hits                                      55594    55586       -8     
- Misses                                    17898    17920      +22     
- Partials                                   5772     5832      +60     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

abadams and others added 3 commits August 16, 2026 15:20
An allocation in MemoryType::Register outside the loops over GPU threads is
storage private to a thread, so what looks like one allocation of many elements
is really a handful of registers held by each thread. The cross-talk check
established that each thread keeps to its own part; this shrinks the allocation
to just that part.

Two accesses by one thread are to the same elements when the distance between
them is the same whatever thread it is, because the thread cancels when only
comparing accesses made by the same one. That is the question get_subtile
already answers for tile memory, so ask it: group the accesses into sets that
are each identical or disjoint, reject a partial overlap, and give each set
registers of its own. Nothing about how an access covers its elements matters,
because the registers a set gets are its own, so a dense ramp reaches them all.

A thread that indexes its own storage dynamically has no fixed register to use
and gets a user error saying so.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The accumulator now lives at block level in registers, which puts the loop over
the reduction above the loop over threads, so one staged panel of each input
serves every thread in the block. The panels are copied from global to shared
asynchronously, laid over the same grid of threads as the compute so that no
thread sits idle in either phase.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@abadams
abadams force-pushed the abadams/gpu_register_sgemm branch from 0ba4a36 to 8861d3b Compare August 16, 2026 22:21
Comment on lines +7 to +11
Target target = get_jit_target_from_environment();
if (!target.has_gpu_feature()) {
printf("[SKIP] No GPU target enabled.\n");
return 0;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same problem as #9325

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants