Reading data from MTLBuffer in Swift
I need to read data from MTLBuffer
after processing on the GPU. So far I've tried the following code, but it always fails with an error code EXC_BAD_ACCESS
.
struct gauss_model {
var mean : [Float32] = [0.0, 0.0, 0.0];
var covMat : [[Float32]] = [[0.0, 0.0, 0.0],[0.0, 0.0, 0.0],[0.0, 0.0, 0.0]];
var invCovMat : [[Float32]] = [[0.0, 0.0, 0.0],[0.0, 0.0, 0.0],[0.0, 0.0, 0.0]];
var samples : Int32 = 0;
}
self.gaussModels = [gauss_model](count: Int(10), repeatedValue: gauss_model())
self.modelsBuffer = self.device.newBufferWithBytes(self.gaussModels, length: self.gaussModels.count * sizeof(gauss_model), options: MTLResourceOptions.OptionCPUCacheModeDefault)
commandEncoder.setBuffer(self.modelsBuffer, offset: 0, atIndex: 0)
// execute GPU code
var model = unsafeBitCast(self.modelsBuffer.contents(), UnsafeMutablePointer<gauss_model>.self)
NSLog("%@", model.memory.mean) // crashes on this statement
I have also tried different approaches for getting a value like
var model = UnsafeMutablePointer<gauss_model>(self.modelsBuffer.contents())
// iterate over models with model.memory and model.successor()
or
var model = UnsafeMutablePointer<[gauss_model]>(self.modelBuffer.contents())
let models : [gauss_model] = model.memory
but none of them worked. Is there a way to do this?
I managed to solve the problem. The problem was my wrong assumption about memory management in Swift and that the function newBufferWithBytes
only does a shallow copy. The function call only copied pointers to mean
, covMat
and invCovMat
arrays, and self.modelBuffer.contents()
contained pointers to uninitialized memory. Memory access caused a failure.