Skip to content

add ElementaryFunctions conformance to SIMD types #312

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 195 additions & 0 deletions Sources/RealModule/SIMD+ElementaryFunctions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
extension SIMD2: @retroactive AdditiveArithmetic where Scalar: FloatingPoint {}
extension SIMD4: @retroactive AdditiveArithmetic where Scalar: FloatingPoint {}
extension SIMD8: @retroactive AdditiveArithmetic where Scalar: FloatingPoint {}
extension SIMD16: @retroactive AdditiveArithmetic where Scalar: FloatingPoint {}
extension SIMD32: @retroactive AdditiveArithmetic where Scalar: FloatingPoint {}
extension SIMD64: @retroactive AdditiveArithmetic where Scalar: FloatingPoint {}

extension SIMD2: ElementaryFunctions where Scalar: ElementaryFunctions & FloatingPoint { }
extension SIMD4: ElementaryFunctions where Scalar: ElementaryFunctions & FloatingPoint { }
extension SIMD8: ElementaryFunctions where Scalar: ElementaryFunctions & FloatingPoint { }
extension SIMD16: ElementaryFunctions where Scalar: ElementaryFunctions & FloatingPoint { }
extension SIMD32: ElementaryFunctions where Scalar: ElementaryFunctions & FloatingPoint { }
extension SIMD64: ElementaryFunctions where Scalar: ElementaryFunctions & FloatingPoint { }

extension SIMD where Scalar: ElementaryFunctions {
@_transparent
public static func exp(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .exp(x[i])
}
return v
}

@_transparent
public static func expMinusOne(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .expMinusOne(x[i])
}
return v
}

@_transparent
public static func cosh(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .cosh(x[i])
}
return v
}

@_transparent
public static func sinh(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .sinh(x[i])
}
return v
}

@_transparent
public static func tanh(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .tanh(x[i])
}
return v
}

@_transparent
public static func cos(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .cos(x[i])
}
return v
}

@_transparent
public static func sin(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .sin(x[i])
}
return v
}

@_transparent
public static func tan(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .tan(x[i])
}
return v
}

@_transparent
public static func log(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .log(x[i])
}
return v
}

@_transparent
public static func log(onePlus x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .log(onePlus: x[i])
}
return v
}

@_transparent
public static func acosh(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .acosh(x[i])
}
return v
}

@_transparent
public static func asinh(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .asinh(x[i])
}
return v
}

@_transparent
public static func atanh(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .atanh(x[i])
}
return v
}

@_transparent
public static func acos(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .acos(x[i])
}
return v
}

@_transparent
public static func asin(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .asin(x[i])
}
return v
}

@_transparent
public static func atan(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .atan(x[i])
}
return v
}

@_transparent
public static func pow(_ x: Self, _ n: Int) -> Self {
var v = Self()
for i in v.indices {
v[i] = .pow(x[i], n)
}
return v
}

@_transparent
public static func pow(_ x: Self, _ y: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .pow(x[i], y[i])
}
return v
}

@_transparent
public static func sqrt(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .sqrt(x[i])
}
return v
}

@_transparent
public static func root(_ x: Self, _ n: Int) -> Self {
var v = Self()
for i in v.indices {
v[i] = .root(x[i], n)
}
return v
}
}
94 changes: 94 additions & 0 deletions Sources/RealModule/SIMD+RealFunctions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@

// Unfortunately we can't conform concrete simd types to `RealFunctions` as we can't implement a simd equivalent of
// `static func signGamma(_ x: Self) -> FloatingPointSign`
extension SIMD where Scalar: RealFunctions {
@_transparent
public static func atan2(y: Self, x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .atan2(y: y[i], x: x[i])
}
return v
}

@_transparent
public static func erf(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .erf(x[i])
}
return v
}

@_transparent
public static func erfc(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .erfc(x[i])
}
return v
}

@_transparent
public static func exp2(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .exp2(x[i])
}
return v
}

@_transparent
public static func exp10(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .exp10(x[i])
}
return v
}

@_transparent
public static func hypot(_ x: Self, _ y: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .hypot(x[i], y[i])
}
return v
}

@_transparent
public static func gamma(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .gamma(x[i])
}
return v
}

@_transparent
public static func log2(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .log2(x[i])
}
return v
}

@_transparent
public static func log10(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .log10(x[i])
}
return v
}

@_transparent
public static func logGamma(_ x: Self) -> Self {
var v = Self()
for i in v.indices {
v[i] = .logGamma(x[i])
}
return v
}
}