FULL PRODUCT VERSION :
java version "1.6.0_12"
Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
Java HotSpot(TM) Client VM (build 11.2-b01, mixed mode, sharing)
FULL OS VERSION :
Microsoft Windows [Version 6.0.6001]
A DESCRIPTION OF THE PROBLEM :
There might be a bug in a floating point (float) arithmetic in 32-bit server HotSpot. Incorrect results appear for 2-D, single precision, not power-of-two sizes, real input, Fast Fourier Transform (http://piotr.wendykier.googlepages.com/jtransforms).
The error occurs only under the following conditions:
- Sun JVM (32-bit)
- "-server" flag
- JIT enabled
- single precision code
Here is a link to the forum, where this problem has been discussed: http://forums.sun.com/thread.jspa?threadID=5368823&tstart=0
THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No
THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Download jtransforms-2.2.jar from http://piotr.wendykier.googlepages.com/jtransforms
2. Compile the attached source code:
javac -cp jtransforms-2.3.jar AccuracyCheckFloatFFT_2D.java
3. Run the code in the client mode (there should be no error):
java -cp .;jtransforms-2.3.jar AccuracyCheckFloatFFT_2D
4. Run the code in the server mode (there should be a few errors):
java -server -cp .;jtransforms-2.3.jar AccuracyCheckFloatFFT_2D
EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected output from step 3:
Checking accuracy of 2D, single precision, real input FFTs
size = 2 x 2; OK
size = 3 x 3; OK
size = 4 x 4; OK
size = 5 x 5; OK
size = 6 x 6; OK
size = 7 x 7; OK
size = 8 x 8; OK
size = 9 x 9; OK
size = 10 x 10; OK
size = 11 x 11; OK
size = 12 x 12; OK
size = 13 x 13; OK
size = 16 x 16; OK
size = 32 x 32; OK
size = 64 x 64; OK
size = 100 x 100; OK
size = 120 x 120; OK
size = 128 x 128; OK
size = 256 x 256; OK
size = 310 x 310; OK
size = 511 x 511; OK
Expected output from step 4:
Checking accuracy of 2D, single precision, real input FFTs
size = 2 x 2; OK
size = 3 x 3; OK
size = 4 x 4; OK
size = 5 x 5; OK
size = 6 x 6; OK
size = 7 x 7; OK
size = 8 x 8; OK
size = 9 x 9; OK
size = 10 x 10; OK
size = 11 x 11; OK
size = 12 x 12; OK
size = 13 x 13; OK
size = 16 x 16; OK
size = 32 x 32; OK
size = 64 x 64; OK
size = 100 x 100; OK
size = 120 x 120; error = 0.230260
size = 128 x 128; OK
size = 256 x 256; OK
size = 310 x 310; error = 0.244690
size = 511 x 511; OK
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.Random;
import edu.emory.mathcs.jtransforms.fft.FloatFFT_2D;
import edu.emory.mathcs.utils.ConcurrencyUtils;
/**
* This is the source code that demonstrates a possible bug in Sun JVM (32-bit
* server HotSpot). To reproduce the error, 32-bit JVM has to be used with
* "-server" flag and JIT compiler enabled.
*
* @author Piotr Wendykier (###@###.###)
*
*/
public class AccuracyCheckFloatFFT_2D {
public static void main(String[] args) {
int[] sizes = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 32, 64, 100, 120, 128, 256, 310, 511 };
ConcurrencyUtils.setNumberOfThreads(1); //use only sequential code
System.out.println("Checking accuracy of 2D, single precision, real input FFTs");
for (int i = 0; i < sizes.length; i++) {
run(sizes[i], sizes[i]);
}
}
/**
* Checks the accuracy of 2D, single precision, real input FFTs
*
* @param rows
* @param columns
*/
private static void run(int rows, int columns) {
float[][] a = new float[rows][2 * columns];
Random rand = new Random(0);
for (int r = 0; r < rows; r++) {
for (int c = 0; c < columns; c++) {
a[r][c] = rand.nextFloat();
}
}
float[][] b = new float[rows][2 * columns];
for (int r = 0; r < rows; r++) {
for (int c = 0; c < columns; c++) {
b[r][2 * c] = a[r][c];
}
}
FloatFFT_2D fft = new FloatFFT_2D(rows, columns);
fft.realForwardFull(a);
fft.complexInverse(a, true);
double err = computeRMSE(a, b);
double eps = 1e-6;
if (err > eps) {
System.out.println(String.format("size = %3d x %3d; error = %f", rows, columns, err));
} else {
System.out.println(String.format("size = %3d x %3d; OK", rows, columns));
}
}
/**
* Computes the Root Mean Square Error of two arrays
*
* @param a
* @param b
* @return
*/
private static double computeRMSE(float[][] a, float[][] b) {
if (a.length != b.length || a[0].length != b[0].length) {
throw new IllegalArgumentException("Arrays are not of the same size.");
}
double rms = 0;
double tmp;
for (int r = 0; r < a.length; r++) {
for (int c = 0; c < a[0].length; c++) {
tmp = (a[r][c] - b[r][c]);
rms += tmp * tmp;
}
}
return Math.sqrt(rms / (a.length * a[0].length));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I have not found one yet.
java version "1.6.0_12"
Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
Java HotSpot(TM) Client VM (build 11.2-b01, mixed mode, sharing)
FULL OS VERSION :
Microsoft Windows [Version 6.0.6001]
A DESCRIPTION OF THE PROBLEM :
There might be a bug in a floating point (float) arithmetic in 32-bit server HotSpot. Incorrect results appear for 2-D, single precision, not power-of-two sizes, real input, Fast Fourier Transform (http://piotr.wendykier.googlepages.com/jtransforms).
The error occurs only under the following conditions:
- Sun JVM (32-bit)
- "-server" flag
- JIT enabled
- single precision code
Here is a link to the forum, where this problem has been discussed: http://forums.sun.com/thread.jspa?threadID=5368823&tstart=0
THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No
THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Download jtransforms-2.2.jar from http://piotr.wendykier.googlepages.com/jtransforms
2. Compile the attached source code:
javac -cp jtransforms-2.3.jar AccuracyCheckFloatFFT_2D.java
3. Run the code in the client mode (there should be no error):
java -cp .;jtransforms-2.3.jar AccuracyCheckFloatFFT_2D
4. Run the code in the server mode (there should be a few errors):
java -server -cp .;jtransforms-2.3.jar AccuracyCheckFloatFFT_2D
EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected output from step 3:
Checking accuracy of 2D, single precision, real input FFTs
size = 2 x 2; OK
size = 3 x 3; OK
size = 4 x 4; OK
size = 5 x 5; OK
size = 6 x 6; OK
size = 7 x 7; OK
size = 8 x 8; OK
size = 9 x 9; OK
size = 10 x 10; OK
size = 11 x 11; OK
size = 12 x 12; OK
size = 13 x 13; OK
size = 16 x 16; OK
size = 32 x 32; OK
size = 64 x 64; OK
size = 100 x 100; OK
size = 120 x 120; OK
size = 128 x 128; OK
size = 256 x 256; OK
size = 310 x 310; OK
size = 511 x 511; OK
Expected output from step 4:
Checking accuracy of 2D, single precision, real input FFTs
size = 2 x 2; OK
size = 3 x 3; OK
size = 4 x 4; OK
size = 5 x 5; OK
size = 6 x 6; OK
size = 7 x 7; OK
size = 8 x 8; OK
size = 9 x 9; OK
size = 10 x 10; OK
size = 11 x 11; OK
size = 12 x 12; OK
size = 13 x 13; OK
size = 16 x 16; OK
size = 32 x 32; OK
size = 64 x 64; OK
size = 100 x 100; OK
size = 120 x 120; error = 0.230260
size = 128 x 128; OK
size = 256 x 256; OK
size = 310 x 310; error = 0.244690
size = 511 x 511; OK
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.Random;
import edu.emory.mathcs.jtransforms.fft.FloatFFT_2D;
import edu.emory.mathcs.utils.ConcurrencyUtils;
/**
* This is the source code that demonstrates a possible bug in Sun JVM (32-bit
* server HotSpot). To reproduce the error, 32-bit JVM has to be used with
* "-server" flag and JIT compiler enabled.
*
* @author Piotr Wendykier (###@###.###)
*
*/
public class AccuracyCheckFloatFFT_2D {
public static void main(String[] args) {
int[] sizes = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 32, 64, 100, 120, 128, 256, 310, 511 };
ConcurrencyUtils.setNumberOfThreads(1); //use only sequential code
System.out.println("Checking accuracy of 2D, single precision, real input FFTs");
for (int i = 0; i < sizes.length; i++) {
run(sizes[i], sizes[i]);
}
}
/**
* Checks the accuracy of 2D, single precision, real input FFTs
*
* @param rows
* @param columns
*/
private static void run(int rows, int columns) {
float[][] a = new float[rows][2 * columns];
Random rand = new Random(0);
for (int r = 0; r < rows; r++) {
for (int c = 0; c < columns; c++) {
a[r][c] = rand.nextFloat();
}
}
float[][] b = new float[rows][2 * columns];
for (int r = 0; r < rows; r++) {
for (int c = 0; c < columns; c++) {
b[r][2 * c] = a[r][c];
}
}
FloatFFT_2D fft = new FloatFFT_2D(rows, columns);
fft.realForwardFull(a);
fft.complexInverse(a, true);
double err = computeRMSE(a, b);
double eps = 1e-6;
if (err > eps) {
System.out.println(String.format("size = %3d x %3d; error = %f", rows, columns, err));
} else {
System.out.println(String.format("size = %3d x %3d; OK", rows, columns));
}
}
/**
* Computes the Root Mean Square Error of two arrays
*
* @param a
* @param b
* @return
*/
private static double computeRMSE(float[][] a, float[][] b) {
if (a.length != b.length || a[0].length != b[0].length) {
throw new IllegalArgumentException("Arrays are not of the same size.");
}
double rms = 0;
double tmp;
for (int r = 0; r < a.length; r++) {
for (int c = 0; c < a[0].length; c++) {
tmp = (a[r][c] - b[r][c]);
rms += tmp * tmp;
}
}
return Math.sqrt(rms / (a.length * a[0].length));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I have not found one yet.
- duplicates
-
JDK-6636138 UseSuperWord enabled failure
- Closed