[JBS] {New} (JDK-8170430) x86 pow() stub from Intel libm is inconsistent with pow() from fdlib
Volker Simonis
volker.simonis at gmail.com
Thu Dec 1 10:01:55 UTC 2016
Vladimir, Joe,
thanks for your detailed descriptions and explanations.
I'll check if our ports comply with the expected behavior.
Regards,
Volker
On Wed, Nov 30, 2016 at 10:02 PM, joe darcy <joe.darcy at oracle.com> wrote:
> Hello,
>
> It is allowed by the specification and desirable for Math.pow to return
> different results than StrictMath.pow, subject to the quality of
> implementation criteria governing both implementations.
>
> For pow those requirements are:
>
> The computed result must be within 1 ulp of the exact result. Results
> must be semi-monotonic.
> http://download.java.net/java/jdk9/docs/api/java/lang/Math.html#pow-double-double-
>
> Having "the computed result must be within 1 ulp of the exact result" means
> (in summary) one of the the two floating-point values bracketing the exact
> mathematical result must be returned. Requiring the results to be
> "semi-monotonic" means that when the true pow function is increasing the
> floating-point approximation must be non-decreasing. A particular example,
> fix the first argument of pow to be some finite X > 1 and for successive
> finite floating-point numbers y1, y2, y3, ... all > 1 it is true
> mathematically that:
>
> pow(X, y1) < pow(X, y2) < pow(X, y3) < ...
>
> and thus by the semi-monotonic requirement the floating-point approximation
> must have the property that:
>
> pow(X, y1) <= pow(X, y2) <= pow(X, y3) <= ...
>
> Say you have two pow implementations, pow1 and pow2, that separately mean
> the accuracy and semi-monotonic requirements above. Is some interleaving of
> pow1 and pow2 also a valid implementation?
>
> Since each of pow1 and pow2 meet the accuracy requirements for a given
> argument, picking one or another is fine. However, the semi-monotonic
> requirement can be problematic. For example, lets say in a flat portion of
> the graph we have a true mathematical result close to (a+ b)/2 with a < b
> and pow1 and pow2 behaving as follows:
>
> pow1(X, y1) = a
> pow1(X, y2) = a
> pow1(X, y3) = a
>
> pow2(X, y1) = b
> pow2(X, y2) = b
> pow2(X, y3) = b
>
> Separately, each of pow1 and pow2 is meeting the accuracy and semi-monotonic
> requirements.
>
> However, if an interleaving pow picks pow2 for (X, y1) and pow1 for (X, y2),
> the semi-monotonic requirement will be violated and the composite
> implementation *illegal*.
>
> Just picking one of pow1 and pow2 and sticking with it for a given JVM run
> avoids having to worry about such subtle issues. For that reason, we've
> worked to make the math instrinics behave consistently independent of being
> run in the interpreter, C1, C2, and so on. Various bugs to implement such
> consistency have been filed and fixed over the years, but I'm dig them up at
> this time.
>
> In this case, I strongly recommend the pow stub be used or not used
> independent of what HotSpot compiler is run.
>
> HTH,
>
> -Joe
>
>
>
> On 11/30/2016 10:25 AM, Vladimir Kozlov wrote:
>>
>> On 11/30/16 9:35 AM, Volker Simonis wrote:
>>>
>>> Hi,
>>>
>>> what is the actual problem here? Is it the fact that Math.pow()
>>> returns different results depending on whether it is executed in
>>> interpreted or in JIT-compiled mode?
>>>
>>> Or in other words - do we insist on having the same results from the
>>> Math functions while promoting from Interpreted to C1 and finally C2?
>>
>>
>> Yes, that is the goal. The result should be the same from Interpreter and
>> from code generated by JIT compilers.
>>
>>> The API-doc for Math says: "Unlike some of the numeric methods of
>>> class StrictMath, all implementations of the equivalent functions of
>>> class Math are not defined to return the bit-for-bit same results.
>>> This relaxation permits better-performing implementations where strict
>>> reproducibility is not required." But I'm not sure if this implies
>>> that Math.FUNC(constant_value) always has to return the bit-for-bit
>>> same result no matter how often we call it?
>>>
>>> The problem is that by default the Java implementation of the Math
>>> functions call the StrictMath version. So if the interpreter does no
>>> optimizations, it will get the exact StrictMath (i.e. fdlibm) results.
>>> But when the Math methods are compiled, they may be intrinisfied, in
>>> which case they are allowed to return less exact values. A further
>>> complication is that the interpreter may optimize himself and either
>>> use optimized assembler stubs for a function (e.g.
>>> StubRoutines::_dsin()) or uses leaf-calls into HotSpots internal
>>> C++-Implementation of the functions (e.g. SharedRuntime::dsin()).
>>
>>
>> JIT compilers should follow the same rule as Interpreter: call
>> StubRoutines::_dsin or SharedRuntime::dsin.
>>
>>>
>>> So what does "strict reproducibility is not required" for Math
>>> functions actually mean? Is it OK for a program like this:
>>>
>>> while(true) {
>>> if (Math.FUNC(val) == XXX) System.out.println("YES");
>>> else System.out.println("NO");
>>> }
>>>
>>> to print both, "YES" and "NO"?
>>
>>
>> No, we try to avoid this. During application one run the answer should be
>> the same regardless how frequent a method is executed (JITed or not). But
>> the result does not necessary need to be the same when an application run
>> with different flags (InlineIntrinsics).
>>
>> This is how I understand it.
>>
>> We had a lot of bugs (for pow() especially) when results were inconsistent
>> during run until we start using the same code in Interpreter and JITed code.
>>
>> Regards,
>> Vladimir
>>
>>>
>>> Thank you and best regards,
>>> Volker
>>>
>>>
>>> On Wed, Nov 30, 2016 at 2:34 AM, Vladimir Kozlov
>>> <vladimir.kozlov at oracle.com> wrote:
>>>>
>>>> Thank you, Vivek
>>>>
>>>> I will sponsor it.
>>>>
>>>> Do you think it is hard to fix stubs code even in some next release?
>>>>
>>>> Thanks,
>>>> Vladimir
>>>>
>>>>
>>>> On 11/29/16 5:26 PM, Deshpande, Vivek R wrote:
>>>>>
>>>>>
>>>>> Hi
>>>>>
>>>>>
>>>>>
>>>>> I have bug fix for avx512 8170430.
>>>>>
>>>>> http://cr.openjdk.java.net/~vdeshpande/8170430/webrev.00/
>>>>>
>>>>> I have also updated the JBS entry.
>>>>>
>>>>> https://bugs.openjdk.java.net/browse/JDK-8170430
>>>>>
>>>>> I have tested it with other libm stubs too along with pow.
>>>>>
>>>>> Would you please review and sponsor it.
>>>>>
>>>>>
>>>>>
>>>>> Regards,
>>>>>
>>>>> Vivek
>>>>>
>>>>>
>>>>
>
More information about the hotspot-compiler-dev
mailing list