mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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.
108 lines
4.2 KiB
Swift
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()
|