That sounds interesting. Would you mind making that pitch on swift-evolution? I just barely understood what you said :/
> On Nov 22, 2016, at 07:46 , Hooman Mehr <hoo...@mac.com> wrote: > > It is good to know that > > extension Array where Element == Double { } > > will work pretty soon with Swift 3.1. > > Back to reduce(0,+): > > If we get specialized instance for a reduce(0,+), so that it is known that > “+” is a (Double, Double)->Double function, LLVM’s auto-vectorization should > be able to optimize it for the CPU’s vector unit. In theory, it should be > possible to add additional optimizers to LLVM layer to use other hardware or > numeric libraries for that purpose, but I don’t think it would be a > Swift-specific thing. > > Swift’s generics still has a long way to go. Since they are aiming for ABI > stability by Swift 4.0, and there isn’t much time left, I don’t think many of > the bigger generics improvements fit with the current Swift evolution > discussions, although they could have huge impact on standard library (hence > the ABI stability). > > One thing that might be worth discussing on Swift evolution and can > potentially make it to standard library and Swift 4.0 is adding a common > protocol for array-like types that have (or can have) contiguous buffers so > that manually vectorizing operations on their elements becomes easier and > cleaner. > > At the moment, we can manually define a protocol that extends > RandomAccessCollection and provides `withUnsafeBufferPointer` and then > declare the conformance of all of the standard library array variants to it > so that we can provide a single generic sum global function for summing all > of them using vDSP. This protocol may be worth adding to the standard library. > >> On Nov 21, 2016, at 7:05 PM, Rick Mann <rm...@latencyzero.com> wrote: >> >> 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 <hoo...@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@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 >>>> rm...@latencyzero.com >>>> >>>> >>>> _______________________________________________ >>>> swift-users mailing list >>>> swift-users@swift.org >>>> https://lists.swift.org/mailman/listinfo/swift-users >>> >> >> >> -- >> Rick Mann >> rm...@latencyzero.com >> >> > -- Rick Mann rm...@latencyzero.com _______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users