металлическая структура данных массива MLTexture для пользовательского слоя coreML - PullRequest
0 голосов
/ 10 сентября 2018

Я запутался в массиве MLTexture для пользовательского слоя coreML.В моем mlmode входной MLTexture пользовательского слоя имеет 32 канала, а выходной - 8 каналов. Тип данных MLTexture - 16-разрядные числа с плавающей запятой или половина, поэтому входной массив texture_array состоит из 8 слайсов, а выходной - из 2 слайсов.

func encode(commandBuffer: MTLCommandBuffer, inputs: [MTLTexture], outputs: [MTLTexture]) throws {
    print(#function, inputs.count, outputs.count)
    if let encoder = commandBuffer.makeComputeCommandEncoder() {
        for i in 0..<inputs.count {
            encoder.setTexture(inputs[i], index: 0)
            encoder.setTexture(outputs[i], index: 1)
            encoder.dispatch(pipeline: psPipeline, texture: inputs[i])
            encoder.endEncoding()
        }
    }
}

В моем вычислительном ядре функция

kernel void pixelshuffle(
    texture2d_array<half, access::read> inTexture [[texture(0)]],
    texture2d_array<half, access::write> outTexture [[texture(1)]],
    ushort3 gid [[thread_position_in_grid]])
{
    if (gid.x >= inTexture.get_width() || gid.y >= inTexture.get_height()
        || gid.z>=inTexture.get_array_size()){
        return;
    }
    const half4 src = half4(inTexture.read(gid.xy, gid.z));
    //do other things
}
)

Если массив текстур ввода и вывода [C] [H] [W]] Для gid = (0,0,0), в каких каналах хранится src.rgba и каковы координаты rgba в его каналах?

- это src.r [0] [0] [0], src.g [1] [0][0], src.b [2] [0] [0], src.a [3] [0] [0]?или src.r [0] [0] [0], src.g [0] [0] [1], src.b [0] [0] [2], src.a [0] [0][3]?

А как я могу получить необработанные данные для входной текстуры в функции кодирования и распечатать ее?

1 Ответ

0 голосов
/ 10 сентября 2018

В вашем вычислительном ядре src содержит значения RGBA одного пикселя в текстуре, а каждое значение представляет собой 16-разрядное число с плавающей запятой.

Ширина текстуры соответствует W, высота текстуры - H, а срезы текстур - C, где каждый срез имеет 4 канала.

Таким образом, количество кусочков в текстуре равно C/4, а gid.z идет от 0 до floor((C + 3)/4).

(Хотя это также зависит от того, что делает ваша encoder.dispatch(pipeline:, texture:) функция, поскольку это не похоже на стандартный метод MTLComputeCommandEncoder.)

Это означает, что src.r - это первый канал в срезе, .g - это второй канал в срезе, .b - это третий канал и .a - четвертый канал в срезе. Первый фрагмент имеет каналы 0-3, второй имеет каналы 4-7 и т. Д.

Итак, ваше первое предположение правильное:

src.r [0] [0] [0], src.g [1] [0] [0], src.b [2] [0] [0], src.a [3] [0 ] [0]

Также обратите внимание, что я написал пост в блоге о пользовательских ядрах в Core ML, который может быть полезен: http://machinethink.net/blog/coreml-custom-layers/

...