[swift-users] Extending Arrays of specific type, and specialization
Rick Mann
rmann at latencyzero.com
Mon Nov 21 21:05:52 CST 2016
Thanks, Hooman. Is it worth posting on swift-evolution the question about specializing something like reduce(0, +) (it's complicated because it would mean specializing reduce() based on both the type and the closure passed, and that seems like something that would be difficult to specify concisely in the syntax).
> On Nov 21, 2016, at 18:29 , Hooman Mehr <hooman at mac.com> wrote:
>
> This is not possible in Swift 3.0. Swift 4.0 will improve things with conditional conformances.
>
> For now, the best solution is using global functions instead of extending types or protocols.
>
> For example you can do this now:
>
> extension Array where Element: FloatingPoint {
>
> func sum() -> Element {
> guard count > 0 else { return 0 }
> switch self[0] {
> case is Double:
> var result = Double()
> vDSP_sveD(unsafeBitCast(self, to: Array<Double>.self), 1, &result, vDSP_Length(count))
> print("vDSP")
> return unsafeBitCast(result, to: Element.self)
> case is Float:
> var result = Float()
> vDSP_sve(unsafeBitCast(self, to: Array<Float>.self), 1, &result, vDSP_Length(count))
> print("vDSP")
> return unsafeBitCast(result, to: Element.self)
> default:
> print("default")
> return reduce(0, +)
> }
> }
> }
>
> But this is not very efficient, especially if it is defined in another module, which limits optimizations.
>
> Instead, a family of overloaded global functions gives you the most coverage and best performance, at the expense of repetition and boilerplate code:
>
> func sum<S: Sequence>(_ sequence: S) -> S.Iterator.Element where S.Iterator.Element: Integer {
> var result: S.Iterator.Element = 0
> for element in sequence { result += element }
> return result
> }
>
> func sum<S: Sequence>(_ sequence: S) -> S.Iterator.Element where S.Iterator.Element: FloatingPoint {
> var result: S.Iterator.Element = 0
> for element in sequence { result += element }
> return result
> }
>
> func sum(_ array: Array<Double>) -> Double {
> var result = Double()
> vDSP_sveD(array, 1, &result, vDSP_Length(array.count))
> return result
> }
>
> func sum(_ array: ContiguousArray<Double>) -> Double {
> var result = Double()
> array.withUnsafeBufferPointer { vDSP_sveD($0.baseAddress!, 1, &result, vDSP_Length(array.count)) }
> return result
> }
>
> func sum(_ array: ArraySlice<Double>) -> Double {
> var result = Double()
> array.withUnsafeBufferPointer { vDSP_sveD($0.baseAddress!, 1, &result, vDSP_Length(array.count)) }
> return result
> }
>
> func sum(_ array: Array<Float>) -> Float {
> var result = Float()
> vDSP_sve(array, 1, &result, vDSP_Length(array.count))
> return result
> }
>
> func sum(_ array: ContiguousArray<Float>) -> Float {
> var result = Float()
> array.withUnsafeBufferPointer { vDSP_sve($0.baseAddress!, 1, &result, vDSP_Length(array.count)) }
> return result
> }
>
> func sum(_ array: ArraySlice<Float>) -> Float {
> var result = Float()
> array.withUnsafeBufferPointer { vDSP_sve($0.baseAddress!, 1, &result, vDSP_Length(array.count)) }
> return result
> }
>
> The above code covers summing any integer or floating point sequence of numbers, while being accelerated for Float and Double array types (Array, ContiguousArray and ArraySlice)
>
>
>> On Nov 21, 2016, at 4:32 PM, Rick Mann via swift-users <swift-users at swift.org> wrote:
>>
>> My googling is not turning up an answer that works in Xcode 8.1. I'd like to do this:
>>
>>
>> import Accelerate
>>
>> extension
>> Array
>> where Element == Double
>> {
>> func
>> sum()
>> -> Double
>> {
>> var result: Double = 0.0
>> vDSP_sveD(self, 1, &result, vDSP_Length(self.count))
>> return result
>> }
>> }
>>
>> But I get "same-type requirement makes generic parameter 'Element' non-generic."
>>
>> Also, will there ever be any way to specialize something like
>>
>> let numbers: [Double] = ...
>> let sum = numbers.reduce(0.0, +)
>>
>> Into a call to vDSP_sveD()? Would it require compiler optimizations for Accelerate?
>>
>> Thanks!
>>
>> --
>> Rick Mann
>> rmann at latencyzero.com
>>
>>
>> _______________________________________________
>> swift-users mailing list
>> swift-users at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users
>
--
Rick Mann
rmann at latencyzero.com
More information about the swift-users
mailing list