2323clip = np .clip
2424
2525
26+ def _jit_backend_available ():
27+ """Whether the miniexpr runtime JIT backend is bundled in this build.
28+
29+ The JIT compiler is not shipped on every platform (e.g. the Windows wheels lack
30+ it); there a DSL kernel still compiles and runs, but via the interpreter rather
31+ than a JIT kernel. Probe a trivial kernel once so the JIT-specific assertions can
32+ be gated on the platform actually having a JIT backend."""
33+ try :
34+
35+ @blosc2 .dsl_kernel
36+ def _probe (a ):
37+ return a + 1.0
38+
39+ return bool (blosc2 .validate_dsl_jit (_probe , [np .float64 ], np .float64 ).get ("jit" ))
40+ except Exception :
41+ return False
42+
43+
44+ JIT_AVAILABLE = _jit_backend_available ()
45+
46+
47+ def _expect_jit (status ):
48+ """Assert *status* compiled, and that it produced a runtime JIT kernel where the
49+ platform actually has a JIT backend (see :func:`_jit_backend_available`)."""
50+ assert status ["compiled" ]
51+ if JIT_AVAILABLE :
52+ assert status ["jit" ]
53+
54+
2655@pytest .fixture (autouse = True )
2756def _no_auto_js_backend (monkeypatch ):
2857 """Keep this module on the miniexpr/DSL path. Under WebAssembly the default prefers the
@@ -330,9 +359,9 @@ def wrapped_set_pref_expr(self, expression, inputs, fp_accuracy, aux_reduc=None,
330359 assert "_n1" in captured ["expr" ]
331360 assert "_i1" in captured ["expr" ]
332361 # ...and it JIT-compiles rather than silently running on the interpreter.
333- assert blosc2 . validate_dsl_jit ( kernel_index_ramp_float_cast , { "x" : np . float32 }, np . float32 , shape = shape )[
334- "jit"
335- ]
362+ _expect_jit (
363+ blosc2 . validate_dsl_jit ( kernel_index_ramp_float_cast , { "x" : np . float32 }, np . float32 , shape = shape )
364+ )
336365
337366
338367def test_dsl_kernel_index_symbols_int_cast_matches_expected_ramp ():
@@ -463,9 +492,11 @@ def wrapped_set_pref_expr(self, expression, inputs, fp_accuracy, aux_reduc=None,
463492 assert "range(niter)" not in captured ["expr" ]
464493 assert "float(niter)" not in captured ["expr" ]
465494 # ...and the loop+scalar kernel JIT-compiles (the original G3 fallback shape).
466- assert blosc2 .validate_dsl_jit (
467- kernel_loop_param , {"x" : a2 .dtype , "y" : b2 .dtype , "niter" : niter }, a2 .dtype , shape = (32 , 32 )
468- )["jit" ]
495+ _expect_jit (
496+ blosc2 .validate_dsl_jit (
497+ kernel_loop_param , {"x" : a2 .dtype , "y" : b2 .dtype , "niter" : niter }, a2 .dtype , shape = (32 , 32 )
498+ )
499+ )
469500 finally :
470501 lazyexpr_mod .try_miniexpr = old_try_miniexpr
471502
@@ -1097,8 +1128,7 @@ def simple(a, b):
10971128
10981129 st = blosc2 .validate_dsl_jit (simple , [np .float64 , np .float64 ], np .float64 )
10991130 assert st ["valid" ]
1100- assert st ["compiled" ]
1101- assert st ["jit" ]
1131+ _expect_jit (st )
11021132 assert st ["status" ] == "ME_COMPILE_SUCCESS"
11031133
11041134 # A scalar param is inlined (passed as a value); a variable named 'out' (the
@@ -1108,7 +1138,7 @@ def simple(a, b):
11081138 "def withk(a, b, niter):\n out = a + b * float(niter)\n return out\n " , "withk"
11091139 )
11101140 st = blosc2 .validate_dsl_jit (with_out , {"a" : np .float64 , "b" : np .float64 , "niter" : 3 }, np .float64 )
1111- assert st [ "jit" ]
1141+ _expect_jit ( st )
11121142
11131143 # Invalid syntax -> not valid, nothing compiled.
11141144 invalid = kernel_from_source ("def k(a, b):\n a = a - b\n return a\n " , "k" )
0 commit comments