nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: GridTools/gt4py
Pull request #1508 (2024-03-20 23:31:50)

bug[eve]: Preserve annex None value in visitors


Patch:
diff --git a/src/gt4py/eve/visitors.py b/src/gt4py/eve/visitors.py
index 750505be..ea76aea1 100644
--- a/src/gt4py/eve/visitors.py
+++ b/src/gt4py/eve/visitors.py
@@ -168,7 +168,7 @@ class NodeTranslator(NodeVisitor):
                 # access to `new_node.annex` implicitly creates the `__node_annex__` attribute in the property getter
                 new_annex_dict = new_node.annex.__dict__
                 for key in self.PRESERVED_ANNEX_ATTRS:
-                    if value := getattr(old_annex, key, None):
+                    if (value := getattr(old_annex, key, NOTHING)) is not NOTHING:
                         assert key not in new_annex_dict
                         new_annex_dict[key] = value
 


Test patch:
diff --git a/tests/eve_tests/unit_tests/test_visitors.py b/tests/eve_tests/unit_tests/test_visitors.py
index 70b7e2e4..1b52243d 100644
--- a/tests/eve_tests/unit_tests/test_visitors.py
+++ b/tests/eve_tests/unit_tests/test_visitors.py
@@ -19,12 +19,14 @@ from gt4py import eve
 
 def test_annex_preservation(compound_node: eve.Node):
     compound_node.annex.foo = 1
-    compound_node.annex.bar = 2
+    compound_node.annex.bar = None  # None is easily forgotten so test seperately
+    compound_node.annex.baz = 2
 
     class SampleTranslator(eve.NodeTranslator):
-        PRESERVED_ANNEX_ATTRS = ("foo",)
+        PRESERVED_ANNEX_ATTRS = ("foo", "bar")
 
     translated_node = SampleTranslator().visit(compound_node)
 
     assert translated_node.annex.foo == 1
-    assert not hasattr(translated_node.annex, "bar")
+    assert translated_node.annex.bar is None
+    assert not hasattr(translated_node.annex, "baz")
Repository: GridTools/gt4py
Pull request #1510 (2024-03-21 00:12:12)

feature[next]: Improve ITIR constant folding
Improves constant folding in ITIR such that mimimum and maximum are eliminated in case the arguments are equal. This greatly simplifies the domain bounds expressions in ITIR that are computed by the temporary pass.


Patch:
diff --git a/src/gt4py/next/iterator/transforms/constant_folding.py b/src/gt4py/next/iterator/transforms/constant_folding.py
index 696a87a1..2d7248cf 100644
--- a/src/gt4py/next/iterator/transforms/constant_folding.py
+++ b/src/gt4py/next/iterator/transforms/constant_folding.py
@@ -26,6 +26,13 @@ class ConstantFolding(PreserveLocationVisitor, NodeTranslator):
         # visit depth-first such that nested constant expressions (e.g. `(1+2)+3`) are properly folded
         new_node = self.generic_visit(node)
 
+        if (
+            isinstance(new_node.fun, ir.SymRef)
+            and new_node.fun.id in ["minimum", "maximum"]
+            and new_node.args[0] == new_node.args[1]
+        ):  # `minimum(a, a)` -> `a`
+            return new_node.args[0]
+
         if (
             isinstance(new_node.fun, ir.SymRef)
             and new_node.fun.id == "if_"


Test patch:
diff --git a/tests/next_tests/unit_tests/iterator_tests/transforms_tests/test_constant_folding.py b/tests/next_tests/unit_tests/iterator_tests/transforms_tests/test_constant_folding.py
index 275412a5..00e95418 100644
--- a/tests/next_tests/unit_tests/iterator_tests/transforms_tests/test_constant_folding.py
+++ b/tests/next_tests/unit_tests/iterator_tests/transforms_tests/test_constant_folding.py
@@ -45,3 +45,10 @@ def test_constant_folding_if():
     )
     actual = ConstantFolding.apply(testee)
     assert actual == expected
+
+
+def test_constant_folding_minimum():
+    testee = im.call("minimum")("a", "a")
+    expected = im.ref("a")
+    actual = ConstantFolding.apply(testee)
+    assert actual == expected
Repository: GridTools/gt4py
Pull request #1523 (2024-04-05 13:51:43)

fix[next]: Fix Program.itir
## Description

Fix diverging behavior of `Program.itir` for embedded vs backend.

## Requirements

- [X] All fixes and/or new features come with corresponding tests.
- [X] Important design decisions have been documented in the approriate ADR inside the [docs/development/ADRs/](docs/development/ADRs/Index.md) folder.


Patch:
diff --git a/src/gt4py/next/ffront/decorator.py b/src/gt4py/next/ffront/decorator.py
index f55e8297..4f1eafeb 100644
--- a/src/gt4py/next/ffront/decorator.py
+++ b/src/gt4py/next/ffront/decorator.py
@@ -208,7 +208,7 @@ class Program:
             kwargs={},
         )
         if self.backend is not None and self.backend.transformer is not None:
-            return self.backend.transformer.past_to_itir(no_args_past)
+            return self.backend.transformer.past_to_itir(no_args_past).program
         return past_to_itir.PastToItirFactory()(no_args_past).program
 
     def __call__(self, *args, offset_provider: dict[str, Dimension], **kwargs: Any) -> None:


Test patch:
diff --git a/tests/next_tests/integration_tests/feature_tests/ffront_tests/test_decorator.py b/tests/next_tests/integration_tests/feature_tests/ffront_tests/test_decorator.py
new file mode 100644
index 00000000..a6d00ab7
--- /dev/null
+++ b/tests/next_tests/integration_tests/feature_tests/ffront_tests/test_decorator.py
@@ -0,0 +1,35 @@
+# GT4Py - GridTools Framework
+#
+# Copyright (c) 2014-2023, ETH Zurich
+# All rights reserved.
+#
+# This file is part of the GT4Py project and the GridTools framework.
+# GT4Py is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or any later
+# version. See the LICENSE.txt file at the top-level directory of this
+# distribution for a copy of the license or check <https://www.gnu.org/licenses/>.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+# TODO(dropd): Remove as soon as `gt4py.next.ffront.decorator` is type checked.
+from gt4py import next as gtx
+from gt4py.next.iterator import ir as itir
+
+from next_tests.integration_tests import cases
+from next_tests.integration_tests.cases import cartesian_case
+from next_tests.integration_tests.feature_tests.ffront_tests.ffront_test_utils import (
+    exec_alloc_descriptor,
+)
+
+
+def test_program_itir_regression(cartesian_case):
+    @gtx.field_operator(backend=None)
+    def testee_op(a: cases.IField) -> cases.IField:
+        return a
+
+    @gtx.program(backend=None)
+    def testee(a: cases.IField, out: cases.IField):
+        testee_op(a, out=out)
+
+    assert isinstance(testee.itir, itir.FencilDefinition)
+    assert isinstance(testee.with_backend(cartesian_case.executor).itir, itir.FencilDefinition)
Repository: GridTools/gt4py
Pull request #1566 (2024-07-01 13:52:24)

bug[next]: Fix missing visit call in call to cast builtin in ITIR type inference
Since `cast_` is a grammar builtin whose return type is given by its second argument it is easy to forget inferring the types of the first argument and its children. This surfaced in icon4py and is fixed here.


Patch:
diff --git a/src/gt4py/next/iterator/type_system/inference.py b/src/gt4py/next/iterator/type_system/inference.py
index 5010821d..c8f80daa 100644
--- a/src/gt4py/next/iterator/type_system/inference.py
+++ b/src/gt4py/next/iterator/type_system/inference.py
@@ -601,6 +601,7 @@ class ITIRTypeInference(eve.NodeTranslator):
         # grammar builtins
         if is_call_to(node, "cast_"):
             value, type_constructor = node.args
+            self.visit(value, ctx=ctx)  # ensure types in value are also inferred
             assert (
                 isinstance(type_constructor, itir.SymRef)
                 and type_constructor.id in itir.TYPEBUILTINS


Test patch:
diff --git a/tests/next_tests/unit_tests/iterator_tests/test_type_inference.py b/tests/next_tests/unit_tests/iterator_tests/test_type_inference.py
index 490bb685..6a57f777 100644
--- a/tests/next_tests/unit_tests/iterator_tests/test_type_inference.py
+++ b/tests/next_tests/unit_tests/iterator_tests/test_type_inference.py
@@ -222,6 +222,19 @@ def test_late_offset_axis():
     assert result.type == it_on_e_of_e_type
 
 
+def test_cast_first_arg_inference():
+    # since cast_ is a grammar builtin whose return type is given by its second argument it is
+    # easy to forget inferring the types of the first argument and its children. Simply check
+    # if the first argument has a type inferred correctly here.
+    testee = im.call("cast_")(
+        im.plus(im.literal_from_value(1), im.literal_from_value(2)), "float64"
+    )
+    result = itir_type_inference.infer(testee, offset_provider={}, allow_undeclared_symbols=True)
+
+    assert result.args[0].type == int_type
+    assert result.type == float64_type
+
+
 # TODO(tehrengruber): Rewrite tests to use itir.Program
 def test_cartesian_fencil_definition():
     cartesian_domain = im.call("cartesian_domain")(