<p dir="ltr">Is there a good reason not to detect single expression multiply adds and just emit a new FMA bytecode?</p>
<p dir="ltr">Is our goal for floats to strictly match the result of the same operations coded in unoptimized C using doubles?</p>
<p dir="ltr">Or can we be more precise on occasion?</p>
<p dir="ltr">I guess a similar question may be asked of all C compilers as they too could emit an FMA instruction on such expressions... If they don't do it by default, that suggests we match them and not do it either.</p>
<p dir="ltr">Regardless +1 on adding math.fma() either way as it is an expression of precise intent.</p>
<p dir="ltr">-gps</p>
<br><div class="gmail_quote"><div dir="ltr">On Mon, Jan 16, 2017, 10:44 AM David Mertz <<a href="mailto:mertz@gnosis.cx">mertz@gnosis.cx</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg">My understanding is that NumPy does NOT currently support a direct FMA operation "natively."  However, higher-level routines like `numpy.linalg.solve` that are linked to MKL or BLAS DO take advantage of FMA within the underlying libraries.</div><div class="gmail_extra gmail_msg"></div><div class="gmail_extra gmail_msg"><br class="gmail_msg"><div class="gmail_quote gmail_msg">On Mon, Jan 16, 2017 at 10:06 AM, Guido van Rossum <span dir="ltr" class="gmail_msg"><<a href="mailto:gvanrossum@gmail.com" class="gmail_msg" target="_blank">gvanrossum@gmail.com</a>></span> wrote:<br class="gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto" class="gmail_msg">Does numpy support this?<br class="gmail_msg"><br class="gmail_msg"><div data-smartmail="gmail_signature" class="gmail_msg">--Guido (mobile)</div></div><div class="m_-9113847478803286698HOEnZb gmail_msg"><div class="m_-9113847478803286698h5 gmail_msg"><div class="gmail_extra gmail_msg"><br class="gmail_msg"><div class="gmail_quote gmail_msg">On Jan 16, 2017 7:27 AM, "Stephan Houben" <<a href="mailto:stephanh42@gmail.com" class="gmail_msg" target="_blank">stephanh42@gmail.com</a>> wrote:<br type="attribution" class="gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg">Hi Steve,<div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Very good!</div><div class="gmail_msg">Here is a version which also handles the nan's, infinities,</div><div class="gmail_msg">negative zeros properly.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">===============</div><div class="gmail_msg"><div class="gmail_msg">import math</div><div class="gmail_msg">from fractions import Fraction</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">def fma2(x, y, z):</div><div class="gmail_msg">    if math.isfinite(x) and math.isfinite(y) and math.isfinite(z):</div><div class="gmail_msg">        result = float(Fraction(x)*Fraction(y) + Fraction(z))</div><div class="gmail_msg">        if not result and not z:</div><div class="gmail_msg">            result = math.copysign(result, x*y+z)</div><div class="gmail_msg">    else:</div><div class="gmail_msg">        result = x * y + z</div><div class="gmail_msg">        assert not math.isfinite(result)</div><div class="gmail_msg">    return result</div><div class="gmail_msg">===========================</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Stephan</div><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div class="gmail_extra gmail_msg"><br class="gmail_msg"><div class="gmail_quote gmail_msg">2017-01-16 12:04 GMT+01:00 Steven D'Aprano <span dir="ltr" class="gmail_msg"><<a href="mailto:steve@pearwood.info" class="gmail_msg" target="_blank">steve@pearwood.info</a>></span>:<br class="gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Mon, Jan 16, 2017 at 11:01:23AM +0100, Stephan Houben wrote:<br class="gmail_msg">
<br class="gmail_msg">
[...]<br class="gmail_msg">
<span class="gmail_msg">> So the following would not be a valid FMA fallback<br class="gmail_msg">
><br class="gmail_msg">
> double bad_fma(double x, double y, double z) {<br class="gmail_msg">
>   return x*y + z;<br class="gmail_msg">
> }<br class="gmail_msg">
</span>[...]<br class="gmail_msg">
<span class="gmail_msg">> Upshot: if we want to provide a software fallback in the Python code, we<br class="gmail_msg">
> need to do something slow and complicated like musl does.<br class="gmail_msg">
<br class="gmail_msg">
</span>I don't know about complicated. I think this is pretty simple:<br class="gmail_msg">
<br class="gmail_msg">
from fractions import Fraction<br class="gmail_msg">
<br class="gmail_msg">
def fma(x, y, z):<br class="gmail_msg">
    # Return x*y + z with only a single rounding.<br class="gmail_msg">
    return float(Fraction(x)*Fraction(y) + Fraction(z))<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
When speed is not the number one priority and accuracy is important,<br class="gmail_msg">
its hard to beat the fractions module.<br class="gmail_msg">
<span class="m_-9113847478803286698m_-6458649721746544018m_2404065159388076217HOEnZb gmail_msg"><font color="#888888" class="gmail_msg"><br class="gmail_msg">
<br class="gmail_msg">
--<br class="gmail_msg">
Steve<br class="gmail_msg">
</font></span><div class="m_-9113847478803286698m_-6458649721746544018m_2404065159388076217HOEnZb gmail_msg"><div class="m_-9113847478803286698m_-6458649721746544018m_2404065159388076217h5 gmail_msg">_______________________________________________<br class="gmail_msg">
Python-ideas mailing list<br class="gmail_msg">
<a href="mailto:Python-ideas@python.org" class="gmail_msg" target="_blank">Python-ideas@python.org</a><br class="gmail_msg">
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" class="gmail_msg" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br class="gmail_msg">
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer" class="gmail_msg" target="_blank">http://python.org/psf/codeofconduct/</a><br class="gmail_msg">
</div></div></blockquote></div><br class="gmail_msg"></div>
<br class="gmail_msg">_______________________________________________<br class="gmail_msg">
Python-ideas mailing list<br class="gmail_msg">
<a href="mailto:Python-ideas@python.org" class="gmail_msg" target="_blank">Python-ideas@python.org</a><br class="gmail_msg">
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" class="gmail_msg" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br class="gmail_msg">
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer" class="gmail_msg" target="_blank">http://python.org/psf/codeofconduct/</a><br class="gmail_msg"></blockquote></div></div>
</div></div><br class="gmail_msg">_______________________________________________<br class="gmail_msg">
Python-ideas mailing list<br class="gmail_msg">
<a href="mailto:Python-ideas@python.org" class="gmail_msg" target="_blank">Python-ideas@python.org</a><br class="gmail_msg">
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" class="gmail_msg" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br class="gmail_msg">
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer" class="gmail_msg" target="_blank">http://python.org/psf/codeofconduct/</a><br class="gmail_msg"></blockquote></div><br class="gmail_msg"><br clear="all" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div></div><div class="gmail_extra gmail_msg">-- <br class="gmail_msg"><div class="m_-9113847478803286698gmail_signature gmail_msg" data-smartmail="gmail_signature">Keeping medicines from the bloodstreams of the sick; food <br class="gmail_msg">from the bellies of the hungry; books from the hands of the <br class="gmail_msg">uneducated; technology from the underdeveloped; and putting <br class="gmail_msg">advocates of freedom in prisons.  Intellectual property is<br class="gmail_msg">to the 21st century what the slave trade was to the 16th.<br class="gmail_msg"></div>
</div>
_______________________________________________<br class="gmail_msg">
Python-ideas mailing list<br class="gmail_msg">
<a href="mailto:Python-ideas@python.org" class="gmail_msg" target="_blank">Python-ideas@python.org</a><br class="gmail_msg">
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" class="gmail_msg" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br class="gmail_msg">
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer" class="gmail_msg" target="_blank">http://python.org/psf/codeofconduct/</a></blockquote></div>