Skip to content

compiler: Keep the outer Dimension parallel on a short par-tile - #3021

Open
mloubout wants to merge 1 commit into
mainfrom
blocking-keep-outer-dim-parallel
Open

compiler: Keep the outer Dimension parallel on a short par-tile#3021
mloubout wants to merge 1 commit into
mainfrom
blocking-keep-outer-dim-parallel

Conversation

@mloubout

@mloubout mloubout commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

When a multi par-tile entry is shorter than the blocked nest, the innermost Dimensions consume the available block sizes and the outermost one runs into a StopIteration. It was then dropped into compact, which promotes it back to its root Dimension, discarding its BlockDimension.

Tested in pro

@codecov

codecov Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.77%. Comparing base (33c3b12) to head (18681a8).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3021   +/-   ##
=======================================
  Coverage   83.77%   83.77%           
=======================================
  Files         257      257           
  Lines       55007    55028   +21     
  Branches     4708     4710    +2     
=======================================
+ Hits        46083    46102   +19     
- Misses       8109     8111    +2     
  Partials      815      815           
Flag Coverage Δ
pytest-gpu-aomp-amdgpuX 68.58% <20.00%> (-0.01%) ⬇️
pytest-gpu-gcc- 78.40% <33.33%> (-0.01%) ⬇️
pytest-gpu-icx- 78.32% <33.33%> (-0.02%) ⬇️
pytest-gpu-nvc-nvidiaX 69.11% <95.83%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ 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.

@mloubout
mloubout force-pushed the blocking-keep-outer-dim-parallel branch from b77ed90 to 173ac59 Compare September 9, 2026 01:03

@FabioLuporini FabioLuporini left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this change is pretty deep and regardless of the tweaks we're going to make it wants some tests across OSS and PRO (tests that are not simply tuner tests)

Comment thread devito/passes/clusters/blocking.py Outdated
Comment thread devito/passes/clusters/blocking.py Outdated
Comment thread devito/passes/clusters/blocking.py Outdated
Comment thread devito/passes/clusters/blocking.py Outdated
@mloubout
mloubout force-pushed the blocking-keep-outer-dim-parallel branch 2 times, most recently from 0c1f941 to 8962a2a Compare September 9, 2026 12:06

@FabioLuporini FabioLuporini left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

much better now than the previous iteration, but still a couple of questions

Comment thread devito/core/operator.py Outdated
def __new__(cls, items, default=None, sparse=None, reduce=None):
# A short entry is padded to the nest it lands on rather than losing its
# outermost BlockDimensions. Only meaningful on a device
stretch = False

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this shouldn't be a class attribute

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It also gets set in separately in the __new__...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

that's why it shouldn't be a class attribute

Comment thread devito/passes/clusters/blocking.py Outdated
"""
Pad `umt` with its innermost size until it covers `dims`.

A user-supplied par-tile entry may be shorter than the nest it lands on.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

essentially this (x loop on the host) would occur for unoptimized kernels, or kernels that are not in normal form (2+1 loops) -- do I get it right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

however, and regardless, UnboundTuple should keep returning the last entry upon repeated next() calls, see here:

https://github.com/devitocodes/devito/blob/main/devito/tools/data_structures.py#L778

so I'm not sure I understand why any of this would be necessary

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

essentially this (x loop on the host) would occur for unoptimized kernels, or kernels that are not in normal form (2+1 loops) -- do I get it right?

yes

@mloubout
mloubout force-pushed the blocking-keep-outer-dim-parallel branch from 8962a2a to 94b8008 Compare September 9, 2026 13:19
Comment thread devito/core/operator.py Outdated
def __new__(cls, items, default=None, sparse=None, reduce=None):
# A short entry is padded to the nest it lands on rather than losing its
# outermost BlockDimensions. Only meaningful on a device
stretch = False

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It also gets set in separately in the __new__...

Comment thread devito/core/gpu.py Outdated
sparse=oo.pop('par-tile-sparse', None),
reduce=oo.pop('par-tile-reduce', None))
reduce=oo.pop('par-tile-reduce', None),
stretch=True)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A more descriptive name (par-tile-stretch or par-tile-extend) might be good?

Comment thread devito/core/operator.py
return obj
elif isinstance(items, bool):
if not default:
raise ValueError("Expected `default` value, got None")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

f"Expected default value, got {default}"?

Comment thread devito/core/operator.py Outdated
stretch=False):
if not items:
return UnboundedMultiTuple()
obj = UnboundedMultiTuple()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I know this is pre-existing, but maybe a brief comment explaining what this short-circuit is for wouldn't go amiss

Comment thread devito/passes/clusters/blocking.py Outdated

umt.iter()

if stretch:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Given stretch relies on self.stretch and self.umt, is it worth having this logic within self.stretched?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this comment is now obsolete

Comment thread devito/passes/clusters/blocking.py Outdated
if stretch:
# Walk this nest's own entry, which repeats its innermost size if
# it is shorter than the nest, rather than running out of sizes
return umt.curitem().reset()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why the reset() at the end ?

When a multi `par-tile` entry is shorter than the blocked nest, the
innermost Dimensions consume the available block sizes and the outermost
one runs into a StopIteration, raised by the top-level tuple once the
entry is exhausted. It was then dropped into `compact`, which promotes it
back to its root Dimension, discarding its BlockDimension.

On a device that is a serialization: the Dimension ends up outside the
blocked nest, `filter_iterations` rejects it as non-parallel, and the
kernel is launched over a 2D grid from a host loop iterating the outer
Dimension one slice at a time.

Walk this nest's own entry instead, which repeats its innermost size for
as long as the nest needs it, so the nest stays fully blocked. Whether to
do so is decided when the par-tile is built, where the target is already
known, rather than by inspecting a cluster back in the pass. It applies
to multi par-tiles on a device only: a single user-supplied par-tile
defines the block rank on purpose, and on a host a short entry is the
documented way to ask for 2.5D blocking.
@mloubout
mloubout force-pushed the blocking-keep-outer-dim-parallel branch from 94b8008 to 18681a8 Compare September 9, 2026 14:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants