I need to read data from a MTLBuffer
after processing on the GPU. So far I've tried following code, but it always crashes with an EXC_BAD_ACCESS
error code.
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've also tried different approaches of obtaining the 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 even a way to do this?
I've managed to fix the problem. The problem was in my wrong assumption about memory management in Swift and the fact that the function newBufferWithBytes
does only a shallow copy. Calling the function only copied the pointers to mean
, covMat
and invCovMat
arrays and self.modelBuffer.contents()
contained pointers to uninitialized memory. Accessing the memory was causing the crash.