示例#1
0
        public static Map1D Reference(Map1D y, int outw, int stride)
        {
            int channels = y.Channels, batch = y.Batch;
            int inw = outw / stride;

            Map1D x = new Map1D(channels, outw, batch);

            for (int th = 0; th < batch; th++)
            {
                for (int ox = 0; ox < outw; ox++)
                {
                    int ix = ox / stride;

                    if (ix < inw)
                    {
                        for (int ch = 0; ch < channels; ch++)
                        {
                            x[ch, ox, th] = y[ch, ix, th] / stride;
                        }
                    }
                    else
                    {
                        for (int ch = 0; ch < channels; ch++)
                        {
                            x[ch, ox, th] = 0;
                        }
                    }
                }
            }

            return(x);
        }
        public void ReferenceTest()
        {
            int inchannels = 12, scale = 2, inwidth = 7;
            int outchannels = inchannels / scale, outwidth = inwidth * scale;

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

            Map1D x = new Map1D(inchannels, inwidth, 1, xval);

            Map1D y = Reference(x, scale);

            float[] y_expect =
            {
                0.000f, 0.001f, 0.002f, 0.003f, 0.004f, 0.005f,
                0.006f, 0.007f, 0.008f, 0.009f, 0.010f, 0.011f,
                0.012f, 0.013f, 0.014f, 0.015f, 0.016f, 0.017f,
                0.018f, 0.019f, 0.020f, 0.021f, 0.022f, 0.023f,
                0.024f, 0.025f, 0.026f, 0.027f, 0.028f, 0.029f,
                0.030f, 0.031f, 0.032f, 0.033f, 0.034f, 0.035f,
                0.036f, 0.037f, 0.038f, 0.039f, 0.040f, 0.041f,
                0.042f, 0.043f, 0.044f, 0.045f, 0.046f, 0.047f,
                0.048f, 0.049f, 0.050f, 0.051f, 0.052f, 0.053f,
                0.054f, 0.055f, 0.056f, 0.057f, 0.058f, 0.059f,
                0.060f, 0.061f, 0.062f, 0.063f, 0.064f, 0.065f,
                0.066f, 0.067f, 0.068f, 0.069f, 0.070f, 0.071f,
                0.072f, 0.073f, 0.074f, 0.075f, 0.076f, 0.077f,
                0.078f, 0.079f, 0.080f, 0.081f, 0.082f, 0.083f,
            };

            float[] y_actual = y.ToArray();

            AssertError.Tolerance(y_expect, y_actual, 1e-7f, 1e-5f, $"mismatch value {inchannels},{outchannels},{scale},{inwidth}");
        }
        public static Map1D Reference(Map1D x, int scale)
        {
            int inw = x.Width, inchannels = x.Channels, batch = x.Batch;

            if (inw % scale != 0)
            {
                throw new ArgumentException(nameof(scale));
            }

            int outw        = inw / scale;
            int outchannels = inchannels * scale;

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

            for (int th = 0; th < batch; th++)
            {
                for (int ox = 0; ox < outw; ox++)
                {
                    for (int kx = 0; kx < scale; kx++)
                    {
                        for (int inch = 0; inch < inchannels; inch++)
                        {
                            int outch = inch + kx * inchannels;

                            y[outch, ox, th] = x[inch, ox *scale + kx, th];
                        }
                    }
                }
            }

            return(y);
        }
        public static Map1D Reference(Map1D y, Filter1D w)
        {
            int inchannels = w.InChannels, outchannels = w.OutChannels, batch = y.Batch;
            int inw = y.Width;

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

            for (int th = 0; th < batch; th++)
            {
                for (int ix = 0; ix < inw; ix++)
                {
                    for (int outch = 0; outch < outchannels; outch++)
                    {
                        double v = y[outch, ix, th];

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

            return(x);
        }
        public static Map1D Reference(Map1D y, Filter1D 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");
            }

            Map1D x = new Map1D(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++)
                        {
                            double 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 Filter1D OptimizedReference(Map1D x, Map1D gy)
        {
            int inchannels = x.Channels, outchannels = gy.Channels, batch = x.Batch;
            int inw = x.Width;

            Filter1D w = new Filter1D(outchannels, inchannels, 1);

            for (int th = 0; th < batch; th++)
            {
                for (int outch, inch = 0; inch < inchannels; inch++)
                {
                    for (outch = 0; outch < outchannels; outch++)
                    {
                        int filter_idx = inch + inchannels * outch;
                        int inmap_idx  = inch + th * inw * inchannels;
                        int outmap_idx = outch + th * inw * outchannels;

                        double sum = 0;

                        for (int ix = 0; ix < inw; ix++)
                        {
                            sum += x[inmap_idx] * gy[outmap_idx];

                            inmap_idx  += inchannels;
                            outmap_idx += outchannels;
                        }

                        w[filter_idx] += sum;
                    }
                }
            }

            return(w);
        }
示例#7
0
        public static Map1D Reference(Map1D x, Filter1D w, int kwidth, int stride)
        {
            int inchannels = x.Channels, outchannels = w.OutChannels, batch = x.Batch;
            int inw = x.Width, outw = (inw - kwidth) / stride + 1;

            Map1D y = new Map1D(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++)
                        {
                            double 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);
        }
示例#8
0
        public static Map1D OptimizedReference(Map1D x, Filter1D w, int kwidth, int stride)
        {
            int channels = x.Channels, batch = x.Batch;
            int inw = x.Width, outw = (inw - kwidth) / stride + 1;

            Map1D y = new Map1D(channels, outw, batch);

            for (int kx = 0; kx < kwidth; kx++)
            {
                int inmap_offset  = kx * channels;
                int kernel_offset = kx * channels;

                for (int th = 0; th < batch; th++)
                {
                    for (int ox = 0; ox < outw; ox++)
                    {
                        int inmap_idx  = inmap_offset + ox * channels * stride + th * inw * channels;
                        int outmap_idx = ox * channels + th * outw * channels;
                        int kernel_idx = kernel_offset;

                        for (int ch = 0; ch < channels; ch++)
                        {
                            y[outmap_idx] += x[inmap_idx] * w[kernel_idx];

                            inmap_idx++;
                            outmap_idx++;
                            kernel_idx++;
                        }
                    }
                }
            }

            return(y);
        }
示例#9
0
        public static Map1D Reference(Map1D x, int stride)
        {
            int channels = x.Channels, batch = x.Batch;
            int inw = x.Width, outw = inw / stride;

            Map1D y = new Map1D(channels, outw, batch);

            for (int th = 0; th < batch; th++)
            {
                for (int ox = 0; ox < outw; ox++)
                {
                    for (int ch = 0; ch < channels; ch++)
                    {
                        double sum = 0;
                        for (int kx = 0; kx < stride; kx++)
                        {
                            sum += x[ch, ox *stride + kx, th];
                        }

                        y[ch, ox, th] = sum / stride;
                    }
                }
            }

            return(y);
        }
        public void OptimizeTest()
        {
            float max_err = 0;

            foreach (int batch in new int[] { 1, 2 })
            {
                foreach (int inchannels in new int[] { 3, 5 })
                {
                    foreach (int scale in new int[] { 2, 3, 4 })
                    {
                        foreach (int outwidth in new int[] { 5, 7, 11 })
                        {
                            int inwidth = outwidth * scale, outchannels = inchannels * scale;

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

                            Map1D x = new Map1D(inchannels, inwidth, batch, xval);

                            Map1D y           = Reference(x, scale);
                            Map1D y_optimized = OptimizedReference(x, scale);

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

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

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

            Console.WriteLine($"maxerr:{max_err}");
        }
        public void OptimizeTest()
        {
            float max_err = 0;

            foreach (int batch in new int[] { 1, 2 })
            {
                foreach (int inchannels in new int[] { 1, 2, 3, 4, 5, 10, 15, 20 })
                {
                    foreach (int outchannels in new int[] { 7, 13 })
                    {
                        foreach (int inwidth in new int[] { 8, 9, 13, 17 })
                        {
                            float[] yval = (new float[inwidth * outchannels * batch]).Select((_, idx) => idx * 1e-4f).ToArray();
                            float[] wval = (new float[inchannels * outchannels]).Select((_, idx) => idx * 1e-4f).Reverse().ToArray();

                            Map1D    y = new Map1D(outchannels, inwidth, batch, yval);
                            Filter1D w = new Filter1D(inchannels, outchannels, 1, wval);

                            Map1D x           = Reference(y, w);
                            Map1D x_optimized = OptimizedReference(y, w);

                            float[] x_expect = x.ToArray();
                            float[] x_actual = x_optimized.ToArray();

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

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

            Console.WriteLine($"maxerr:{max_err}");
        }
        public static Map1D OptimizedReference(Map1D x, int scale)
        {
            int inw = x.Width, inchannels = x.Channels, batch = x.Batch;

            if (inw % scale != 0)
            {
                throw new ArgumentException(nameof(scale));
            }

            int outw        = inw / scale;
            int outchannels = inchannels * scale;

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

            for (int th = 0; th < batch; th++)
            {
                for (int ox = 0; ox < outw; ox++)
                {
                    int inmap_idx  = ox * scale * inchannels + th * inw * inchannels;
                    int outmap_idx = ox * outchannels + th * outw * outchannels;

                    for (int i = 0; i < scale * inchannels; i++)
                    {
                        y[outmap_idx] = x[inmap_idx];

                        inmap_idx++;
                        outmap_idx++;
                    }
                }
            }

            return(y);
        }
示例#13
0
        public static Map1D Reference(Map1D x, int scale)
        {
            int inw = x.Width, channels = x.Channels, batch = x.Batch;

            int   outw = inw * scale;
            Map1D y    = new Map1D(channels, outw, batch);

            for (int th = 0; th < batch; th++)
            {
                for (int ix = 0; ix < inw; ix++)
                {
                    for (int f = 0; f < channels; f++)
                    {
                        double c = x[f, ix, th];
                        double l = x[f, Math.Max(0, ix - 1), th];
                        double r = x[f, Math.Min(inw - 1, ix + 1), th];

                        y[f, ix * 2, th]     = (2 * c + l) / 3;
                        y[f, ix * 2 + 1, th] = (2 * c + r) / 3;
                    }
                }
            }

            return(y);
        }
        public static Filter1D Reference(Map1D x, Map1D 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");
            }

            Filter1D w = new Filter1D(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++)
                        {
                            double sum = 0;

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

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

            return(w);
        }
        public static Filter1D Reference(Map1D x, Map1D gy)
        {
            int inchannels = x.Channels, outchannels = gy.Channels, batch = x.Batch;
            int inw = x.Width;

            Filter1D w = new Filter1D(inchannels, outchannels, 1);

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

                        for (int ix = 0; ix < inw; ix++)
                        {
                            sum += x[inch, ix, th] * gy[outch, ix, th];
                        }

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

            return(w);
        }
        public void OptimizeTest()
        {
            float max_err = 0;

            foreach (int batch in new int[] { 1, 2 })
            {
                foreach (int inchannels in new int[] { 1, 2, 3, 4, 5, 10, 15, 20 })
                {
                    foreach (int outchannels in new int[] { 7, 13 })
                    {
                        foreach (int inwidth in new int[] { 8, 9, 13, 17 })
                        {
                            float[] xval  = (new float[inwidth * inchannels * batch]).Select((_, idx) => idx * 1e-3f).ToArray();
                            float[] gyval = (new float[inwidth * outchannels * batch]).Select((_, idx) => idx * 1e-3f).Reverse().ToArray();

                            Map1D x  = new Map1D(inchannels, inwidth, batch, xval);
                            Map1D gy = new Map1D(outchannels, inwidth, batch, gyval);

                            Filter1D gw           = Reference(x, gy);
                            Filter1D gw_optimized = OptimizedReference(x, gy);

                            float[] gw_expect = gw.ToArray();
                            float[] gw_actual = gw_optimized.ToArray();

                            AssertError.Tolerance(gw_expect, gw_actual, 1e-7f, 1e-5f, $"mismatch value {inchannels},{outchannels},{inwidth},{batch}");

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

            Console.WriteLine($"maxerr:{max_err}");
        }
        public void ReferenceTest()
        {
            int inchannels = 7, outchannels = 11, inwidth = 13;

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

            Map1D x  = new Map1D(inchannels, inwidth, 1, xval);
            Map1D gy = new Map1D(outchannels, inwidth, 1, gyval);

            Filter1D gw = Reference(x, gy);

            float[] gw_expect =
            {
                2.748200e-02f, 2.847000e-02f, 2.945800e-02f, 3.044600e-02f, 3.143400e-02f, 3.242200e-02f, 3.341000e-02f,
                2.693600e-02f, 2.791100e-02f, 2.888600e-02f, 2.986100e-02f, 3.083600e-02f, 3.181100e-02f, 3.278600e-02f,
                2.639000e-02f, 2.735200e-02f, 2.831400e-02f, 2.927600e-02f, 3.023800e-02f, 3.120000e-02f, 3.216200e-02f,
                2.584400e-02f, 2.679300e-02f, 2.774200e-02f, 2.869100e-02f, 2.964000e-02f, 3.058900e-02f, 3.153800e-02f,
                2.529800e-02f, 2.623400e-02f, 2.717000e-02f, 2.810600e-02f, 2.904200e-02f, 2.997800e-02f, 3.091400e-02f,
                2.475200e-02f, 2.567500e-02f, 2.659800e-02f, 2.752100e-02f, 2.844400e-02f, 2.936700e-02f, 3.029000e-02f,
                2.420600e-02f, 2.511600e-02f, 2.602600e-02f, 2.693600e-02f, 2.784600e-02f, 2.875600e-02f, 2.966600e-02f,
                2.366000e-02f, 2.455700e-02f, 2.545400e-02f, 2.635100e-02f, 2.724800e-02f, 2.814500e-02f, 2.904200e-02f,
                2.311400e-02f, 2.399800e-02f, 2.488200e-02f, 2.576600e-02f, 2.665000e-02f, 2.753400e-02f, 2.841800e-02f,
                2.256800e-02f, 2.343900e-02f, 2.431000e-02f, 2.518100e-02f, 2.605200e-02f, 2.692300e-02f, 2.779400e-02f,
                2.202200e-02f, 2.288000e-02f, 2.373800e-02f, 2.459600e-02f, 2.545400e-02f, 2.631200e-02f, 2.717000e-02f,
            };

            float[] gw_actual = gw.ToArray();

            AssertError.Tolerance(gw_expect, gw_actual, 1e-7f, 1e-5f, $"mismatch value {inchannels},{outchannels},{inwidth}");
        }
        public static Map1D Reference(Map1D x, Filter1D w)
        {
            int inchannels = x.Channels, outchannels = w.OutChannels, batch = x.Batch;
            int inw = x.Width;

            Map1D y = new Map1D(outchannels, inw, batch);

            for (int th = 0; th < batch; th++)
            {
                for (int ix = 0; ix < inw; ix++)
                {
                    for (int outch = 0; outch < outchannels; outch++)
                    {
                        double sum = y[outch, ix, th];

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

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

            return(y);
        }
示例#19
0
        public void ReferenceTest()
        {
            int channels = 7, kwidth = 3, stride = 2, inwidth = 13, batch = 2;
            int outwidth = (inwidth - kwidth) / stride + 1;

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

            Map1D    x = new Map1D(channels, inwidth, batch, xval);
            Filter1D w = new Filter1D(channels, 1, kwidth, wval);

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

            float[] y_expect =
            {
                1.7500000e-04f, 1.9000000e-04f, 1.9900000e-04f, 2.0200000e-04f, 1.9900000e-04f, 1.9000000e-04f, 1.7500000e-04f,
                7.2100000e-04f, 6.9400000e-04f, 6.6100000e-04f, 6.2200000e-04f, 5.7700000e-04f, 5.2600000e-04f, 4.6900000e-04f,
                1.2670000e-03f, 1.1980000e-03f, 1.1230000e-03f, 1.0420000e-03f, 9.5500000e-04f, 8.6200000e-04f, 7.6300000e-04f,
                1.8130000e-03f, 1.7020000e-03f, 1.5850000e-03f, 1.4620000e-03f, 1.3330000e-03f, 1.1980000e-03f, 1.0570000e-03f,
                2.3590000e-03f, 2.2060000e-03f, 2.0470000e-03f, 1.8820000e-03f, 1.7110000e-03f, 1.5340000e-03f, 1.3510000e-03f,
                2.9050000e-03f, 2.7100000e-03f, 2.5090000e-03f, 2.3020000e-03f, 2.0890000e-03f, 1.8700000e-03f, 1.6450000e-03f,
                3.7240000e-03f, 3.4660000e-03f, 3.2020000e-03f, 2.9320000e-03f, 2.6560000e-03f, 2.3740000e-03f, 2.0860000e-03f,
                4.2700000e-03f, 3.9700000e-03f, 3.6640000e-03f, 3.3520000e-03f, 3.0340000e-03f, 2.7100000e-03f, 2.3800000e-03f,
                4.8160000e-03f, 4.4740000e-03f, 4.1260000e-03f, 3.7720000e-03f, 3.4120000e-03f, 3.0460000e-03f, 2.6740000e-03f,
                5.3620000e-03f, 4.9780000e-03f, 4.5880000e-03f, 4.1920000e-03f, 3.7900000e-03f, 3.3820000e-03f, 2.9680000e-03f,
                5.9080000e-03f, 5.4820000e-03f, 5.0500000e-03f, 4.6120000e-03f, 4.1680000e-03f, 3.7180000e-03f, 3.2620000e-03f,
                6.4540000e-03f, 5.9860000e-03f, 5.5120000e-03f, 5.0320000e-03f, 4.5460000e-03f, 4.0540000e-03f, 3.5560000e-03f,
            };

            float[] y_actual = y.ToArray();

            AssertError.Tolerance(y_expect, y_actual, 1e-7f, 1e-5f, $"mismatch value {channels},{kwidth},{stride},{inwidth},{batch}");
        }
        public void ReferenceTest()
        {
            int inchannels = 7, outchannels = 11, kwidth = 3, stride = 2, inwidth = 13, batch = 2;
            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]).Select((_, idx) => idx * 1e-3f).Reverse().ToArray();

            Map1D    y = new Map1D(outchannels, outwidth, batch, yval);
            Filter1D w = new Filter1D(inchannels, outchannels, kwidth, wval);

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

            float[] x_expect =
            {
                9.955000e-03f, 9.900000e-03f, 9.845000e-03f, 9.790000e-03f, 9.735000e-03f,
                9.680000e-03f, 9.625000e-03f, 5.720000e-03f, 5.665000e-03f, 5.610000e-03f,
                5.555000e-03f, 5.500000e-03f, 5.445000e-03f, 5.390000e-03f, 3.503500e-02f,
                3.480400e-02f, 3.457300e-02f, 3.434200e-02f, 3.411100e-02f, 3.388000e-02f,
                3.364900e-02f, 1.999800e-02f, 1.982200e-02f, 1.964600e-02f, 1.947000e-02f,
                1.929400e-02f, 1.911800e-02f, 1.894200e-02f, 6.359100e-02f, 6.311800e-02f,
                6.264500e-02f, 6.217200e-02f, 6.169900e-02f, 6.122600e-02f, 6.075300e-02f,
                3.427600e-02f, 3.397900e-02f, 3.368200e-02f, 3.338500e-02f, 3.308800e-02f,
                3.279100e-02f, 3.249400e-02f, 9.214700e-02f, 9.143200e-02f, 9.071700e-02f,
                9.000200e-02f, 8.928700e-02f, 8.857200e-02f, 8.785700e-02f, 4.855400e-02f,
                4.813600e-02f, 4.771800e-02f, 4.730000e-02f, 4.688200e-02f, 4.646400e-02f,
                4.604600e-02f, 1.207030e-01f, 1.197460e-01f, 1.187890e-01f, 1.178320e-01f,
                1.168750e-01f, 1.159180e-01f, 1.149610e-01f, 6.283200e-02f, 6.229300e-02f,
                6.175400e-02f, 6.121500e-02f, 6.067600e-02f, 6.013700e-02f, 5.959800e-02f,
                1.492590e-01f, 1.480600e-01f, 1.468610e-01f, 1.456620e-01f, 1.444630e-01f,
                1.432640e-01f, 1.420650e-01f, 7.711000e-02f, 7.645000e-02f, 7.579000e-02f,
                7.513000e-02f, 7.447000e-02f, 7.381000e-02f, 7.315000e-02f, 2.629000e-02f,
                2.563000e-02f, 2.497000e-02f, 2.431000e-02f, 2.365000e-02f, 2.299000e-02f,
                2.233000e-02f, 1.515250e-01f, 1.507440e-01f, 1.499630e-01f, 1.491820e-01f,
                1.484010e-01f, 1.476200e-01f, 1.468390e-01f, 9.138800e-02f, 9.060700e-02f,
                8.982600e-02f, 8.904500e-02f, 8.826400e-02f, 8.748300e-02f, 8.670200e-02f,
                2.063710e-01f, 2.046880e-01f, 2.030050e-01f, 2.013220e-01f, 1.996390e-01f,
                1.979560e-01f, 1.962730e-01f, 1.056660e-01f, 1.047640e-01f, 1.038620e-01f,
                1.029600e-01f, 1.020580e-01f, 1.011560e-01f, 1.002540e-01f, 2.349270e-01f,
                2.330020e-01f, 2.310770e-01f, 2.291520e-01f, 2.272270e-01f, 2.253020e-01f,
                2.233770e-01f, 1.199440e-01f, 1.189210e-01f, 1.178980e-01f, 1.168750e-01f,
                1.158520e-01f, 1.148290e-01f, 1.138060e-01f, 2.634830e-01f, 2.613160e-01f,
                2.591490e-01f, 2.569820e-01f, 2.548150e-01f, 2.526480e-01f, 2.504810e-01f,
                1.342220e-01f, 1.330780e-01f, 1.319340e-01f, 1.307900e-01f, 1.296460e-01f,
                1.285020e-01f, 1.273580e-01f, 2.920390e-01f, 2.896300e-01f, 2.872210e-01f,
                2.848120e-01f, 2.824030e-01f, 2.799940e-01f, 2.775850e-01f, 1.485000e-01f,
                1.472350e-01f, 1.459700e-01f, 1.447050e-01f, 1.434400e-01f, 1.421750e-01f,
                1.409100e-01f, 3.205950e-01f, 3.179440e-01f, 3.152930e-01f, 3.126420e-01f,
                3.099910e-01f, 3.073400e-01f, 3.046890e-01f, 1.627780e-01f, 1.613920e-01f,
                1.600060e-01f, 1.586200e-01f, 1.572340e-01f, 1.558480e-01f, 1.544620e-01f,
                5.605600e-02f, 5.467000e-02f, 5.328400e-02f, 5.189800e-02f, 5.051200e-02f,
                4.912600e-02f, 4.774000e-02f,
            };

            float[] x_actual = x.ToArray();

            AssertError.Tolerance(x_expect, x_actual, 1e-7f, 1e-5f, $"mismatch value {inchannels},{kwidth},{stride},{inwidth},{batch}");
        }
示例#21
0
        public void ExecuteTest()
        {
            float max_err = 0;

            Random rd = new Random(1234);

            foreach (int batch in new int[] { 1, 2 })
            {
                foreach (int channels in new int[] { 1, 2, 3, 4, 5, 6, 7, 8 })
                {
                    foreach (int stride in new int[] { 2, 3, 4 })
                    {
                        foreach (int inwidth in new int[] { 5, 7, 11 })
                        {
                            int outwidth = inwidth / stride;

                            float[] xval  = (new float[inwidth * channels * batch]).Select((_) => (float)rd.NextDouble()).ToArray();
                            float[] gyval = (new float[outwidth * channels * batch]).Select((_) => (float)rd.NextDouble()).ToArray();

                            Map1D x  = new Map1D(channels, inwidth, batch, xval);
                            Map1D gy = new Map1D(channels, outwidth, batch, gyval);

                            Map1D gx = Reference(x, gy, stride);

                            OverflowCheckedTensor x_tensor  = new OverflowCheckedTensor(Shape.Map1D(channels, inwidth, batch), xval);
                            OverflowCheckedTensor y_tensor  = new OverflowCheckedTensor(Shape.Map1D(channels, outwidth, batch));
                            OverflowCheckedTensor gy_tensor = new OverflowCheckedTensor(Shape.Map1D(channels, outwidth, batch), gyval);
                            OverflowCheckedTensor gx_tensor = new OverflowCheckedTensor(Shape.Map1D(channels, inwidth, batch));

                            MaxPooling ope_pool = new MaxPooling(inwidth, channels, stride, batch);
                            ope_pool.Execute(x_tensor, y_tensor);

                            MaxUnpooling ope_unpool = new MaxUnpooling(inwidth, channels, stride, batch);
                            ope_unpool.Execute(gy_tensor, x_tensor, y_tensor, gx_tensor);

                            float[] gx_expect = gx.ToArray();
                            float[] gx_actual = gx_tensor.State;

                            int gx_expect_nonzero = gx_expect.Count((v) => v != 0);
                            int gx_actual_nonzero = gx_expect.Count((v) => v != 0);

                            CollectionAssert.AreEqual(xval, x_tensor.State);
                            CollectionAssert.AreEqual(gyval, gy_tensor.State);

                            Assert.AreEqual(y_tensor.Length, gx_expect_nonzero);
                            Assert.AreEqual(y_tensor.Length, gx_actual_nonzero);

                            AssertError.Tolerance(gx_expect, gx_actual, 1e-7f, 1e-5f, $"mismatch value {channels},{stride},{inwidth},{batch}");

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

            Console.WriteLine($"maxerr:{max_err}");
        }
        public void ReferenceTest()
        {
            int inchannels = 12, scale = 2, inwidth = 7;

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

            Map1D x = new Map1D(inchannels, inwidth, 1, xval);

            Map1D y = Reference(ChannelToSpaceTest.Reference(x, scale), scale);

            CollectionAssert.AreEqual(x.ToArray(), y.ToArray());
        }
示例#23
0
        public void ExecuteTest()
        {
            float max_err = 0;

            foreach (int batch in new int[] { 1, 2 })
            {
                foreach (int inchannels in new int[] { 1, 2, 3, 4, 5, 10, 15, 20 })
                {
                    foreach (int outchannels in new int[] { 7, 13 })
                    {
                        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]).Select((_, idx) => idx * 1e-3f).Reverse().ToArray();

                                    Map1D    x = new Map1D(inchannels, inwidth, batch, xval);
                                    Filter1D w = new Filter1D(inchannels, outchannels, kwidth, wval);

                                    Map1D 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, kwidth), wval);

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

                                    Convolution ope = new Convolution(inwidth, inchannels, outchannels, kwidth, stride, 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}");
        }
        public void ExecuteTest()
        {
            float max_err = 0;

            foreach (int batch in new int[] { 1, 2 })
            {
                foreach (int channels in new int[] { 1, 2, 3, 4, 5, 10, 15, 20 })
                {
                    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 * channels * batch]).Select((_, idx) => idx * 1e-3f).ToArray();
                                float[] gyval = (new float[outwidth * channels * batch]).Select((_, idx) => idx * 1e-3f).Reverse().ToArray();

                                Map1D x  = new Map1D(channels, inwidth, batch, xval);
                                Map1D gy = new Map1D(channels, outwidth, batch, gyval);

                                Filter1D gw = Reference(x, gy, kwidth, stride);

                                OverflowCheckedTensor x_tensor  = new OverflowCheckedTensor(Shape.Map1D(channels, inwidth, batch), xval);
                                OverflowCheckedTensor gy_tensor = new OverflowCheckedTensor(Shape.Map1D(channels, outwidth, batch), gyval);

                                OverflowCheckedTensor gw_tensor = new OverflowCheckedTensor(Shape.Kernel1D(channels, 1, kwidth));

                                ChannelwiseKernelProduct ope = new ChannelwiseKernelProduct(inwidth, channels, kwidth, stride, batch);

                                ope.Execute(x_tensor, gy_tensor, gw_tensor);

                                float[] gw_expect = gw.ToArray();
                                float[] gw_actual = gw_tensor.State;

                                CollectionAssert.AreEqual(xval, x_tensor.State);
                                CollectionAssert.AreEqual(gyval, gy_tensor.State);

                                AssertError.Tolerance(gw_expect, gw_actual, 1e-7f, 1e-5f, ref max_err, $"mismatch value {channels},{kwidth},{stride},{inwidth},{batch}");

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

            Console.WriteLine($"maxerr:{max_err}");
        }
示例#25
0
        public static Map1D Reference(Map1D x, Map1D gy, int stride)
        {
            int channels = x.Channels, batch = x.Batch;
            int inw = x.Width, outw = inw / stride;

            Map1D y  = new Map1D(channels, outw, batch);
            Map1D gx = new Map1D(channels, inw, batch);

            for (int th = 0; th < batch; th++)
            {
                for (int ox = 0; ox < outw; ox++)
                {
                    for (int ch = 0; ch < channels; ch++)
                    {
                        double max = 0;
                        for (int kx = 0; kx < stride; kx++)
                        {
                            max = Math.Max(max, x[ch, ox * stride + kx, th]);
                        }

                        y[ch, ox, th] = max;
                    }
                }
            }

            for (int th = 0; th < batch; th++)
            {
                for (int ix = 0; ix < inw; ix++)
                {
                    int ox = ix / stride;

                    if (ox < outw)
                    {
                        for (int ch = 0; ch < channels; ch++)
                        {
                            gx[ch, ix, th] = (y[ch, ox, th] <= x[ch, ix, th]) ? gy[ch, ox, th] : 0;
                        }
                    }
                    else
                    {
                        for (int ch = 0; ch < channels; ch++)
                        {
                            gx[ch, ix, th] = 0;
                        }
                    }
                }
            }

            return(gx);
        }
示例#26
0
        public void ExecuteTest()
        {
            float max_err = 0;

            Random random = new Random();

            foreach (int batch in new int[] { 1, 2 })
            {
                foreach (int channels in new int[] { 1, 2, 3, 4, 5, 6, 7, 8 })
                {
                    foreach (int leftpad in new int[] { 0, 1, 2 })
                    {
                        foreach (int rightpad in new int[] { 0, 1, 2 })
                        {
                            foreach (int inwidth in new int[] { 5, 7, 11 })
                            {
                                int outwidth = inwidth + leftpad + rightpad;

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

                                Map1D x = new Map1D(channels, inwidth, batch, xval);

                                Map1D y = Reference(x, leftpad, rightpad);

                                OverflowCheckedTensor x_tensor = new OverflowCheckedTensor(Shape.Map1D(channels, inwidth, batch), xval);
                                OverflowCheckedTensor y_tensor = new OverflowCheckedTensor(Shape.Map1D(channels, outwidth, batch));

                                TensorShaderAvxBackend.Randomize.Uniform((uint)y_tensor.Length, y_tensor.Buffer, random);

                                ZeroPadding ope = new ZeroPadding(inwidth, channels, leftpad, rightpad, batch);

                                ope.Execute(x_tensor, y_tensor);

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

                                CollectionAssert.AreEqual(xval, x_tensor.State);

                                AssertError.Tolerance(y_expect, y_actual, 1e-7f, 1e-5f, ref max_err, $"mismatch value {channels},{leftpad},{rightpad},{inwidth},{batch}");

                                Console.WriteLine($"pass: {channels},{leftpad},{rightpad},{inwidth},{batch}");
                            }
                        }
                    }
                }
            }

            Console.WriteLine($"maxerr:{max_err}");
        }
示例#27
0
        public void ReferenceTest()
        {
            int inchannels = 7, outchannels = 11, kwidth = 3, stride = 2, inwidth = 13, batch = 2;
            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]).Select((_, idx) => idx * 1e-3f).Reverse().ToArray();

            Map1D    x = new Map1D(inchannels, inwidth, batch, xval);
            Filter1D w = new Filter1D(inchannels, outchannels, kwidth, wval);

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

            float[] y_expect =
            {
                2.387000e-02f, 2.240000e-02f, 2.093000e-02f, 1.946000e-02f, 1.799000e-02f,
                1.652000e-02f, 1.505000e-02f, 1.358000e-02f, 1.211000e-02f, 1.064000e-02f,
                9.170000e-03f, 6.797000e-02f, 6.444200e-02f, 6.091400e-02f, 5.738600e-02f,
                5.385800e-02f, 5.033000e-02f, 4.680200e-02f, 4.327400e-02f, 3.974600e-02f,
                3.621800e-02f, 3.269000e-02f, 1.120700e-01f, 1.064840e-01f, 1.008980e-01f,
                9.531200e-02f, 8.972600e-02f, 8.414000e-02f, 7.855400e-02f, 7.296800e-02f,
                6.738200e-02f, 6.179600e-02f, 5.621000e-02f, 1.561700e-01f, 1.485260e-01f,
                1.408820e-01f, 1.332380e-01f, 1.255940e-01f, 1.179500e-01f, 1.103060e-01f,
                1.026620e-01f, 9.501800e-02f, 8.737400e-02f, 7.973000e-02f, 2.002700e-01f,
                1.905680e-01f, 1.808660e-01f, 1.711640e-01f, 1.614620e-01f, 1.517600e-01f,
                1.420580e-01f, 1.323560e-01f, 1.226540e-01f, 1.129520e-01f, 1.032500e-01f,
                2.443700e-01f, 2.326100e-01f, 2.208500e-01f, 2.090900e-01f, 1.973300e-01f,
                1.855700e-01f, 1.738100e-01f, 1.620500e-01f, 1.502900e-01f, 1.385300e-01f,
                1.267700e-01f, 3.105200e-01f, 2.956730e-01f, 2.808260e-01f, 2.659790e-01f,
                2.511320e-01f, 2.362850e-01f, 2.214380e-01f, 2.065910e-01f, 1.917440e-01f,
                1.768970e-01f, 1.620500e-01f, 3.546200e-01f, 3.377150e-01f, 3.208100e-01f,
                3.039050e-01f, 2.870000e-01f, 2.700950e-01f, 2.531900e-01f, 2.362850e-01f,
                2.193800e-01f, 2.024750e-01f, 1.855700e-01f, 3.987200e-01f, 3.797570e-01f,
                3.607940e-01f, 3.418310e-01f, 3.228680e-01f, 3.039050e-01f, 2.849420e-01f,
                2.659790e-01f, 2.470160e-01f, 2.280530e-01f, 2.090900e-01f, 4.428200e-01f,
                4.217990e-01f, 4.007780e-01f, 3.797570e-01f, 3.587360e-01f, 3.377150e-01f,
                3.166940e-01f, 2.956730e-01f, 2.746520e-01f, 2.536310e-01f, 2.326100e-01f,
                4.869200e-01f, 4.638410e-01f, 4.407620e-01f, 4.176830e-01f, 3.946040e-01f,
                3.715250e-01f, 3.484460e-01f, 3.253670e-01f, 3.022880e-01f, 2.792090e-01f,
                2.561300e-01f, 5.310200e-01f, 5.058830e-01f, 4.807460e-01f, 4.556090e-01f,
                4.304720e-01f, 4.053350e-01f, 3.801980e-01f, 3.550610e-01f, 3.299240e-01f,
                3.047870e-01f, 2.796500e-01f,
            };

            float[] y_actual = y.ToArray();

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

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

            Map1D    y = new Map1D(channels, outwidth, batch, yval);
            Filter1D w = new Filter1D(channels, 1, kwidth, wval);

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

            float[] x_expect =
            {
                0.0000e+00f, 1.9000e-05f, 3.6000e-05f, 5.1000e-05f, 6.4000e-05f, 7.5000e-05f, 8.4000e-05f,
                0.0000e+00f, 1.2000e-05f, 2.2000e-05f, 3.0000e-05f, 3.6000e-05f, 4.0000e-05f, 4.2000e-05f,
                1.4000e-04f, 1.5700e-04f, 1.7000e-04f, 1.7900e-04f, 1.8400e-04f, 1.8500e-04f, 1.8200e-04f,
                9.1000e-05f, 9.6000e-05f, 9.9000e-05f, 1.0000e-04f, 9.9000e-05f, 9.6000e-05f, 9.1000e-05f,
                3.2200e-04f, 3.2500e-04f, 3.2400e-04f, 3.1900e-04f, 3.1000e-04f, 2.9700e-04f, 2.8000e-04f,
                1.8200e-04f, 1.8000e-04f, 1.7600e-04f, 1.7000e-04f, 1.6200e-04f, 1.5200e-04f, 1.4000e-04f,
                5.0400e-04f, 4.9300e-04f, 4.7800e-04f, 4.5900e-04f, 4.3600e-04f, 4.0900e-04f, 3.7800e-04f,
                2.7300e-04f, 2.6400e-04f, 2.5300e-04f, 2.4000e-04f, 2.2500e-04f, 2.0800e-04f, 1.8900e-04f,
                6.8600e-04f, 6.6100e-04f, 6.3200e-04f, 5.9900e-04f, 5.6200e-04f, 5.2100e-04f, 4.7600e-04f,
                3.6400e-04f, 3.4800e-04f, 3.3000e-04f, 3.1000e-04f, 2.8800e-04f, 2.6400e-04f, 2.3800e-04f,
                8.6800e-04f, 8.2900e-04f, 7.8600e-04f, 7.3900e-04f, 6.8800e-04f, 6.3300e-04f, 5.7400e-04f,
                4.5500e-04f, 4.3200e-04f, 4.0700e-04f, 3.8000e-04f, 3.5100e-04f, 3.2000e-04f, 2.8700e-04f,
                2.1000e-04f, 1.8000e-04f, 1.4800e-04f, 1.1400e-04f, 7.8000e-05f, 4.0000e-05f, 0.0000e+00f,
                8.4000e-04f, 8.1700e-04f, 7.9200e-04f, 7.6500e-04f, 7.3600e-04f, 7.0500e-04f, 6.7200e-04f,
                5.4600e-04f, 5.1600e-04f, 4.8400e-04f, 4.5000e-04f, 4.1400e-04f, 3.7600e-04f, 3.3600e-04f,
                1.2320e-03f, 1.1650e-03f, 1.0940e-03f, 1.0190e-03f, 9.4000e-04f, 8.5700e-04f, 7.7000e-04f,
                6.3700e-04f, 6.0000e-04f, 5.6100e-04f, 5.2000e-04f, 4.7700e-04f, 4.3200e-04f, 3.8500e-04f,
                1.4140e-03f, 1.3330e-03f, 1.2480e-03f, 1.1590e-03f, 1.0660e-03f, 9.6900e-04f, 8.6800e-04f,
                7.2800e-04f, 6.8400e-04f, 6.3800e-04f, 5.9000e-04f, 5.4000e-04f, 4.8800e-04f, 4.3400e-04f,
                1.5960e-03f, 1.5010e-03f, 1.4020e-03f, 1.2990e-03f, 1.1920e-03f, 1.0810e-03f, 9.6600e-04f,
                8.1900e-04f, 7.6800e-04f, 7.1500e-04f, 6.6000e-04f, 6.0300e-04f, 5.4400e-04f, 4.8300e-04f,
                1.7780e-03f, 1.6690e-03f, 1.5560e-03f, 1.4390e-03f, 1.3180e-03f, 1.1930e-03f, 1.0640e-03f,
                9.1000e-04f, 8.5200e-04f, 7.9200e-04f, 7.3000e-04f, 6.6600e-04f, 6.0000e-04f, 5.3200e-04f,
                1.9600e-03f, 1.8370e-03f, 1.7100e-03f, 1.5790e-03f, 1.4440e-03f, 1.3050e-03f, 1.1620e-03f,
                1.0010e-03f, 9.3600e-04f, 8.6900e-04f, 8.0000e-04f, 7.2900e-04f, 6.5600e-04f, 5.8100e-04f,
                4.6200e-04f, 3.9000e-04f, 3.1600e-04f, 2.4000e-04f, 1.6200e-04f, 8.2000e-05f, 0.0000e+00f,
            };

            float[] x_actual = x.ToArray();

            AssertError.Tolerance(x_expect, x_actual, 1e-7f, 1e-5f, $"mismatch value {channels},{kwidth},{stride},{inwidth},{batch}");
        }
        public void ReferenceTest()
        {
            int inchannels = 7, outchannels = 11, inwidth = 13, batch = 2;

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

            Map1D    y = new Map1D(outchannels, inwidth, batch, yval);
            Filter1D w = new Filter1D(inchannels, outchannels, 1, wval);

            Map1D x = Reference(y, w);

            float[] x_expect =
            {
                1.485000e-03f, 1.430000e-03f, 1.375000e-03f, 1.320000e-03f, 1.265000e-03f, 1.210000e-03f, 1.155000e-03f,
                6.446000e-03f, 6.270000e-03f, 6.094000e-03f, 5.918000e-03f, 5.742000e-03f, 5.566000e-03f, 5.390000e-03f,
                1.140700e-02f, 1.111000e-02f, 1.081300e-02f, 1.051600e-02f, 1.021900e-02f, 9.922000e-03f, 9.625000e-03f,
                1.636800e-02f, 1.595000e-02f, 1.553200e-02f, 1.511400e-02f, 1.469600e-02f, 1.427800e-02f, 1.386000e-02f,
                2.132900e-02f, 2.079000e-02f, 2.025100e-02f, 1.971200e-02f, 1.917300e-02f, 1.863400e-02f, 1.809500e-02f,
                2.629000e-02f, 2.563000e-02f, 2.497000e-02f, 2.431000e-02f, 2.365000e-02f, 2.299000e-02f, 2.233000e-02f,
                3.125100e-02f, 3.047000e-02f, 2.968900e-02f, 2.890800e-02f, 2.812700e-02f, 2.734600e-02f, 2.656500e-02f,
                3.621200e-02f, 3.531000e-02f, 3.440800e-02f, 3.350600e-02f, 3.260400e-02f, 3.170200e-02f, 3.080000e-02f,
                4.117300e-02f, 4.015000e-02f, 3.912700e-02f, 3.810400e-02f, 3.708100e-02f, 3.605800e-02f, 3.503500e-02f,
                4.613400e-02f, 4.499000e-02f, 4.384600e-02f, 4.270200e-02f, 4.155800e-02f, 4.041400e-02f, 3.927000e-02f,
                5.109500e-02f, 4.983000e-02f, 4.856500e-02f, 4.730000e-02f, 4.603500e-02f, 4.477000e-02f, 4.350500e-02f,
                5.605600e-02f, 5.467000e-02f, 5.328400e-02f, 5.189800e-02f, 5.051200e-02f, 4.912600e-02f, 4.774000e-02f,
                6.101700e-02f, 5.951000e-02f, 5.800300e-02f, 5.649600e-02f, 5.498900e-02f, 5.348200e-02f, 5.197500e-02f,
                6.597800e-02f, 6.435000e-02f, 6.272200e-02f, 6.109400e-02f, 5.946600e-02f, 5.783800e-02f, 5.621000e-02f,
                7.093900e-02f, 6.919000e-02f, 6.744100e-02f, 6.569200e-02f, 6.394300e-02f, 6.219400e-02f, 6.044500e-02f,
                7.590000e-02f, 7.403000e-02f, 7.216000e-02f, 7.029000e-02f, 6.842000e-02f, 6.655000e-02f, 6.468000e-02f,
                8.086100e-02f, 7.887000e-02f, 7.687900e-02f, 7.488800e-02f, 7.289700e-02f, 7.090600e-02f, 6.891500e-02f,
                8.582200e-02f, 8.371000e-02f, 8.159800e-02f, 7.948600e-02f, 7.737400e-02f, 7.526200e-02f, 7.315000e-02f,
                9.078300e-02f, 8.855000e-02f, 8.631700e-02f, 8.408400e-02f, 8.185100e-02f, 7.961800e-02f, 7.738500e-02f,
                9.574400e-02f, 9.339000e-02f, 9.103600e-02f, 8.868200e-02f, 8.632800e-02f, 8.397400e-02f, 8.162000e-02f,
                1.007050e-01f, 9.823000e-02f, 9.575500e-02f, 9.328000e-02f, 9.080500e-02f, 8.833000e-02f, 8.585500e-02f,
                1.056660e-01f, 1.030700e-01f, 1.004740e-01f, 9.787800e-02f, 9.528200e-02f, 9.268600e-02f, 9.009000e-02f,
                1.106270e-01f, 1.079100e-01f, 1.051930e-01f, 1.024760e-01f, 9.975900e-02f, 9.704200e-02f, 9.432500e-02f,
                1.155880e-01f, 1.127500e-01f, 1.099120e-01f, 1.070740e-01f, 1.042360e-01f, 1.013980e-01f, 9.856000e-02f,
                1.205490e-01f, 1.175900e-01f, 1.146310e-01f, 1.116720e-01f, 1.087130e-01f, 1.057540e-01f, 1.027950e-01f,
                1.255100e-01f, 1.224300e-01f, 1.193500e-01f, 1.162700e-01f, 1.131900e-01f, 1.101100e-01f, 1.070300e-01f,
            };

            float[] x_actual = x.ToArray();

            AssertError.Tolerance(x_expect, x_actual, 1e-7f, 1e-5f, $"mismatch value {inchannels},{outchannels},{inwidth},{batch}");
        }
        public void ReferenceTest()
        {
            int inchannels = 7, outchannels = 11, inwidth = 13, batch = 2;

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

            Map1D    x = new Map1D(inchannels, inwidth, batch, xval);
            Filter1D w = new Filter1D(inchannels, outchannels, 1, wval);

            Map1D y = Reference(x, w);

            float[] y_expect =
            {
                1.505000e-03f, 1.358000e-03f, 1.211000e-03f, 1.064000e-03f, 9.170000e-04f, 7.700000e-04f, 6.230000e-04f, 4.760000e-04f, 3.290000e-04f, 1.820000e-04f, 3.500000e-05f,
                5.082000e-03f, 4.592000e-03f, 4.102000e-03f, 3.612000e-03f, 3.122000e-03f, 2.632000e-03f, 2.142000e-03f, 1.652000e-03f, 1.162000e-03f, 6.720000e-04f, 1.820000e-04f,
                8.659000e-03f, 7.826000e-03f, 6.993000e-03f, 6.160000e-03f, 5.327000e-03f, 4.494000e-03f, 3.661000e-03f, 2.828000e-03f, 1.995000e-03f, 1.162000e-03f, 3.290000e-04f,
                1.223600e-02f, 1.106000e-02f, 9.884000e-03f, 8.708000e-03f, 7.532000e-03f, 6.356000e-03f, 5.180000e-03f, 4.004000e-03f, 2.828000e-03f, 1.652000e-03f, 4.760000e-04f,
                1.581300e-02f, 1.429400e-02f, 1.277500e-02f, 1.125600e-02f, 9.737000e-03f, 8.218000e-03f, 6.699000e-03f, 5.180000e-03f, 3.661000e-03f, 2.142000e-03f, 6.230000e-04f,
                1.939000e-02f, 1.752800e-02f, 1.566600e-02f, 1.380400e-02f, 1.194200e-02f, 1.008000e-02f, 8.218000e-03f, 6.356000e-03f, 4.494000e-03f, 2.632000e-03f, 7.700000e-04f,
                2.296700e-02f, 2.076200e-02f, 1.855700e-02f, 1.635200e-02f, 1.414700e-02f, 1.194200e-02f, 9.737000e-03f, 7.532000e-03f, 5.327000e-03f, 3.122000e-03f, 9.170000e-04f,
                2.654400e-02f, 2.399600e-02f, 2.144800e-02f, 1.890000e-02f, 1.635200e-02f, 1.380400e-02f, 1.125600e-02f, 8.708000e-03f, 6.160000e-03f, 3.612000e-03f, 1.064000e-03f,
                3.012100e-02f, 2.723000e-02f, 2.433900e-02f, 2.144800e-02f, 1.855700e-02f, 1.566600e-02f, 1.277500e-02f, 9.884000e-03f, 6.993000e-03f, 4.102000e-03f, 1.211000e-03f,
                3.369800e-02f, 3.046400e-02f, 2.723000e-02f, 2.399600e-02f, 2.076200e-02f, 1.752800e-02f, 1.429400e-02f, 1.106000e-02f, 7.826000e-03f, 4.592000e-03f, 1.358000e-03f,
                3.727500e-02f, 3.369800e-02f, 3.012100e-02f, 2.654400e-02f, 2.296700e-02f, 1.939000e-02f, 1.581300e-02f, 1.223600e-02f, 8.659000e-03f, 5.082000e-03f, 1.505000e-03f,
                4.085200e-02f, 3.693200e-02f, 3.301200e-02f, 2.909200e-02f, 2.517200e-02f, 2.125200e-02f, 1.733200e-02f, 1.341200e-02f, 9.492000e-03f, 5.572000e-03f, 1.652000e-03f,
                4.442900e-02f, 4.016600e-02f, 3.590300e-02f, 3.164000e-02f, 2.737700e-02f, 2.311400e-02f, 1.885100e-02f, 1.458800e-02f, 1.032500e-02f, 6.062000e-03f, 1.799000e-03f,
                4.800600e-02f, 4.340000e-02f, 3.879400e-02f, 3.418800e-02f, 2.958200e-02f, 2.497600e-02f, 2.037000e-02f, 1.576400e-02f, 1.115800e-02f, 6.552000e-03f, 1.946000e-03f,
                5.158300e-02f, 4.663400e-02f, 4.168500e-02f, 3.673600e-02f, 3.178700e-02f, 2.683800e-02f, 2.188900e-02f, 1.694000e-02f, 1.199100e-02f, 7.042000e-03f, 2.093000e-03f,
                5.516000e-02f, 4.986800e-02f, 4.457600e-02f, 3.928400e-02f, 3.399200e-02f, 2.870000e-02f, 2.340800e-02f, 1.811600e-02f, 1.282400e-02f, 7.532000e-03f, 2.240000e-03f,
                5.873700e-02f, 5.310200e-02f, 4.746700e-02f, 4.183200e-02f, 3.619700e-02f, 3.056200e-02f, 2.492700e-02f, 1.929200e-02f, 1.365700e-02f, 8.022000e-03f, 2.387000e-03f,
                6.231400e-02f, 5.633600e-02f, 5.035800e-02f, 4.438000e-02f, 3.840200e-02f, 3.242400e-02f, 2.644600e-02f, 2.046800e-02f, 1.449000e-02f, 8.512000e-03f, 2.534000e-03f,
                6.589100e-02f, 5.957000e-02f, 5.324900e-02f, 4.692800e-02f, 4.060700e-02f, 3.428600e-02f, 2.796500e-02f, 2.164400e-02f, 1.532300e-02f, 9.002000e-03f, 2.681000e-03f,
                6.946800e-02f, 6.280400e-02f, 5.614000e-02f, 4.947600e-02f, 4.281200e-02f, 3.614800e-02f, 2.948400e-02f, 2.282000e-02f, 1.615600e-02f, 9.492000e-03f, 2.828000e-03f,
                7.304500e-02f, 6.603800e-02f, 5.903100e-02f, 5.202400e-02f, 4.501700e-02f, 3.801000e-02f, 3.100300e-02f, 2.399600e-02f, 1.698900e-02f, 9.982000e-03f, 2.975000e-03f,
                7.662200e-02f, 6.927200e-02f, 6.192200e-02f, 5.457200e-02f, 4.722200e-02f, 3.987200e-02f, 3.252200e-02f, 2.517200e-02f, 1.782200e-02f, 1.047200e-02f, 3.122000e-03f,
                8.019900e-02f, 7.250600e-02f, 6.481300e-02f, 5.712000e-02f, 4.942700e-02f, 4.173400e-02f, 3.404100e-02f, 2.634800e-02f, 1.865500e-02f, 1.096200e-02f, 3.269000e-03f,
                8.377600e-02f, 7.574000e-02f, 6.770400e-02f, 5.966800e-02f, 5.163200e-02f, 4.359600e-02f, 3.556000e-02f, 2.752400e-02f, 1.948800e-02f, 1.145200e-02f, 3.416000e-03f,
                8.735300e-02f, 7.897400e-02f, 7.059500e-02f, 6.221600e-02f, 5.383700e-02f, 4.545800e-02f, 3.707900e-02f, 2.870000e-02f, 2.032100e-02f, 1.194200e-02f, 3.563000e-03f,
                9.093000e-02f, 8.220800e-02f, 7.348600e-02f, 6.476400e-02f, 5.604200e-02f, 4.732000e-02f, 3.859800e-02f, 2.987600e-02f, 2.115400e-02f, 1.243200e-02f, 3.710000e-03f,
            };

            float[] y_actual = y.ToArray();

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