<div dir="ltr">David, <div>We aren't talking about Ring laws here, so lets not pull that in yet please :) </div><div><br></div><div>as Merijn also noted, one possible semantics is have signalling Nans, so that any haskell calculation that yields a Nan instead triggers an exception via cpu stuff. Or the next FP instruction that touches the nan will trigger in the case of it coming from C land (I just reread all the relevant sections of the intel architecture manual, its quite explicit on this corner, and still be superbly IEEE float compliant, AND place nice with code that DOES want nan via stateful stuff if need be)</div><div><br></div><div>on the matter of Nan, in a quiet nan universe, theres a whole universe of Nans, and they're all different, and in fact the iEEE standard is quite clear that a language could pick different nans for different errors (eg have all the bits form a bit set of possible errors). Or one of several  other approaches.</div><div><br></div><div>point being, we can have nice things.</div><div><br></div><div>mind you, i'm still doing this hackery over time. But I genuinely see a path thats thread safe, makes the MXCSR register state act local per haskell thread, doesn't change the default semantics for C ffi calls, and still allows those who want quiet NANs to do whatever they want if they really really want to. </div><div><br></div><div>I do agree that any such changes can't break code in the wild that depends on FPU state stuff, nor those who like Quiet Nans more than exceptional/signalling ones. And thats a burden on me / any collaborators for successful execution.</div><div><br></div><div><b>punchline</b> Lawful Ord and NanFree Float for all, with no leaky breakages,  Every Num has Div By Zero error already,  lets recognize all NAN computations as being similarly exceptional by default. :) </div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Feb 7, 2019 at 4:41 PM David Feuer <<a href="mailto:david.feuer@gmail.com">david.feuer@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto">Even if Ord becomes lawful for floating point, there will still be massive problems reasoning about it because the Num instances can't support the ring laws, let alone the ordered ring laws. What should `compare NaN n` be? If it's an exception, then the ordering is not total, you can't store NaN in a Set, etc. If it's LT or GT, then you get a total ordering, but a rather weird one. So yeah, you'd be able to store NaN in a Set and have an NaN key in a Map, but then as soon as you start looking at where these are coming from and where they're going, everything goes weird and you need type-specific code anyway.</div><br><div class="gmail_quote"><div dir="ltr">On Thu, Feb 7, 2019, 4:29 PM Carter Schonwald <<a href="mailto:carter.schonwald@gmail.com" target="_blank">carter.schonwald@gmail.com</a> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">to further add weight, i'm still doing preliminary hackery on the signalling approach, but the signalling for FP state stuff seems to be OS thread local, so it can be treated as an exception perfectly well!</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Feb 7, 2019 at 4:27 PM Carter Schonwald <<a href="mailto:carter.schonwald@gmail.com" rel="noreferrer" target="_blank">carter.schonwald@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">@sven and @henning : <br><div>i'm actually doing some preliminary work to add save and restore for FPU state to the GHC RTS, at the green/haskell thread layer. after first ripping out x87 code gen, which just needs some more docs written out before its merged in. note that i'm speaking specifically of the MXCSR register save and restore, not the more hefty operations you might be thinking.</div><div><br></div><div>FPU mode state save and restore is done already on EVERY OS when switching threads/processes, and in the agner fog latency tables  the cost of manipulating  mxcsr registers is pretty small!</div><div><a href="https://www.agner.org/optimize/instruction_tables.pdf" rel="noreferrer" target="_blank">https://www.agner.org/optimize/instruction_tables.pdf</a><br></div><div><br></div><div>LDMXCSR  (restore) and STMXCSR  (save) have cpu latencies at like 5-20 cycles  (more often 8-15), so having the current C ffi calls set the default C FPU environment (as we currently have ordinarily) is super doable to ensure no breakage of existing C bindings, plus have a new ccall variant that inherits the host haskell thread FPU state.  we're talking sub 10 nanosecond overhead on x86 and x86_64 platforms (and either way, on those platforms soon ghc will only be using the sse2 or higher ).<br></div><div><br></div><div>point being: aside from like AMD piledriver micro architecture and some stuff from VIA, the performance of the CPU instruction for the signalling nans state setup and related rounding mode etc, should work perfectly well, </div><div><br></div><div><a class="gmail_plusreply" id="gmail-m_-7154108951562915579m_-9024428208040194083gmail-m_2450203141496634152gmail-plusReplyChip-2" href="mailto:chessai1996@gmail.com" rel="noreferrer" target="_blank">@Daniel Cartwright</a>  I do not support documenting false laws in any enshrined way, it will result in broken code. (Also i'm actually working to do some fixes, if you reread my remarks and merijn's, and i think we can have our cake and eat it, with the finest floats). Lets fix stuff and then document true laws!<br></div><div><br></div><div><br></div></div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Feb 7, 2019 at 12:05 PM Sven Panne <<a href="mailto:svenpanne@gmail.com" rel="noreferrer" target="_blank">svenpanne@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">Am Do., 7. Feb. 2019 um 17:22 Uhr schrieb Henning Thielemann <<a href="mailto:lemming@henning-thielemann.de" rel="noreferrer" target="_blank">lemming@henning-thielemann.de</a>>:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">[...] What about calling into foreign code? If I call a BLAS routine and one <br>
element of the result vector is NaN, shall this be trapped? Or shall it be <br>
trapped once I access the NaN element?<br></blockquote><div><br></div><div>IMHO this is the biggest show stopper for some exotic NaN handling, as correct as it may be mathematically or aesthetically: The floating point environment is a thread-local (i.e. basically global) entity on most platforms, and most programming language runtimes expect a "default" environment, i.e. no traps when NaNs are encountered. So if Haskell wants to do things differently, the FPE has to be set/reset around foreign calls and for around every Haskell callback. I am not sure if this is really worth the trouble and the performance loss. For some special applications it might be OK or even important, but my gut feeling is that trapping NaNs is the wrong default in our current world...</div></div></div></div></div>
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" rel="noreferrer" target="_blank">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
</blockquote></div>
</blockquote></div>
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" rel="noreferrer" target="_blank">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
</blockquote></div>
</blockquote></div>