2014-12-30 3 views
3

GPU에서 처리 한 후 MTLBuffer에서 데이터를 읽어야합니다. 지금까지 다음 코드를 시도했지만 항상 오류 코드 EXC_BAD_ACCESS로 중단됩니다.스위프트의 MTLBuffer에서 데이터 읽기

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 

는 또한

var model = UnsafeMutablePointer<gauss_model>(self.modelsBuffer.contents()) 
// iterate over models with model.memory and model.successor() 

또는

var model = UnsafeMutablePointer<[gauss_model]>(self.modelBuffer.contents()) 
let models : [gauss_model] = model.memory 

같은 값을 얻는 다른 접근을 시도했지만 그들 중 누구도 일했다. 이것을 할 수있는 방법이 있습니까?

답변

0

문제를 해결할 수있었습니다. 문제는 Swift의 메모리 관리에 대한 잘못된 가정과 함수 newBufferWithBytes이 얕은 복사본 만 수행한다는 사실이었습니다. 함수를 호출하면 mean, covMatinvCovMat 배열에 포인터가 복사되고 self.modelBuffer.contents()에는 초기화되지 않은 메모리에 대한 포인터가 복사됩니다. 메모리에 액세스하면 충돌이 발생했습니다.

+2

'MTLBuffer에서 읽는 중'이 여기에서 빨리 리드하므로 실제 답변에서 작동하는 코드를 포함 할 수 있다면 좋을 것입니다. –

+0

여기에 있습니다. 나는 또한 이것을 발견했다 : http://metalkit.org/2017/04/30/working-with-memory-in-metal.html – user965972