From 38deb2850fb0e7f204ebf079148327fc9bc4e29a Mon Sep 17 00:00:00 2001
From: Andreas Kloeckner <inform@tiker.net>
Date: Mon, 15 Apr 2024 13:42:49 -0500
Subject: [PATCH] Work around numpy2's changed repr for scalars

Closes gh-835
---
 loopy/target/c/codegen/expression.py | 22 +++++++++++++++++-----
 test/test_fortran.py                 |  4 +++-
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/loopy/target/c/codegen/expression.py b/loopy/target/c/codegen/expression.py
index f0c1fabd5..a29325fa9 100644
--- a/loopy/target/c/codegen/expression.py
+++ b/loopy/target/c/codegen/expression.py
@@ -448,10 +448,10 @@ class ExpressionToCExpressionMapper(IdentityMapper):
 
             # FIXME: This assumes a 32-bit architecture.
             if isinstance(expr, np.float32):
-                return Literal(repr(expr)+"f")
+                return Literal(repr(float(expr))+"f")
 
             elif isinstance(expr, np.float64):
-                return Literal(repr(expr))
+                return Literal(repr(float(expr)))
 
             # Disabled for now, possibly should be a subtarget.
             # elif isinstance(expr, np.float128):
@@ -464,7 +464,7 @@ class ExpressionToCExpressionMapper(IdentityMapper):
                     suffix += "u"
                 if iinfo.max > (2**31-1):
                     suffix += "l"
-                return Literal(repr(expr)+suffix)
+                return Literal(repr(int(expr))+suffix)
             elif isinstance(expr, np.bool_):
                 return Literal("true") if expr else Literal("false")
             else:
@@ -473,7 +473,7 @@ class ExpressionToCExpressionMapper(IdentityMapper):
 
         elif np.isfinite(expr):
             if type_context == "f":
-                return Literal(repr(np.float32(expr))+"f")
+                return Literal(repr(float((expr)))+"f")
             elif type_context == "d":
                 return Literal(repr(float(expr)))
             elif type_context in ["i", "b"]:
@@ -633,7 +633,19 @@ class CExpressionToCodeMapper(RecursiveMapper):
     # }}}
 
     def map_constant(self, expr, prec):
-        return repr(expr)
+        if isinstance(expr, np.generic):
+            if isinstance(expr, np.integer):
+                # FIXME: Add type suffixes?
+                return repr(int(expr))
+            elif isinstance(expr, np.float32):
+                return f"{repr(float(expr))}f"
+            elif isinstance(expr, np.float64):
+                return repr(float(expr))
+            else:
+                raise NotImplementedError(
+                        f"unimplemented numpy-to-C conversion: {type(expr)}")
+        else:
+            return repr(expr)
 
     def map_call(self, expr, enclosing_prec):
         from pymbolic.primitives import Variable
diff --git a/test/test_fortran.py b/test/test_fortran.py
index 45e83b384..55f1dab10 100644
--- a/test/test_fortran.py
+++ b/test/test_fortran.py
@@ -130,7 +130,9 @@ def test_assign_single_precision_scalar(ctx_factory):
         """
 
     t_unit = lp.parse_fortran(fortran_src)
-    assert "1.1f" in lp.generate_code_v2(t_unit).device_code()
+
+    import re
+    assert re.search("1.1000000[0-9]*f", lp.generate_code_v2(t_unit).device_code())
 
     a_dev = cl.array.empty(queue, 1, dtype=np.float64, order="F")
     t_unit(queue, a=a_dev)
-- 
GitLab