Skip to content

Commit

Permalink
8301833: Add wide-ranging tests for FDLIBM porting
Browse files Browse the repository at this point in the history
Reviewed-by: bpb, alanb
  • Loading branch information
jddarcy committed Feb 12, 2023
1 parent 6a44120 commit 8049e59
Showing 1 changed file with 169 additions and 0 deletions.
169 changes: 169 additions & 0 deletions test/jdk/java/lang/StrictMath/ExhaustingTests.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/*
* @test
* @bug 8301833
* @build Tests
* @build FdlibmTranslit
* @build ExhaustingTests
* @run main ExhaustingTests
* @summary Compare StrictMath.foo and FdlibmTranslit.foo for many inputs.
*/

/*
* Note on usage: for more exhaustive testing to help validate changes
* to StrictMath, the DEFAULT_SHIFT setting should be set to 0. This
* will test all float values against the unary methods. Running all
* the float values for a single method takes on the order of a minute
* or two. The default setting is a shift of 10, meaning every 1024th
* float value is tested and the overall test runs within the typical
* time expectations of a tier 1 test.
*/

import java.util.function.DoubleBinaryOperator;
import java.util.function.DoubleUnaryOperator;

public class ExhaustingTests {
public static void main(String... args) {
long failures = 0;

failures += testUnaryMethods();
failures += testBinaryMethods();

if (failures > 0) {
System.err.println("Comparing StrictMath and FdlibmTranslit"
+ " incurred " + failures + " failures.");
throw new RuntimeException();
}
}

private static final int DEFAULT_SHIFT = 10;

/**
* Test the unary (one-argument) StrictMath methods from FDLIBM.
*/
private static long testUnaryMethods() {
long failures = 0;
UnaryTestCase[] testCases = {
// new UnaryTestCase("sqrt", FdlibmTranslit::sqrt, StrictMath::sqrt, DEFAULT_SHIFT),
new UnaryTestCase("cbrt", FdlibmTranslit::cbrt, StrictMath::cbrt, DEFAULT_SHIFT),

new UnaryTestCase("log", FdlibmTranslit::log, StrictMath::log, DEFAULT_SHIFT),
new UnaryTestCase("log10", FdlibmTranslit::log10, StrictMath::log10, DEFAULT_SHIFT),
new UnaryTestCase("log1p", FdlibmTranslit::log1p, StrictMath::log1p, DEFAULT_SHIFT),

// new UnaryTestCase("exp", FdlibmTranslit::exp, StrictMath::exp, DEFAULT_SHIFT),
new UnaryTestCase("expm1", FdlibmTranslit::expm1, StrictMath::expm1, DEFAULT_SHIFT),

// new UnaryTestCase("sinh", FdlibmTranslit::sinh, StrictMath::sinh, DEFAULT_SHIFT),
// new UnaryTestCase("cosh", FdlibmTranslit::cosh, StrictMath::cosh, DEFAULT_SHIFT),
// new UnaryTestCase("tanh", FdlibmTranslit::tanh, StrictMath::tanh, DEFAULT_SHIFT),

// new UnaryTestCase("sin", FdlibmTranslit::sin, StrictMath::sin, DEFAULT_SHIFT),
// new UnaryTestCase("cos", FdlibmTranslit::cos, StrictMath::cos, DEFAULT_SHIFT),
// new UnaryTestCase("tan", FdlibmTranslit::tan, StrictMath::tan, DEFAULT_SHIFT),

// new UnaryTestCase("asin", FdlibmTranslit::asin, StrictMath::asin, DEFAULT_SHIFT),
// new UnaryTestCase("acos", FdlibmTranslit::acos, StrictMath::acos, DEFAULT_SHIFT),
// new UnaryTestCase("atan", FdlibmTranslit::atan, StrictMath::atan, DEFAULT_SHIFT),
};

for (var testCase : testCases) {
System.out.println("Testing " + testCase.name());
System.out.flush();
int i = Integer.MAX_VALUE; // overflow to Integer.MIN_VALUE at start of loop
int increment = 1 << testCase.shiftDistance;
do {
i += increment;
double input = (double)Float.intBitsToFloat(i);
failures += Tests.test(testCase.name(),
input,
testCase.strictMath,
testCase.translit.applyAsDouble(input));
} while (i != Integer.MAX_VALUE);
}
return failures;
}

private static record UnaryTestCase(String name,
DoubleUnaryOperator translit,
DoubleUnaryOperator strictMath,
int shiftDistance) {
UnaryTestCase {
if (shiftDistance < 0 || shiftDistance >= 31) {
throw new IllegalArgumentException("Shift out of range");
}
}
}

/**
* Test the binary (two-argument) StrictMath methods from FDLIBM.
*/
private static long testBinaryMethods() {
long failures = 0;
// Note: pow does _not_ have translit a port

// Shift of 16 for a binary method gives comparable running
// time to exhaustive testing of a unary method (testing every
// 2^16 floating point values over two arguments is 2^32
// probes).
BinaryTestCase[] testCases = {
new BinaryTestCase("hypot", FdlibmTranslit::hypot, StrictMath::hypot, 20, 20),
// new BinaryTestCase("atan2", FdlibmTranslit::atan2, StrictMath::atan2, 20, 20),
};

for (var testCase : testCases) {
System.out.println("Testing " + testCase.name());
System.out.flush();

int iIncrement = 1 << testCase.xShift;
int jIncrement = 1 << testCase.yShift;

for (long i = Integer.MIN_VALUE; i <= Integer.MAX_VALUE; i += iIncrement) {
for (long j = Integer.MIN_VALUE; j <= Integer.MAX_VALUE; j += jIncrement) {
double input1 = (double)Float.intBitsToFloat((int)i);
double input2 = (double)Float.intBitsToFloat((int)j);
failures += Tests.test(testCase.name(),
input1, input2,
testCase.strictMath,
testCase.translit.applyAsDouble(input1, input2));
}
}
}
return failures;
}

private static record BinaryTestCase(String name,
DoubleBinaryOperator translit,
DoubleBinaryOperator strictMath,
int xShift,
int yShift) {
BinaryTestCase {
if (xShift < 0 || xShift >= 31 ||
yShift < 0 || yShift >= 31 ) {
throw new IllegalArgumentException("Shift out of range");
}
}
}
}

1 comment on commit 8049e59

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.