Example #1
0
        public override void Concat(Volume <float> right, Volume <float> result)
        {
            var batchSize = Math.Max(this.Shape.Dimensions[3], right.Shape.Dimensions[3]);

            if (this.Shape.TotalLength > 1 && right.Shape.TotalLength > 1)
            {
                var left = ReShape(new Shape(1, 1, -1, batchSize));
                right = right.ReShape(new Shape(1, 1, -1, batchSize));

                var elementPerBatch = result.Shape.TotalLength / batchSize;
                var threshold       = left.Shape.Dimensions[2];

                for (var n = 0; n < batchSize; n++)
                {
                    for (var i = 0; i < elementPerBatch; i++)
                    {
                        result.Set(0, 0, i, n, i < threshold ? left.Get(0, 0, i, n) : right.Get(0, 0, i - threshold, n));
                    }
                }
            }
            else if (this.Shape.TotalLength == 1 && right.Shape.TotalLength > 1)
            {
                // Left volume is actually a scalar => broadcast its value

                right = right.ReShape(new Shape(1, 1, -1, batchSize));
                var elementPerBatch = result.Shape.TotalLength / batchSize;
                var threshold       = 1;

                for (var n = 0; n < batchSize; n++)
                {
                    for (var i = 0; i < elementPerBatch; i++)
                    {
                        result.Set(0, 0, i, n, i < threshold ? Get(0) : right.Get(0, 0, i - threshold, n));
                    }
                }
            }
            else
            {
                // Right volume is actually a scalar => broadcast its value

                var left            = ReShape(new Shape(1, 1, -1, batchSize));
                var elementPerBatch = result.Shape.TotalLength / batchSize;
                var threshold       = left.Shape.Dimensions[2];

                for (var n = 0; n < batchSize; n++)
                {
                    for (var i = 0; i < elementPerBatch; i++)
                    {
                        result.Set(0, 0, i, n, i < threshold ? left.Get(0, 0, i, n) : right.Get(0));
                    }
                }
            }
        }
Example #2
0
        public override void Sum(Volume <float> result)
        {
            var batchsize = this.Shape.Dimensions[3];
            var channel   = this.Shape.Dimensions[2];
            var height    = this.Shape.Dimensions[1];
            var width     = this.Shape.Dimensions[0];

            var resultWIsOne = result.Shape.Dimensions[0] == 1;
            var resultHIsOne = result.Shape.Dimensions[1] == 1;
            var resultCIsOne = result.Shape.Dimensions[2] == 1;
            var resultNIsOne = result.Shape.Dimensions[3] == 1;

            for (var n = 0; n < batchsize; n++)
            {
                for (var c = 0; c < channel; c++)
                {
                    for (var h = 0; h < height; h++)
                    {
                        for (var w = 0; w < width; w++)
                        {
                            var val = Get(w, h, c, n);

                            var resultW = resultWIsOne ? 0 : w;
                            var resultH = resultHIsOne ? 0 : h;
                            var resultC = resultCIsOne ? 0 : c;
                            var resultN = resultNIsOne ? 0 : n;

                            var current = result.Get(resultW, resultH, resultC, resultN);
                            result.Set(resultW, resultH, resultC, resultN, current + val);
                        }
                    }
                }
            }
        }
Example #3
0
        public override void Tile(Volume <float> reps, Volume <float> result)
        {
            var batchsize = this.Shape.Dimensions[3];
            var channel   = this.Shape.Dimensions[2];
            var height    = this.Shape.Dimensions[1];
            var width     = this.Shape.Dimensions[0];

            var outputBatchSize = result.Shape.Dimensions[3];
            var outputChannel   = result.Shape.Dimensions[2];
            var outputHeight    = result.Shape.Dimensions[1];
            var outputWidth     = result.Shape.Dimensions[0];

            for (var n = 0; n < outputBatchSize; n++)
            {
                for (var c = 0; c < outputChannel; c++)
                {
                    for (var h = 0; h < outputHeight; h++)
                    {
                        for (var w = 0; w < outputWidth; w++)
                        {
                            result.Set(w, h, c, n, Get(w % width, h % height, c % channel, n % batchsize));
                        }
                    }
                }
            }
        }
Example #4
0
        public override void DoSum(Volume <float> result)
        {
            var batchsize = this.Shape.GetDimension(3);
            var channel   = this.Shape.GetDimension(2);
            var height    = this.Shape.GetDimension(1);
            var width     = this.Shape.GetDimension(0);

            var resultWIsOne = result.Shape.GetDimension(0) == 1;
            var resultHIsOne = result.Shape.GetDimension(1) == 1;
            var resultCIsOne = result.Shape.GetDimension(2) == 1;
            var resultNIsOne = result.Shape.GetDimension(3) == 1;

            for (int n = 0; n < batchsize; n++)
            {
                for (int c = 0; c < channel; c++)
                {
                    for (int h = 0; h < height; h++)
                    {
                        for (int w = 0; w < width; w++)
                        {
                            var val = this.Get(w, h, c, n);

                            var resultW = resultWIsOne ? 0 : w;
                            var resultH = resultHIsOne ? 0 : h;
                            var resultC = resultCIsOne ? 0 : c;
                            var resultN = resultNIsOne ? 0 : n;

                            var current = result.Get(resultW, resultH, resultC, resultN);
                            result.Set(resultW, resultH, resultC, resultN, current + val);
                        }
                    }
                }
            }
        }
Example #5
0
        public override void Norm1(Volume <float> result)
        {
            var batchSize = this.Shape.Dimensions[3];
            var reshape   = ReShape(-1, batchSize);

            var n = reshape.Shape.Dimensions[0];

            for (var i = 0; i < batchSize; i++)
            {
                var sum = 0.0f;

                for (var j = 0; j < n; j++)
                {
                    var d = reshape.Get(j, i);
                    sum += Math.Abs(d);
                }

                result.Set(new[] { i }, sum);
            }
        }
Example #6
0
        public override void DoSum(Volume <float> result)
        {
            var batchSize = this.Shape.DimensionCount > 1 ? this.Shape.GetDimension(-1) : 1;
            var reshape   = ReShape(-1, batchSize);

            var n = reshape.Shape.GetDimension(0);

            for (var i = 0; i < batchSize; i++)
            {
                var sum = 0.0f;

                for (var j = 0; j < n; j++)
                {
                    var d = reshape.Get(j, i);
                    sum += d;
                }

                result.Set(new[] { i }, sum);
            }
        }
Example #7
0
        public override void Transpose(Volume <float> result)
        {
            var expectedShape = new Shape(this.Shape.Dimensions[1], this.Shape.Dimensions[0], 1, this.Shape.Dimensions[3]);

            if (!result.Shape.Equals(expectedShape))
            {
                throw new ArgumentException($"Result shape should be {expectedShape}");
            }

            for (var n = 0; n < this.Shape.Dimensions[3]; n++)
            {
                for (var j = 0; j < this.Shape.Dimensions[1]; j++)
                {
                    for (var i = 0; i < this.Shape.Dimensions[0]; i++)
                    {
                        result.Set(j, i, 0, n, this.Get(i, j, 0, n));
                    }
                }
            }
        }
Example #8
0
        public override void DoSum(Volume <float> result)
        {
            var batchSize    = this.Shape.DimensionCount > 1 ? this.Shape.GetDimension(-1) : 1;
            var inputReshape = ReShape(-1, batchSize);

            var n = inputReshape.Shape.GetDimension(0);

            if (batchSize > 1 && result.Shape.DimensionCount > 1 && result.Shape.GetDimension(3) == 1)
            {
                var resultReshape = result.ReShape(-1, 1);

                for (var j = 0; j < n; j++)
                {
                    var sum = 0.0f;

                    // Sum over batch
                    for (var i = 0; i < batchSize; i++)
                    {
                        var d = inputReshape.Get(j, i);
                        sum += d;
                    }

                    resultReshape.Set(j, 0, sum);
                }
            }
            else
            {
                for (var i = 0; i < batchSize; i++)
                {
                    var sum = 0.0f;

                    for (var j = 0; j < n; j++)
                    {
                        var d = inputReshape.Get(j, i);
                        sum += d;
                    }

                    result.Set(new[] { i }, sum);
                }
            }
        }
Example #9
0
        public override void Extract(int length, int offset, Volume <float> result)
        {
            var input = ReShape(1, 1, Shape.None, Shape.Keep);

            if (input.Shape.TotalLength == 1)
            {
                var v = input.Get(0);
                this.Storage.Map(x => v, result.Storage);
            }
            else
            {
                var batchSize = this.Shape.Dimensions[3];
                for (var n = 0; n < batchSize; n++)
                {
                    for (var i = 0; i < length; i++)
                    {
                        result.Set(0, 0, i, n, input.Get(0, 0, i + offset, n));
                    }
                }
            }
        }
Example #10
0
        public override void MatMultiply(Volume <float> right, Volume <float> result)
        {
            if (this.Shape.Dimensions[2] != 1 || right.Shape.Dimensions[2] != 1)
            {
                throw new ArgumentException($"Left and right volumes should be [w, h, 1, b]. left = {this.Shape} right = {right.Shape}");
            }

            var broadCastLeft  = this.Shape.Dimensions[3] == 1;
            var broadCastRight = right.Shape.Dimensions[3] == 1;

            if (this.Shape.Dimensions[3] != right.Shape.Dimensions[3] && !(broadCastLeft || broadCastRight))
            {
                throw new ArgumentException($"Left and right volumes should have the same batch size. left = {this.Shape.Dimensions[3]} right = {right.Shape.Dimensions[3]}");
            }

            var expectedShape = ComputeMatMultiplyShape(this.Shape, right.Shape);

            if (!result.Shape.Equals(expectedShape))
            {
                throw new ArgumentException($"Result shape should be {expectedShape} but is {result.Shape}");
            }

            for (var n = 0; n < this.Shape.Dimensions[3]; n++)
            {
                for (var i = 0; i < expectedShape.Dimensions[0]; i++)
                {
                    for (var j = 0; j < expectedShape.Dimensions[1]; j++)
                    {
                        var cell = 0.0f;
                        for (var k = 0; k < this.Shape.Dimensions[0]; k++)
                        {
                            cell += this.Get(k, j, 0, broadCastLeft ? 0 : n) * right.Get(i, k, 0, broadCastRight ? 0 : n);
                        }

                        result.Set(i, j, 0, n, cell);
                    }
                }
            }
        }
Example #11
0
        public override void Min(Volume <float> result)
        {
            var batchSize = this.Shape.Dimensions[3];
            var reshape   = ReShape(-1, batchSize);

            var n = reshape.Shape.Dimensions[0];

            for (var i = 0; i < batchSize; i++)
            {
                var min = float.MaxValue;

                for (var j = 0; j < n; j++)
                {
                    var d = reshape.Get(j, i);
                    if (d < min)
                    {
                        min = d;
                    }
                }

                result.Set(new[] { i }, min);
            }
        }
Example #12
0
        public override void DoMax(Volume <float> result)
        {
            var batchSize = this.Shape.DimensionCount > 1 ? this.Shape.GetDimension(-1) : 1;
            var reshape   = ReShape(-1, batchSize);

            var n = reshape.Shape.GetDimension(0);

            for (var i = 0; i < batchSize; i++)
            {
                var max = float.MinValue;

                for (var j = 0; j < n; j++)
                {
                    var d = reshape.Get(j, i);
                    if (d > max)
                    {
                        max = d;
                    }
                }

                result.Set(new[] { i }, max);
            }
        }