Как передать массив с плавающей точкой в ​​функцию ядра металла? - PullRequest
0 голосов
/ 20 марта 2019

Я не хочу использовать texture1d_array.Могу ли я просто передать массив с плавающей точкой?Я напишу в него внутри своей функции ядра.

1 Ответ

2 голосов
/ 20 марта 2019

Чтобы записать в массив функции с плавающей точкой внутри функции ядра, вам необходимо предоставить в буфер аргумент буфера.Параметр должен иметь тип device float * и иметь атрибут buffer, указывающий, какой слот таблицы аргументов он будет занимать:

kernel void my_kernel(device float *data [[buffer(0)]],
                      uint threadIndex [[thread_position_in_grid]])
{
    data[threadIndex] = /* calculate value for this element */;
}

Чтобы создать такой буфер в коде приложения, запросите его:быть назначенным вашим устройством Metal:

let buffer = device.makeBuffer(length: MemoryLayout<Float>.stride * dataCount,
                               options: [])!

На Mac вы можете создать буфер с опцией .storageModeManaged, которая не будет автоматически синхронизировать значения, записываемые из вашего ядра, обратно в CPU-читаемая память.Вы можете использовать блитовый кодер и метод synchronize(resource:) для копирования обратно из памяти графического процессора.В iOS управляемые буферы не существуют, и синхронизация не требуется, кроме обычной (гарантируя, что вы никогда не читаете из того же места, которое пишет кто-то другой).

Когда вы будете готовы отправить своювычислите работу, привяжите буфер в качестве аргумента вашего кодировщика команд вычисления:

computeCommandEncoder.setBuffer(buffer, offset: 0, index: 0)

Отправьте любой размер сетки, который имеет смысл, чтобы выполнить работу.Кодируйте любую другую работу, которая вам может потребоваться (включая команды синхронизации), в своем буфере команд, зафиксируйте буфер команд и убедитесь, что он завершен, прежде чем пытаться прочитать содержимое буфера.

Чтобы прочитать содержимоеbuffer, приведите содержимое буфера к UnsafeMutableBufferPointer соответствующего типа, что позволяет вам обращаться с буфером так же, как с любым другим Sequence:

let data = UnsafeMutableBufferPointer<Float>(start: buffer.contents().assumingMemoryBound(to: Float.self),
                                             count:dataCount)
// iterate over elements of data or whatever...
...