/** @copydoc KernelParameter::Copy */
        public override void Copy(LayerParameterBase src)
        {
            base.Copy(src);

            if (src is ConvolutionParameter)
            {
                ConvolutionParameter p = (ConvolutionParameter)src;
                m_nNumOutput = p.m_nNumOutput;
                m_bBiasTerm  = p.m_bBiasTerm;
                m_nGroup     = p.m_nGroup;

                if (p.m_fillerParam_bias != null)
                {
                    m_fillerParam_bias = p.m_fillerParam_bias.Clone();
                }

                if (p.m_fillerParam_weights != null)
                {
                    m_fillerParam_weights = p.m_fillerParam_weights.Clone();
                }

                m_nAxis                        = p.m_nAxis;
                m_bForceNDIm2Col               = p.m_bForceNDIm2Col;
                m_nCudnnWorkspaceLimit         = p.m_nCudnnWorkspaceLimit;
                m_bCudnnWorkspaceAllowOnGroups = p.m_bCudnnWorkspaceAllowOnGroups;
            }
        }
        /** @copydoc KernelParameter::Clone */
        public override LayerParameterBase Clone()
        {
            ConvolutionParameter p = new ConvolutionParameter();

            p.Copy(this);
            return(p);
        }
        /** @copydoc KernelParameter::FromProto */
        public static new ConvolutionParameter FromProto(RawProto rp)
        {
            string strVal;
            ConvolutionParameter p = new ConvolutionParameter();

            ((KernelParameter)p).Copy(KernelParameter.FromProto(rp));

            if ((strVal = rp.FindValue("num_output")) != null)
            {
                p.num_output = uint.Parse(strVal);
            }

            if ((strVal = rp.FindValue("bias_term")) != null)
            {
                p.bias_term = bool.Parse(strVal);
            }

            if ((strVal = rp.FindValue("group")) != null)
            {
                p.group = uint.Parse(strVal);
            }

            RawProto rpWeightFiller = rp.FindChild("weight_filler");

            if (rpWeightFiller != null)
            {
                p.weight_filler = FillerParameter.FromProto(rpWeightFiller);
            }

            RawProto rpBiasFiller = rp.FindChild("bias_filler");

            if (rpBiasFiller != null)
            {
                p.bias_filler = FillerParameter.FromProto(rpBiasFiller);
            }

            if ((strVal = rp.FindValue("axis")) != null)
            {
                p.axis = int.Parse(strVal);
            }

            if ((strVal = rp.FindValue("force_nd_im2col")) != null)
            {
                p.force_nd_im2col = bool.Parse(strVal);
            }

            if ((strVal = rp.FindValue("cudnn_workspace_limit")) != null)
            {
                p.cudnn_workspace_limit = int.Parse(strVal);
            }

            if ((strVal = rp.FindValue("cudnn_worspace_allow_on_groups")) != null)
            {
                p.cudnn_workspace_allow_on_groups = bool.Parse(strVal);
            }

            return(p);
        }
        /** @copydoc KernelParameter::Load */
        public override object Load(System.IO.BinaryReader br, bool bNewInstance = true)
        {
            RawProto             proto = RawProto.Parse(br.ReadString());
            ConvolutionParameter p     = FromProto(proto);

            if (!bNewInstance)
            {
                Copy(p);
            }

            return(p);
        }