The Metal Performance Shader mechanism provides support for creating custom convolutional neural networks. When creating, for example, MSPCNNConvolution
this requires the 4D weight tensor as the init
parameter, which is represented as a 1D swimming pointer.
init(device: MTLDevice, convolutionDescriptor: MPSCNNConvolutionDescriptor, kernelWeights: UnsafePointer<Float>, biasTerms: UnsafePointer<Float>?, flags: MPSCNNConvolutionFlags)
The documentation has something to say about the 4D tensor
The filter weight layout is designed so that it can be reinterpreted as a 4D tensor (array) Weight [outputChannels] [kernelHeight] [kernelWidth] [inputChannels / groups]
Unfortunately, this information does not tell me how to organize a 4D array into a one-dimensional Float
pointer.
I tried to arrange the scales as required by BNNS
, but with no luck.
How to correctly represent a 4D tensor (array) as a 1D Float
pointer (array)?
PS: I tried to organize it as an array of C and get a pointer to a flat array, but it did not work.
UPDATE
@RhythmicFistman: This is how I saved it in a simple array that I can convert to UsafePointer<Float>
(but does not work):
var output = Array<Float>(repeating: 0, count: weights.count) for o in 0..<outputChannels { for ky in 0..<kernelHeight { for kx in 0..<kernelWidth { for i in 0..<inputChannels { let offset = ((o * kernelHeight + ky) * kernelWidth + kx) * inputChannels + i output[offset] = ... } } } }
source share