bugGNU Octave - Bugs: bug #45264, ov-java.cc-tst fails with...

 
 

bug #45264: ov-java.cc-tst fails with openjdk-7 jre 32 bit on octave 4.0.0

Submitter:  Tatsuro MATSUOKA <tmacchant>
Submitted:  Sat 06 Jun 2015 05:45:36 AM UTC
   
 
Category:  Interpreter Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Incorrect Result
Status:  Fixed Assigned to:  carandraug
Originator Name:  Open/Closed:  * Closed
Release:  * 4.0.0 Operating System:  * GNU/Linux
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Wed 10 Jun 2015 08:15:32 AM UTC, comment #13: 

I have also confirmed the fix. Great.
(under Lubuntu 14.04 32bit with openjdk-7)

Tatsuro MATSUOKA <tmacchant>
Wed 10 Jun 2015 07:16:11 AM UTC, comment #12: 

Great, it works for me, thank you Rik.

Julien Bect <jbect>
Tue 09 Jun 2015 11:13:38 PM UTC, comment #11: 

I committed the change here (http://hg.savannah.gnu.org/hgweb/octave/rev/209ee4a730f6).  This will be a part of the 4.0.1 bug release version on the stable branch.

Rik <rik5>
Group administrator
Tue 09 Jun 2015 07:16:14 PM UTC, comment #10: 

Rik, your patch looks good to me. Seems that somehow I forgot about doubles on my patch. Somehow, the code then falls through the ClassHelper where it is converted to float.

Could you please push it? Does this counts as a 4.0 regression?

I'm guessing we may have some duplicated code between our java and C++ code which I'll need to take a closer look.

Carnë Draug <carandraug>
Group Member
Mon 08 Jun 2015 07:56:57 PM UTC, comment #9: 

I've attached a diff which seems to fix the problem.  But Carnë should review since I'm not really a Java expert.

(file #34182)

Rik <rik5>
Group administrator
Mon 08 Jun 2015 07:14:33 PM UTC, comment #8: 

Actually, the bisection was off slightly.  The real changeset that introduced the bug was:


changeset:   20122:81fcf4aa9e03
user:        Carnë Draug <carandraug@octave.org>
date:        Mon Apr 20 17:40:39 2015 +0100
summary:     Automatically convert octave vectors into java primitive arrays (bug #44882)


I uncommented out the println() debugging in ClassHelper.java:castArgument and I see


expType:double[] <= type:float[]
expType:double <= type:float
expType:double <= type:float
expType:double <= type:float




Rik <rik5>
Group administrator
Mon 08 Jun 2015 06:56:31 PM UTC, comment #7: 

I did a bisection and found that the changeset that introduced the problem was:


changeset:   20120:2db2db2df55b
user:        Carnë Draug <carandraug@octave.org>
date:        Mon Apr 20 15:01:27 2015 +0100
summary:     Automatically convert arrays of java primitives into Octave types (bug #44882)


I'm adding Carnë to the CC list for this bug.  Maybe he will know why this is a problem.

Rik <rik5>
Group administrator
Mon 08 Jun 2015 04:24:32 PM UTC, comment #6: 

I have replicated the results in comment #5 on 64-bit Ubuntu (12.04 LTS) with both Octave 3.8.2 (works) and Octave 4.0.0 (fails).  Maybe it was obvious, but after creating the Myclass.java file I also needed to run 'javac Myclass.java' to create a .class file.

Just quickly glancing through the Mercurial logs, this changeset looks suspicious.


changeset:   17665:78e9bfdc544e
user:        Michael Goffioul <michael.goffioul@gmail.com>
date:        Tue Oct 15 21:43:00 2013 -0400
summary:     * scripts/java/org/octave/ClassHelper.java (castArgument): Handle conversion of float.

diff -r f4b0430fa5fd -r 78e9bfdc544e scripts/java/org/octave/ClassHelper.java
--- a/scripts/java/org/octave/ClassHelper.java  Tue Oct 15 16:33:30 2013 -0700
+++ b/scripts/java/org/octave/ClassHelper.java  Tue Oct 15 21:43:00 2013 -0400
@@ -623,6 +623,10 @@ public class ClassHelper
           {
             return new Long (((Number) obj).longValue ());
           }
+        else if (expType.equals (Float.TYPE) || expType.equals (Float.class))
+          {
+            return new Float (((Number) obj).floatValue ());
+          }
       }
     else if (isBooleanClass (expType))
       {



Rik <rik5>
Group administrator
Sun 07 Jun 2015 11:53:07 PM UTC, comment #5: 

It was actually the CastException in comment #1 that made me suspect there might be an unintended cast from double to float. The cast could lead both to the test failure and to the observed loss of precision introduced in octave 4.0.0.

Below I'll provide a minimal example to show what is described in comment #4.




Java class: myjavapackage/Myclass.java:

package myjavapackage;

/**
 * Minimal example
 */
public class Myclass {

    private double[] t;

    public Myclass(double[] t) {
        this.t = t;
    }

    /**
     * Print the array
     */
    public void list() {
        for (double entry : t) System.out.println(entry);
    }

    /**
     * Return the array
     */
    public double[] gett() {
        return t;
    }
}


Test on octave 3.8.1 (Ubuntu 32bit). Works as expected:

GNU Octave, version 3.8.1
Copyright (C) 2014 John W. Eaton and others.
This is free software; see the source code for copying conditions.
There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  For details, type 'warranty'.

Octave was configured for "i686-pc-linux-gnu".

Additional information about Octave is available at http://www.octave.org.

Please contribute if you find this software useful.
For more information, visit http://www.octave.org/get-involved.html

Read http://www.octave.org/bugs.html to learn how to submit bug reports.
For information about changes from previous versions, type 'news'.

octave:1> format long
octave:2> t = [0.123456789123456; 0.234567891234567; 0.345678912345678]
t =

   0.123456789123456
   0.234567891234567
   0.345678912345678

octave:3> javaaddpath('.')
octave:4> # Pass (double precision) vector to java
octave:4> jobj = javaObject("myjavapackage.Myclass",t);
octave:5> # See what java received
octave:5> jobj.list
0.123456789123456
0.234567891234567
0.345678912345678
ans = [](0x0)
octave:6> jobj.list
0.123456789123456
0.234567891234567
0.345678912345678
ans = [](0x0)
octave:7> # Get the vector back
octave:7> t2 = java2mat(jobj.gett)
t2 =

   0.123456789123456   0.234567891234567   0.345678912345678

octave:8>
octave:8> # t and t2 should be the same
octave:8> t2' - t
ans =

   0
   0
   0

octave:9>


Test on octave 4.0.0 (OpenSuse 34bit). Looses precision when passing double to java:

GNU Octave, version 4.0.0
Copyright (C) 2015 John W. Eaton and others.
This is free software; see the source code for copying conditions.
There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  For details, type 'warranty'.

Octave was configured for "x86_64-suse-linux-gnu".

Additional information about Octave is available at http://www.octave.org.

Please contribute if you find this software useful.
For more information, visit http://www.octave.org/get-involved.html

Read http://www.octave.org/bugs.html to learn how to submit bug reports.
For information about changes from previous versions, type 'news'.

>> format long
>> t = [0.123456789123456; 0.234567891234567; 0.345678912345678]
t =

   0.123456789123456
   0.234567891234567
   0.345678912345678

>> javaaddpath('.')
>> # Pass (double precision) vector to java
>> jobj = javaObject("myjavapackage.Myclass",t);
>> # See what java received
>> jobj.list
0.12345679104328156
0.23456789553165436
0.3456789255142212
ans = [](0x0)
>> # Get the vector back
>> t2 = jobj.gett
t2 =

   0.123456791043282
   0.234567895531654
   0.345678925514221

>>
>> # t and t2 should be the same
>> t2 - t
ans =

   1.91982554853531e-09
   4.29708735261158e-09
   1.31685432003259e-08

>>




The test shows that the precision is lost when passing the vector from octave to java.


I tried to find the changes in octave code that could cause the change. As I don't know the code base and beeing familiar with java only I had no success.
Could someone check if it is related to changeset 20122:81fcf4aa9e03 ? In the current file libinterp/octave-value/ov-java.cc at lines 1284-1308 I don't see anything about double type, might it be missing (just a random guess)?


I hope this information is useful.

Adrian V. <adrian>
Sun 07 Jun 2015 01:37:19 AM UTC, comment #4: 

Possibly only confusing, but here is a related report from Adrian from the octave-maintainer's list.

I'm not sure if the following observation concerning the java interface is related to the topic, but maybe.

When I compare results I get from calculations that are actually done by a java library (input vector passed to a java lib), then I notice that the results are numerically slightly different on different octave versions.

- Octave 3.6.1 (windows) and octave 3.8.1 (linux 64bit) give the same results.  The result is actually the same when using java only (reading in data in the java class instead of octave), so I'm convinced it is correct.

- Octave 4.0.0 (both on windows 64bit and linux 64bit) give slightly different results. The first 5 digits are the same, so for my use it is precise enough, but still a bit weird.

When I investigate, it seems that in octave 4.0.0 vectors are passed to the java class with lower precision (maybe float).

Sincerely,
Adrian

(Tested on OpenSuse 13.1 64bit, with OpenJDK 1.7.0 64bit with octave 4.0.0 x86_64 from repositoriy "science")


Rik <rik5>
Group administrator
Sat 06 Jun 2015 11:20:40 PM UTC, comment #3: 

Mike, Julien

Thank you for your test.

I have also built octave-4.0.0 using openjdk-8.


>> test ov-java.cc-tst
PASSES 5 out of 5 tests


Is this issue openjdk-7, 32 bit and ubuntu specific?

#Notes
openjdk-8 can be installed to ubuntu (on June 2015) through openjdk-r/ppa


sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-8-jdk


In some situation, you have to add configure option for octave
build.


--with-java-homedir=/usr/lib/jvm/java-8-openjdk-i386/bin \
--with-java-includedir=/usr/lib/jvm/java-8-openjdk-i386/lib \
--with-java-includedir=/usr/lib/jvm/java-8-openjdk-i386/include \



Tatsuro MATSUOKA <tmacchant>
Sat 06 Jun 2015 06:20:49 PM UTC, comment #2: 

@Tatsuro: yes, it was using openjdk-7.

I have just built again with openjdk-8 and now all tests pass.

Julien Bect <jbect>
Sat 06 Jun 2015 02:31:38 PM UTC, comment #1: 

Interesting that this error doesn't show up in the Hydra build of Octave, built against OpenJDK 7 32-bit, see full build log at

https://hydra.nixos.org/build/22885523/log/raw

Excerpts:


  Java home:                   /nix/store/141pw5w6cyipqbx7s7bh35f31f7ggz8x-openjdk-7u65b32
  Java JVM path:               /nix/store/141pw5w6cyipqbx7s7bh35f31f7ggz8x-openjdk-7u65b32/lib/openjdk/jre/lib/i386/client
  Java CPPFLAGS:               -I/nix/store/141pw5w6cyipqbx7s7bh35f31f7ggz8x-openjdk-7u65b32/include -I/nix/store/141pw5w6cyipqbx7s7bh35f31f7ggz8x-openjdk-7u65b32/include/linux
  Java libraries:
...
  libinterp/octave-value/ov-java.cc-tst ....................... PASS      5/5


Mike Miller <mtmiller>
Group Member
Sat 06 Jun 2015 05:45:36 AM UTC, original submission:  

The topic originally has been discussed at:
http://octave.1599824.n4.nabble.com/Re-ov-java-cc-tst-fails-on-Lubuntu-14-04-td4670605.html

On octave 4.0.0 build with openjdk-7 on 32 bit platform (ubuntu), ov-java.cc-tst fails:


 assert (javaMethod ("binarySearch", "java.util.Arrays", [90 100 255], 255), 2);
 assert (javaMethod ("binarySearch", "java.util.Arrays", uint8 ([90 100 255]), uint8 (255)) < 0);
 assert (javaMethod ("binarySearch", "java.util.Arrays", uint8 ([90 100 128]), uint8 (128)) < 0);
 assert (javaMethod ("binarySearch", "java.util.Arrays", uint8 ([90 100 127]), uint8 (127)), 2);
 assert (javaMethod ("binarySearch", "java.util.Arrays", uint16 ([90 100 128]), uint16 (128)), 2);
!!!!! test failed


The same fail was observed by Julien Bect with Ubuntu 14.10 / 32 bits / gcc 4.9.1. (Perhaps openjdk-7 is used.)


In the above, only the first test in in failure.


>> assert (javaMethod ("binarySearch", "java.util.Arrays", [90 100 255], 255), 2);
error: [java] java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Float
error: evaluating argument list element number 1


This error appears on octave-4.0.0 + openjdk-7 + 32 bit.
On 64 bit ubuntu with openjdk-7, on 32 bit ubuntu with openjdk-6,
this error does not occur.

The test suggested by Rik,


assert (javaMethod ("binarySearch", "java.util.Arrays",  single ([90 100 255]), single (255)), 2);


passes on octave-4.0.0 built with openjdk-7 on 32bit ubuntu.
 
Rik stated in the thread introduced at the top,

Maybe the default numeric type for a 32-bit JRE is float rather than double?  Seems odd though.  The 32-bit JRE is supposed to be about the size of references and therefore about the size of addressable
memory.

Tatsuro MATSUOKA <tmacchant>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files
file #34182:  ov-java.diff added by rik5 (777B - application/x-download)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by rik5
  • -email is unavailable- added by adrian (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by jbect (Posted a comment)
  • -email is unavailable- added by mtmiller (Posted a comment)
  • -email is unavailable- added by jbect
  • -email is unavailable- added by tmacchant (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 7 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2015-06-09 rik5 StatusConfirmed Fixed
        Open/ClosedOpen Closed
    2015-06-08 rik5 Attached File- Added ov-java.diff, #34182
    2015-06-08 rik5 Carbon-Copy- Added carandraug
    2015-06-08 rik5 Assigned toNone carandraug
    2015-06-08 rik5 StatusNone Confirmed
    2015-06-06 jbect Carbon-Copy- Added -email is unavailable-

    Back to the top

    Powered by Savane 3.13-4448.
    Corresponding source code