Share library calls from java and c code results are different

S

Sergio

I have the following problem; I want to call some legacy code from
java (some mathematical processing routines).

So I have prepared a java (JNI) wrapper using the swig tool and
everything went ok. I am able to call the c code from the java code
and it doesn't reports any errors, but the results are slightly
different from the same code called from C (something like 1.1e-12).

The C code is only called from the java, there isn't any parameters
passing between them and the C code writes its results to files.

This seems some kind of problem with the Virtual machine handling of
the Shared Library, I there someone that had this kind of problem?


I am using the following versions:

jvm
java version "1.4.1_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_02-b06)
Java HotSpot(TM) Client VM (build 1.4.1_02-b06, mixed mode)

gcc
gcc version 3.3 20030226 (prerelease) (SuSE Linux)

swig
SWIG Version 1.3.19
 
P

Paul Lutus

Sergio said:
I have the following problem; I want to call some legacy code from
java (some mathematical processing routines).

So I have prepared a java (JNI) wrapper using the swig tool and
everything went ok. I am able to call the c code from the java code
and it doesn't reports any errors, but the results are slightly
different from the same code called from C (something like 1.1e-12).

The C code is only called from the java, there isn't any parameters
passing between them and the C code writes its results to files.

Then change how C writes its textual results. It is possible to get perfect
repeatability in textual FP results if you will format the C code printf()
statements correctly. I regularly get perfect correspondence between
different languages using textual FP representations, and this happens to
be something that Java does without any effort, but C and C++ require, more
or less:

printf("%.18e",x);

To assure that the textual result will contain all the resolution contained
in the original binary representation. When Java scans this text form, the
original binary double is recreated perfectly, in all cases.
This seems some kind of problem with the Virtual machine handling of
the Shared Library, I there someone that had this kind of problem?

Are you not describing what I think you are? Aren't you concerned only that
the two results agree?
 
E

Eric Sosman

Sergio said:
I have the following problem; I want to call some legacy code from
java (some mathematical processing routines).

So I have prepared a java (JNI) wrapper using the swig tool and
everything went ok. I am able to call the c code from the java code
and it doesn't reports any errors, but the results are slightly
different from the same code called from C (something like 1.1e-12).
[...]

Since another responder seems to have interpreted your
question differently, I'll restate my understanding of the
situation. You have a C function or library of functions,
and you have two ways of running it: Embedded in a stand-
alone C program, or invoked from Java via JNI. When you
run it stand-alone you get a result X, but when you invoke
it from Java you get a slightly different result Y. If
that's not the correct statement of the problem, just
ignore what follows.

Software systems being what they are, there's a huge
number of possible causes. However, two occur to me as
likely candidates:

1) Does the C start-up code place the machine in the
same state Java does? I'm thinking about things like
floating-point rounding modes: Does C establish "round
toward zero" for exact-halfway quantities while Java uses
"round to even?" Or vice versa, or something along those
lines? If there are functions (probably platform-specific)
to discover things like rounding modes, it'd be instructive
to insert some code to display them at the point where the
C code starts; you could then see if they're different when
run from stand-alone C and from Java.

1a) Along the same lines: Is there a SIGFPE handler in
the picture anywhere? If so, is the SIGFPE handling set up
by the JVM different from that used by stand-alone C?

2) Maybe the C code has a bug that causes it to read
and calculate with an uninitialized variable. It's quite
possible that the "random" value of such a variable would
be different when the code runs under JNI than when it runs
stand-alone. If (1) and (1a) don't lead anywhere, it may
be time for some valgrind sessions -- I haven't used it
myself, but I'm told it's pretty good at finding such bugs.

Good luck!
 
S

Sergio

Thanks a lot for your answer. I have tried all the options but I still
have the same results:

1) Rounding Mode
I have checked the rounding mode (using the fegetround()function)
while starting the Shared library from C and from java and they given
the same result - rounding mode 0.

I have checked also the rounding environment (fegetenv()function) and
actually the rounding environment are slightly different. So I tried
to set them to the same values but I wasn't able to (my guess is that
some of the registers are internal and reflect status information).
Any way the results are the same as previous.

1a) I have checked also the SIGFPE, but this is only used to trap
exceptions related with the Floating Point Environment (so I think
that the usage of fegetenv(), fesetenv(), fegetrounf() and fesetrounf
are more apropriate to get /change the floating Point environment)

2) I checked the code against valgrind but the code is ok.

Any way if I am able to fix this I will let you know.

Ps: I still think this is a floating point rounding error!!!!

Thanks
Sérgio Amado


Eric Sosman said:
Sergio said:
I have the following problem; I want to call some legacy code from
java (some mathematical processing routines).

So I have prepared a java (JNI) wrapper using the swig tool and
everything went ok. I am able to call the c code from the java code
and it doesn't reports any errors, but the results are slightly
different from the same code called from C (something like 1.1e-12).
[...]

Since another responder seems to have interpreted your
question differently, I'll restate my understanding of the
situation. You have a C function or library of functions,
and you have two ways of running it: Embedded in a stand-
alone C program, or invoked from Java via JNI. When you
run it stand-alone you get a result X, but when you invoke
it from Java you get a slightly different result Y. If
that's not the correct statement of the problem, just
ignore what follows.

Software systems being what they are, there's a huge
number of possible causes. However, two occur to me as
likely candidates:

1) Does the C start-up code place the machine in the
same state Java does? I'm thinking about things like
floating-point rounding modes: Does C establish "round
toward zero" for exact-halfway quantities while Java uses
"round to even?" Or vice versa, or something along those
lines? If there are functions (probably platform-specific)
to discover things like rounding modes, it'd be instructive
to insert some code to display them at the point where the
C code starts; you could then see if they're different when
run from stand-alone C and from Java.

1a) Along the same lines: Is there a SIGFPE handler in
the picture anywhere? If so, is the SIGFPE handling set up
by the JVM different from that used by stand-alone C?

2) Maybe the C code has a bug that causes it to read
and calculate with an uninitialized variable. It's quite
possible that the "random" value of such a variable would
be different when the code runs under JNI than when it runs
stand-alone. If (1) and (1a) don't lead anywhere, it may
be time for some valgrind sessions -- I haven't used it
myself, but I'm told it's pretty good at finding such bugs.

Good luck!
 
S

Sergio

Thanks for your answer, but actually I think that the problem is a bit
different, I have a C code that is called from java and from C. And
this C code is responsible for writing the files in both cases (when I
call it from java or when I call it from C).
So this isn't a problem of 2 different ways of writing Floating
Points.

Thanks anyway
Sérgio Amado
 
P

Paul Lutus

Sergio said:
Thanks for your answer, but actually I think that the problem is a bit
different, I have a C code that is called from java and from C. And
this C code is responsible for writing the files in both cases (when I
call it from java or when I call it from C).
So this isn't a problem of 2 different ways of writing Floating
Points.

This problem will not be solved through your saying what the problem is not.
Can you please make a clear statement of the problem? Who gets information
from whom, and how exactly? How exactly do they differ?

I ask this because if the floating-point values are transferred completely
and correctly (by any consistent means: in binary or textual form), then
the two programs should produce exactly the same results if the outputs are
formatted correctly. And floating-point formatting is not a set of groovy
choices that languages are free to make in any number of ways. It is more
of a science whose results are adhered to strictly by all modern languages.
 
S

Sergio

I will try to better explain my problem ...

I have a function named FF() implemented in C that makes some
simulation calculations and writes the results to a file.
As you can see my function FF() doesn't receive any parameters and it
doesn't returns any result(it only writes a file).

Them I have made a wrapper to this function with swig in order to call
it from java (throught JNI).

My problem is that when I call my FF() function from java I get
different results that the ones I get if I call it from plain C(the
results files aren't equal as expected, but they present slight
differences on the reported values).

I hope this presents a clear view of the problem.

Thanks again for all your support
Sérgio Amado
 
G

Gordon Beaton

I have a function named FF() implemented in C that makes some
simulation calculations and writes the results to a file. As you can
see my function FF() doesn't receive any parameters and it doesn't
returns any result(it only writes a file).

Them I have made a wrapper to this function with swig in order to
call it from java (throught JNI).

My problem is that when I call my FF() function from java I get
different results that the ones I get if I call it from plain C(the
results files aren't equal as expected, but they present slight
differences on the reported values).

Does your function use any mathematical functions provided by the C
standard libraries, and is it not possible that the JVM executable
either provides its own or is linked with different versions of some
of these functions?

If that's the case, it could explain the behaviour you're seeing. You
could use dlsym() (if it's available on your platform) to load a
specific version of the functions for use in your function.

Do you know which of the two is the correct behaviour, or only that
they differ?

/gordon
 
P

Paul Lutus

Sergio said:
I will try to better explain my problem ...

I have a function named FF() implemented in C that makes some
simulation calculations and writes the results to a file.

You have a chance to get an accurate copy into Java only if you write a text
representation of the values. Do not try to write and read binary. See
below.
As you can see my function FF() doesn't receive any parameters and it
doesn't returns any result(it only writes a file).

Them I have made a wrapper to this function with swig in order to call
it from java (throught JNI).

My problem is that when I call my FF() function from java I get
different results that the ones I get if I call it from plain C(the
results files aren't equal as expected, but they present slight
differences on the reported values).

Then post your code. In particular, the C printing function should use:

printf("%.18e",v);

Or an equivalent, to assure an accurate textual representation of the
floating-point values, and the Java side should use an appropriate scanning
method (this is easier in Java than C). If both these steps are taken, the
binary floating point values will be *identical* in both environments,
because both languages use the same floating-point representations, and a
perfect reproduction of the original binary value is *assured* in all cases
of valid numbers if reasonable care is taken in the conversion to and from
text.
 
P

P.Hill

Paul said:
the Java side should use an appropriate scanning
method (this is easier in Java than C). If both these steps are taken, the
binary floating point values will be *identical* in both environments,
because both languages use the same floating-point representations, and a
perfect reproduction of the original binary value is *assured* in all cases
of valid numbers if reasonable care is taken in the conversion to and from
text.

As far as I can tell Sergio never said he was then recanning the value back into
Java. What he said was the C code writes a file.

Sergio, have you left out a step and you actually are rescanning the file output
back into Java? Alternatively, I was guessing you were looking at the output
with an editor and see different results depending on how it is called.

-Paul
 
S

Sergio

Yes, I'm not scanning the values again to java, I am reading it on an
hexEditor as the file is writen in a mat compliant file format.

Thanks
Sérgio
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top