I am migrating my neural network from the deprecated:
init(device: MTLDevice, convolutionDescriptor: MPSCNNConvolutionDescriptor, kernelWeights: UnsafePointer<Float>, biasTerms: UnsafePointer<Float>?, flags: MPSCNNConvolutionFlags)
to
init(device: MTLDevice, weights: MPSCNNConvolutionDataSource)
I have implemented a MPSCNNConvolutionDataSource
which is well debugged and which works for all of my layers except one. Just for testing purposes I am calling here the datasource functions myself along with the deprecated init() of MPSCNNFullyConnected
to be sure the datasource is implemented correctly. I know that this not the intended use of it, but I wanted the same data go into both MPSCNNFullyConnected() constructors. The following code runs and the NN works properly.
/* This code runs as intended */
let datasource = DataSource("test", 8, 8, 224, 1024, .reLU)
_ = datasource.load()
let layer = MPSCNNFullyConnected(device: device,
convolutionDescriptor: datasource.descriptor(),
kernelWeights: UnsafeMutablePointer<Float>(mutating: datasource.weights().assumingMemoryBound(to: Float.self)),
biasTerms: datasource.biasTerms(),
flags: .none)
When I instantiate the fully connected layer with the new init() the network fails. The following code runs but the NN does not work properly.
/* This code does run, but the layer does NOT output the correct values */
let datasource = DataSource("test", 8, 8, 224, 1024, .reLU)
let layer = MPSCNNFullyConnected(device: device, weights: datasource)
Any suggestions why both calls are not identical ?
Finally I solved it. The difference between both calls is that you have to set the layer.offset explicitly if you use:
init(device: MTLDevice, weights: MPSCNNConvolutionDataSource)
The deprecated call:
init(device: MTLDevice, convolutionDescriptor: MPSCNNConvolutionDescriptor, kernelWeights: UnsafePointer<Float>, biasTerms: UnsafePointer<Float>?, flags: MPSCNNConvolutionFlags)
seems to have done that implicitly.
This code works:
let datasource = DataSource("test", 8, 8, 224, 1024, .reLU)
let layer = MPSCNNFullyConnected(device: device, weights: datasource)
layer.offset = MPSOffset(x: 8/2, y: 8/2, z: 0)
I guess this documented nowhere ! Thanks Apple for three days hardcore debugging.