Skip to content

Commit 2641459

Browse files
authored
Add SIMD vector generators for Float16
1 parent 7059858 commit 2641459

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed

Sources/PropertyBased/Gen+SIMD.swift

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,35 @@ extension Gen<SIMD4<Double>> {
103103
}
104104
}
105105

106+
#if !((os(macOS) || targetEnvironment(macCatalyst)) && arch(x86_64))
107+
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
108+
extension Gen<SIMD2<Float16>> {
109+
/// A generator of vectors with length 1.
110+
public static var unitVector: Generator<SIMD2<Float16>, Shrink.None<(Float16, Float16)>> {
111+
let gen = Gen<Float16>.float16(in: 0...1)
112+
return gen.simd2.map { normalize($0) }.filter { $0.x.isFinite }.withoutShrink()
113+
}
114+
}
115+
116+
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
117+
extension Gen<SIMD3<Float16>> {
118+
/// A generator of vectors with length 1.
119+
public static var unitVector: Generator<SIMD3<Float16>, Shrink.None<(Float16, Float16, Float16)>> {
120+
let gen = Gen<Float16>.float16(in: 0...1)
121+
return gen.simd3.map { normalize($0) }.filter { $0.x.isFinite }.withoutShrink()
122+
}
123+
}
124+
125+
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
126+
extension Gen<SIMD4<Float16>> {
127+
/// A generator of vectors with length 1.
128+
public static var unitVector: Generator<SIMD4<Float16>, Shrink.None<(Float16, Float16, Float16, Float16)>> {
129+
let gen = Gen<Float16>.float16(in: 0...1)
130+
return gen.simd4.map { normalize($0) }.filter { $0.x.isFinite }.withoutShrink()
131+
}
132+
}
133+
#endif
134+
106135
#if canImport(simd)
107136
extension Gen where Value == simd_quatf {
108137
/// A generator of rotation quaternions with length 1 and a random angle.
@@ -121,6 +150,19 @@ extension Gen where Value == simd_quatd {
121150
return zip(angle, vector).map { t in simd.simd_quatd(angle: t.0, axis: t.1) }
122151
}
123152
}
153+
154+
#if !((os(macOS) || targetEnvironment(macCatalyst)) && arch(x86_64))
155+
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
156+
extension Gen where Value == simd_quath {
157+
/// A generator of rotation quaternions with length 1 and a random angle.
158+
public static var simd_quath: Generator<simd_quath, Shrink.Tuple<(Float, (Float, Float, Float))>> {
159+
return Gen<simd_quatf>.simd_quatf.map { q in
160+
simd.simd_quath(vector: simd_half4(q.vector))
161+
}
162+
}
163+
}
164+
#endif
165+
124166
#endif
125167

126168
@_disfavoredOverload

Tests/PropertyBasedTests/GenTests+SIMD.swift

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,21 @@ import simd
7474
await unitVectorCheck(Gen<SIMD4<Double>>.unitVector)
7575
}
7676

77+
#if !((os(macOS) || targetEnvironment(macCatalyst)) && arch(x86_64))
78+
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
79+
@Test func testUnitVectorHalf2() async {
80+
await unitVectorCheck(Gen<SIMD2<Float16>>.unitVector)
81+
}
82+
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
83+
@Test func testUnitVectorHalf3() async {
84+
await unitVectorCheck(Gen<SIMD3<Float16>>.unitVector)
85+
}
86+
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
87+
@Test func testUnitVectorHalf4() async {
88+
await unitVectorCheck(Gen<SIMD4<Float16>>.unitVector)
89+
}
90+
#endif
91+
7792
@Test func testVectorLength() {
7893
#expect(!length([2, 0] as SIMD2<Float>).isApproximately(1))
7994
#expect(length([3, 0] as SIMD2<Float>).isApproximately(3))
@@ -96,11 +111,23 @@ import simd
96111
#expect(quat.length.isApproximately(1))
97112
}
98113
}
114+
115+
#if !((os(macOS) || targetEnvironment(macCatalyst)) && arch(x86_64))
116+
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
117+
@Test func testQuatH() async {
118+
await testGen(Gen.simd_quath.map(\.vector))
119+
await propertyCheck(input: Gen.simd_quath) { quat in
120+
let cast = simd_quatf(vector: .init(quat.vector))
121+
#expect(cast.length.isApproximately(1))
122+
}
123+
}
124+
#endif
125+
99126
#endif
100127
}
101128

102129
extension FloatingPoint where Self: ExpressibleByFloatLiteral {
103-
func isApproximately(_ other: Self, tolerance: Self = 0.001) -> Bool {
130+
func isApproximately(_ other: Self, tolerance: Self = 0.01) -> Bool {
104131
return abs(self - other) < tolerance
105132
}
106133
}

0 commit comments

Comments
 (0)