Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ibex-lib changing standard Java double behavior #3

Closed
schmittjoaopedro opened this issue Sep 29, 2020 · 5 comments
Closed

Ibex-lib changing standard Java double behavior #3

schmittjoaopedro opened this issue Sep 29, 2020 · 5 comments

Comments

@schmittjoaopedro
Copy link
Contributor

Hello,

I've noticed a strange behavior in the ibex-java integration. After installing ibex-java for linux environments (or MacOSX), the ibex.build is changing the default double behavior for Java. The following listing presentes the problem calling Math.pow operation before and after calling ibex.buid();

Ibex ibex = new Ibex(new double[]{0.000001, 0.000001});
ibex.add_ctr("{0}=acos({1})");
System.out.println(Math.pow(10, 6)); // Prints: 1000000.0
ibex.build();
System.out.println(Math.pow(10, 6)); // Prints: 1000000.0000000001

Environment

  • Java version: OpenJDK 11 x64
  • Ibex: 2.8.8
  • Docker image: maven:3.6.3-openjdk-11-slim

Steps to reproduce

In a linux server with docker, execute the following steps:

> docker run -it -p 17035:5005 maven:3.6.3-openjdk-11-slim /bin/bash
> cd /opt
> apt-get update
> apt-get install -y wget vim python flex bison gcc g++ make pkg-config
> wget https://github.com/ibex-team/ibex-lib/archive/ibex-2.8.8.tar.gz
> tar xvfz ibex-2.8.8.tar.gz
> mv ibex-lib-ibex-2.8.8/ ibex-2.8.8
> cd ibex-2.8.8
> chmod -R 777 *
> ./waf configure --lp-lib=soplex
> ./waf install
> cd plugins/
> wget https://github.com/ibex-team/ibex-java/archive/1.0.0.tar.gz
> tar xvfz 1.0.0.tar.gz
> mv ibex-java-1.0.0/ ibex-java
> cd ..
> export | grep JAVA_HOME
> ./waf configure --enable-shared --with-jni --java-package-name=org.chocosolver.solver.constraints.real
> ./waf install
> ./waf configure --enable-shared --with-jni --java-package-name=org.chocosolver.solver.constraints.real
> ./waf install
> ./waf install
> cd examples
> mkdir java
> cd java
> touch App.java
> vim App.java

Then in App.java, past the following program:

import org.chocosolver.solver.constraints.real.Ibex;

public class App {

    public static void main(String[] args) {
        Ibex ibex = new Ibex(new double[]{0.000001, 0.000001});
        ibex.add_ctr("{0}=acos({1})");

        System.out.println(Math.pow(10, 6));
        ibex.build();
        System.out.println(Math.pow(10, 6));

        double domains[] = {-10_000.0, 10_000.0, -0.6, 0.6};
        System.out.println("([" + domains[0] + "," + domains[1] + "] ; [" + domains[2] + "," + domains[3] + "])");
        int result = ibex.contract(0, domains);
        if (result == Ibex.FAIL) {
            System.out.println("Failed!");
        } else if (result == Ibex.CONTRACT) {
            System.out.println("After contract:");
            System.out.println("([" + domains[0] + "," + domains[1] + "] ; [" + domains[2] + "," + domains[3] + "])");
        } else {
            System.out.println("Nothing.");
        }
        ibex.release();
    }
}

Then compile and execute with the following commands:

> javac -cp ".:/usr/local/share/java/org.chocosolver.solver.constraints.real.jar" App.java
> export LD_LIBRARY_PATH=/usr/local/lib/
> java  -cp ".:/usr/local/share/java/org.chocosolver.solver.constraints.real.jar" App

This issue is was discovered in choco-solver (ISSUE-740)

@gchabert
Copy link

gchabert commented Sep 30, 2020

Thanks for the neat report. I think I fixed it (master branch) but there is now a little loss of efficiency we could avoid.
Indeed, Ibex (at least under Linux/MacOS) is now changing the rounding mode twice every time it is called. The best option would be to let Ibex manage the rounding mode, which would be set correctly once for all. This could be done right from the constructor.
Do you really need to have a control on the rounding mode? Or are you just annoyed by the discrepancies of the results in your example? Setting the rounding mode in the constructor would fix the latter.

@schmittjoaopedro
Copy link
Contributor Author

schmittjoaopedro commented Sep 30, 2020

Hello @gchabert,

Thanks for your reply and solution. Yes I would like to have control of the rounding mode, at least I need it to keep the sandard Java behavior. I mean it because, besides choco and ibex, I use other math libraries and I don't want this rounding propagating side effects for other calculations.
However, it could be an option for ibex configuration (like a parameter in the contructor). I don't think that I in every software it will be necessary to pay this performance price for keep the standard java rounding mode.

I'm trying to be little pragmatic here, some time ago we've discussed about the performance bottleneck related to Ibex constraints construction (link). My question is, the performance reduction is more significant than ibex constraints construction? Do you have an idea of time (in ms or us) that I will have to pay to use this rounding reset?

I've tested your changes in my environment and now it's working. If you do agree with my arguments, could you release a new version of the library? I'll feel more confortable in use something that was released.

Thanks for all,

@gchabert
Copy link

@schmittjoaopedro It is a good idea to give the choice to the user and add a parameter in the constructor. I'm integrating your suggestion and publish a new release.

I can't compare the performance loss due to the rounding mode switch compared to the constructor call. Of course, the constructor takes way more time, but it is only called once. The number of calls to contractors greatly depends on the problem.
Note that preserving the rounding mode in Ibex is actually only interesting with polynomial constraints.

Gilles

@schmittjoaopedro
Copy link
Contributor Author

schmittjoaopedro commented Sep 30, 2020

I see,

For now, I'm developing in choco-solver the necessary modifications to support this new version. I'm very anxious to solve the following issues:

Thanks to the dynamic nature of JNI, it will be possible to keep the backwards compatibility with previous versions of choco and ibex-java.

Thanks for your support @gchabert

FYI: @cprudhom

@gchabert
Copy link

gchabert commented Oct 2, 2020

This is done. See 1d6d7f5
I've made a new release (1.2.0).
Gilles

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants