A categorical programming language
Revisión | 4baf5e2d7637d274495705c7d28f69ce1ac5baeb (tree) |
---|---|
Tiempo | 2021-11-06 07:13:23 |
Autor | Corbin <cds@corb...> |
Commiter | Corbin |
cammy-run: Better NaN handling in f-add and f-mul.
@@ -10,14 +10,10 @@ util.find_library = patched_find_library | ||
10 | 10 | |
11 | 11 | import math, sys |
12 | 12 | |
13 | -from rpython.rlib.jit import JitDriver, set_param, unroll_safe | |
14 | -from rpython.rlib.parsing.main import make_parser_from_file | |
15 | -from rpython.rlib.parsing.tree import RPythonVisitor | |
13 | +from rpython.rlib.jit import JitDriver, set_param, unroll_safe, we_are_jitted | |
16 | 14 | from rpython.rlib.rbigint import rbigint |
17 | -from rpython.rlib.rfile import create_stdio | |
18 | 15 | from rpython.rlib.rfloat import string_to_float |
19 | 16 | from rpython.rlib.rstring import StringBuilder, split |
20 | -from rpython.rlib.unroll import unrolling_iterable | |
21 | 17 | |
22 | 18 | import stb |
23 | 19 |
@@ -69,7 +65,7 @@ class F(Element): | ||
69 | 65 | _immutable_ = True |
70 | 66 | |
71 | 67 | def __init__(self, f): |
72 | - if math.isnan(f): | |
68 | + if not we_are_jitted() and math.isnan(f): | |
73 | 69 | raise TypeFail("runtime NaN") |
74 | 70 | self._f = f |
75 | 71 |
@@ -259,21 +255,23 @@ class FLT(Arrow): | ||
259 | 255 | class FAdd(Arrow): |
260 | 256 | _immutable_ = True |
261 | 257 | def run(self, x): |
262 | - f = x.first().f() + x.second().f() | |
263 | - # The only case handled is Infinity - Infinity, for which we apply: | |
264 | - # x - x == 0.0 | |
265 | - return F(0.0 if math.isnan(f) else f) | |
258 | + rv = x.first().f() + x.second().f() | |
259 | + # The only time addition can NaN is Infinity - Infinity, which is 0.0. | |
260 | + if math.isnan(rv): | |
261 | + rv = 0.0 | |
262 | + return F(rv) | |
266 | 263 | |
267 | 264 | class FMul(Arrow): |
268 | 265 | _immutable_ = True |
269 | 266 | def run(self, x): |
270 | 267 | y = x.first().f() |
271 | 268 | z = x.second().f() |
272 | - # Check for division by zero. | |
273 | - if y in (0.0, -0.0) or z in (0.0, -0.0): | |
274 | - return F(0.0 * math.copysign(1.0, y) * math.copysign(1.0, z)) | |
275 | - else: | |
276 | - return F(y * z) | |
269 | + rv = y * z | |
270 | + # The only time multiplication can NaN is 0.0 * Infinity. We define it | |
271 | + # to be 0.0, but must respect source signs. | |
272 | + if math.isnan(rv): | |
273 | + rv = 0.0 * math.copysign(1.0, y) * math.copysign(1.0, z) | |
274 | + return F(rv) | |
277 | 275 | |
278 | 276 | class FSqrt(Arrow): |
279 | 277 | _immutable_ = True |
@@ -435,7 +433,8 @@ class Window(object): | ||
435 | 433 | c2 = scale(self._corners[1], self._corners[3], dh + ih * h) |
436 | 434 | return c1, c2 |
437 | 435 | |
438 | -driver = JitDriver(greens=["program"], reds=["x", "y"]) | |
436 | +driver = JitDriver(greens=["program"], | |
437 | + reds=["x", "y"]) | |
439 | 438 | |
440 | 439 | def sample(program, x, y): |
441 | 440 | driver.jit_merge_point(program=program, x=x, y=y) |