Exemple #1
0
        public void Forward(K210UploadLayerArgument argument, ForwardContext context)
        {
            var src  = context.GetMainRamAt((int)argument.MainMemoryInputAddress);
            var dest = context.GetKpuRamAt((int)argument.KPUMemoryOutputAddress);

            K210Helper.KpuUpload(dest, src, (int)argument.Width, (int)argument.Height, (int)argument.Channels);
        }
Exemple #2
0
        public K210Conv2dLayerArgument Convert(K210Conv2d layer, ConvertContext context)
        {
            var config = new K210ConvLayerConfig {
                BNConfigs = new K210LayerBNConfig[layer.OutputChannels], ActConfigs = new K210LayerActConfig[16]
            };

            (var sw, var bw) = QuantizeWeights(layer.Conv2dType == K210Conv2dType.Conv2d, layer.Weights, config, context.WeightsBits);
            (var sx, var bx) = QuantizeInput(context.Quantization.Distributions[layer.Input.Connection.From].Global, config);
            config.ArgAdd    = (long)Math.Round(bw * bx * layer.KernelWidth * layer.KernelHeight);

            var scale = new double[layer.OutputChannels];

            for (int i = 0; i < scale.Length; i++)
            {
                scale[i] = sw[i] * sx;
            }

            QuantizeBiasAndOutput(layer, layer.Bias, context.Quantization.Distributions[layer.Output], context.Quantization.AdditionalDistributions[layer.OutputBeforeActivation], scale, config);

            config.InputChannels  = layer.InputChannels;
            config.OutputChannels = layer.OutputChannels;

            config.InputWidth  = layer.Input.Dimensions[3];
            config.InputHeight = layer.Input.Dimensions[2];
            (config.InputGroups, config.InputRowLength) = K210Helper.GetRowLayout(config.InputWidth);
            config.OutputWidth  = layer.Output.Dimensions[3];
            config.OutputHeight = layer.Output.Dimensions[2];
            (config.OutputGroups, config.OutputRowLength) = K210Helper.GetRowLayout(config.OutputWidth);

            config.KernelType  = layer.KernelWidth == 3 ? 1 : 0;
            config.IsDepthwise = layer.Conv2dType == K210Conv2dType.DepthwiseConv2d;
            config.PoolType    = (int)layer.PoolType;

            config.PadValue = (int)Math.Round(-bx);

            if (layer.Conv2dType == K210Conv2dType.Conv2d)
            {
                var kernelSize      = (int)layer.Weights.Length * context.WeightsBits / 8;
                var oneChannelSize  = layer.KernelWidth * layer.KernelHeight * layer.InputChannels * context.WeightsBits / 8;
                var sizeLimit       = context.WeightsBits == 8 ? 30 : 60;
                var oneLoadChannels = Math.Min(layer.OutputChannels, (int)Math.Floor(sizeLimit * 1024.0 / oneChannelSize));
                config.OneLoadKernelsSize   = oneChannelSize * oneLoadChannels;
                config.LoadTimes            = (int)Math.Ceiling(layer.OutputChannels / (double)oneLoadChannels);
                config.OutputChannelsOnTime = oneLoadChannels;
            }
            else
            {
                config.OneLoadKernelsSize   = (int)layer.Weights.Length * context.WeightsBits / 8;
                config.LoadTimes            = 1;
                config.OutputChannelsOnTime = layer.OutputChannels;
            }

            var inputOneLineChannels = Math.Min(layer.InputChannels, config.InputGroups);

            config.InputSize = config.InputRowLength * config.InputHeight * config.InputChannels / inputOneLineChannels;
            var outputOneLineChannels = Math.Min(layer.OutputChannels, config.OutputGroups);

            config.OutputSize = config.OutputRowLength * config.OutputHeight * config.OutputChannels / outputOneLineChannels;

            return(new K210Conv2dLayerArgument
            {
                Config = config,
                ParamAddress = new K210Conv2dParamAddress()
            });
        }