Skip to content

feat[next]: Embedded domain construction from dimension comparison#2532

Merged
havogt merged 9 commits intoGridTools:mainfrom
havogt:add_dim_operations_for_embedded
Mar 20, 2026
Merged

feat[next]: Embedded domain construction from dimension comparison#2532
havogt merged 9 commits intoGridTools:mainfrom
havogt:add_dim_operations_for_embedded

Conversation

@havogt
Copy link
Contributor

@havogt havogt commented Mar 13, 2026

Adds dimension comparison creating domains and basic domain union opertations as a first step towards concat_where(I == 0, ..., ...).

Limitations are described in the ADR.

@havogt havogt requested a review from egparedes March 13, 2026 12:21
Copy link
Contributor

@egparedes egparedes left a comment

Choose a reason for hiding this comment

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

Just a couple of questions.

@overload
def __eq__(self, value: core_defs.IntegralScalar) -> Domain: ... # type: ignore[overload-overlap] # intentionally returns Domain, not bool
@overload
def __eq__(self, value: object) -> bool: ...
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure if this works, but IIUC, this is the implemented behavior. If this works, a similar change could be applied to __ne__

Suggested change
def __eq__(self, value: object) -> bool: ...
def __eq__(self, value: object) -> Literal[False]: ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

mypy doesn't like it: Overloaded function signatures 1 and 3 overlap with incompatible return types

@havogt havogt requested a review from egparedes March 19, 2026 10:03
Copy link
Contributor

@egparedes egparedes left a comment

Choose a reason for hiding this comment

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

LGTM. I'm approving the PR but have a couple of comments.

Comment on lines +123 to +129
@overload
def __eq__(self, value: Dimension) -> bool: ...
@overload
def __eq__(self, value: core_defs.IntegralScalar) -> Domain: ... # type: ignore[overload-overlap] # intentionally returns Domain, not bool
@overload
def __eq__(self, value: object) -> bool: ...
def __eq__(self, value: object) -> bool | Domain:
Copy link
Contributor

Choose a reason for hiding this comment

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

Wait a second, do we really need to add the overload for object? It doesn't make sense because it overlaps with everything. I think the correct type hint is:

Suggested change
@overload
def __eq__(self, value: Dimension) -> bool: ...
@overload
def __eq__(self, value: core_defs.IntegralScalar) -> Domain: ... # type: ignore[overload-overlap] # intentionally returns Domain, not bool
@overload
def __eq__(self, value: object) -> bool: ...
def __eq__(self, value: object) -> bool | Domain:
@overload
def __eq__(self, value: Dimension) -> bool: ...
@overload
def __eq__(self, value: core_defs.IntegralScalar) -> Domain: ... # type: ignore[overload-overlap] # intentionally returns Domain, not bool
def __eq__(self, value: Dimension | core_defs.IntegralScalar) -> bool | Domain:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we want/need to support Dimension(...) == some_other_object comparison?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we go with your proposal, I should remove the else branch, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

But does it makes sense to support Dimension == Any? Shouldn't that just raise a TypeError? Something like:

Suggested change
@overload
def __eq__(self, value: Dimension) -> bool: ...
@overload
def __eq__(self, value: core_defs.IntegralScalar) -> Domain: ... # type: ignore[overload-overlap] # intentionally returns Domain, not bool
@overload
def __eq__(self, value: object) -> bool: ...
def __eq__(self, value: object) -> bool | Domain:
if isinstance(value, Dimension):
return self.value == value.value
if isinstance(value, core_defs.INTEGRAL_TYPES):
int_value = cast(core_defs.IntegralScalar, value)
return Domain(dims=(self,), ranges=(UnitRange(int_value, int_value + 1),))
raise TypeError(....)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we have cases, but I can try...

Comment on lines +138 to +142
@overload
def __ne__(self, value: Dimension) -> bool: ...
@overload
def __ne__(self, value: object) -> bool: ...
def __ne__(self, value: object) -> bool:
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment as above

- `Dimension.__ne__(value)` raises `NotImplementedError` when called with an integer value, since it would produce two disjoint domains.
- `Domain.__or__` raises `NotImplementedError` for both multidimensional domains and for 1D domains that are disjoint (non-overlapping and non-adjacent).

The domain expression API only supports operations that result in a single contiguous `Domain`.
Copy link
Contributor

Choose a reason for hiding this comment

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

This is the only place in the ADR where contiguous is used. Everywhere else non-contiguous is used, is that on purpose?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah forgot to push the file, because my directory wasn't clean and my brain filtered .md files when adding stuff to commit...

Copy link
Contributor

@egparedes egparedes left a comment

Choose a reason for hiding this comment

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

LGTM

@havogt havogt merged commit 6f5a9e5 into GridTools:main Mar 20, 2026
24 checks passed
@havogt havogt deleted the add_dim_operations_for_embedded branch March 20, 2026 20:07
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