nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: GridTools/gt4py
Pull request #1723 (2024-11-04 15:28:27)

bug[next]: extract scalar value with correct dtype
credits to @egparedes for this pattern and realizing that `item()` decays to a python type.


Patch:
diff --git a/src/gt4py/next/embedded/nd_array_field.py b/src/gt4py/next/embedded/nd_array_field.py
index 655a1137..9ff5feaa 100644
--- a/src/gt4py/next/embedded/nd_array_field.py
+++ b/src/gt4py/next/embedded/nd_array_field.py
@@ -148,7 +148,8 @@ class NdArrayField(
             raise ValueError(
                 f"'as_scalar' is only valid on 0-dimensional 'Field's, got a {self.domain.ndim}-dimensional 'Field'."
             )
-        return self.ndarray.item()
+        # note: `.item()` will return a Python type, therefore we use indexing with an empty tuple
+        return self.asnumpy()[()]  # type: ignore[return-value] # should be ensured by the 0-d check
 
     @property
     def codomain(self) -> type[core_defs.ScalarT]:
diff --git a/src/gt4py/next/program_processors/runners/dace_common/dace_backend.py b/src/gt4py/next/program_processors/runners/dace_common/dace_backend.py
index bbf45a82..db0df7d1 100644
--- a/src/gt4py/next/program_processors/runners/dace_common/dace_backend.py
+++ b/src/gt4py/next/program_processors/runners/dace_common/dace_backend.py
@@ -28,11 +28,7 @@ def _convert_arg(arg: Any, sdfg_param: str, use_field_canonical_representation:
         return arg
     if len(arg.domain.dims) == 0:
         # Pass zero-dimensional fields as scalars.
-        # We need to extract the scalar value from the 0d numpy array without changing its type.
-        # Note that 'ndarray.item()' always transforms the numpy scalar to a python scalar,
-        # which may change its precision. To avoid this, we use here the empty tuple as index
-        # for 'ndarray.__getitem__()'.
-        return arg.asnumpy()[()]
+        return arg.as_scalar()
     # field domain offsets are not supported
     non_zero_offsets = [
         (dim, dim_range)


Test patch:
diff --git a/tests/next_tests/unit_tests/embedded_tests/test_nd_array_field.py b/tests/next_tests/unit_tests/embedded_tests/test_nd_array_field.py
index 9fba633c..063e79d9 100644
--- a/tests/next_tests/unit_tests/embedded_tests/test_nd_array_field.py
+++ b/tests/next_tests/unit_tests/embedded_tests/test_nd_array_field.py
@@ -264,6 +264,16 @@ def test_binary_operations_with_intersection(binary_arithmetic_op, dims, expecte
     assert np.allclose(op_result.ndarray, expected_result)
 
 
+def test_as_scalar(nd_array_implementation):
+    testee = common._field(
+        nd_array_implementation.asarray(42.0, dtype=np.float32), domain=common.Domain()
+    )
+
+    result = testee.as_scalar()
+    assert result == 42.0
+    assert isinstance(result, np.float32)
+
+
 def product_nd_array_implementation_params():
     for xp1 in nd_array_field._nd_array_implementations:
         for xp2 in nd_array_field._nd_array_implementations:
Repository: GridTools/gt4py
Pull request #1794 (2025-01-10 01:27:15)

feat[next]: Only inline scalars outside of stencils
The `InlineScalar` pass previously inlined all scalar expressions which is not needed and unnecessarily increases the tree size. Instead we only inline them in field view now.


Patch:
diff --git a/src/gt4py/next/iterator/transforms/inline_scalar.py b/src/gt4py/next/iterator/transforms/inline_scalar.py
index 87b576d1..d8a6e14d 100644
--- a/src/gt4py/next/iterator/transforms/inline_scalar.py
+++ b/src/gt4py/next/iterator/transforms/inline_scalar.py
@@ -21,6 +21,12 @@ class InlineScalar(eve.NodeTranslator):
         program = itir_inference.infer(program, offset_provider_type=offset_provider_type)
         return cls().visit(program)
 
+    def generic_visit(self, node, **kwargs):
+        if cpm.is_call_to(node, "as_fieldop"):
+            return node
+
+        return super().generic_visit(node, **kwargs)
+
     def visit_Expr(self, node: itir.Expr):
         node = self.generic_visit(node)
 


Test patch:
diff --git a/tests/next_tests/unit_tests/iterator_tests/transforms_tests/test_inline_scalar.py b/tests/next_tests/unit_tests/iterator_tests/transforms_tests/test_inline_scalar.py
new file mode 100644
index 00000000..3e655b71
--- /dev/null
+++ b/tests/next_tests/unit_tests/iterator_tests/transforms_tests/test_inline_scalar.py
@@ -0,0 +1,47 @@
+# GT4Py - GridTools Framework
+#
+# Copyright (c) 2014-2024, ETH Zurich
+# All rights reserved.
+#
+# Please, refer to the LICENSE file in the root directory.
+# SPDX-License-Identifier: BSD-3-Clause
+import pytest
+
+from gt4py.next import common
+from gt4py.next.iterator import ir as itir
+from gt4py.next.type_system import type_specifications as ts
+from gt4py.next.iterator.transforms import inline_scalar
+from gt4py.next.iterator.ir_utils import ir_makers as im
+
+TDim = common.Dimension(value="TDim")
+int_type = ts.ScalarType(kind=ts.ScalarKind.INT32)
+
+
+def program_factory(expr: itir.Expr) -> itir.Program:
+    return itir.Program(
+        id="testee",
+        function_definitions=[],
+        params=[im.sym("out", ts.FieldType(dims=[TDim], dtype=int_type))],
+        declarations=[],
+        body=[
+            itir.SetAt(
+                expr=expr,
+                target=im.ref("out"),
+                domain=im.domain(common.GridType.CARTESIAN, {TDim: (0, 1)}),
+            )
+        ],
+    )
+
+
+def test_simple():
+    testee = program_factory(im.let("a", 1)(im.op_as_fieldop("plus")("a", "a")))
+    expected = program_factory(im.op_as_fieldop("plus")(1, 1))
+    actual = inline_scalar.InlineScalar.apply(testee, offset_provider_type={})
+    assert actual == expected
+
+
+def test_fo_inline_only():
+    scalar_expr = im.let("a", 1)(im.plus("a", "a"))
+    testee = program_factory(im.as_fieldop(im.lambda_()(scalar_expr))())
+    actual = inline_scalar.InlineScalar.apply(testee, offset_provider_type={})
+    assert actual == testee
Repository: GridTools/gt4py
Pull request #1845 (2025-02-03 08:38:53)

fix[next]: reshuffling for fields with non-zero domain start


Patch:
diff --git a/src/gt4py/next/embedded/nd_array_field.py b/src/gt4py/next/embedded/nd_array_field.py
index e15fb426..53748250 100644
--- a/src/gt4py/next/embedded/nd_array_field.py
+++ b/src/gt4py/next/embedded/nd_array_field.py
@@ -657,7 +657,10 @@ def _reshuffling_premap(
             conn_map[dim] = _identity_connectivity(new_domain, dim, cls=type(connectivity))
 
     # Take data
-    take_indices = tuple(conn_map[dim].ndarray for dim in data.domain.dims)
+    take_indices = tuple(
+        conn_map[dim].ndarray - data.domain[dim].unit_range.start  # shift to 0-based indexing
+        for dim in data.domain.dims
+    )
     new_buffer = data._ndarray.__getitem__(take_indices)
 
     return data.__class__.from_array(


Test patch:
diff --git a/tests/next_tests/unit_tests/embedded_tests/test_nd_array_field.py b/tests/next_tests/unit_tests/embedded_tests/test_nd_array_field.py
index 9dde5bb4..9bdc6ab5 100644
--- a/tests/next_tests/unit_tests/embedded_tests/test_nd_array_field.py
+++ b/tests/next_tests/unit_tests/embedded_tests/test_nd_array_field.py
@@ -364,10 +364,11 @@ def test_reshuffling_premap():
 
     ij_field = common._field(
         np.asarray([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]]),
-        domain=common.Domain(dims=(I, J), ranges=(UnitRange(0, 3), UnitRange(0, 3))),
+        domain=common.Domain(dims=(I, J), ranges=(UnitRange(1, 4), UnitRange(2, 5))),
     )
+
     max_ij_conn = common._connectivity(
-        np.fromfunction(lambda i, j: np.maximum(i, j), (3, 3), dtype=int),
+        np.asarray([[1, 2, 3], [2, 2, 3], [3, 3, 3]], dtype=int),
         domain=common.Domain(
             dims=ij_field.domain.dims,
             ranges=ij_field.domain.ranges,
@@ -378,7 +379,7 @@ def test_reshuffling_premap():
     result = ij_field.premap(max_ij_conn)
     expected = common._field(
         np.asarray([[0.0, 4.0, 8.0], [3.0, 4.0, 8.0], [6.0, 7.0, 8.0]]),
-        domain=common.Domain(dims=(I, J), ranges=(UnitRange(0, 3), UnitRange(0, 3))),
+        domain=common.Domain(dims=(I, J), ranges=(UnitRange(1, 4), UnitRange(2, 5))),
     )
 
     assert result.domain == expected.domain