Skip to content

Commit a532756

Browse files
authored
[AutoDiff] Split forward_mode.swift test into separate files. (swiftlang#33728)
Splits the large `forward_mode.swift` test file into 3 files: - `forward_mode_simple.swift` - `forward_mode_array.swift` - `forward_mode_simd.swift` This significantly speeds up testing time when tests are run in parallel.
1 parent c8cfd2c commit a532756

File tree

3 files changed

+366
-348
lines changed

3 files changed

+366
-348
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
// RUN: %target-run-simple-swift(-Xfrontend -enable-experimental-forward-mode-differentiation)
2+
// REQUIRES: executable_test
3+
4+
import StdlibUnittest
5+
import DifferentiationUnittest
6+
7+
var ForwardModeTests = TestSuite("ForwardModeDifferentiation")
8+
9+
//===----------------------------------------------------------------------===//
10+
// Array methods from ArrayDifferentiation.swift
11+
//===----------------------------------------------------------------------===//
12+
13+
typealias FloatArrayTan = Array<Float>.TangentVector
14+
15+
ForwardModeTests.test("Array.+") {
16+
func sumFirstThreeConcatenating(_ a: [Float], _ b: [Float]) -> Float {
17+
let c = a + b
18+
return c[0] + c[1] + c[2]
19+
}
20+
21+
expectEqual(3, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([1, 1]), .init([1, 1])))
22+
expectEqual(0, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([0, 0]), .init([0, 1])))
23+
expectEqual(1, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([0, 1]), .init([0, 1])))
24+
expectEqual(1, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([1, 0]), .init([0, 1])))
25+
expectEqual(1, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([0, 0]), .init([1, 1])))
26+
expectEqual(2, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([1, 1]), .init([0, 1])))
27+
28+
expectEqual(
29+
3,
30+
differential(at: [0, 0, 0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([1, 1, 1, 1]), .init([1, 1])))
31+
expectEqual(
32+
3,
33+
differential(at: [0, 0, 0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([1, 1, 1, 0]), .init([0, 0])))
34+
35+
expectEqual(
36+
3,
37+
differential(at: [], [0, 0, 0, 0], in: sumFirstThreeConcatenating)(.init([]), .init([1, 1, 1, 1])))
38+
expectEqual(
39+
0,
40+
differential(at: [], [0, 0, 0, 0], in: sumFirstThreeConcatenating)(.init([]), .init([0, 0, 0, 1])))
41+
}
42+
43+
ForwardModeTests.test("Array.init(repeating:count:)") {
44+
@differentiable
45+
func repeating(_ x: Float) -> [Float] {
46+
Array(repeating: x, count: 10)
47+
}
48+
expectEqual(Float(10), derivative(at: .zero) { x in
49+
repeating(x).differentiableReduce(0, {$0 + $1})
50+
})
51+
expectEqual(Float(20), differential(at: .zero, in: { x in
52+
repeating(x).differentiableReduce(0, {$0 + $1})
53+
})(2))
54+
}
55+
56+
ForwardModeTests.test("Array.DifferentiableView.init") {
57+
@differentiable
58+
func constructView(_ x: [Float]) -> Array<Float>.DifferentiableView {
59+
return Array<Float>.DifferentiableView(x)
60+
}
61+
62+
let forward = differential(at: [5, 6, 7, 8], in: constructView)
63+
expectEqual(
64+
FloatArrayTan([1, 2, 3, 4]),
65+
forward(FloatArrayTan([1, 2, 3, 4])))
66+
}
67+
68+
ForwardModeTests.test("Array.DifferentiableView.base") {
69+
@differentiable
70+
func accessBase(_ x: Array<Float>.DifferentiableView) -> [Float] {
71+
return x.base
72+
}
73+
74+
let forward = differential(
75+
at: Array<Float>.DifferentiableView([5, 6, 7, 8]),
76+
in: accessBase)
77+
expectEqual(
78+
FloatArrayTan([1, 2, 3, 4]),
79+
forward(FloatArrayTan([1, 2, 3, 4])))
80+
}
81+
82+
ForwardModeTests.test("Array.differentiableMap") {
83+
let x: [Float] = [1, 2, 3]
84+
let tan = Array<Float>.TangentVector([1, 1, 1])
85+
86+
func multiplyMap(_ a: [Float]) -> [Float] {
87+
return a.differentiableMap({ x in 3 * x })
88+
}
89+
expectEqual([3, 3, 3], differential(at: x, in: multiplyMap)(tan))
90+
91+
func squareMap(_ a: [Float]) -> [Float] {
92+
return a.differentiableMap({ x in x * x })
93+
}
94+
expectEqual([2, 4, 6], differential(at: x, in: squareMap)(tan))
95+
}
96+
97+
ForwardModeTests.test("Array.differentiableReduce") {
98+
let x: [Float] = [1, 2, 3]
99+
let tan = Array<Float>.TangentVector([1, 1, 1])
100+
101+
func sumReduce(_ a: [Float]) -> Float {
102+
return a.differentiableReduce(0, { $0 + $1 })
103+
}
104+
expectEqual(1 + 1 + 1, differential(at: x, in: sumReduce)(tan))
105+
106+
func productReduce(_ a: [Float]) -> Float {
107+
return a.differentiableReduce(1, { $0 * $1 })
108+
}
109+
expectEqual(x[1] * x[2] + x[0] * x[2] + x[0] * x[1], differential(at: x, in: productReduce)(tan))
110+
111+
func sumOfSquaresReduce(_ a: [Float]) -> Float {
112+
return a.differentiableReduce(0, { $0 + $1 * $1 })
113+
}
114+
expectEqual(2 * x[0] + 2 * x[1] + 2 * x[2], differential(at: x, in: sumOfSquaresReduce)(tan))
115+
}
116+
117+
runAllTests()
Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
// RUN: %target-run-simple-swift(-Xfrontend -enable-experimental-forward-mode-differentiation)
2+
// REQUIRES: executable_test
3+
4+
import StdlibUnittest
5+
import DifferentiationUnittest
6+
7+
var ForwardModeTests = TestSuite("ForwardModeDifferentiation")
8+
9+
//===----------------------------------------------------------------------===//
10+
// SIMD methods from SIMDDifferentiation.swift.gyb
11+
// Tests replicate reverse mode tests from test/AutoDiff/stdlib/simd.swift
12+
//===----------------------------------------------------------------------===//
13+
14+
ForwardModeTests.test("init(repeating:)") {
15+
func foo1(x: Float) -> SIMD4<Float> {
16+
return SIMD4<Float>(repeating: 2 * x)
17+
}
18+
let (val1, df1) = valueWithDifferential(at: 5, in: foo1)
19+
expectEqual(SIMD4<Float>(10, 10, 10, 10), val1)
20+
expectEqual(SIMD4<Float>(6, 6, 6, 6), df1(3))
21+
}
22+
23+
ForwardModeTests.test("Identity") {
24+
let a = SIMD4<Float>(1, 2, 3, 4)
25+
let g = SIMD4<Float>(1, 1, 1, 1)
26+
27+
func foo1(x: SIMD4<Float>) -> SIMD4<Float> {
28+
return x
29+
}
30+
let (val1, df1) = valueWithDifferential(at: a, in: foo1)
31+
expectEqual(a, val1)
32+
expectEqual(g, df1(.init(g)))
33+
}
34+
35+
ForwardModeTests.test("Negate") {
36+
let a = SIMD4<Float>(1, 2, 3, 4)
37+
let g = SIMD4<Float>(1, 1, 1, 1)
38+
39+
func foo1(x: SIMD4<Float>) -> SIMD4<Float> {
40+
return -x
41+
}
42+
let (val1, df1) = valueWithDifferential(at: a, in: foo1)
43+
expectEqual(-a, val1)
44+
expectEqual(-g, df1(.init(g)))
45+
}
46+
47+
ForwardModeTests.test("subscript") {
48+
let a = SIMD4<Float>(1, 2, 3, 4)
49+
50+
func foo1(x: SIMD4<Float>) -> Float {
51+
return x[3]
52+
}
53+
54+
let (val1, df1) = valueWithDifferential(at: a, in: foo1)
55+
expectEqual(4, val1)
56+
expectEqual(4, df1(a))
57+
}
58+
59+
ForwardModeTests.test("Addition") {
60+
let a = SIMD4<Float>(1, 2, 3, 4)
61+
let g = SIMD4<Float>(1, 1, 1, 1)
62+
63+
// SIMD + SIMD
64+
func foo1(x: SIMD4<Float>, y: SIMD4<Float>) -> SIMD4<Float> {
65+
return x + y
66+
}
67+
let (val1, df1) = valueWithDifferential(at: a, a, in: foo1)
68+
expectEqual(SIMD4<Float>(2, 4, 6, 8), val1)
69+
expectEqual(a + g, df1(a, g))
70+
71+
// SIMD + Scalar
72+
func foo2(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
73+
return x + y
74+
}
75+
let (val2, df2) = valueWithDifferential(at: a, 5, in: foo2)
76+
expectEqual(SIMD4<Float>(6, 7, 8, 9), val2)
77+
expectEqual(g + 1, df2(g, 1))
78+
79+
// Scalar + SIMD
80+
func foo3(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
81+
return y + x
82+
}
83+
let (val3, df3) = valueWithDifferential(at: a, 5, in: foo3)
84+
expectEqual(SIMD4<Float>(6, 7, 8, 9), val3)
85+
expectEqual(2 + g, df3(g, 2))
86+
}
87+
88+
ForwardModeTests.test("Subtraction") {
89+
let a = SIMD4<Float>(1, 2, 3, 4)
90+
let g = SIMD4<Float>(1, 1, 1, 1)
91+
92+
// SIMD - SIMD
93+
func foo1(x: SIMD4<Float>, y: SIMD4<Float>) -> SIMD4<Float> {
94+
return x - y
95+
}
96+
let (val1, df1) = valueWithDifferential(at: a, a, in: foo1)
97+
expectEqual(SIMD4<Float>(0, 0, 0, 0), val1)
98+
expectEqual(g - a, df1(g, a))
99+
100+
// SIMD - Scalar
101+
func foo2(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
102+
return x - y
103+
}
104+
let (val2, df2) = valueWithDifferential(at: a, 5, in: foo2)
105+
expectEqual(SIMD4<Float>(-4, -3, -2, -1), val2)
106+
expectEqual(g - 1, df2(g, 1))
107+
108+
// Scalar - SIMD
109+
func foo3(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
110+
return y - x
111+
}
112+
let (val3, df3) = valueWithDifferential(at: a, 5, in: foo3)
113+
expectEqual(SIMD4<Float>(4, 3, 2, 1), val3)
114+
expectEqual(2 - g, df3(g, 2))
115+
}
116+
117+
ForwardModeTests.test("Multiplication") {
118+
let a = SIMD4<Float>(1, 2, 3, 4)
119+
let a2 = SIMD4<Float>(4, 3, 2, 1)
120+
let g = SIMD4<Float>(1, 1, 1, 1)
121+
let g2 = SIMD4<Float>(0, 2, 1, 3)
122+
123+
// SIMD * SIMD
124+
func foo1(x: SIMD4<Float>, y: SIMD4<Float>) -> SIMD4<Float> {
125+
return x * y
126+
}
127+
let (val1, df1) = valueWithDifferential(at: a, a2, in: foo1)
128+
expectEqual(a * a2, val1)
129+
expectEqual(a * g2 + g * a2, df1(g, g2))
130+
131+
// SIMD * Scalar
132+
func foo2(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
133+
return x * y
134+
}
135+
let (val2, df2) = valueWithDifferential(at: a, 5, in: foo2)
136+
expectEqual(a * 5, val2)
137+
expectEqual(a * 2 + g * 5, df2(g, 2))
138+
139+
// Scalar * SIMD
140+
func foo3(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
141+
return y * x
142+
}
143+
let (val3, df3) = valueWithDifferential(at: a, 5, in: foo3)
144+
expectEqual(a * 5, val3)
145+
expectEqual(a * 3 + g * 5, df3(g, 3))
146+
}
147+
148+
ForwardModeTests.test("Division") {
149+
let a = SIMD4<Float>(1, 2, 3, 4)
150+
let g = SIMD4<Float>(1, 1, 1, 1)
151+
152+
// SIMD / SIMD
153+
func foo1(x: SIMD4<Float>, y: SIMD4<Float>) -> SIMD4<Float> {
154+
return x / y
155+
}
156+
let (val1, df1) = valueWithDifferential(at: a, a, in: foo1)
157+
expectEqual(a / a, val1)
158+
expectEqual((g * a - a * g) / (a * a)/* == 0 */, df1(g, g))
159+
160+
// SIMD / Scalar
161+
func foo2(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
162+
return x / y
163+
}
164+
let (val2, df2) = valueWithDifferential(at: a, 5, in: foo2)
165+
expectEqual(a / 5, val2)
166+
expectEqual((g * 5 - a * 2) / (5 * 5), df2(g, 2))
167+
168+
// Scalar / SIMD
169+
func foo3(x: Float, y: SIMD4<Float>) -> SIMD4<Float> {
170+
return x / y
171+
}
172+
let (val3, df3) = valueWithDifferential(at: 5, a, in: foo3)
173+
expectEqual(5 / a, val3)
174+
expectEqual((3 * a - 5 * g) / (a * a), df3(3, g))
175+
}
176+
177+
ForwardModeTests.test("Generics") {
178+
let a = SIMD3<Double>(1, 2, 3)
179+
let g = SIMD3<Double>(1, 1, 1)
180+
181+
// FIXME(SR-13210): Fix forward-mode SIL verification error.
182+
/*
183+
func testInit<Scalar, SIMDType: SIMD>(x: Scalar) -> SIMDType
184+
where SIMDType.Scalar == Scalar,
185+
SIMDType : Differentiable,
186+
Scalar : BinaryFloatingPoint & Differentiable,
187+
SIMDType.TangentVector == SIMDType,
188+
Scalar.TangentVector == Scalar {
189+
return SIMDType.init(repeating: x)
190+
}
191+
func simd3Init(x: Double) -> SIMD3<Double> { testInit(x: x) }
192+
let (val1, df1) = valueWithDifferential(at: 10, in: simd3Init)
193+
expectEqual(SIMD3<Double>(10, 10, 10), val1)
194+
expectEqual(SIMD3<Double>(5, 5, 5), df1(5))
195+
*/
196+
197+
// SIMDType + SIMDType
198+
func testAddition<Scalar, SIMDType: SIMD>(lhs: SIMDType, rhs: SIMDType)
199+
-> SIMDType
200+
where SIMDType.Scalar == Scalar,
201+
SIMDType : Differentiable,
202+
SIMDType.TangentVector : SIMD,
203+
Scalar : BinaryFloatingPoint,
204+
SIMDType.TangentVector.Scalar : BinaryFloatingPoint {
205+
return lhs + rhs
206+
}
207+
func simd3Add(lhs: SIMD3<Double>, rhs: SIMD3<Double>) -> SIMD3<Double> {
208+
return testAddition(lhs: lhs, rhs: rhs)
209+
}
210+
let (val2, df2) = valueWithDifferential(at: a, a, in: simd3Add)
211+
expectEqual(SIMD3<Double>(2, 4, 6), val2)
212+
expectEqual(g + a, df2(g, a))
213+
214+
// Scalar - SIMDType
215+
func testSubtraction<Scalar, SIMDType: SIMD>(lhs: Scalar, rhs: SIMDType)
216+
-> SIMDType
217+
where SIMDType.Scalar == Scalar,
218+
SIMDType : Differentiable,
219+
Scalar : BinaryFloatingPoint & Differentiable,
220+
SIMDType.TangentVector == SIMDType,
221+
Scalar.TangentVector == Scalar {
222+
return lhs - rhs
223+
}
224+
func simd3Subtract(lhs: Double, rhs: SIMD3<Double>) -> SIMD3<Double> {
225+
return testSubtraction(lhs: lhs, rhs: rhs)
226+
}
227+
let (val3, df3) = valueWithDifferential(at: 5, a, in: simd3Subtract)
228+
expectEqual(SIMD3<Double>(4, 3, 2), val3)
229+
expectEqual(2 - g, df3(2, g))
230+
231+
// SIMDType * Scalar
232+
func testMultipication<Scalar, SIMDType: SIMD>(lhs: SIMDType, rhs: Scalar)
233+
-> SIMDType
234+
where SIMDType.Scalar == Scalar,
235+
SIMDType : Differentiable,
236+
Scalar : BinaryFloatingPoint & Differentiable,
237+
SIMDType.TangentVector == SIMDType,
238+
Scalar.TangentVector == Scalar {
239+
return lhs * rhs
240+
}
241+
func simd3Multiply(lhs: SIMD3<Double>, rhs: Double) -> SIMD3<Double> {
242+
return testMultipication(lhs: lhs, rhs: rhs)
243+
}
244+
let (val4, df4) = valueWithDifferential(at: a, 5, in: simd3Multiply)
245+
expectEqual(SIMD3<Double>(5, 10, 15), val4)
246+
expectEqual(a * 3 + g * 5 , df4(g, 3))
247+
}
248+
249+
runAllTests()

0 commit comments

Comments
 (0)