Skip to content

[Embedded] Enable SIMD types in embedded Swift #70674

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

Merged
merged 3 commits into from
Jan 4, 2024
Merged
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
3 changes: 3 additions & 0 deletions stdlib/public/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,9 @@ split_embedded_sources(
if(SWIFT_STDLIB_ENABLE_VECTOR_TYPES)
list(APPEND SWIFTLIB_SOURCES SIMDVector.swift)
list(APPEND SWIFTLIB_GYB_SOURCES SIMDConcreteOperations.swift.gyb SIMDVectorTypes.swift.gyb)

list(APPEND SWIFTLIB_EMBEDDED_SOURCES SIMDVector.swift)
list(APPEND SWIFTLIB_EMBEDDED_GYB_SOURCES SIMDConcreteOperations.swift.gyb SIMDVectorTypes.swift.gyb)
endif()

list(APPEND SWIFTLIB_EMBEDDED_SOURCES
Expand Down
43 changes: 37 additions & 6 deletions stdlib/public/core/SIMDVector.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ prefix operator .!
/// conform to `SIMD`.
public protocol SIMDStorage {
/// The type of scalars in the vector space.
#if $Embedded
associatedtype Scalar: Hashable
#else
associatedtype Scalar: Codable, Hashable

#endif

/// The number of scalars, or elements, in the vector.
var scalarCount: Int { get }

Expand Down Expand Up @@ -71,6 +75,20 @@ public protocol SIMDScalar {
associatedtype SIMD64Storage: SIMDStorage where SIMD64Storage.Scalar == Self
}

#if $Embedded
/// A SIMD vector of a fixed number of elements.
public protocol SIMD<Scalar>:
SIMDStorage,
Hashable,
ExpressibleByArrayLiteral
{
/// The mask type resulting from pointwise comparisons of this vector type.
associatedtype MaskStorage: SIMD
where MaskStorage.Scalar: FixedWidthInteger & SignedInteger
}

#else

/// A SIMD vector of a fixed number of elements.
public protocol SIMD<Scalar>:
SIMDStorage,
Expand All @@ -84,6 +102,8 @@ public protocol SIMD<Scalar>:
where MaskStorage.Scalar: FixedWidthInteger & SignedInteger
}

#endif

extension SIMD {
/// The valid indices for subscripting the vector.
@_transparent
Expand Down Expand Up @@ -111,7 +131,9 @@ extension SIMD {
public func hash(into hasher: inout Hasher) {
for i in indices { hasher.combine(self[i]) }
}


#if !$Embedded

/// Encodes the scalars of this vector into the given encoder in an unkeyed
/// container.
///
Expand All @@ -125,7 +147,7 @@ extension SIMD {
try container.encode(self[i])
}
}

/// Creates a new vector by decoding scalars from the given decoder.
///
/// This initializer throws an error if reading from the decoder fails, or
Expand All @@ -147,14 +169,16 @@ extension SIMD {
self[i] = try container.decode(Scalar.self)
}
}

/// A textual description of the vector.
public var description: String {
get {
return "\(Self.self)(" + indices.map({"\(self[$0])"}).joined(separator: ", ") + ")"
}
}


#endif

/// A vector mask with the result of a pointwise equality comparison.
///
/// Equivalent to:
Expand Down Expand Up @@ -541,6 +565,7 @@ extension SIMD where Scalar: FixedWidthInteger {

/// Returns a vector with random values from within the specified range in
/// all lanes, using the given generator as a source for randomness.
@_unavailableInEmbedded
@inlinable
public static func random<T: RandomNumberGenerator>(
in range: Range<Scalar>,
Expand All @@ -555,14 +580,16 @@ extension SIMD where Scalar: FixedWidthInteger {

/// Returns a vector with random values from within the specified range in
/// all lanes.
@_unavailableInEmbedded
@inlinable
public static func random(in range: Range<Scalar>) -> Self {
var g = SystemRandomNumberGenerator()
return Self.random(in: range, using: &g)
}

/// Returns a vector with random values from within the specified range in
/// all lanes, using the given generator as a source for randomness.
@_unavailableInEmbedded
@inlinable
public static func random<T: RandomNumberGenerator>(
in range: ClosedRange<Scalar>,
Expand All @@ -577,11 +604,13 @@ extension SIMD where Scalar: FixedWidthInteger {

/// Returns a vector with random values from within the specified range in
/// all lanes.
@_unavailableInEmbedded
@inlinable
public static func random(in range: ClosedRange<Scalar>) -> Self {
var g = SystemRandomNumberGenerator()
return Self.random(in: range, using: &g)
}

}

extension SIMD where Scalar: FloatingPoint {
Expand All @@ -608,6 +637,7 @@ extension SIMD where Scalar: FloatingPoint {
}
}

@_unavailableInEmbedded
extension SIMD
where Scalar: BinaryFloatingPoint, Scalar.RawSignificand: FixedWidthInteger {
/// Returns a vector with random values from within the specified range in
Expand Down Expand Up @@ -695,6 +725,7 @@ public struct SIMDMask<Storage>: SIMD
}
}

@_unavailableInEmbedded
extension SIMDMask {
/// Returns a vector mask with `true` or `false` randomly assigned in each
/// lane, using the given generator as a source for randomness.
Expand Down
1 change: 1 addition & 0 deletions stdlib/public/core/SIMDVectorTypes.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ extension SIMD${n} where Scalar: FixedWidthInteger {
}
}

@_unavailableInEmbedded
extension SIMD${n}: CustomDebugStringConvertible {
public var debugDescription: String {
return "SIMD${n}<\(Scalar.self)>(${', '.join(map(lambda c:
Expand Down
28 changes: 28 additions & 0 deletions test/embedded/simd.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// RUN: %empty-directory(%t)

// RUN: %target-swift-frontend %s %S/Inputs/print.swift -parse-as-library -enable-experimental-feature Embedded -c -o %t/main.o
// RUN: %target-clang %t/main.o -o %t/a.out -dead_strip
// RUN: %target-run %t/a.out | %FileCheck %s

// REQUIRES: swift_in_compiler
// REQUIRES: executable_test
// REQUIRES: optimized_stdlib
// REQUIRES: OS=macosx || OS=linux-gnu

@inline(never)
public func sum(_ v: SIMD4<Float>) -> Float {
return v.x + v.y + v.z + v.w
}

@main
struct Main {
static func main() {
let v = SIMD4<Float>(1.0, 2.0, 3.0, 4.0)
guard v.sum() == sum(v) else {
fatalError()
}

// CHECK: success
print("success")
}
}