Files
swift-mirror/test/AutoDiff/stdlib/floating_point.swift.gyb
Slava Pestov 4f6ba29715 AutoDiff: Disable requirement machine when building or testing Differentiation library
The SIL type lowering logic for AutoDiff gets the substituted generic signature
mixed up with the invocation generic signature, so it tries to ask questions
about DependentMemberTypes in a signature with no requirements. This triggers
assertions when the requirement machine is enabled.

Disable the requirement machine until this is fixed.
2021-07-30 19:42:31 -04:00

108 lines
4.2 KiB
Swift

// RUN: %target-run-simple-swiftgyb(-Xfrontend -enable-experimental-forward-mode-differentiation -Xfrontend -requirement-machine=off)
// REQUIRES: executable_test
#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
typealias TestLiteralType = Float80
#else
typealias TestLiteralType = Double
#endif
import _Differentiation
import StdlibUnittest
var FloatingPointDerivativeTests = TestSuite("FloatingPointDerivatives")
func expectEqualWithTolerance<T>(_ expected: TestLiteralType, _ actual: T,
ulps allowed: T = 3,
file: String = #file, line: UInt = #line
) where T: BinaryFloatingPoint {
if actual == T(expected) || actual.isNaN && expected.isNaN {
return
}
// Compute error in ulp, compare to tolerance.
let absoluteError = T(abs(TestLiteralType(actual) - expected))
let ulpError = absoluteError / T(expected).ulp
expectTrue(ulpError <= allowed,
"\(actual) != \(expected) as \(T.self)" +
"\n \(ulpError)-ulp error exceeds \(allowed)-ulp tolerance.",
file: file, line: line)
}
%for Self in ['Float', 'Double', 'Float80']:
%if Self == 'Float80':
#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
%end
FloatingPointDerivativeTests.test("${Self}.+") {
expectEqual((1, 1), gradient(at: ${Self}(4), ${Self}(5), of: +))
expectEqual((10, 10), pullback(at: ${Self}(4), ${Self}(5), of: +)(${Self}(10)))
expectEqual(2, derivative(at: ${Self}(4), ${Self}(5), of: +))
expectEqual(20, differential(at: ${Self}(4), ${Self}(5), of: +)(${Self}(10), ${Self}(10)))
}
FloatingPointDerivativeTests.test("${Self}.-") {
expectEqual((1, -1), gradient(at: ${Self}(4), ${Self}(5), of: -))
expectEqual((10, -10), pullback(at: ${Self}(4), ${Self}(5), of: -)(${Self}(10)))
expectEqual(0, derivative(at: ${Self}(4), ${Self}(5), of: -))
expectEqual(-5, differential(at: ${Self}(4), ${Self}(5), of: -)(${Self}(5), ${Self}(10)))
}
FloatingPointDerivativeTests.test("${Self}.*") {
expectEqual((5, 4), gradient(at: ${Self}(4), ${Self}(5), of: *))
expectEqual((50, 40), pullback(at: ${Self}(4), ${Self}(5), of: *)(${Self}(10)))
expectEqual(9, derivative(at: ${Self}(4), ${Self}(5), of: *))
expectEqual(90, differential(at: ${Self}(4), ${Self}(5), of: *)(${Self}(10), ${Self}(10)))
}
FloatingPointDerivativeTests.test("${Self}./") {
do {
let (dx, dy) = gradient(at: ${Self}(4), ${Self}(5), of: /)
expectEqual(0.2, dx)
expectEqual(-0.16, dy)
}
do {
let (dx, dy) = pullback(at: ${Self}(4), ${Self}(5), of: /)(${Self}(10))
expectEqual(2, dx)
expectEqualWithTolerance(-1.6, dy)
}
expectEqualWithTolerance(0.04, derivative(at: ${Self}(4), ${Self}(5), of: /))
expectEqual(90, differential(at: ${Self}(4), ${Self}(5), of: *)(${Self}(10), ${Self}(10)))
}
FloatingPointDerivativeTests.test("${Self}.squareRoot") {
expectEqual(0.5, gradient(at: 1, of: { $0.squareRoot() }))
expectEqual(0.25, gradient(at: 4, of: { $0.squareRoot() }))
}
FloatingPointDerivativeTests.test("${Self}.addingProduct") {
expectEqual((1, 2, 3), gradient(at: ${Self}(10), 3, 2, of: { $0.addingProduct($1, $2) }))
}
FloatingPointDerivativeTests.test("${Self}.minimum") {
expectEqual((1.0, 0.0), gradient(at: ${Self}(1), ${Self}(2), of: { ${Self}.minimum($0, $1) }))
expectEqual((1.0, 0.0), gradient(at: ${Self}(1), ${Self}(1), of: { ${Self}.minimum($0, $1) }))
expectEqual((0.0, 1.0), gradient(at: ${Self}(2), ${Self}(1), of: { ${Self}.minimum($0, $1) }))
expectEqual((1.0, 0.0), gradient(at: ${Self}(1), .nan, of: { ${Self}.minimum($0, $1) }))
expectEqual((0.0, 1.0), gradient(at: .nan, ${Self}(1), of: { ${Self}.minimum($0, $1) }))
}
FloatingPointDerivativeTests.test("${Self}.maximum") {
expectEqual((0.0, 1.0), gradient(at: ${Self}(1), ${Self}(2), of: { ${Self}.maximum($0, $1) }))
expectEqual((0.0, 1.0), gradient(at: ${Self}(1), ${Self}(1), of: { ${Self}.maximum($0, $1) }))
expectEqual((1.0, 0.0), gradient(at: ${Self}(2), ${Self}(1), of: { ${Self}.maximum($0, $1) }))
expectEqual((1.0, 0.0), gradient(at: ${Self}(1), .nan, of: { ${Self}.maximum($0, $1) }))
expectEqual((0.0, 1.0), gradient(at: .nan, ${Self}(1), of: { ${Self}.maximum($0, $1) }))
}
%if Self == 'Float80':
#endif
%end
%end # for Self in ['Float', 'Double', 'Float80']:
runAllTests()