Skip to content

Instantly share code, notes, and snippets.

@laevandus
Last active November 2, 2017 18:25
Show Gist options
  • Save laevandus/6c0d55047890532aacb822e52bce3a12 to your computer and use it in GitHub Desktop.
Save laevandus/6c0d55047890532aacb822e52bce3a12 to your computer and use it in GitHub Desktop.
Running Metal compute kernel.
func process(data: ContiguousArray<Float>) -> ContiguousArray<Float>
{
let dataBuffer = data.withUnsafeBytes { (bufferPointer) -> MTLBuffer? in
guard let baseAddress = bufferPointer.baseAddress else { return nil }
return device.makeBuffer(bytes: baseAddress, length: bufferPointer.count, options: .storageModeShared)
}
guard let inputBuffer = dataBuffer else { return [] }
guard let outputBuffer = device.makeBuffer(length: inputBuffer.length, options: .storageModeShared) else { return [] }
guard let commandBuffer = commandQueue.makeCommandBuffer() else { return [] }
guard let commandEncoder = commandBuffer.makeComputeCommandEncoder() else { return [] }
commandEncoder.setComputePipelineState(computePipelineState)
commandEncoder.setBuffer(inputBuffer, offset: 0, index: 0)
commandEncoder.setBuffer(outputBuffer, offset: 0, index: 1)
let threadsPerThreadgroup = MTLSize(width: 10, height: 1, depth: 1)
let threadgroupsPerGrid = MTLSize(width: data.count / threadsPerThreadgroup.width, height: threadsPerThreadgroup.height, depth: threadsPerThreadgroup.depth)
commandEncoder.dispatchThreadgroups(threadgroupsPerGrid, threadsPerThreadgroup: threadsPerThreadgroup)
commandEncoder.endEncoding()
commandBuffer.commit()
commandBuffer.waitUntilCompleted()
let outputPointer = outputBuffer.contents().assumingMemoryBound(to: Float.self)
let outputDataBufferPointer = UnsafeBufferPointer<Float>(start: outputPointer, count: data.count)
return ContiguousArray<Float>(outputDataBufferPointer)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment