biniou
biniou copied to clipboard
test_biniou fails on ppc64
A float comparison fails on ppc64 on line 264 of the test_biniou file. As it can be seen from the log below, I added a print to the respective line in the test and it fails although both numbers seem equal.
$ ./test_biniou x = 1.001470 y = 1.001470 Fatal error: exception File "bi_io.ml", line 265, characters 4-10: Assertion failed
Sorry I haven't found the time to look into it.
This is a copy of the test from bi_io.ml:
let safety_test () =
let s = "\x3f\xf0\x06\x05\x04\x03\x02\x01" in
let x = 1.00146962706651288 in
let y = read_untagged_float64 (Bi_inbuf.from_string s) in
if x <> y then
assert false;
let ob = Bi_outbuf.create 8 in
write_untagged_float64 ob x;
if Bi_outbuf.contents ob <> s then
assert false
Could you post the result of the following code:
let x = 1.00146962706651288 in
let ob = Bi_outbuf.create 8 in
Bi_io.write_untagged_float64 ob x;
Bi_outbuf.contents ob
It should end in \003\002\001
or \x03\x02\x01
like in the original s
.
Martin - my colleague is not an OCaml developer so he's not very familiar with using the compiler, toplevel and so on.
Rafael - here is how to get the results that Martin wants. This assumes: (1) You have ocaml-findlib
installed. (2) You have ocaml-easy-format-devel
installed. (3) You have the biniou source checked out somewhere and compiled (or you've compiled it using fedpkg build
). You will have to change the path to the biniou source in the fragment below.
Step 1: Create a file called test.ml
with the content below, but modify the #directory
path to point to the location of the biniou source that you have checked out and compiled.
#use "topfind";;
#require "easy-format";;
#directory "/home/rjones/d/fedora/ocaml-biniou/master/biniou-1.0.9";;
#load "biniou.cma";;
open Printf;;
let s : string =
let x = 1.00146962706651288 in
let ob = Bi_outbuf.create 8 in
Bi_io.write_untagged_float64 ob x;
Bi_outbuf.contents ob
let () = printf "%S\n" s
Step 2: Run it using:
ocaml test.ml
The output on x86 (NOT affected by the bug) is:
"?\240\006\005\004\003\002\001"
Of course there is (maybe?) the problem that by using ocaml
you're testing the bytecode compiler, not the native code compiler. Using the native code compiler isn't too hard though:
Step 3: Remove all #
lines from the test.ml
file.
Step 4: Run these two command (again, changing the path):
ocamlfind ocamlopt -I /home/rjones/d/fedora/ocaml-biniou/master/biniou-1.0.9 -package easy-format -linkpkg biniou.cmxa test.ml -o test
./test
Richard, thank you for the explanation.
Here is the result ('le' means little endian): ppc64le: "?\240\006\005\004\003?Z" ppc64: "?\240\006\005\004\003?Z"
Martin: When analyzing this, don't discount the possibility that there could be a bug in the compiler. We are using our own non-upstream ppc64 & ppc64le backends, and while they are generally reliable, we have found bugs before.
Thanks guys. Here's a test that should tell us if the bug is in OCaml or in the biniou library:
File float_bits.ml
:
open Printf
let read_bits_from_constant () =
let expected = "3ff0060504030201" in
let result =
sprintf "%0Lx"
(Int64.bits_of_float 1.00146962706651288)
in
printf "read_bits_from_constant: %s %s\n"
result (if result = expected then "OK" else "ERROR")
let read_bits_from_string () =
let expected = "3ff0060504030201" in
let result =
sprintf "%0Lx"
(Int64.bits_of_float (float_of_string "1.00146962706651288"))
in
printf "read_bits_from_string: %s %s\n"
result (if result = expected then "OK" else "ERROR")
let main () =
read_bits_from_constant ();
read_bits_from_string ()
let () = main ()
Test the bytecode version of the program with:
ocamlc -o float_bits.run float_bits.ml
./float_bits.run
Test the native code version of the program with:
ocamlopt -o float_bits.opt float_bits.ml
./float_bits.opt
In both cases, the output should be:
read_bits_from_constant: 3ff0060504030201 OK
read_bits_from_string: 3ff0060504030201 OK
Bytecode version: read_bits_from_constant: 3ff0060504030201 OK read_bits_from_string: 3ff0060504030201 OK
Native version: read_bits_from_constant: 3ff0060504033f5a ERROR read_bits_from_string: 3ff0060504030201 OK
Thanks. That's interesting. It looks like a somewhat limited problem, which would affect folks who hardcode long constants.
As a workaround, I can modify the test in bi_io.ml
so it passes on ppc64, by reading the float from a string at runtime.
I'm gonna file a report for this bug with the OCaml bug tracker. I'll post the link here.
The bug report is at http://caml.inria.fr/mantis/view.php?id=6963 You may have to confirm the version of OCaml (I entered 4.02.3, which is the latest) or give other platform details.
Martin, thank you for debugging the issue and filling the report. I added a comment there specifying the ocaml version used. And thank you for the detailed test code.
From what I see this has been fixed in upstream by providing a compiler with ppc64 support directly.