用于coreML的自定义层的MLTexture数组的金属数据结构

时间:2018-09-10 02:31:53

标签: coreml

我对coreML的自定义层的MLTexture数组感到困惑。 在我的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 :(得分:0)

在您的计算内核中,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/