public static SlimMPSCnnFullyConnected Create(uint kernelWidth, uint kernelHeight, uint inputFeatureChannels, uint outputFeatureChannels, MPSCnnNeuron neuronFilter, IMTLDevice device, string kernelParamsBinaryName, uint destinationFeatureChannelOffset = 0) { // get the url to this layer's weights and bias var wtPath = NSBundle.MainBundle.PathForResource($"weights_{kernelParamsBinaryName}", "dat"); var bsPath = NSBundle.MainBundle.PathForResource($"bias_{kernelParamsBinaryName}", "dat"); unsafe { using (var mmfW = MemoryMappedFile.CreateFromFile(wtPath, FileMode.Open, null, 0, MemoryMappedFileAccess.Read)) using (var mmfB = MemoryMappedFile.CreateFromFile(bsPath, FileMode.Open, null, 0, MemoryMappedFileAccess.Read)) using (var wView = mmfW.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read)) using (var bView = mmfB.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read)) { byte *w = null; wView.SafeMemoryMappedViewHandle.AcquirePointer(ref w); byte *b = null; bView.SafeMemoryMappedViewHandle.AcquirePointer(ref b); var convDesc = MPSCnnConvolutionDescriptor.GetConvolutionDescriptor( kernelWidth, kernelHeight, inputFeatureChannels, outputFeatureChannels, neuronFilter); return(new SlimMPSCnnFullyConnected(device, convDesc, (IntPtr)w, (IntPtr)b, MPSCnnConvolutionFlags.None) { DestinationFeatureChannelOffset = destinationFeatureChannelOffset }); } } }
/// <summary> /// Initializes a fully connected kernel. /// Returns: A valid SlimMPSCnnConvolution object or null, if failure. /// </summary> /// <param name="kernelWidth">Kernel Width</param> /// <param name="kernelHeight">Kernel Height</param> /// <param name="inputFeatureChannels">Number feature channels in input of this layer</param> /// <param name="outputFeatureChannels">Number feature channels from output of this layer</param> /// <param name="neuronFilter">A neuronFilter to add at the end as activation (could be null)</param> /// <param name="device">The IMTLDevice on which this SlimMPSCnnConvolution filter will be used</param> /// <param name="kernelParamsBinaryName">name of the layer to fetch kernelParameters by adding a prefix "weights_" or "bias_"</param> /// <param name="padding">Bool value whether to use padding or not</param> /// <param name="strideX">Stride of the filter</param> /// <param name="strideY">Stride of the filter</param> /// <param name="destinationFeatureChannelOffset">FeatureChannel no. in the destination MPSImage to start writing from, helps with concat operations</param> /// <param name="groupNum">if grouping is used, default value is 1 meaning no groups</param> public static SlimMPSCnnConvolution Create(uint kernelWidth, uint kernelHeight, uint inputFeatureChannels, uint outputFeatureChannels, MPSCnnNeuron neuronFilter, IMTLDevice device, string kernelParamsBinaryName, bool padding, uint strideX, uint strideY, uint destinationFeatureChannelOffset, uint groupNum) { // get the url to this layer's weights and bias var wtPath = NSBundle.MainBundle.PathForResource($"weights_{kernelParamsBinaryName}", "dat"); var bsPath = NSBundle.MainBundle.PathForResource($"bias_{kernelParamsBinaryName}", "dat"); // create appropriate convolution descriptor with appropriate stride var convDesc = MPSCnnConvolutionDescriptor.GetConvolutionDescriptor( kernelWidth, kernelHeight, inputFeatureChannels, outputFeatureChannels, neuronFilter); convDesc.StrideInPixelsX = strideX; convDesc.StrideInPixelsY = strideY; if (groupNum <= 0) { throw new ArgumentException("Group size can't be less than 1"); } convDesc.Groups = groupNum; unsafe { using (var mmfW = MemoryMappedFile.CreateFromFile(wtPath, FileMode.Open, null, 0, MemoryMappedFileAccess.Read)) using (var mmfB = MemoryMappedFile.CreateFromFile(bsPath, FileMode.Open, null, 0, MemoryMappedFileAccess.Read)) using (var wView = mmfW.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read)) using (var bView = mmfB.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read)) { byte *w = null; wView.SafeMemoryMappedViewHandle.AcquirePointer(ref w); byte *b = null; bView.SafeMemoryMappedViewHandle.AcquirePointer(ref b); return(new SlimMPSCnnConvolution(device, convDesc, (IntPtr)w, (IntPtr)b, MPSCnnConvolutionFlags.None) { DestinationFeatureChannelOffset = destinationFeatureChannelOffset, padding = padding }); } } }