Conforming to AccelerateBuffer

Hello,

I'd like to perform some math on a fairly large number of CGPoint instances stored in an array so I thought I'd look into using Accelerate and start by conforming CGPoint to AccelerateBuffer, followed by extending Array to conform as well.

My problem is that I don't understand what to do with the requirement

Code Block Swiftpublic func withUnsafeBufferPointer<R>(_ body: (UnsafeBufferPointer<CGFloat>) throws -> R) rethrows -> R

How am I supposed to implement this? Are there any code examples somewhere that I can look into?

Many thanks.
Answered by oro_boris in 622509022
Follow-up...

After some more digging, and reading, and trial and error, I managed to get the implementation below, which I think is correct. However, now Xcode gives me a vDSP error that I don't understand, since CGPoint is now conforming to the types that vDSP expects its arguments and return values to have. What am I doing incorrectly?

(The code below is in a Playground)

Code Block swiftimport Foundationimport CoreGraphicsimport Accelerateextension CGPoint: AccelerateMutableBuffer {    public var count: Int { 2 }    public func withUnsafeBufferPointer<R>(			_ body: (UnsafeBufferPointer<CGFloat>) throws -> R		) rethrows -> R {        var varself = self        let ubp = withUnsafeBytes(of: &varself) { urbp in            urbp.bindMemory(to: CGFloat.self)        }        return try body(ubp)    }    public mutating func withUnsafeMutableBufferPointer<R>(			_ body: (inout UnsafeMutableBufferPointer<CGFloat>) throws -> R		) rethrows -> R {        var varself = self        var ubp = withUnsafeMutableBytes(of: &varself) { urbp in            urbp.bindMemory(to: CGFloat.self)        }        return try body(&ubp)    }}let p1 = CGPoint(x: 1.5, y: -3.5)let p2 = CGPoint(x: -0.5, y: 2.5)var p: CGPoint = .zerovDSP.add(p1, p2, result: &p)	// Error: "No exact matches in call to static method 'add(_:_:result:)'"p


Accepted Answer
Follow-up...

After some more digging, and reading, and trial and error, I managed to get the implementation below, which I think is correct. However, now Xcode gives me a vDSP error that I don't understand, since CGPoint is now conforming to the types that vDSP expects its arguments and return values to have. What am I doing incorrectly?

(The code below is in a Playground)

Code Block swiftimport Foundationimport CoreGraphicsimport Accelerateextension CGPoint: AccelerateMutableBuffer {    public var count: Int { 2 }    public func withUnsafeBufferPointer<R>(			_ body: (UnsafeBufferPointer<CGFloat>) throws -> R		) rethrows -> R {        var varself = self        let ubp = withUnsafeBytes(of: &varself) { urbp in            urbp.bindMemory(to: CGFloat.self)        }        return try body(ubp)    }    public mutating func withUnsafeMutableBufferPointer<R>(			_ body: (inout UnsafeMutableBufferPointer<CGFloat>) throws -> R		) rethrows -> R {        var varself = self        var ubp = withUnsafeMutableBytes(of: &varself) { urbp in            urbp.bindMemory(to: CGFloat.self)        }        return try body(&ubp)    }}let p1 = CGPoint(x: 1.5, y: -3.5)let p2 = CGPoint(x: -0.5, y: 2.5)var p: CGPoint = .zerovDSP.add(p1, p2, result: &p)	// Error: "No exact matches in call to static method 'add(_:_:result:)'"p


Doh! 🤦🏻‍♂️ I accidentally clicked on that checkmark button and now I can't uncheck it. This question is not yet resolved!
I understand the error message now. The Element type of the type conforming to Accelerate[Mutable]Buffer must be a Double. I can live with that since CGFloat is a Double on a 64-bit platform. Still, vDSP is not returning the correct result. Again, what am I doing incorrectly?

Many thanks.

Code Block swiftimport Foundationimport CoreGraphicsimport Accelerateextension CGPoint: AccelerateMutableBuffer {    public typealias Element = Double    public var count: Int { 2 }    public func withUnsafeBufferPointer <R> (        _ body: (UnsafeBufferPointer<Element>) throws -> R    ) rethrows -> R {        var varself = self        let ubp = withUnsafeBytes(of: &varself) { urbp in            urbp.bindMemory(to: Element.self)        }        return try body(ubp)    }    public mutating func withUnsafeMutableBufferPointer <R> (        _ body: (inout UnsafeMutableBufferPointer<Element>) throws -> R    ) rethrows -> R {        var varself = self        var umbp = withUnsafeMutableBytes(of: &varself) { umrbp in            umrbp.bindMemory(to: Element.self)        }        return try body(&umbp)    }}let p1 = CGPoint(x: 1.5, y: 3.5)let p2 = CGPoint(x: 0.5, y: 2.5)var p: CGPoint = .zerovDSP.add(p1, p2, result: &p)p	 //	result is (0.0, 0.0), not the expected (2.0, 6.0)


Edit: I've since figured it out. Here's the correct solution, as far as I know. It compiles without errors, runs without problems, and gives the correct result. So, unless someone sees a problem I'm not seeing, I'm now happy to consider this question resolved.

The problem with the previous implementation is on line 23: by creating a local mutable copy of self and operating on *that*, self itself doesn't get changed.

Code Block swiftimport Foundationimport CoreGraphicsimport Accelerateextension CGPoint: AccelerateMutableBuffer {		public typealias Element = Double		public var count: Int { 2 }		public func withUnsafeBufferPointer<R>(_ body: (UnsafeBufferPointer<Double>) throws -> R) rethrows -> R {				try Swift.withUnsafeBytes(of: self) { urbp in						try body(urbp.bindMemory(to: Double.self))				}		}		public mutating func withUnsafeMutableBufferPointer <R> (				_ body: (inout UnsafeMutableBufferPointer<Double>) throws -> R		) rethrows -> R {				try Swift.withUnsafeMutableBytes(of: &self) { umrbp in						var umbp = umrbp.bindMemory(to: Double.self)						return try body(&umbp)				}		}}let p1 = CGPoint(x: 1.5, y: 3.5)let p2 = CGPoint(x: 0.5, y: 2.5)var p: CGPoint = .zerovDSP.add(p1, p2, result: &p)p // (x: 2, y: 6)	✅

Conforming to AccelerateBuffer
 
 
Q