Непоследовательные результаты при использовании Metal Performance Shaders между MacBook Pro и iMac - PullRequest
0 голосов
/ 02 марта 2019

Я пытаюсь впервые погрузиться в программирование на GPU.Я подумал, что начну с чего-то простого и использую готовые ядра (отсюда и MPS) и просто попытаюсь выдать команды графическому процессору.

Я пытался просто суммировать все значения от 1 до 1000Я поместил каждое значение в матрицу 1x1 и использовал сумму матрицы MPS.

На моем MacBook Pro это работает так, как я ожидаю.

На моем iMac в качестве результата выдается [0.0].Я подумал, что это связано с памятью, так как я использую iGPU на своем MacBook Pro и dGPU на своем iMac, однако, насколько я могу судить, storageModeShared не должен приводить к этому.Я даже пытался добавить .synchronize () к матрице результатов, прежде чем пытаться читать из нее, хотя я почти уверен, что в этом не должно быть необходимости с storageModeShared.

Код не элегантный, потому что он простодля быстрого понимания работы по выдаче команд с помощью MPS, и я попытался немного исправить проблемы, не отслеживая структуру, но все же это должно быть довольно легко читаемым;Если нет, дайте мне знать, и я проведу его рефакторинг.

Операторы печати предназначены только для отладки, кроме print (output)

Я ненавижу вставлять так много кода, но ябоюсь, я не могу больше изолировать свою проблему.

import Cocoa
import Quartz
import PlaygroundSupport
import MetalPerformanceShaders

let device = MTLCopyAllDevices()[0]
print(MTLCopyAllDevices())


let shaderKernel = MPSMatrixSum.init(device: device, count: 1000, rows: 1, columns: 1, transpose: false)


var matrixList: [MPSMatrix] = []
var GPUStorageBuffers: [MTLBuffer] = []
for i in 1...1000 {
    var a = Float32(i)
    var b: [Float32] = []
    let descriptor = MPSMatrixDescriptor.init(rows: 1, columns: 1, rowBytes: 4, dataType: .float32)
    b.append(a)

    let buffer = device.makeBuffer(bytes: b, length: 4, options: .storageModeShared)

    GPUStorageBuffers.append(buffer!)

    let GPUStoredMatrices = MPSMatrix.init(buffer: buffer!, descriptor: descriptor)

    matrixList.append(GPUStoredMatrices)
}

let matrices: [MPSMatrix] = matrixList

print(matrices.count)
print("\n")

print(matrices[4].debugDescription)
print("\n")
var printer: [Float32] = []
let pointer2 = matrices[4].data.contents()
let typedPointer2 = pointer2.bindMemory(to: Float32.self, capacity: 1)
let buffpoint2 = UnsafeBufferPointer(start: typedPointer2, count: 1)

buffpoint2.map({value in
    printer += [value]
})
print(printer)


let CMDQue = device.makeCommandQueue()

let CMDBuffer = CMDQue!.makeCommandBuffer()

var resultMatrix = MPSMatrix.init(device: device, descriptor: MPSMatrixDescriptor.init(rows: 1, columns: 1, rowBytes: 4, dataType: .float32))

shaderKernel.encode(to: CMDBuffer!, sourceMatrices: matrices, resultMatrix: resultMatrix, scale: nil, offsetVector: nil, biasVector: nil, start: 0)

print(CMDBuffer.debugDescription)
CMDBuffer!.commit()
print(CMDBuffer.debugDescription)
print(CMDQue.debugDescription)
let GPUStartTime = CACurrentMediaTime()
CMDBuffer!.waitUntilCompleted()

var output = [Float32]()
resultMatrix.synchronize(on: CMDBuffer!)

let pointer = resultMatrix.data.contents()
let typedPointer = pointer.bindMemory(to: Float32.self, capacity: 1)
let buffpoint = UnsafeBufferPointer(start: typedPointer, count: 1)

buffpoint.map({value in
    output += [value]
})
print(output)
let finish = GPUStartTime - CACurrentMediaTime()
print("\n")
print(finish)
...