Exemple #1
0
        public static QuaternionMap1D Reference(QuaternionMap1D x, QuaternionFilter1D w, int kwidth, int stride)
        {
            int inchannels = x.Channels, outchannels = w.OutChannels, batch = x.Batch;
            int inw = x.Width, outw = (inw - kwidth) / stride + 1;

            QuaternionMap1D y = new QuaternionMap1D(outchannels, outw, batch);

            for (int kx = 0; kx < kwidth; kx++)
            {
                for (int th = 0; th < batch; th++)
                {
                    for (int ox = 0; ox < outw; ox++)
                    {
                        for (int outch = 0; outch < outchannels; outch++)
                        {
                            Quaternion sum = y[outch, ox, th];

                            for (int inch = 0; inch < inchannels; inch++)
                            {
                                sum += x[inch, kx + ox * stride, th] * w[inch, outch, kx];
                            }

                            y[outch, ox, th] = sum;
                        }
                    }
                }
            }

            return(y);
        }
        public static QuaternionMap1D Reference(QuaternionMap1D y, QuaternionFilter1D w, int inw, int kwidth, int stride)
        {
            int inchannels = w.InChannels, outchannels = w.OutChannels, batch = y.Batch;
            int outw = (inw - kwidth) / stride + 1;

            if (y.Width != outw)
            {
                throw new ArgumentException("mismatch shape");
            }

            QuaternionMap1D x = new QuaternionMap1D(inchannels, inw, batch);

            for (int kx = 0; kx < kwidth; kx++)
            {
                for (int th = 0; th < batch; th++)
                {
                    for (int ox = 0; ox < outw; ox++)
                    {
                        for (int outch = 0; outch < outchannels; outch++)
                        {
                            Quaternion v = y[outch, ox, th];

                            for (int inch = 0; inch < inchannels; inch++)
                            {
                                x[inch, kx + ox * stride, th] += v * w[inch, outch, kx];
                            }
                        }
                    }
                }
            }

            return(x);
        }
        public static QuaternionFilter1D Reference(QuaternionMap1D x, QuaternionMap1D gy, int kwidth, int stride)
        {
            int inchannels = x.Channels, outchannels = gy.Channels, batch = x.Batch;
            int inw = x.Width, outw = gy.Width;

            if (outw != (inw - kwidth) / stride + 1)
            {
                throw new ArgumentException("mismatch shape");
            }

            QuaternionFilter1D w = new QuaternionFilter1D(inchannels, outchannels, kwidth);

            for (int kx = 0; kx < kwidth; kx++)
            {
                for (int th = 0; th < batch; th++)
                {
                    for (int inch, outch = 0; outch < outchannels; outch++)
                    {
                        for (inch = 0; inch < inchannels; inch++)
                        {
                            Quaternion sum = 0;

                            for (int ix = kx, ox = 0; ox < outw; ix += stride, ox++)
                            {
                                sum += Quaternion.MulGrad(gy[outch, ox, th], x[inch, ix, th]);
                            }

                            w[inch, outch, kx] += sum;
                        }
                    }
                }
            }

            return(w);
        }
Exemple #4
0
        public void ExecuteTest()
        {
            float max_err = 0;

            foreach (int batch in new int[] { 1, 2, 3 })
            {
                foreach (int inchannels in new int[] { 4, 8, 12 })
                {
                    foreach (int outchannels in new int[] { 4, 8, 12 })
                    {
                        foreach (int kwidth in new int[] { 1, 3, 5 })
                        {
                            foreach (int stride in new int[] { 1, 2, 3 })
                            {
                                foreach (int inwidth in new int[] { 8, 9, 13, 17 })
                                {
                                    int outwidth = (inwidth - kwidth) / stride + 1;

                                    float[] xval = (new float[inwidth * inchannels * batch]).Select((_, idx) => idx * 1e-3f).ToArray();
                                    float[] wval = (new float[kwidth * inchannels * outchannels / 4]).Select((_, idx) => idx * 1e-3f).Reverse().ToArray();

                                    Quaternion[] xcval = (new Quaternion[xval.Length / 4])
                                                         .Select((_, idx) => new Quaternion(xval[idx * 4], xval[idx * 4 + 1], xval[idx * 4 + 2], xval[idx * 4 + 3])).ToArray();

                                    Quaternion[] wcval = (new Quaternion[wval.Length / 4])
                                                         .Select((_, idx) => new Quaternion(wval[idx * 4], wval[idx * 4 + 1], wval[idx * 4 + 2], wval[idx * 4 + 3])).ToArray();

                                    QuaternionMap1D    x = new QuaternionMap1D(inchannels / 4, inwidth, batch, xcval);
                                    QuaternionFilter1D w = new QuaternionFilter1D(inchannels / 4, outchannels / 4, kwidth, wcval);

                                    QuaternionMap1D y = Reference(x, w, kwidth, stride);

                                    OverflowCheckedTensor x_tensor = new OverflowCheckedTensor(Shape.Map1D(inchannels, inwidth, batch), xval);
                                    OverflowCheckedTensor w_tensor = new OverflowCheckedTensor(Shape.Kernel1D(inchannels, outchannels / 4, kwidth), wval);

                                    OverflowCheckedTensor y_tensor = new OverflowCheckedTensor(Shape.Map1D(outchannels, outwidth, batch));

                                    QuaternionConvolution1D ope = new QuaternionConvolution1D(inwidth, inchannels, outchannels, kwidth, stride, gradmode: false, batch);

                                    ope.Execute(x_tensor, w_tensor, y_tensor);

                                    float[] y_expect = y.ToArray();
                                    float[] y_actual = y_tensor.State;

                                    CollectionAssert.AreEqual(xval, x_tensor.State);
                                    CollectionAssert.AreEqual(wval, w_tensor.State);

                                    AssertError.Tolerance(y_expect, y_actual, 1e-7f, 1e-5f, ref max_err, $"mismatch value {inchannels},{outchannels},{kwidth},{stride},{inwidth},{batch}");

                                    Console.WriteLine($"pass: {inchannels},{outchannels},{kwidth},{stride},{inwidth},{batch}");
                                }
                            }
                        }
                    }
                }
            }

            Console.WriteLine($"maxerr:{max_err}");
        }
Exemple #5
0
        public void OverflowTest()
        {
            foreach (bool gradmode in new bool[] { false, true })
            {
                foreach (int batch in new int[] { 1, 2, 3 })
                {
                    foreach (int inchannels in new int[] { 4, 8, 12 })
                    {
                        foreach (int outchannels in new int[] { 4, 8, 12 })
                        {
                            foreach (int kwidth in new int[] { 1, 3, 5 })
                            {
                                foreach (int stride in new int[] { 1, 2, 3 })
                                {
                                    foreach (int inwidth in new int[] { 8, 9, 13, 17 })
                                    {
                                        int outwidth = (inwidth - kwidth) / stride + 1;

                                        float[] xval = (new float[inwidth * inchannels * batch]).Select((_, idx) => idx * 1e-3f).ToArray();
                                        float[] wval = (new float[kwidth * inchannels * outchannels / 4]).Select((_, idx) => idx * 1e-3f).Reverse().ToArray();

                                        Quaternion[] xcval = (new Quaternion[xval.Length / 4])
                                                             .Select((_, idx) => new Quaternion(xval[idx * 4], xval[idx * 4 + 1], xval[idx * 4 + 2], xval[idx * 4 + 3])).ToArray();

                                        Quaternion[] wcval = (new Quaternion[wval.Length / 4])
                                                             .Select((_, idx) => new Quaternion(wval[idx * 4], wval[idx * 4 + 1], wval[idx * 4 + 2], wval[idx * 4 + 3])).ToArray();

                                        QuaternionMap1D    x = new QuaternionMap1D(inchannels / 4, inwidth, batch, xcval);
                                        QuaternionFilter1D w = new QuaternionFilter1D(inchannels / 4, outchannels / 4, kwidth, wcval);

                                        QuaternionMap1D y = Reference(x, w, kwidth, stride);

                                        OverflowCheckedTensor x_tensor = new OverflowCheckedTensor(Shape.Map1D(inchannels, inwidth, batch), xval);
                                        OverflowCheckedTensor w_tensor = new OverflowCheckedTensor(Shape.Kernel1D(inchannels, outchannels / 4, kwidth), wval);

                                        OverflowCheckedTensor y_tensor = new OverflowCheckedTensor(Shape.Map1D(outchannels, outwidth, batch));

                                        QuaternionConvolution1D ope = new QuaternionConvolution1D(inwidth, inchannels, outchannels, kwidth, stride, gradmode, batch);

                                        ope.Execute(x_tensor, w_tensor, y_tensor);

                                        CollectionAssert.AreEqual(xval, x_tensor.State);
                                        CollectionAssert.AreEqual(wval, w_tensor.State);

                                        y_tensor.CheckOverflow();

                                        Console.WriteLine($"pass: {inchannels},{outchannels},{kwidth},{stride},{inwidth},{batch},{gradmode}");
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        public void ReferenceTest()
        {
            int inchannels = 8, outchannels = 12, kwidth = 3, stride = 2, inwidth = 13;
            int outwidth = (inwidth - kwidth) / stride + 1, batch = 1;

            float[] xval = (new float[inwidth * inchannels * batch]).Select((_, idx) => idx * 1e-3f).ToArray();
            float[] yval = (new float[outwidth * outchannels * batch]).Select((_, idx) => idx * 1e-3f).Reverse().ToArray();

            Quaternion[] xcval = (new Quaternion[xval.Length / 4])
                                 .Select((_, idx) => new Quaternion(xval[idx * 4], xval[idx * 4 + 1], xval[idx * 4 + 2], xval[idx * 4 + 3])).ToArray();

            Quaternion[] ycval = (new Quaternion[yval.Length / 4])
                                 .Select((_, idx) => new Quaternion(yval[idx * 4], yval[idx * 4 + 1], yval[idx * 4 + 2], yval[idx * 4 + 3])).ToArray();

            QuaternionMap1D x = new QuaternionMap1D(inchannels / 4, inwidth, batch, xcval);
            QuaternionMap1D y = new QuaternionMap1D(outchannels / 4, outwidth, batch, ycval);

            QuaternionFilter1D gw = Reference(x, y, kwidth, stride);

            float[] gw_expect =
            {
                2.587200000e-02f,  -0.000000000e+00f, -1.944000000e-03f, -9.720000000e-04f,  2.966400000e-02f, -0.000000000e+00f,
                -2.040000000e-03f, -1.020000000e-03f,  2.188800000e-02f, -8.673617380e-19f, -1.848000000e-03f, -9.240000000e-04f,
                2.529600000e-02f,   8.673617380e-19f, -1.944000000e-03f, -9.720000000e-04f,  1.790400000e-02f, -8.673617380e-19f,
                -1.752000000e-03f, -8.760000000e-04f,  2.092800000e-02f, -8.673617380e-19f, -1.848000000e-03f, -9.240000000e-04f,
                3.345600000e-02f,  -0.000000000e+00f, -2.136000000e-03f, -1.068000000e-03f,  3.724800000e-02f,  1.734723476e-18f,
                -2.232000000e-03f, -1.116000000e-03f,  2.870400000e-02f, -1.734723476e-18f, -2.040000000e-03f, -1.020000000e-03f,
                3.211200000e-02f,   1.734723476e-18f, -2.136000000e-03f, -1.068000000e-03f,  2.395200000e-02f, -0.000000000e+00f,
                -1.944000000e-03f, -9.720000000e-04f,  2.697600000e-02f, -8.673617380e-19f, -2.040000000e-03f, -1.020000000e-03f,
                4.104000000e-02f,  -1.734723476e-18f, -2.328000000e-03f, -1.164000000e-03f,  4.483200000e-02f,  1.734723476e-18f,
                -2.424000000e-03f, -1.212000000e-03f,  3.552000000e-02f, -0.000000000e+00f, -2.232000000e-03f, -1.116000000e-03f,
                3.892800000e-02f,  -0.000000000e+00f, -2.328000000e-03f, -1.164000000e-03f,  3.000000000e-02f,  8.673617380e-19f,
                -2.136000000e-03f, -1.068000000e-03f,  3.302400000e-02f,  3.469446952e-18f, -2.232000000e-03f, -1.116000000e-03f,
            };

            float[] gw_actual = gw.ToArray();

            AssertError.Tolerance(gw_expect, gw_actual, 1e-7f, 1e-5f, $"mismatch value {inchannels},{outchannels},{kwidth},{stride},{inwidth},{batch}");
        }
Exemple #7
0
        public void ReferenceTest()
        {
            int inchannels = 8, outchannels = 12, kwidth = 3, stride = 2, inwidth = 13, batch = 3;
            int outwidth = (inwidth - kwidth) / stride + 1;

            float[] xval = (new float[batch * inwidth * inchannels]).Select((_, idx) => idx * 1e-3f).ToArray();
            float[] wval = (new float[kwidth * outchannels * inchannels / 4]).Select((_, idx) => idx * 1e-3f).Reverse().ToArray();

            Quaternion[] xcval = (new Quaternion[xval.Length / 4])
                                 .Select((_, idx) => new Quaternion(xval[idx * 4], xval[idx * 4 + 1], xval[idx * 4 + 2], xval[idx * 4 + 3])).ToArray();

            Quaternion[] wcval = (new Quaternion[wval.Length / 4])
                                 .Select((_, idx) => new Quaternion(wval[idx * 4], wval[idx * 4 + 1], wval[idx * 4 + 2], wval[idx * 4 + 3])).ToArray();

            QuaternionMap1D    x = new QuaternionMap1D(inchannels / 4, inwidth, batch, xcval);
            QuaternionFilter1D w = new QuaternionFilter1D(inchannels / 4, outchannels / 4, kwidth, wcval);

            QuaternionMap1D y = Reference(x, w, kwidth, stride);

            float[] y_expect =
            {
                -4.992000000e-03f, 3.696000000e-03f,  4.896000000e-03f, 4.116000000e-03f, -3.744000000e-03f, 2.736000000e-03f,
                3.744000000e-03f,  3.060000000e-03f, -2.496000000e-03f, 1.776000000e-03f,  2.592000000e-03f, 2.004000000e-03f,
                -1.305600000e-02f, 1.214400000e-02f,  1.353600000e-02f, 1.237200000e-02f, -1.027200000e-02f, 9.648000000e-03f,
                1.084800000e-02f,  9.780000000e-03f, -7.488000000e-03f, 7.152000000e-03f,  8.160000000e-03f, 7.188000000e-03f,
                -2.112000000e-02f, 2.059200000e-02f,  2.217600000e-02f, 2.062800000e-02f, -1.680000000e-02f, 1.656000000e-02f,
                1.795200000e-02f,  1.650000000e-02f, -1.248000000e-02f, 1.252800000e-02f,  1.372800000e-02f, 1.237200000e-02f,
                -2.918400000e-02f, 2.904000000e-02f,  3.081600000e-02f, 2.888400000e-02f, -2.332800000e-02f, 2.347200000e-02f,
                2.505600000e-02f,  2.322000000e-02f, -1.747200000e-02f, 1.790400000e-02f,  1.929600000e-02f, 1.755600000e-02f,
                -3.724800000e-02f, 3.748800000e-02f,  3.945600000e-02f, 3.714000000e-02f, -2.985600000e-02f, 3.038400000e-02f,
                3.216000000e-02f,  2.994000000e-02f, -2.246400000e-02f, 2.328000000e-02f,  2.486400000e-02f, 2.274000000e-02f,
                -4.531200000e-02f, 4.593600000e-02f,  4.809600000e-02f, 4.539600000e-02f, -3.638400000e-02f, 3.729600000e-02f,
                3.926400000e-02f,  3.666000000e-02f, -2.745600000e-02f, 2.865600000e-02f,  3.043200000e-02f, 2.792400000e-02f,
                -5.740800000e-02f, 5.860800000e-02f,  6.105600000e-02f, 5.778000000e-02f, -4.617600000e-02f, 4.766400000e-02f,
                4.992000000e-02f,  4.674000000e-02f, -3.494400000e-02f, 3.672000000e-02f,  3.878400000e-02f, 3.570000000e-02f,
                -6.547200000e-02f, 6.705600000e-02f,  6.969600000e-02f, 6.603600000e-02f, -5.270400000e-02f, 5.457600000e-02f,
                5.702400000e-02f,  5.346000000e-02f, -3.993600000e-02f, 4.209600000e-02f,  4.435200000e-02f, 4.088400000e-02f,
                -7.353600000e-02f, 7.550400000e-02f,  7.833600000e-02f, 7.429200000e-02f, -5.923200000e-02f, 6.148800000e-02f,
                6.412800000e-02f,  6.018000000e-02f, -4.492800000e-02f, 4.747200000e-02f,  4.992000000e-02f, 4.606800000e-02f,
                -8.160000000e-02f, 8.395200000e-02f,  8.697600000e-02f, 8.254800000e-02f, -6.576000000e-02f, 6.840000000e-02f,
                7.123200000e-02f,  6.690000000e-02f, -4.992000000e-02f, 5.284800000e-02f,  5.548800000e-02f, 5.125200000e-02f,
                -8.966400000e-02f, 9.240000000e-02f,  9.561600000e-02f, 9.080400000e-02f, -7.228800000e-02f, 7.531200000e-02f,
                7.833600000e-02f,  7.362000000e-02f, -5.491200000e-02f, 5.822400000e-02f,  6.105600000e-02f, 5.643600000e-02f,
                -9.772800000e-02f, 1.008480000e-01f,  1.042560000e-01f, 9.906000000e-02f, -7.881600000e-02f, 8.222400000e-02f,
                8.544000000e-02f,  8.034000000e-02f, -5.990400000e-02f, 6.360000000e-02f,  6.662400000e-02f, 6.162000000e-02f,
                -1.098240000e-01f, 1.135200000e-01f,  1.172160000e-01f, 1.114440000e-01f, -8.860800000e-02f, 9.259200000e-02f,
                9.609600000e-02f,  9.042000000e-02f, -6.739200000e-02f, 7.166400000e-02f,  7.497600000e-02f, 6.939600000e-02f,
                -1.178880000e-01f, 1.219680000e-01f,  1.258560000e-01f, 1.197000000e-01f, -9.513600000e-02f, 9.950400000e-02f,
                1.032000000e-01f,  9.714000000e-02f, -7.238400000e-02f, 7.704000000e-02f,  8.054400000e-02f, 7.458000000e-02f,
                -1.259520000e-01f, 1.304160000e-01f,  1.344960000e-01f, 1.279560000e-01f, -1.016640000e-01f, 1.064160000e-01f,
                1.103040000e-01f,  1.038600000e-01f, -7.737600000e-02f, 8.241600000e-02f,  8.611200000e-02f, 7.976400000e-02f,
                -1.340160000e-01f, 1.388640000e-01f,  1.431360000e-01f, 1.362120000e-01f, -1.081920000e-01f, 1.133280000e-01f,
                1.174080000e-01f,  1.105800000e-01f, -8.236800000e-02f, 8.779200000e-02f,  9.168000000e-02f, 8.494800000e-02f,
                -1.420800000e-01f, 1.473120000e-01f,  1.517760000e-01f, 1.444680000e-01f, -1.147200000e-01f, 1.202400000e-01f,
                1.245120000e-01f,  1.173000000e-01f, -8.736000000e-02f, 9.316800000e-02f,  9.724800000e-02f, 9.013200000e-02f,
                -1.501440000e-01f, 1.557600000e-01f,  1.604160000e-01f, 1.527240000e-01f, -1.212480000e-01f, 1.271520000e-01f,
                1.316160000e-01f,  1.240200000e-01f, -9.235200000e-02f, 9.854400000e-02f,  1.028160000e-01f, 9.531600000e-02f,
            };

            float[] y_actual = y.ToArray();

            AssertError.Tolerance(y_expect, y_actual, 1e-7f, 1e-5f, $"mismatch value {inchannels},{outchannels},{kwidth},{stride},{inwidth},{batch}");
        }
        public void ReferenceTest()
        {
            int inchannels = 8, outchannels = 12, kwidth = 3, stride = 2, inwidth = 13, batch = 3;
            int outwidth = (inwidth - kwidth) / stride + 1;

            float[] yval = (new float[outwidth * outchannels * batch]).Select((_, idx) => idx * 1e-3f).ToArray();
            float[] wval = (new float[kwidth * outchannels * inchannels / 4]).Select((_, idx) => idx * 1e-3f).Reverse().ToArray();

            Quaternion[] ycval = (new Quaternion[yval.Length / 4])
                                 .Select((_, idx) => new Quaternion(yval[idx * 4], yval[idx * 4 + 1], yval[idx * 4 + 2], yval[idx * 4 + 3])).ToArray();

            Quaternion[] wcval = (new Quaternion[wval.Length / 4])
                                 .Select((_, idx) => new Quaternion(wval[idx * 4], wval[idx * 4 + 1], wval[idx * 4 + 2], wval[idx * 4 + 3])).ToArray();

            QuaternionMap1D    y = new QuaternionMap1D(outchannels / 4, outwidth, batch, ycval);
            QuaternionFilter1D w = new QuaternionFilter1D(inchannels / 4, outchannels / 4, kwidth, wcval);

            QuaternionMap1D x = Reference(y, w, inwidth, kwidth, stride);

            float[] x_expect =
            {
                -2.404000000e-03f, 1.360000000e-03f,  2.140000000e-03f, 1.714000000e-03f, -2.236000000e-03f, 1.264000000e-03f,
                1.996000000e-03f,  1.594000000e-03f, -1.396000000e-03f, 7.840000000e-04f,  1.276000000e-03f, 9.940000000e-04f,
                -1.228000000e-03f, 6.880000000e-04f,  1.132000000e-03f, 8.740000000e-04f, -7.112000000e-03f, 6.032000000e-03f,
                7.088000000e-03f,  6.380000000e-03f, -6.488000000e-03f, 5.552000000e-03f,  6.512000000e-03f, 5.852000000e-03f,
                -3.988000000e-03f, 3.520000000e-03f,  4.084000000e-03f, 3.658000000e-03f, -3.532000000e-03f, 3.136000000e-03f,
                3.652000000e-03f,  3.250000000e-03f, -1.229600000e-02f, 1.150400000e-02f,  1.270400000e-02f, 1.170800000e-02f,
                -1.109600000e-02f, 1.044800000e-02f,  1.155200000e-02f, 1.060400000e-02f, -6.580000000e-03f, 6.256000000e-03f,
                6.892000000e-03f,  6.322000000e-03f, -5.836000000e-03f, 5.584000000e-03f,  6.172000000e-03f, 5.626000000e-03f,
                -1.748000000e-02f, 1.697600000e-02f,  1.832000000e-02f, 1.703600000e-02f, -1.570400000e-02f, 1.534400000e-02f,
                1.659200000e-02f,  1.535600000e-02f, -9.172000000e-03f, 8.992000000e-03f,  9.700000000e-03f, 8.986000000e-03f,
                -8.140000000e-03f, 8.032000000e-03f,  8.692000000e-03f, 8.002000000e-03f, -2.266400000e-02f, 2.244800000e-02f,
                2.393600000e-02f,  2.236400000e-02f, -2.031200000e-02f, 2.024000000e-02f,  2.163200000e-02f, 2.010800000e-02f,
                -1.176400000e-02f, 1.172800000e-02f,  1.250800000e-02f, 1.165000000e-02f, -1.044400000e-02f, 1.048000000e-02f,
                1.121200000e-02f,  1.037800000e-02f, -2.784800000e-02f, 2.792000000e-02f,  2.955200000e-02f, 2.769200000e-02f,
                -2.492000000e-02f, 2.513600000e-02f,  2.667200000e-02f, 2.486000000e-02f, -1.435600000e-02f, 1.446400000e-02f,
                1.531600000e-02f,  1.431400000e-02f, -1.274800000e-02f, 1.292800000e-02f,  1.373200000e-02f, 1.275400000e-02f,
                -4.708000000e-03f, 5.248000000e-03f,  5.812000000e-03f, 4.954000000e-03f, -3.100000000e-03f, 3.712000000e-03f,
                4.228000000e-03f,  3.394000000e-03f, -2.832400000e-02f, 2.814400000e-02f,  2.935600000e-02f, 2.806600000e-02f,
                -2.642800000e-02f, 2.632000000e-02f,  2.748400000e-02f, 2.621800000e-02f, -1.694800000e-02f, 1.720000000e-02f,
                1.812400000e-02f,  1.697800000e-02f, -1.505200000e-02f, 1.537600000e-02f,  1.625200000e-02f, 1.513000000e-02f,
                -3.821600000e-02f, 3.886400000e-02f,  4.078400000e-02f, 3.834800000e-02f, -3.413600000e-02f, 3.492800000e-02f,
                3.675200000e-02f,  3.436400000e-02f, -1.954000000e-02f, 1.993600000e-02f,  2.093200000e-02f, 1.964200000e-02f,
                -1.735600000e-02f, 1.782400000e-02f,  1.877200000e-02f, 1.750600000e-02f, -4.340000000e-02f, 4.433600000e-02f,
                4.640000000e-02f,  4.367600000e-02f, -3.874400000e-02f, 3.982400000e-02f,  4.179200000e-02f, 3.911600000e-02f,
                -2.213200000e-02f, 2.267200000e-02f,  2.374000000e-02f, 2.230600000e-02f, -1.966000000e-02f, 2.027200000e-02f,
                2.129200000e-02f,  1.988200000e-02f, -4.858400000e-02f, 4.980800000e-02f,  5.201600000e-02f, 4.900400000e-02f,
                -4.335200000e-02f, 4.472000000e-02f,  4.683200000e-02f, 4.386800000e-02f, -2.472400000e-02f, 2.540800000e-02f,
                2.654800000e-02f,  2.497000000e-02f, -2.196400000e-02f, 2.272000000e-02f,  2.381200000e-02f, 2.225800000e-02f,
                -5.376800000e-02f, 5.528000000e-02f,  5.763200000e-02f, 5.433200000e-02f, -4.796000000e-02f, 4.961600000e-02f,
                5.187200000e-02f,  4.862000000e-02f, -2.731600000e-02f, 2.814400000e-02f,  2.935600000e-02f, 2.763400000e-02f,
                -2.426800000e-02f, 2.516800000e-02f,  2.633200000e-02f, 2.463400000e-02f, -5.895200000e-02f, 6.075200000e-02f,
                6.324800000e-02f,  5.966000000e-02f, -5.256800000e-02f, 5.451200000e-02f,  5.691200000e-02f, 5.337200000e-02f,
                -2.990800000e-02f, 3.088000000e-02f,  3.216400000e-02f, 3.029800000e-02f, -2.657200000e-02f, 2.761600000e-02f,
                2.885200000e-02f,  2.701000000e-02f, -9.892000000e-03f, 1.129600000e-02f,  1.229200000e-02f, 1.057000000e-02f,
                -6.556000000e-03f, 8.032000000e-03f,  8.980000000e-03f, 7.282000000e-03f, -5.424400000e-02f, 5.492800000e-02f,
                5.657200000e-02f,  5.441800000e-02f, -5.062000000e-02f, 5.137600000e-02f,  5.297200000e-02f, 5.084200000e-02f,
                -3.250000000e-02f, 3.361600000e-02f,  3.497200000e-02f, 3.296200000e-02f, -2.887600000e-02f, 3.006400000e-02f,
                3.137200000e-02f,  2.938600000e-02f, -6.932000000e-02f, 7.169600000e-02f,  7.448000000e-02f, 7.031600000e-02f,
                -6.178400000e-02f, 6.430400000e-02f,  6.699200000e-02f, 6.287600000e-02f, -3.509200000e-02f, 3.635200000e-02f,
                3.778000000e-02f,  3.562600000e-02f, -3.118000000e-02f, 3.251200000e-02f,  3.389200000e-02f, 3.176200000e-02f,
                -7.450400000e-02f, 7.716800000e-02f,  8.009600000e-02f, 7.564400000e-02f, -6.639200000e-02f, 6.920000000e-02f,
                7.203200000e-02f,  6.762800000e-02f, -3.768400000e-02f, 3.908800000e-02f,  4.058800000e-02f, 3.829000000e-02f,
                -3.348400000e-02f, 3.496000000e-02f,  3.641200000e-02f, 3.413800000e-02f, -7.968800000e-02f, 8.264000000e-02f,
                8.571200000e-02f,  8.097200000e-02f, -7.100000000e-02f, 7.409600000e-02f,  7.707200000e-02f, 7.238000000e-02f,
                -4.027600000e-02f, 4.182400000e-02f,  4.339600000e-02f, 4.095400000e-02f, -3.578800000e-02f, 3.740800000e-02f,
                3.893200000e-02f,  3.651400000e-02f, -8.487200000e-02f, 8.811200000e-02f,  9.132800000e-02f, 8.630000000e-02f,
                -7.560800000e-02f, 7.899200000e-02f,  8.211200000e-02f, 7.713200000e-02f, -4.286800000e-02f, 4.456000000e-02f,
                4.620400000e-02f,  4.361800000e-02f, -3.809200000e-02f, 3.985600000e-02f,  4.145200000e-02f, 3.889000000e-02f,
                -9.005600000e-02f, 9.358400000e-02f,  9.694400000e-02f, 9.162800000e-02f, -8.021600000e-02f, 8.388800000e-02f,
                8.715200000e-02f,  8.188400000e-02f, -4.546000000e-02f, 4.729600000e-02f,  4.901200000e-02f, 4.628200000e-02f,
                -4.039600000e-02f, 4.230400000e-02f,  4.397200000e-02f, 4.126600000e-02f, -1.507600000e-02f, 1.734400000e-02f,
                1.877200000e-02f,  1.618600000e-02f, -1.001200000e-02f, 1.235200000e-02f,  1.373200000e-02f, 1.117000000e-02f,
            };

            float[] x_actual = x.ToArray();

            AssertError.Tolerance(x_expect, x_actual, 1e-7f, 1e-5f, $"mismatch value {inchannels},{outchannels},{kwidth},{stride},{inwidth},{batch}");
        }