Quantcast

How to describe this bug?

classic Classic list List threaded Threaded
22 messages Options
12
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

How to describe this bug?

Soenke Hahn
Hi!

I've discovered a strange bug that violates simple equational reasoning.
Basically, something similar to this:

let a = f x
in a == f x

evaluates to False.

I'd like to report this on ghc-trac, but I realised, that I don't know a
good name for behaviour like this. Is there one? "Broken referential
transparency", perhaps?

Thanks,
Sönke


_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Christopher Done-2
Depends what the real offending code is. For example, if it contains
unsafePerformIO then it's not a bug.

On 10 July 2012 12:42, Sönke Hahn <[hidden email]> wrote:

> Hi!
>
> I've discovered a strange bug that violates simple equational reasoning.
> Basically, something similar to this:
>
> let a = f x
> in a == f x
>
> evaluates to False.
>
> I'd like to report this on ghc-trac, but I realised, that I don't know a
> good name for behaviour like this. Is there one? "Broken referential
> transparency", perhaps?
>
> Thanks,
> Sönke
>
>
> _______________________________________________
> Glasgow-haskell-users mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Malcolm Wallace-2
Also, it is more likely to be a buggy instance of Eq, than a real loss of referential transparency.
Regards,
    Malcolm

On Jul 10, 2012, at 11:49 AM, Christopher Done <[hidden email]> wrote:

Depends what the real offending code is. For example, if it contains
unsafePerformIO then it's not a bug.

On 10 July 2012 12:42, Sönke Hahn <[hidden email]> wrote:
> Hi!
>
> I've discovered a strange bug that violates simple equational reasoning.
> Basically, something similar to this:
>
> let a = f x
> in a == f x
>
> evaluates to False.
>
> I'd like to report this on ghc-trac, but I realised, that I don't know a
> good name for behaviour like this. Is there one? "Broken referential
> transparency", perhaps?
>
> Thanks,
> Sönke
>
>
> _______________________________________________
> Glasgow-haskell-users mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Soenke Hahn
I've attached the code. The code does not make direct use of
unsafePerformIO. It uses QuickCheck, but I don't think, this is a
QuickCheck bug. The used Eq-instance is the one for Float.

I've only managed to reproduce this bug on 32-bit-linux with ghc-7.4.2
when compiling with -O2.

(The code might seem a bit odd, but this is the most boiled down version
I could come up with. Even removing the "module Main where" line changes
the behaviour.)

Cheers,
Sönke


On 07/10/2012 12:51 PM, malcolm.wallace wrote:

> Also, it is more likely to be a buggy instance of Eq, than a real loss
> of referential transparency.
>
> Regards,
>     Malcolm
>
>
> On Jul 10, 2012, at 11:49 AM, Christopher Done <[hidden email]> wrote:
>
>> Depends what the real offending code is. For example, if it contains
>> unsafePerformIO then it's not a bug.
>>
>> On 10 July 2012 12:42, Sönke Hahn <[hidden email]
>> <mailto:[hidden email]>> wrote:
>> > Hi!
>> >
>> > I've discovered a strange bug that violates simple equational reasoning.
>> > Basically, something similar to this:
>> >
>> > let a = f x
>> > in a == f x
>> >
>> > evaluates to False.
>> >
>> > I'd like to report this on ghc-trac, but I realised, that I don't know a
>> > good name for behaviour like this. Is there one? "Broken referential
>> > transparency", perhaps?
>> >
>> > Thanks,
>> > Sönke
>> >
>> >
>> > _______________________________________________
>> > Glasgow-haskell-users mailing list
>> > [hidden email]
>> <mailto:[hidden email]>
>> > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>
>> _______________________________________________
>> Glasgow-haskell-users mailing list
>> [hidden email]
>> <mailto:[hidden email]>
>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>
>
> _______________________________________________
> Glasgow-haskell-users mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>


_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

test.hs (245 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Aleksey Khudyakov
On Tue, Jul 10, 2012 at 3:06 PM, Sönke Hahn <[hidden email]> wrote:
> I've attached the code. The code does not make direct use of
> unsafePerformIO. It uses QuickCheck, but I don't think, this is a
> QuickCheck bug. The used Eq-instance is the one for Float.
>
> I've only managed to reproduce this bug on 32-bit-linux with ghc-7.4.2
> when compiling with -O2.
>
It's expected behaviour with floats. Calculations in FPU are done in
maximul precision available.  If one evaluation result is kept in registers
and another has been moved to memory and rounded and move back to registers
number will be not the same indeed.

In short. Never compare floating point number for equality unless you
really know
what are you doing.

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Simon Marlow-7
On 10/07/2012 12:21, Aleksey Khudyakov wrote:

> On Tue, Jul 10, 2012 at 3:06 PM, Sönke Hahn <[hidden email]> wrote:
>> I've attached the code. The code does not make direct use of
>> unsafePerformIO. It uses QuickCheck, but I don't think, this is a
>> QuickCheck bug. The used Eq-instance is the one for Float.
>>
>> I've only managed to reproduce this bug on 32-bit-linux with ghc-7.4.2
>> when compiling with -O2.
>>
> It's expected behaviour with floats. Calculations in FPU are done in
> maximul precision available.  If one evaluation result is kept in registers
> and another has been moved to memory and rounded and move back to registers
> number will be not the same indeed.
>
> In short. Never compare floating point number for equality unless you
> really know
> what are you doing.

I consider it a bug, because as the original poster pointed out it is a
violation of referential transparency.  What's more, it is *not* an
inherent property of floating point arithmetic, because if the compiler
is careful to do all the operations at the correct precision then you
can get determinstic results.  This is why GHC has the
-fexcess-precision flag: you have to explicitly ask to break referential
transparency.

The bug is that the x86 native code generator behaves as if
-fexcess-precision is always on.  I seriously doubt that we'll ever fix
this "bug": you can get correct behaviour by enabling -msse2, or using a
64-bit machine.  I don't off-hand know what the LLVM backend does here,
but I would guess that it has the same bug.

Cheers,
        Simon

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Christian Maeder-2
In reply to this post by Soenke Hahn
Am 10.07.2012 13:06, schrieb Sönke Hahn:
> I've attached the code. The code does not make direct use of
> unsafePerformIO. It uses QuickCheck, but I don't think, this is a
> QuickCheck bug. The used Eq-instance is the one for Float.

The Eq-instance for floats is broken wrt NaN

Prelude> (0/0 :: Float) == 0/0
False

I do not know if you create NaN in your tests, though.

C.

>
> I've only managed to reproduce this bug on 32-bit-linux with ghc-7.4.2
> when compiling with -O2.
>
> (The code might seem a bit odd, but this is the most boiled down version
> I could come up with. Even removing the "module Main where" line changes
> the behaviour.)
>
> Cheers,
> Sönke
>
>
> On 07/10/2012 12:51 PM, malcolm.wallace wrote:
>> Also, it is more likely to be a buggy instance of Eq, than a real loss
>> of referential transparency.
>>
>> Regards,
>>      Malcolm
>>
>>
>> On Jul 10, 2012, at 11:49 AM, Christopher Done <[hidden email]> wrote:
>>
>>> Depends what the real offending code is. For example, if it contains
>>> unsafePerformIO then it's not a bug.
>>>
>>> On 10 July 2012 12:42, Sönke Hahn <[hidden email]
>>> <mailto:[hidden email]>> wrote:
>>>> Hi!
>>>>
>>>> I've discovered a strange bug that violates simple equational reasoning.
>>>> Basically, something similar to this:
>>>>
>>>> let a = f x
>>>> in a == f x
>>>>
>>>> evaluates to False.
>>>>
>>>> I'd like to report this on ghc-trac, but I realised, that I don't know a
>>>> good name for behaviour like this. Is there one? "Broken referential
>>>> transparency", perhaps?
>>>>
>>>> Thanks,
>>>> Sönke
>>>>
>>>>
>>>> _______________________________________________
>>>> Glasgow-haskell-users mailing list
>>>> [hidden email]
>>> <mailto:[hidden email]>
>>>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>>
>>> _______________________________________________
>>> Glasgow-haskell-users mailing list
>>> [hidden email]
>>> <mailto:[hidden email]>
>>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>
>>
>> _______________________________________________
>> Glasgow-haskell-users mailing list
>> [hidden email]
>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>
>
>
>
>
> _______________________________________________
> Glasgow-haskell-users mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>


_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Christian Maeder-2
In reply to this post by Soenke Hahn
It also works (exposes the bug on x86) without Quickcheck and Doubles:

main = prop 6.0 0.109998815
prop m x = do
     let a = x * m
     putStrLn (show a ++ " foo")
     print (x * m == a)


0.65999289 foo
False

The middle line seems to prevent CSE.

C.

Am 10.07.2012 13:06, schrieb Sönke Hahn:

> I've attached the code. The code does not make direct use of
> unsafePerformIO. It uses QuickCheck, but I don't think, this is a
> QuickCheck bug. The used Eq-instance is the one for Float.
>
> I've only managed to reproduce this bug on 32-bit-linux with ghc-7.4.2
> when compiling with -O2.
>
> (The code might seem a bit odd, but this is the most boiled down version
> I could come up with. Even removing the "module Main where" line changes
> the behaviour.)
>
> Cheers,
> Sönke
>
>
> On 07/10/2012 12:51 PM, malcolm.wallace wrote:
>> Also, it is more likely to be a buggy instance of Eq, than a real loss
>> of referential transparency.
>>
>> Regards,
>>      Malcolm
>>
>>
>> On Jul 10, 2012, at 11:49 AM, Christopher Done <[hidden email]> wrote:
>>
>>> Depends what the real offending code is. For example, if it contains
>>> unsafePerformIO then it's not a bug.
>>>
>>> On 10 July 2012 12:42, Sönke Hahn <[hidden email]
>>> <mailto:[hidden email]>> wrote:
>>>> Hi!
>>>>
>>>> I've discovered a strange bug that violates simple equational reasoning.
>>>> Basically, something similar to this:
>>>>
>>>> let a = f x
>>>> in a == f x
>>>>
>>>> evaluates to False.
>>>>
>>>> I'd like to report this on ghc-trac, but I realised, that I don't know a
>>>> good name for behaviour like this. Is there one? "Broken referential
>>>> transparency", perhaps?
>>>>
>>>> Thanks,
>>>> Sönke
>>>>
>>>>
>>>> _______________________________________________
>>>> Glasgow-haskell-users mailing list
>>>> [hidden email]
>>> <mailto:[hidden email]>
>>>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>>
>>> _______________________________________________
>>> Glasgow-haskell-users mailing list
>>> [hidden email]
>>> <mailto:[hidden email]>
>>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>
>>
>> _______________________________________________
>> Glasgow-haskell-users mailing list
>> [hidden email]
>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>
>
>
>
>
> _______________________________________________
> Glasgow-haskell-users mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>


_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Tyson Whitehead
In reply to this post by Christian Maeder-2
On July 10, 2012 09:28:27 Christian Maeder wrote:

> Am 10.07.2012 13:06, schrieb Sönke Hahn:
> > I've attached the code. The code does not make direct use of
> > unsafePerformIO. It uses QuickCheck, but I don't think, this is a
> > QuickCheck bug. The used Eq-instance is the one for Float.
>
> The Eq-instance for floats is broken wrt NaN
>
> Prelude> (0/0 :: Float) == 0/0
> False
>
> I do not know if you create NaN in your tests, though.

Would that really be broken though?  NaN can arrise from many contexts (e.g.,
sqrt(-1)), so it would also not make much sense to return True.

The IEEE standard actually defines a mutually exclusive fourth "unordered"
state wrt to NaNs for comparisons (in addition to lesser, greater, and equal).

I would like to suggest native floating point might be better modelled as
"Maybe Float", with NaN being the builtin "Nothing", but leaves out Inf.

Cheers!  -Tyson

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

roconnor
In reply to this post by Soenke Hahn
On Tue, 10 Jul 2012, Sönke Hahn wrote:

> Hi!
>
> I've discovered a strange bug that violates simple equational reasoning.
> Basically, something similar to this:
>
> let a = f x
> in a == f x

While this code as it stands doesn't quite illustrate the referential
transparency error, since == isn't guarenteed to return True on the same
floating point value (see NaN), with a small tweek we can turn into an
example that does illustrate the lack of referential transparency:

(let a = f x in a == f x) == (let a = f x in a == a)

or also perhaps

(let a = f x in a == f x) == (f x == f x)

If either of these return False than it is an error of referential
transparency since equality on equivalent Bool expressions is always
supposed to return True or diverge.

--
Russell O'Connor                                      <http://r6.ca/>
``All talk about `theft,''' the general counsel of the American Graphophone
Company wrote, ``is the merest claptrap, for there exists no property in
ideas musical, literary or artistic, except as defined by statute.''
_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Tyson Whitehead
In reply to this post by Tyson Whitehead
On July 10, 2012 10:39:41 Colin Adams wrote:
> Sure they would be better modelled that way, but the whole point of using
> floating point arithmetic is to sacrifice accuracy for performance, is it
> not?

True.  I just find it interesting that some types have a builtin Nothing value.

Some further examples are pointer (where NULL is Nothing) and
clamped/saturation arithmetic (where min and max values are Nothing).

It would be nice if somehow they could be unified at the top level without the
performance penalty associated with a genuine Maybe value.

Another possibility might be to consider NaN to encode bottom in Float#.  When
you constructed Float from Float# with a NaN it would give bottom.

Would the existance of unboxed lifted types be a problem?

Cheers!  -Tyson

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Christian Maeder-2
In reply to this post by Simon Marlow-7
Hi,

I think this bug is serious and should be turned into a ticket on
http://hackage.haskell.org/trac/ghc/
Would you do so Sönke?

The abstraction of floats (Float or Double) is broken if equality
considers (random and invisible) excess bits that are not part of the
ordinary sign, exponent and fraction representation.

It should also hold: show f1 == show f2  => f1 == f2
and: read (show f) == f
(apart from NaN)

Why do you "doubt that we'll ever fix this", Simon?

What is the problem to disable -fexcess-precision or enable -msse2 (on
most machines) by default?

Cheers Christian

Am 10.07.2012 14:33, schrieb Simon Marlow:

> On 10/07/2012 12:21, Aleksey Khudyakov wrote:
>> On Tue, Jul 10, 2012 at 3:06 PM, Sönke Hahn <[hidden email]>
>> wrote:
>>> I've attached the code. The code does not make direct use of
>>> unsafePerformIO. It uses QuickCheck, but I don't think, this is a
>>> QuickCheck bug. The used Eq-instance is the one for Float.
>>>
>>> I've only managed to reproduce this bug on 32-bit-linux with ghc-7.4.2
>>> when compiling with -O2.
>>>
>> It's expected behaviour with floats. Calculations in FPU are done in
>> maximul precision available.  If one evaluation result is kept in
>> registers
>> and another has been moved to memory and rounded and move back to
>> registers
>> number will be not the same indeed.
>>
>> In short. Never compare floating point number for equality unless you
>> really know
>> what are you doing.
>
> I consider it a bug, because as the original poster pointed out it is a
> violation of referential transparency.  What's more, it is *not* an
> inherent property of floating point arithmetic, because if the compiler
> is careful to do all the operations at the correct precision then you
> can get determinstic results.  This is why GHC has the
> -fexcess-precision flag: you have to explicitly ask to break referential
> transparency.
>
> The bug is that the x86 native code generator behaves as if
> -fexcess-precision is always on.  I seriously doubt that we'll ever fix
> this "bug": you can get correct behaviour by enabling -msse2, or using a
> 64-bit machine.  I don't off-hand know what the LLVM backend does here,
> but I would guess that it has the same bug.
>
> Cheers,
>      Simon
>
> _______________________________________________
> Glasgow-haskell-users mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Simon Marlow-7
On 11/07/2012 08:36, Christian Maeder wrote:

> Hi,
>
> I think this bug is serious and should be turned into a ticket on
> http://hackage.haskell.org/trac/ghc/
> Would you do so Sönke?
>
> The abstraction of floats (Float or Double) is broken if equality
> considers (random and invisible) excess bits that are not part of the
> ordinary sign, exponent and fraction representation.
>
> It should also hold: show f1 == show f2  => f1 == f2
> and: read (show f) == f
> (apart from NaN)
>
> Why do you "doubt that we'll ever fix this", Simon?

Several reasons:

  - the fix hurts performance badly, because you have to store floats
    into memory after every operation. (c.f. gcc's -ffloat-store option)
  - the fix is complicated
  - good workarounds exist (-msse2)
  - it is rarely a problem

> What is the problem to disable -fexcess-precision or enable -msse2 (on
> most machines) by default?

-fexcess-precision cannot be disabled on x86 (that is the bug).

-msse2 is not supported on all processors, so we can't enable it by default.

Cheers,
        Simon



> Cheers Christian
>
> Am 10.07.2012 14:33, schrieb Simon Marlow:
>> On 10/07/2012 12:21, Aleksey Khudyakov wrote:
>>> On Tue, Jul 10, 2012 at 3:06 PM, Sönke Hahn <[hidden email]>
>>> wrote:
>>>> I've attached the code. The code does not make direct use of
>>>> unsafePerformIO. It uses QuickCheck, but I don't think, this is a
>>>> QuickCheck bug. The used Eq-instance is the one for Float.
>>>>
>>>> I've only managed to reproduce this bug on 32-bit-linux with ghc-7.4.2
>>>> when compiling with -O2.
>>>>
>>> It's expected behaviour with floats. Calculations in FPU are done in
>>> maximul precision available.  If one evaluation result is kept in
>>> registers
>>> and another has been moved to memory and rounded and move back to
>>> registers
>>> number will be not the same indeed.
>>>
>>> In short. Never compare floating point number for equality unless you
>>> really know
>>> what are you doing.
>>
>> I consider it a bug, because as the original poster pointed out it is a
>> violation of referential transparency.  What's more, it is *not* an
>> inherent property of floating point arithmetic, because if the compiler
>> is careful to do all the operations at the correct precision then you
>> can get determinstic results.  This is why GHC has the
>> -fexcess-precision flag: you have to explicitly ask to break referential
>> transparency.
>>
>> The bug is that the x86 native code generator behaves as if
>> -fexcess-precision is always on.  I seriously doubt that we'll ever fix
>> this "bug": you can get correct behaviour by enabling -msse2, or using a
>> 64-bit machine.  I don't off-hand know what the LLVM backend does here,
>> but I would guess that it has the same bug.
>>
>> Cheers,
>>      Simon
>>
>> _______________________________________________
>> Glasgow-haskell-users mailing list
>> [hidden email]
>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>



_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Christian Maeder-2
Am 11.07.2012 10:25, schrieb Simon Marlow:

> On 11/07/2012 08:36, Christian Maeder wrote:
>> Hi,
>>
>> I think this bug is serious and should be turned into a ticket on
>> http://hackage.haskell.org/trac/ghc/
>> Would you do so Sönke?
>>
>> The abstraction of floats (Float or Double) is broken if equality
>> considers (random and invisible) excess bits that are not part of the
>> ordinary sign, exponent and fraction representation.
>>
>> It should also hold: show f1 == show f2  => f1 == f2
>> and: read (show f) == f
>> (apart from NaN)
>>
>> Why do you "doubt that we'll ever fix this", Simon?
>
> Several reasons:
>
>   - the fix hurts performance badly, because you have to store floats
>     into memory after every operation. (c.f. gcc's -ffloat-store option)

If we sacrifice correctness for performance then we should clearly
document this!

Is it not enough to store floats into memory just before equality tests
(or add rounding in the instance definitions of Float and Double in Eq
and Ord)?

>   - the fix is complicated
>   - good workarounds exist (-msse2)
>   - it is rarely a problem

Rare cases are extremely hard to track down if they occur!

>> What is the problem to disable -fexcess-precision or enable -msse2 (on
>> most machines) by default?
>
> -fexcess-precision cannot be disabled on x86 (that is the bug).
>
> -msse2 is not supported on all processors, so we can't enable it by
> default.

Can't "configure" find this out?

C.

> Cheers,
>      Simon
>
>
>
>> Cheers Christian
>>
>> Am 10.07.2012 14:33, schrieb Simon Marlow:
>>> On 10/07/2012 12:21, Aleksey Khudyakov wrote:
>>>> On Tue, Jul 10, 2012 at 3:06 PM, Sönke Hahn <[hidden email]>
>>>> wrote:
>>>>> I've attached the code. The code does not make direct use of
>>>>> unsafePerformIO. It uses QuickCheck, but I don't think, this is a
>>>>> QuickCheck bug. The used Eq-instance is the one for Float.
>>>>>
>>>>> I've only managed to reproduce this bug on 32-bit-linux with ghc-7.4.2
>>>>> when compiling with -O2.
>>>>>
>>>> It's expected behaviour with floats. Calculations in FPU are done in
>>>> maximul precision available.  If one evaluation result is kept in
>>>> registers
>>>> and another has been moved to memory and rounded and move back to
>>>> registers
>>>> number will be not the same indeed.
>>>>
>>>> In short. Never compare floating point number for equality unless you
>>>> really know
>>>> what are you doing.
>>>
>>> I consider it a bug, because as the original poster pointed out it is a
>>> violation of referential transparency.  What's more, it is *not* an
>>> inherent property of floating point arithmetic, because if the compiler
>>> is careful to do all the operations at the correct precision then you
>>> can get determinstic results.  This is why GHC has the
>>> -fexcess-precision flag: you have to explicitly ask to break referential
>>> transparency.
>>>
>>> The bug is that the x86 native code generator behaves as if
>>> -fexcess-precision is always on.  I seriously doubt that we'll ever fix
>>> this "bug": you can get correct behaviour by enabling -msse2, or using a
>>> 64-bit machine.  I don't off-hand know what the LLVM backend does here,
>>> but I would guess that it has the same bug.
>>>
>>> Cheers,
>>>      Simon
>>>
>>> _______________________________________________
>>> Glasgow-haskell-users mailing list
>>> [hidden email]
>>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>
>
>



_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Simon Marlow-7
On 11/07/2012 09:51, Christian Maeder wrote:

> Am 11.07.2012 10:25, schrieb Simon Marlow:
>> On 11/07/2012 08:36, Christian Maeder wrote:
>>> Hi,
>>>
>>> I think this bug is serious and should be turned into a ticket on
>>> http://hackage.haskell.org/trac/ghc/
>>> Would you do so Sönke?
>>>
>>> The abstraction of floats (Float or Double) is broken if equality
>>> considers (random and invisible) excess bits that are not part of the
>>> ordinary sign, exponent and fraction representation.
>>>
>>> It should also hold: show f1 == show f2  => f1 == f2
>>> and: read (show f) == f
>>> (apart from NaN)
>>>
>>> Why do you "doubt that we'll ever fix this", Simon?
>>
>> Several reasons:
>>
>>   - the fix hurts performance badly, because you have to store floats
>>     into memory after every operation. (c.f. gcc's -ffloat-store option)
>
> If we sacrifice correctness for performance then we should clearly
> document this!

I will document it in the User's Guide along with the other known bugs.

>>> What is the problem to disable -fexcess-precision or enable -msse2 (on
>>> most machines) by default?
>>
>> -fexcess-precision cannot be disabled on x86 (that is the bug).
>>
>> -msse2 is not supported on all processors, so we can't enable it by
>> default.
>
> Can't "configure" find this out?

Configure will detect whether the machine you're building on supports
-msse2, but not whether the machine that you will eventually *run* the
code on does.  For instance, when building GHC for distribution we have
to assume that the target machine does not support SSE2, so all the
libraries must be built without -msse2.

Cheers,
        Simon



> C.
>
>> Cheers,
>>      Simon
>>
>>
>>
>>> Cheers Christian
>>>
>>> Am 10.07.2012 14:33, schrieb Simon Marlow:
>>>> On 10/07/2012 12:21, Aleksey Khudyakov wrote:
>>>>> On Tue, Jul 10, 2012 at 3:06 PM, Sönke Hahn <[hidden email]>
>>>>> wrote:
>>>>>> I've attached the code. The code does not make direct use of
>>>>>> unsafePerformIO. It uses QuickCheck, but I don't think, this is a
>>>>>> QuickCheck bug. The used Eq-instance is the one for Float.
>>>>>>
>>>>>> I've only managed to reproduce this bug on 32-bit-linux with
>>>>>> ghc-7.4.2
>>>>>> when compiling with -O2.
>>>>>>
>>>>> It's expected behaviour with floats. Calculations in FPU are done in
>>>>> maximul precision available.  If one evaluation result is kept in
>>>>> registers
>>>>> and another has been moved to memory and rounded and move back to
>>>>> registers
>>>>> number will be not the same indeed.
>>>>>
>>>>> In short. Never compare floating point number for equality unless you
>>>>> really know
>>>>> what are you doing.
>>>>
>>>> I consider it a bug, because as the original poster pointed out it is a
>>>> violation of referential transparency.  What's more, it is *not* an
>>>> inherent property of floating point arithmetic, because if the compiler
>>>> is careful to do all the operations at the correct precision then you
>>>> can get determinstic results.  This is why GHC has the
>>>> -fexcess-precision flag: you have to explicitly ask to break
>>>> referential
>>>> transparency.
>>>>
>>>> The bug is that the x86 native code generator behaves as if
>>>> -fexcess-precision is always on.  I seriously doubt that we'll ever fix
>>>> this "bug": you can get correct behaviour by enabling -msse2, or
>>>> using a
>>>> 64-bit machine.  I don't off-hand know what the LLVM backend does here,
>>>> but I would guess that it has the same bug.
>>>>
>>>> Cheers,
>>>>      Simon
>>>>
>>>> _______________________________________________
>>>> Glasgow-haskell-users mailing list
>>>> [hidden email]
>>>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>>
>>
>>
>
>



_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Tyson Whitehead
In reply to this post by Christian Maeder-2
On July 11, 2012 04:51:50 Christian Maeder wrote:
> Is it not enough to store floats into memory just before equality tests
> (or add rounding in the instance definitions of Float and Double in Eq
> and Ord)?

You have to be 100% consistent in how you do every operations in all cases
otherwise different levels of rounding errors will creep into the results.

It isn't too hard to imagine a floating point expression getting inlined
somewhere, and the compiler generating code to evalulate it all in registers.  
Intermediate operations will then be done to 80 bit precision.

Elsewhere, it doesn't get inlined and the compiler generates code to store
intermediate results in memory.  Intermediate operations will then be done to
32 bit precision.  Different results will occur on the rounding boundaires.

Always storing and reloading after every operations will give you consistent
results.  I guess the other option is to disable inlining etc. or somehow
ensure they are applied consistently in all use cases of an expression.

Cheers!  -Tyson

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Aleksey Khudyakov
On 11.07.2012 20:05, Tyson Whitehead wrote:

> On July 11, 2012 04:51:50 Christian Maeder wrote:
>> Is it not enough to store floats into memory just before equality tests
>> (or add rounding in the instance definitions of Float and Double in Eq
>> and Ord)?
>
> You have to be 100% consistent in how you do every operations in all cases
> otherwise different levels of rounding errors will creep into the results.
>
> It isn't too hard to imagine a floating point expression getting inlined
> somewhere, and the compiler generating code to evalulate it all in registers.
> Intermediate operations will then be done to 80 bit precision.
>
> Elsewhere, it doesn't get inlined and the compiler generates code to store
> intermediate results in memory.  Intermediate operations will then be done to
> 32 bit precision.  Different results will occur on the rounding boundaires.
>
> Always storing and reloading after every operations will give you consistent
> results.  I guess the other option is to disable inlining etc. or somehow
> ensure they are applied consistently in all use cases of an expression.
>
There are more possibilities. With optimizations turned on compiler may
be able to squeeze everything into registers and do store/load
operations otherwise. However I don't consider it a problem. If your
result depends on rounding you are in deep trouble and it's quite likely
result is garbage.

Equality is a bit more complicated. It's rarely meaningful and if you do
need exact equality you'd better to ensure that number is stored because
exact behaviour depends on hardware, compiler and compiler flags.

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Bardur Arantsson-2
In reply to this post by Malcolm Wallace-2
On 07/10/2012 12:51 PM, malcolm.wallace wrote:
> Also, it is more likely to be a buggy instance of Eq, than a real loss
> of referential transparency.
>

Speaking of which... would it be remiss of me to mention the elephant in
the room, namely the Eq instance for Float?

AFAICT there is no possible way for a Float value to fulfill the Eq type
class requirements, so why is it an instance? (I'm thinking of the
"weird" Nan/Infinity behvaior primarily). Is there *really* such a huge
amount of code out there that relies on an Eq (or Ord for that matter!)
instance for Float? If so... shouldn't that code be fixed rather than
being subtly buggy?

Regards,


_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Soenke Hahn
On 07/13/2012 03:12 AM, Bardur Arantsson wrote:
> Speaking of which... would it be remiss of me to mention the elephant in
> the room, namely the Eq instance for Float?
>
> AFAICT there is no possible way for a Float value to fulfill the Eq type
> class requirements, so why is it an instance? (I'm thinking of the
> "weird" Nan/Infinity behvaior primarily). Is there *really* such a huge
> amount of code out there that relies on an Eq (or Ord for that matter!)
> instance for Float? If so... shouldn't that code be fixed rather than
> being subtly buggy?

Num inherits from Eq, so Float couldn't have an instance for Num if we
didn't have that Eq instance.

BTW: My newsgroup client seems to have eaten my last mail. I filed a bug
report here:

http://hackage.haskell.org/trac/ghc/ticket/7069

Cheers,
Sönke


_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to describe this bug?

Aleksey Khudyakov
On 13.07.2012 14:18, Sönke Hahn wrote:

> On 07/13/2012 03:12 AM, Bardur Arantsson wrote:
>> Speaking of which... would it be remiss of me to mention the elephant in
>> the room, namely the Eq instance for Float?
>>
>> AFAICT there is no possible way for a Float value to fulfill the Eq type
>> class requirements, so why is it an instance? (I'm thinking of the
>> "weird" Nan/Infinity behvaior primarily). Is there *really* such a huge
>> amount of code out there that relies on an Eq (or Ord for that matter!)
>> instance for Float? If so... shouldn't that code be fixed rather than
>> being subtly buggy?
>
> Num inherits from Eq, so Float couldn't have an instance for Num if we
> didn't have that Eq instance.
>
No more since GHC 7.4. But Eq is indeed superclass of Ord and it Ord is
used a lot.

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
12
Loading...