Example #1
0
        // Just finding offsets, then use them to determine max width, start X location, etc.
        public static void FindMaximumOffsets(
            RangedLayer layer,
            out Expression OffsetX,
            out Expression OffsetY,
            out Expression OffsetZ)
        {
            if (layer == null)
            {
                throw new ArgumentNullException("layer");
            }

            OffsetX = layer.OffsetX;
            OffsetY = layer.OffsetY;
            OffsetZ = layer.OffsetZ;

            foreach (var input in layer.Inputs)
            {
                if (input == null)
                {
                    continue;
                }

                Expression iOffsetX, iOffsetY, iOffsetZ;
                FindMaximumOffsets(input, out iOffsetX, out iOffsetY, out iOffsetZ);

                OffsetX = GetSmallestOrLargestExpression(OffsetX, iOffsetX, true);
                OffsetY = GetSmallestOrLargestExpression(OffsetY, iOffsetY, true);
                OffsetZ = GetSmallestOrLargestExpression(OffsetZ, iOffsetZ, true);
            }
        }
Example #2
0
        /// <summary>
        /// Process an input runtime layer.
        /// </summary>
        /// <param name="ranged">The current ranged layer.</param>
        /// <param name="layer">The current runtime layer.</param>
        /// <param name="input">The input runtime layer.</param>
        /// <returns>The input ranged layer.</returns>
        private static RangedLayer ProcessInput(RangedLayer currentRanged, RuntimeLayer currentRuntime, RuntimeLayer inputRuntime)
        {
            // Set up the new ranged layer.
            var inputRanged = new RangedLayer();

            inputRanged.X      = currentRanged.X;
            inputRanged.Y      = currentRanged.Y;
            inputRanged.Z      = currentRanged.Z;
            inputRanged.Width  = currentRanged.Width;
            inputRanged.Height = currentRanged.Height;
            inputRanged.Depth  = currentRanged.Depth;
            inputRanged.Layer  = inputRuntime;

            // Determine if we need to adjust the width, height and depth.
            if (currentRuntime.Algorithm.InputWidthAtHalfSize[0])
            {
                inputRanged.Width = CreateDivideByTwo(inputRanged.Width);
            }
            if (currentRuntime.Algorithm.InputHeightAtHalfSize[0])
            {
                inputRanged.Height = CreateDivideByTwo(inputRanged.Height);
            }
            if (currentRuntime.Algorithm.InputDepthAtHalfSize[0])
            {
                inputRanged.Depth = CreateDivideByTwo(inputRanged.Depth);
            }

            // Determine if we need to adjust the X, Y or Z offsets.
            if (currentRuntime.Algorithm.RequiredXBorder[0] > 0)
            {
                inputRanged.X = CreateSubtraction(inputRanged.X, currentRuntime.Algorithm.RequiredXBorder[0]);
                //inputRanged.Width = CreateAddition(inputRanged.Width, currentRuntime.Algorithm.RequiredXBorder * 2);
            }
            if (currentRuntime.Algorithm.RequiredYBorder[0] > 0)
            {
                inputRanged.Y = CreateSubtraction(inputRanged.Y, currentRuntime.Algorithm.RequiredYBorder[0]);
                //inputRanged.Height = CreateAddition(inputRanged.Height, currentRuntime.Algorithm.RequiredYBorder * 2);
            }
            if (currentRuntime.Algorithm.RequiredZBorder[0] > 0)
            {
                inputRanged.Z = CreateSubtraction(inputRanged.Z, currentRuntime.Algorithm.RequiredZBorder[0]);
                //inputRanged.Depth = CreateAddition(inputRanged.Depth, currentRuntime.Algorithm.RequiredZBorder * 2);
            }

            // Process inputs recursively.
            var inputs = inputRuntime.GetInputs();

            inputRanged.Inputs = new RangedLayer[inputs.Length];
            for (var i = 0; i < inputs.Length; i++)
            {
                inputRanged.Inputs[i] = inputs[i] == null ? null : ProcessInput(inputRanged, inputRuntime, inputs[i]);
            }

            // Return the new layer.
            return(inputRanged);
        }
Example #3
0
        public void AllBorderTest()
        {
            var perlin = this.CreateRuntimeLayer(new AlgorithmPerlin());
            var passthrough = this.CreateRuntimeLayer(new AlgorithmPassthrough { XBorder = 7, YBorder = 9, ZBorder = 11 });
            passthrough.SetInput(0, perlin);

            var ranged = new RangedLayer(passthrough);
            Assert.Equal("x", ranged.X.GetText());
            Assert.Equal("y", ranged.Y.GetText());
            Assert.Equal("z", ranged.Z.GetText());
            Assert.Equal("x + width", ranged.OuterX.GetText());
            Assert.Equal("y + height", ranged.OuterY.GetText());
            Assert.Equal("z + depth", ranged.OuterZ.GetText());
            Assert.Equal("width", ranged.Width.GetText());
            Assert.Equal("height", ranged.Height.GetText());
            Assert.Equal("depth", ranged.Depth.GetText());
            Assert.Equal("14", ranged.CalculationStartI.GetText());
            Assert.Equal("18", ranged.CalculationStartJ.GetText());
            Assert.Equal("22", ranged.CalculationStartK.GetText());
            Assert.Equal("(width + 14)", ranged.CalculationEndI.GetText());
            Assert.Equal("(height + 18)", ranged.CalculationEndJ.GetText());
            Assert.Equal("(depth + 22)", ranged.CalculationEndK.GetText());
            Assert.Equal("-7", ranged.OffsetI.GetText());
            Assert.Equal("-9", ranged.OffsetJ.GetText());
            Assert.Equal("-11", ranged.OffsetK.GetText());
            Assert.Equal("-7", ranged.OffsetX.GetText());
            Assert.Equal("-9", ranged.OffsetY.GetText());
            Assert.Equal("-11", ranged.OffsetZ.GetText());

            ranged = ranged.Inputs[0];
            Assert.Equal("(x - 7)", ranged.X.GetText());
            Assert.Equal("(y - 9)", ranged.Y.GetText());
            Assert.Equal("(z - 11)", ranged.Z.GetText());
            Assert.Equal("(x + width + 7)", ranged.OuterX.GetText());
            Assert.Equal("(y + height + 9)", ranged.OuterY.GetText());
            Assert.Equal("(z + depth + 11)", ranged.OuterZ.GetText());
            Assert.Equal("(width + 14)", ranged.Width.GetText());
            Assert.Equal("(height + 18)", ranged.Height.GetText());
            Assert.Equal("(depth + 22)", ranged.Depth.GetText());
            Assert.Equal("0", ranged.CalculationStartI.GetText());
            Assert.Equal("0", ranged.CalculationStartJ.GetText());
            Assert.Equal("0", ranged.CalculationStartK.GetText());
            Assert.Equal("(width + 14)", ranged.CalculationEndI.GetText());
            Assert.Equal("(height + 18)", ranged.CalculationEndJ.GetText());
            Assert.Equal("(depth + 22)", ranged.CalculationEndK.GetText());
            Assert.Equal("0", ranged.OffsetI.GetText());
            Assert.Equal("0", ranged.OffsetJ.GetText());
            Assert.Equal("0", ranged.OffsetK.GetText());
            Assert.Equal("-7", ranged.OffsetX.GetText());
            Assert.Equal("-9", ranged.OffsetY.GetText());
            Assert.Equal("-11", ranged.OffsetZ.GetText());
        }
Example #4
0
        /// <summary>
        /// Given the specified ranged layer, find expressions which determine the total
        /// extent of the main loop for the compilation process.
        /// </summary>
        public static void FindMaximumBounds(
            RangedLayer layer,
            out Expression x,
            out Expression y,
            out Expression z,
            out Expression width,
            out Expression height,
            out Expression depth,
            out Expression outerx,
            out Expression outery,
            out Expression outerz)
        {
            if (layer == null)
            {
                throw new ArgumentNullException("layer");
            }

            // Set initial values.
            x      = layer.X;
            y      = layer.Y;
            z      = layer.Z;
            width  = layer.Width;
            height = layer.Height;
            depth  = layer.Depth;
            outerx = layer.OuterX;
            outery = layer.OuterY;
            outerz = layer.OuterZ;

            // For each of the inputs, evaluate which is the appropriate
            // expression.
            foreach (var input in layer.Inputs)
            {
                if (input == null)
                {
                    continue;
                }

                Expression ix, iy, iz, iwidth, iheight, idepth, iouterx, ioutery, iouterz;
                FindMaximumBounds(input, out ix, out iy, out iz, out iwidth, out iheight, out idepth, out iouterx, out ioutery, out iouterz);

                x      = GetSmallestOrLargestExpression(x, ix, false);
                y      = GetSmallestOrLargestExpression(y, iy, false);
                z      = GetSmallestOrLargestExpression(z, iz, false);
                width  = GetSmallestOrLargestExpression(width, iwidth, true);
                height = GetSmallestOrLargestExpression(height, iheight, true);
                depth  = GetSmallestOrLargestExpression(depth, idepth, true);
                outerx = GetSmallestOrLargestExpression(outerx, iouterx, true);
                outery = GetSmallestOrLargestExpression(outery, ioutery, true);
                outerz = GetSmallestOrLargestExpression(outerz, iouterz, true);
            }
        }
Example #5
0
        private static ProcessedResult ProcessRuntimeLayer(RuntimeLayer layer)
        {
            // Create our own processed result; a copy of our own state plus
            // somewhere to accumulate code.
            var result = new ProcessedResult();

            result.ProcessedCode = "";

            // Get a reference to the algorithm that the runtime layer is using.
            var algorithm = layer.Algorithm;

            if (algorithm == null)
            {
                throw new InvalidOperationException("Attempted to compile null runtime layer!");
            }

            // Use RangedLayer to work out the metrics.
            var        ranged = new RangedLayer(layer);
            Expression ix, iy, iz, iwidth, iheight, idepth, iouterx, ioutery, iouterz;

            RangedLayer.FindMaximumBounds(ranged, out ix, out iy, out iz, out iwidth, out iheight, out idepth, out iouterx, out ioutery, out iouterz);

            // Add __cwidth, __cheight and __cdepth declarations.
            result.Declarations += "int __cx = (int)((x - (" + ix.GetText(null) + ")));\n";
            result.Declarations += "int __cy = (int)((y - (" + iy.GetText(null) + ")));\n";
            result.Declarations += "int __cz = (int)((z - (" + iz.GetText(null) + ")));\n";
            result.Declarations += "int __cwidth = " + iwidth.GetText(null) + ";\n";
            result.Declarations += "int __cheight = " + iheight.GetText(null) + ";\n";
            result.Declarations += "int __cdepth = " + idepth.GetText(null) + ";\n";

            // Create the for loop that our calculations are done within.
            result.ProcessedCode += @"for (var k = (int)((" + iz.GetText(null) + ") - z); k < " + iouterz.GetText(null) + @"; k++)
for (var i = (int)((" + ix.GetText(null) + ") - x); i < " + iouterx.GetText(null) + @"; i++)
for (var j = (int)((" + iy.GetText(null) + ") - y); j < " + ioutery.GetText(null) + @"; j++)
{
";

            // Now add the code for the layer.
            var inputResult = CompileRuntimeLayer(layer, ranged, null);

            result.ProcessedCode     += inputResult.ProcessedCode;
            result.OutputVariableName = inputResult.OutputVariableName;
            result.OutputVariableType = inputResult.OutputVariableType;
            result.Declarations      += inputResult.Declarations;

            // Terminate the for loop and return the result.
            result.ProcessedCode += "}";
            return(result);
        }
Example #6
0
        /// <summary>
        /// Initializes the ranged layer from a runtime layer.
        /// </summary>
        private static void InitializeFromRuntime(RangedLayer ranged, RuntimeLayer layer)
        {
            // Set up the initial expressions.
            ranged.X      = new IdentifierExpression("x");
            ranged.Y      = new IdentifierExpression("y");
            ranged.Z      = new IdentifierExpression("z");
            ranged.Width  = new IdentifierExpression("width");
            ranged.Height = new IdentifierExpression("height");
            ranged.Depth  = new IdentifierExpression("depth");

            // Go through all of the inputs and process them.
            var inputs = layer.GetInputs();

            ranged.Inputs = new RangedLayer[inputs.Length];
            for (var i = 0; i < inputs.Length; i++)
            {
                ranged.Inputs[i] = inputs[i] == null ? null : ProcessInput(ranged, layer, inputs[i]);
            }
        }
Example #7
0
        private static ProcessedResult CompileRuntimeLayer(RuntimeLayer layer, RangedLayer ranged, IAlgorithm parent)
        {
            // Create our own processed result; a copy of our own state plus
            // somewhere to accumulate code.
            var result = new ProcessedResult();

            result.ProcessedCode = "";

            // Get a reference to the algorithm that the runtime layer is using.
            var algorithm = layer.Algorithm;

            if (algorithm == null)
            {
                throw new InvalidOperationException("Attempted to compile null runtime layer!");
            }
            var algorithmType = algorithm.GetType();

            // If the runtime layer has inputs, we need to process them first.
            if (layer.Algorithm.InputTypes.Length > 0)
            {
                var inputs = layer.GetInputs();
                result.InputVariableNames = new string[inputs.Length];
                for (var i = 0; i < inputs.Length; i++)
                {
                    var inputResult = CompileRuntimeLayer(inputs[i], ranged.Inputs[i], layer.Algorithm);
                    result.ProcessedCode        += inputResult.ProcessedCode;
                    result.InputVariableNames[i] = inputResult.OutputVariableName;
                    result.Declarations         += inputResult.Declarations;
                }
            }

            // Create the storage array.
            result.OutputVariableName = GenerateRandomIdentifier();
            result.OutputVariableType = algorithm.OutputType.FullName;
            result.Declarations      += result.OutputVariableType + "[] " + result.OutputVariableName +
                                        " = new " + result.OutputVariableType + "[__cwidth * __cheight * __cdepth];\n";

            Console.WriteLine(ranged.ToString());

            // Add the conditional container.
            string code = "if (k >= (int)((" + ranged.Z.GetText(null) + ") - z) && i >= (int)((" + ranged.X.GetText(null) + ") - x) && j >= (int)((" + ranged.Y.GetText(null) + ") - y)" +
                          " && k < " + ranged.OuterZ.GetText(null) + " && i < " + ranged.OuterX.GetText(null) + " && j < " + ranged.OuterY.GetText(null) + @")
{
";

            /*result.Declarations += "Console.WriteLine(\"COMPILED: \" + " +
             *  "" + ranged.X + " + \" \" + " +
             *  "" + ranged.Y + " + \" \" + " +
             *  "" + ranged.Z + " + \" \" + " +
             *  "" + ranged.Width + " + \" \" + " +
             *  "" + ranged.Height + " + \" \" + " +
             *  "" + ranged.Depth + ");";*/

            // Refactor the method.
            AstBuilder astBuilder;
            var        method = DecompileUtil.GetAlgorithmCode(algorithmType, out astBuilder);

            AlgorithmRefactorer.InlineMethod(algorithm, method, result.OutputVariableName, result.InputVariableNames,
                                             "__cx", "__cy", "__cz",
                                             "__cwidth", "__cheight", "__cdepth");
            AlgorithmRefactorer.RemoveUsingStatements(astBuilder.CompilationUnit, result.UsingStatements);
            code += method.Body.GetText();

            // Terminate the conditional container and return.
            code += "computations += 1;";
            code += "}\n";
            result.ProcessedCode += code;
            return(result);
        }
        public override int Run(string[] remainingArguments)
        {
            var runtime = this.m_Configuration.GetConfiguration() as RuntimeLayer;
            if (runtime == null)
            {
                Console.WriteLine("Configuration is already compiled.");
                return 1;
            }

            // ------- RANGED --------
            Expression xl, yl, zl, width, height, depth, outerX, outerY, outerZ;
            var ranged = new RangedLayer(runtime);
            PrintRangedTree(ranged);
            RangedLayer.FindMaximumBounds(
                ranged,
                out xl, out yl, out zl,
                out width, out height, out depth,
                out outerX, out outerY, out outerZ);
            Console.WriteLine();
            Console.WriteLine("Information about this structure:");
            Console.WriteLine(
                " * The minimum X, Y, Z positions to be encountered are: " +
                xl + ", " +
                yl + ", " +
                zl + ".");
            Console.WriteLine(
                " * The maximum X, Y, Z positions to be encountered are: " +
                outerX + ", " +
                outerY + ", " +
                outerZ + ".");
            Console.WriteLine();
            Console.WriteLine("How the processing will occur:");
            Console.WriteLine(
                " * The size of the storage arrays in the generated code will be: " +
                width + ", " +
                height + ", " +
                depth + ".");
            Console.WriteLine(" * The i, j, k values will start at 0, 0, 0.");
            Console.WriteLine(
                " * The i, j, k values will end at " +
                width + ", " +
                height + ", " +
                depth + ".");
            Console.WriteLine();

            // ------- TEST CODE -------

            var compiledCode = LayerCompiler.GenerateCode(runtime, this.m_ShowOptimizedCode);

            Console.WriteLine("The generated code is:");
            Console.WriteLine();
            Console.WriteLine(compiledCode);

            var compiled = LayerCompiler.Compile(runtime, this.m_UseOptimizedCode);

            int computations;
            var runtimeData = runtime.GenerateData(-10, -10, -10, 20, 20, 20, out computations);
            var compiledData = compiled.GenerateData(-10, -10, -10, 20, 20, 20, out computations);
            var matches = true;
            var count = 0;
            var total = 0;
            for (var x = 0; x < 20; x++)
            for (var y = 0; y < 20; y++)
            for (var z = 0; z < 20; z++)
            {
                total += 1;
                if (runtimeData[x + y * 20 + z * 20 * 20] != compiledData[x + y * 20 + z * 20 * 20])
                {
                    count += 1;
                    /*Console.WriteLine("Runtime (" +
                    runtimeData[x + y * 20 + z * 20 * 20] +
                    ") at " + x + ", " + y + ", " + z + " doesn't match compiled (" +
                    compiledData[x + y * 20 + z * 20 * 20] + ").");*/
                    matches = false;
                }
            }
            if (matches)
                Console.WriteLine("Compiled layer matches runtime.");
            else
                Console.WriteLine("Compiled layer is " + (count / (double)total) * 100 + "% different to runtime.");

            return 0;
        }
 private void PrintRangedTree(RangedLayer layer, string indent = " ", string desired = "\x250E")
 {
     var i = "  ";
     var d = "\x250E";
     foreach (var input in layer.Inputs)
     {
         PrintRangedTree(input, indent + i, d);
         i = " \x2503";
         d = "\x2520";
     }
     var x = "\x2500\x2500";
     if (layer.Inputs.Length > 0)
         x = "\x2500\x2538";
     var line =
         indent.Substring(0, indent.Length - 1) +
         desired + x + " " +
         layer.Layer.Algorithm.GetType().FullName;
     while (line.Length < 80) line += " ";
     line += "runs from " + layer.X + ", " + layer.Y + ", " + layer.Z;
     Console.WriteLine(line);
     var writeLine = new Action<string>(s =>
     {
         var line2 = indent.Substring(0, indent.Length - 1) + "\x2503" + " " + " ";
         while (line2.Length < 80) line2 += " ";
         line2 += s;
         Console.WriteLine(line2);
     });
     writeLine("runs to   " + layer.OuterX + ", " + layer.OuterY + ", " + layer.OuterZ);
     writeLine("with size " + layer.Width + ", " + layer.Height + ", " + layer.Depth);
     writeLine(
         "calculation begins when i, j, k is " +
         layer.CalculationStartI + ", " +
         layer.CalculationStartJ + ", " +
         layer.CalculationStartK);
     writeLine(
         "calculation ends when i, j, k is " +
         layer.CalculationEndI + ", " +
         layer.CalculationEndJ + ", " +
         layer.CalculationEndK);
     writeLine(
         "during calculation i, j, k is offset by " +
         layer.OffsetI + ", " +
         layer.OffsetJ + ", " +
         layer.OffsetK);
     writeLine(
         "during calculation x, y, z is offset by " +
         layer.OffsetX + ", " +
         layer.OffsetY + ", " +
         layer.OffsetZ);
 }
Example #10
0
        private static ProcessedResult CompileRuntimeLayer(RuntimeLayer layer, RangedLayer ranged, IAlgorithm parent)
        {
            // Create our own processed result; a copy of our own state plus
            // somewhere to accumulate code.
            var result = new ProcessedResult();
            result.ProcessedCode = string.Empty;
            result.InitializationCode = string.Empty;

            // Get a reference to the algorithm that the runtime layer is using.
            var algorithm = layer.Algorithm;
            if (algorithm == null)
                throw new InvalidOperationException("Attempted to compile null runtime layer!");
            var algorithmType = algorithm.GetType();

            // If the runtime layer has inputs, we need to process them first.
            var inputs = layer.GetInputs();
            result.InputVariableNames = new string[inputs.Length];
            for (var i = 0; i < inputs.Length; i++)
            {
                var inputResult = CompileRuntimeLayer(inputs[i], ranged.Inputs[i], layer.Algorithm);
                result.ProcessedCode += inputResult.ProcessedCode;
                result.InitializationCode += inputResult.InitializationCode;
                result.InputVariableNames[i] = inputResult.OutputVariableName;
                result.Declarations += inputResult.Declarations;
                result.UsingStatements.AddRange(inputResult.UsingStatements);
            }

            // Create the storage array.
            result.OutputVariableName = GenerateRandomIdentifier();
            result.OutputVariableType = algorithm.OutputType.FullName;
            result.Declarations += result.OutputVariableType + "[] " + result.OutputVariableName +
                                   " = new " + result.OutputVariableType + "[__cwidth * __cheight * __cdepth];\n";

            // Add the conditional container.
            var code = "if (i >= " + ranged.CalculationStartI.GetText(null) + " && " +
                       "    j >= " + ranged.CalculationStartJ.GetText(null) + " && " +
                       "    k >= " + ranged.CalculationStartK.GetText(null) + " && " +
                       "    i <= " + ranged.CalculationEndI.GetText(null) + " && " +
                       "    j <= " + ranged.CalculationEndJ.GetText(null) + " && " +
                       "    k <= " + ranged.CalculationEndK.GetText(null) + ") {";

            // Refactor the method.
            AstBuilder astBuilder;
            var method = DecompileUtil.GetMethodCode(algorithmType, out astBuilder, "ProcessCell");
            MethodDeclaration initialize = null;
            try
            {
                initialize = DecompileUtil.GetMethodCode(algorithmType, out astBuilder, "Initialize");
            }
            catch (MissingMethodException)
            {
            }

            AlgorithmRefactorer.InlineMethod(
                algorithm,
                method,
                result.OutputVariableName,
                result.InputVariableNames,
                new ParenthesizedExpression(
                    new BinaryOperatorExpression(
                        new BinaryOperatorExpression(
                            new IdentifierExpression("x"),
                            BinaryOperatorType.Add,
                            ranged.OffsetX.Clone()),
                        BinaryOperatorType.Add,
                        new BinaryOperatorExpression(
                            new IdentifierExpression("i"),
                            BinaryOperatorType.Add,
                            ranged.OffsetI.Clone()))),
                new ParenthesizedExpression(
                    new BinaryOperatorExpression(
                        new BinaryOperatorExpression(
                            new IdentifierExpression("y"),
                            BinaryOperatorType.Add,
                            ranged.OffsetY.Clone()),
                        BinaryOperatorType.Add,
                        new BinaryOperatorExpression(
                            new IdentifierExpression("j"),
                            BinaryOperatorType.Add,
                            ranged.OffsetJ.Clone()))),
                new ParenthesizedExpression(
                    new BinaryOperatorExpression(
                        new BinaryOperatorExpression(
                            new IdentifierExpression("z"),
                            BinaryOperatorType.Add,
                            ranged.OffsetZ.Clone()),
                        BinaryOperatorType.Add,
                        new BinaryOperatorExpression(
                            new IdentifierExpression("k"),
                            BinaryOperatorType.Add,
                            ranged.OffsetK.Clone()))),
                new ParenthesizedExpression(
                    new BinaryOperatorExpression(
                        new IdentifierExpression("i"),
                        BinaryOperatorType.Add,
                        ranged.OffsetI.Clone())),
                new ParenthesizedExpression(
                    new BinaryOperatorExpression(
                        new IdentifierExpression("j"),
                        BinaryOperatorType.Add,
                        ranged.OffsetJ.Clone())),
                new ParenthesizedExpression(
                    new BinaryOperatorExpression(
                        new IdentifierExpression("k"),
                        BinaryOperatorType.Add,
                        ranged.OffsetK.Clone())),
                new IdentifierExpression("__cwidth"),
                new IdentifierExpression("__cheight"),
                new IdentifierExpression("__cdepth"),
                new PrimitiveExpression(0),
                new PrimitiveExpression(0),
                new PrimitiveExpression(0));
            if (initialize != null)
                AlgorithmRefactorer.InlineInitialize(algorithm, initialize);
            AlgorithmRefactorer.RemoveUsingStatements(astBuilder.CompilationUnit, result.UsingStatements);
            AlgorithmRefactorer.FactorOutAlgorithmFields(algorithmType, method, initialize, ref result.Declarations);
            code += method.Body.GetText();

            // Terminate the conditional container and return.
            code += "computations += 1;";
            code += "}\n";
            result.ProcessedCode += code;
            if (initialize != null)
                result.InitializationCode += initialize.Body.GetText();
            return result;
        }
Example #11
0
        /// <summary>
        /// Initializes the ranged layer from a runtime layer.
        /// </summary>
        private static void InitializeFromRuntime(RangedLayer ranged, RuntimeLayer layer)
        {
            // Set up the initial expressions.
            ranged.X = new IdentifierExpression("x");
            ranged.Y = new IdentifierExpression("y");
            ranged.Z = new IdentifierExpression("z");
            ranged.Layer = layer;
            ranged.Width = new IdentifierExpression("width");
            ranged.Height = new IdentifierExpression("height");
            ranged.Depth = new IdentifierExpression("depth");
            ranged.OuterX = new BinaryOperatorExpression(
                ranged.X.Clone(),
                BinaryOperatorType.Add,
                ranged.Width.Clone());
            ranged.OuterY = new BinaryOperatorExpression(
                ranged.Y.Clone(),
                BinaryOperatorType.Add,
                ranged.Height.Clone());
            ranged.OuterZ = new BinaryOperatorExpression(
                ranged.Z.Clone(),
                BinaryOperatorType.Add,
                ranged.Depth.Clone());

            // Go through all of the inputs and process them.
            var inputs = layer.GetInputs();
            ranged.Inputs = new RangedLayer[inputs.Length];
            for (var i = 0; i < inputs.Length; i++)
            {
                ranged.Inputs[i] = inputs[i] == null ? null : ProcessInput(ranged, layer, inputs[i], i);
            }

            // Now we have to find the maximum values.
            Expression mx, my, mz, mwidth, mheight, mdepth, mouterx, moutery, mouterz;
            FindMaximumBounds(
                ranged,
                out mx,
                out my,
                out mz,
                out mwidth,
                out mheight,
                out mdepth,
                out mouterx,
                out moutery,
                out mouterz);

            // And recalculate back all of the calculation start / end values.
            ranged.CalculationStartI = DetermineCalculationStartForRootLayerFromMaximumBound(mx.Clone(), "x");
            ranged.CalculationStartJ = DetermineCalculationStartForRootLayerFromMaximumBound(my.Clone(), "y");
            ranged.CalculationStartK = DetermineCalculationStartForRootLayerFromMaximumBound(mz.Clone(), "z");
            ranged.CalculationEndI = mwidth.Clone();
            ranged.CalculationEndJ = mheight.Clone();
            ranged.CalculationEndK = mdepth.Clone();
            ranged.OffsetI = DetermineRelativeOffsetForLayerFromXYZ(ranged.CalculationStartI, ranged.X, mx, "x");
            ranged.OffsetJ = DetermineRelativeOffsetForLayerFromXYZ(ranged.CalculationStartJ, ranged.Y, my, "y");
            ranged.OffsetK = DetermineRelativeOffsetForLayerFromXYZ(ranged.CalculationStartK, ranged.Z, mz, "z");
            ranged.OffsetX = DetermineAbsoluteOffsetForRootLayerFromMaximumBound(mx.Clone(), "x");
            ranged.OffsetY = DetermineAbsoluteOffsetForRootLayerFromMaximumBound(my.Clone(), "y");
            ranged.OffsetZ = DetermineAbsoluteOffsetForRootLayerFromMaximumBound(mz.Clone(), "z");

            // Go through all of the inputs and backfill them.
            for (var i = 0; i < inputs.Length; i++)
            {
                BackfillInput(ranged, layer, ranged.Inputs[i], i, mx, my, mz);
            }
        }
Example #12
0
        /// <summary>
        /// Backfills the ranged input layer to calculate the CalculationStart/End properties.
        /// </summary>
        /// <param name="currentRanged">The current ranged layer.</param>
        /// <param name="currentRuntime">The current runtime layer.</param>
        /// <param name="inputRanged">The input ranged layer.</param>
        /// <param name="idx">The index of the input layer in the parent layer.</param>
        private static void BackfillInput(
            RangedLayer currentRanged,
            RuntimeLayer currentRuntime,
            RangedLayer inputRanged,
            int idx,
            Expression mx,
            Expression my,
            Expression mz)
        {
            inputRanged.CalculationStartI = currentRanged.CalculationStartI.Clone();
            inputRanged.CalculationStartJ = currentRanged.CalculationStartJ.Clone();
            inputRanged.CalculationStartK = currentRanged.CalculationStartK.Clone();
            inputRanged.CalculationEndI = currentRanged.CalculationEndI.Clone();
            inputRanged.CalculationEndJ = currentRanged.CalculationEndJ.Clone();
            inputRanged.CalculationEndK = currentRanged.CalculationEndK.Clone();
            inputRanged.OffsetX = currentRanged.OffsetX.Clone();
            inputRanged.OffsetY = currentRanged.OffsetY.Clone();
            inputRanged.OffsetZ = currentRanged.OffsetZ.Clone();

            if (currentRuntime.Algorithm.RequiredXBorder[idx] > 0)
                inputRanged.CalculationStartI = CreateSubtraction(
                    inputRanged.CalculationStartI,
                    currentRuntime.Algorithm.RequiredXBorder[idx] * 2);
            if (currentRuntime.Algorithm.RequiredYBorder[idx] > 0)
                inputRanged.CalculationStartJ = CreateSubtraction(
                    inputRanged.CalculationStartJ,
                    currentRuntime.Algorithm.RequiredYBorder[idx] * 2);
            if (currentRuntime.Algorithm.RequiredZBorder[idx] > 0)
                inputRanged.CalculationStartK = CreateSubtraction(
                    inputRanged.CalculationStartK,
                    currentRuntime.Algorithm.RequiredZBorder[idx] * 2);

            if (currentRuntime.Algorithm.InputWidthAtHalfSize[idx])
                inputRanged.CalculationEndI = CreateDivideByTwo(inputRanged.CalculationEndI);
            if (currentRuntime.Algorithm.InputHeightAtHalfSize[idx])
                inputRanged.CalculationEndJ = CreateDivideByTwo(inputRanged.CalculationEndJ);
            if (currentRuntime.Algorithm.InputDepthAtHalfSize[idx])
                inputRanged.CalculationEndK = CreateDivideByTwo(inputRanged.CalculationEndK);

            inputRanged.OffsetI = DetermineRelativeOffsetForLayerFromXYZ(
                inputRanged.CalculationStartI,
                inputRanged.X,
                mx,
                "x");
            inputRanged.OffsetJ = DetermineRelativeOffsetForLayerFromXYZ(
                inputRanged.CalculationStartJ,
                inputRanged.Y,
                my,
                "y");
            inputRanged.OffsetK = DetermineRelativeOffsetForLayerFromXYZ(
                inputRanged.CalculationStartK,
                inputRanged.Z,
                mz,
                "z");

            // Run AST visitors over the expression to simplify.
            inputRanged.CalculationStartI = AstHelpers.OptimizeExpression(inputRanged.CalculationStartI);
            inputRanged.CalculationStartJ = AstHelpers.OptimizeExpression(inputRanged.CalculationStartJ);
            inputRanged.CalculationStartK = AstHelpers.OptimizeExpression(inputRanged.CalculationStartK);
            inputRanged.CalculationEndI = AstHelpers.OptimizeExpression(inputRanged.CalculationEndI);
            inputRanged.CalculationEndJ = AstHelpers.OptimizeExpression(inputRanged.CalculationEndJ);
            inputRanged.CalculationEndK = AstHelpers.OptimizeExpression(inputRanged.CalculationEndK);
            inputRanged.OffsetI = AstHelpers.OptimizeExpression(inputRanged.OffsetI);
            inputRanged.OffsetJ = AstHelpers.OptimizeExpression(inputRanged.OffsetJ);
            inputRanged.OffsetK = AstHelpers.OptimizeExpression(inputRanged.OffsetK);
            inputRanged.OffsetX = AstHelpers.OptimizeExpression(inputRanged.OffsetX);
            inputRanged.OffsetY = AstHelpers.OptimizeExpression(inputRanged.OffsetY);
            inputRanged.OffsetZ = AstHelpers.OptimizeExpression(inputRanged.OffsetZ);

            // Go through all of the inputs and backfill them.
            for (var i = 0; i < inputRanged.Inputs.Length; i++)
            {
                BackfillInput(inputRanged, inputRanged.Layer, inputRanged.Inputs[i], i, mx, my, mz);
            }
        }
Example #13
0
        /// <summary>
        /// Given the specified ranged layer, find expressions which determine the total
        /// extent of the main loop for the compilation process.
        /// </summary>
        public static void FindMaximumBounds(
            RangedLayer layer,
            out Expression x,
            out Expression y,
            out Expression z,
            out Expression width,
            out Expression height,
            out Expression depth,
            out Expression outerx,
            out Expression outery,
            out Expression outerz)
        {
            if (layer == null)
                throw new ArgumentNullException("layer");

            // Set initial values.
            x = layer.X;
            y = layer.Y;
            z = layer.Z;
            width = layer.Width;
            height = layer.Height;
            depth = layer.Depth;
            outerx = layer.OuterX;
            outery = layer.OuterY;
            outerz = layer.OuterZ;

            // For each of the inputs, evaluate which is the appropriate
            // expression.
            foreach (var input in layer.Inputs)
            {
                if (input == null)
                    continue;

                Expression ix, iy, iz, iwidth, iheight, idepth, iouterx, ioutery, iouterz;
                FindMaximumBounds(
                    input,
                    out ix,
                    out iy,
                    out iz,
                    out iwidth,
                    out iheight,
                    out idepth,
                    out iouterx,
                    out ioutery,
                    out iouterz);

                x = GetSmallestOrLargestExpression(x, ix, false);
                y = GetSmallestOrLargestExpression(y, iy, false);
                z = GetSmallestOrLargestExpression(z, iz, false);
                width = GetSmallestOrLargestExpression(width, iwidth, true);
                height = GetSmallestOrLargestExpression(height, iheight, true);
                depth = GetSmallestOrLargestExpression(depth, idepth, true);
                outerx = GetSmallestOrLargestExpression(outerx, iouterx, true);
                outery = GetSmallestOrLargestExpression(outery, ioutery, true);
                outerz = GetSmallestOrLargestExpression(outerz, iouterz, true);
            }
        }
Example #14
0
        public void ComplexBorderTest()
        {
            var perlin = this.CreateRuntimeLayer(new AlgorithmPerlin { Layer2D = false });
            var add = this.CreateRuntimeLayer(new AlgorithmAdd { Layer2d = false });
            var perlin2 = this.CreateRuntimeLayer(new AlgorithmPerlin { Layer2D = false });
            var passthrough = this.CreateRuntimeLayer(new AlgorithmPassthrough { XBorder = 7, YBorder = 9, ZBorder = 11, Layer2D = false });
            var heightC = this.CreateRuntimeLayer(new AlgorithmHeightChange { Layer2D = false });
            passthrough.SetInput(0, perlin2);
            add.SetInput(0, perlin);
            add.SetInput(1, passthrough);
            heightC.SetInput(0, add);

            var ranged_heightC = new RangedLayer(heightC);
            var ranged_add = ranged_heightC.Inputs[0];
            var ranged_passthrough = ranged_add.Inputs[1];
            var ranged_perlin2 = ranged_passthrough.Inputs[0];
            var ranged_perlin = ranged_add.Inputs[0];

            Assert.Equal("x", ranged_heightC.X.GetText());
            Assert.Equal("y", ranged_heightC.Y.GetText());
            Assert.Equal("z", ranged_heightC.Z.GetText());
            Assert.Equal("x + width", ranged_heightC.OuterX.GetText());
            Assert.Equal("y + height", ranged_heightC.OuterY.GetText());
            Assert.Equal("z + depth", ranged_heightC.OuterZ.GetText());
            Assert.Equal("width", ranged_heightC.Width.GetText());
            Assert.Equal("height", ranged_heightC.Height.GetText());
            Assert.Equal("depth", ranged_heightC.Depth.GetText());
            Assert.Equal("18", ranged_heightC.CalculationStartI.GetText());
            Assert.Equal("22", ranged_heightC.CalculationStartJ.GetText());
            Assert.Equal("22", ranged_heightC.CalculationStartK.GetText());
            Assert.Equal("(width + 18)", ranged_heightC.CalculationEndI.GetText());
            Assert.Equal("(height + 22)", ranged_heightC.CalculationEndJ.GetText());
            Assert.Equal("(depth + 22)", ranged_heightC.CalculationEndK.GetText());
            Assert.Equal("-9", ranged_heightC.OffsetI.GetText());
            Assert.Equal("-11", ranged_heightC.OffsetJ.GetText());
            Assert.Equal("-11", ranged_heightC.OffsetK.GetText());
            Assert.Equal("-9", ranged_heightC.OffsetX.GetText());
            Assert.Equal("-11", ranged_heightC.OffsetY.GetText());
            Assert.Equal("-11", ranged_heightC.OffsetZ.GetText());

            Assert.Equal("(x - 2)", ranged_add.X.GetText());
            Assert.Equal("(y - 2)", ranged_add.Y.GetText());
            Assert.Equal("z", ranged_add.Z.GetText());
            Assert.Equal("(x + width + 2)", ranged_add.OuterX.GetText());
            Assert.Equal("(y + height + 2)", ranged_add.OuterY.GetText());
            Assert.Equal("z + depth", ranged_add.OuterZ.GetText());
            Assert.Equal("(width + 4)", ranged_add.Width.GetText());
            Assert.Equal("(height + 4)", ranged_add.Height.GetText());
            Assert.Equal("depth", ranged_add.Depth.GetText());
            Assert.Equal("14", ranged_add.CalculationStartI.GetText());
            Assert.Equal("18", ranged_add.CalculationStartJ.GetText());
            Assert.Equal("22", ranged_add.CalculationStartK.GetText());
            Assert.Equal("(width + 18)", ranged_add.CalculationEndI.GetText());
            Assert.Equal("(height + 22)", ranged_add.CalculationEndJ.GetText());
            Assert.Equal("(depth + 22)", ranged_add.CalculationEndK.GetText());
            Assert.Equal("-7", ranged_add.OffsetI.GetText());
            Assert.Equal("-9", ranged_add.OffsetJ.GetText());
            Assert.Equal("-11", ranged_add.OffsetK.GetText());
            Assert.Equal("-9", ranged_add.OffsetX.GetText());
            Assert.Equal("-11", ranged_add.OffsetY.GetText());
            Assert.Equal("-11", ranged_add.OffsetZ.GetText());

            Assert.Equal("(x - 2)", ranged_passthrough.X.GetText());
            Assert.Equal("(y - 2)", ranged_passthrough.Y.GetText());
            Assert.Equal("z", ranged_passthrough.Z.GetText());
            Assert.Equal("(x + width + 2)", ranged_passthrough.OuterX.GetText());
            Assert.Equal("(y + height + 2)", ranged_passthrough.OuterY.GetText());
            Assert.Equal("z + depth", ranged_passthrough.OuterZ.GetText());
            Assert.Equal("(width + 4)", ranged_passthrough.Width.GetText());
            Assert.Equal("(height + 4)", ranged_passthrough.Height.GetText());
            Assert.Equal("depth", ranged_passthrough.Depth.GetText());
            Assert.Equal("14", ranged_passthrough.CalculationStartI.GetText());
            Assert.Equal("18", ranged_passthrough.CalculationStartJ.GetText());
            Assert.Equal("22", ranged_passthrough.CalculationStartK.GetText());
            Assert.Equal("(width + 18)", ranged_passthrough.CalculationEndI.GetText());
            Assert.Equal("(height + 22)", ranged_passthrough.CalculationEndJ.GetText());
            Assert.Equal("(depth + 22)", ranged_passthrough.CalculationEndK.GetText());
            Assert.Equal("-7", ranged_passthrough.OffsetI.GetText());
            Assert.Equal("-9", ranged_passthrough.OffsetJ.GetText());
            Assert.Equal("-11", ranged_passthrough.OffsetK.GetText());
            Assert.Equal("-9", ranged_passthrough.OffsetX.GetText());
            Assert.Equal("-11", ranged_passthrough.OffsetY.GetText());
            Assert.Equal("-11", ranged_passthrough.OffsetZ.GetText());

            Assert.Equal("(x - 9)", ranged_perlin2.X.GetText());
            Assert.Equal("(y - 11)", ranged_perlin2.Y.GetText());
            Assert.Equal("(z - 11)", ranged_perlin2.Z.GetText());
            Assert.Equal("(x + width + 9)", ranged_perlin2.OuterX.GetText());
            Assert.Equal("(y + height + 11)", ranged_perlin2.OuterY.GetText());
            Assert.Equal("(z + depth + 11)", ranged_perlin2.OuterZ.GetText());
            Assert.Equal("(width + 18)", ranged_perlin2.Width.GetText());
            Assert.Equal("(height + 22)", ranged_perlin2.Height.GetText());
            Assert.Equal("(depth + 22)", ranged_perlin2.Depth.GetText());
            Assert.Equal("0", ranged_perlin2.CalculationStartI.GetText());
            Assert.Equal("0", ranged_perlin2.CalculationStartJ.GetText());
            Assert.Equal("0", ranged_perlin2.CalculationStartK.GetText());
            Assert.Equal("(width + 18)", ranged_perlin2.CalculationEndI.GetText());
            Assert.Equal("(height + 22)", ranged_perlin2.CalculationEndJ.GetText());
            Assert.Equal("(depth + 22)", ranged_perlin2.CalculationEndK.GetText());
            Assert.Equal("0", ranged_perlin2.OffsetI.GetText());
            Assert.Equal("0", ranged_perlin2.OffsetJ.GetText());
            Assert.Equal("0", ranged_perlin2.OffsetK.GetText());
            Assert.Equal("-9", ranged_perlin2.OffsetX.GetText());
            Assert.Equal("-11", ranged_perlin2.OffsetY.GetText());
            Assert.Equal("-11", ranged_perlin2.OffsetZ.GetText());

            Assert.Equal("(x - 2)", ranged_perlin.X.GetText());
            Assert.Equal("(y - 2)", ranged_perlin.Y.GetText());
            Assert.Equal("z", ranged_perlin.Z.GetText());
            Assert.Equal("(x + width + 2)", ranged_perlin.OuterX.GetText());
            Assert.Equal("(y + height + 2)", ranged_perlin.OuterY.GetText());
            Assert.Equal("z + depth", ranged_perlin.OuterZ.GetText());
            Assert.Equal("(width + 4)", ranged_perlin.Width.GetText());
            Assert.Equal("(height + 4)", ranged_perlin.Height.GetText());
            Assert.Equal("depth", ranged_perlin.Depth.GetText());
            Assert.Equal("14", ranged_perlin.CalculationStartI.GetText());
            Assert.Equal("18", ranged_perlin.CalculationStartJ.GetText());
            Assert.Equal("22", ranged_perlin.CalculationStartK.GetText());
            Assert.Equal("(width + 18)", ranged_perlin.CalculationEndI.GetText());
            Assert.Equal("(height + 22)", ranged_perlin.CalculationEndJ.GetText());
            Assert.Equal("(depth + 22)", ranged_perlin.CalculationEndK.GetText());
            Assert.Equal("-7", ranged_perlin.OffsetI.GetText());
            Assert.Equal("-9", ranged_perlin.OffsetJ.GetText());
            Assert.Equal("-11", ranged_perlin.OffsetK.GetText());
            Assert.Equal("-9", ranged_perlin.OffsetX.GetText());
            Assert.Equal("-11", ranged_perlin.OffsetY.GetText());
            Assert.Equal("-11", ranged_perlin.OffsetZ.GetText());
        }
Example #15
0
        public void XBorderTest()
        {
            var perlin = this.CreateRuntimeLayer(new AlgorithmPerlin());
            var passthrough = this.CreateRuntimeLayer(new AlgorithmPassthrough { XBorder = 2 });
            passthrough.SetInput(0, perlin);

            var ranged = new RangedLayer(passthrough);
            Assert.Equal("x", ranged.X.GetText());
            Assert.Equal("y", ranged.Y.GetText());
            Assert.Equal("z", ranged.Z.GetText());
            Assert.Equal("x + width", ranged.OuterX.GetText());
            Assert.Equal("y + height", ranged.OuterY.GetText());
            Assert.Equal("z + depth", ranged.OuterZ.GetText());
            Assert.Equal("width", ranged.Width.GetText());
            Assert.Equal("height", ranged.Height.GetText());
            Assert.Equal("depth", ranged.Depth.GetText());
            Assert.Equal("4", ranged.CalculationStartI.GetText());
            Assert.Equal("0", ranged.CalculationStartJ.GetText());
            Assert.Equal("0", ranged.CalculationStartK.GetText());
            Assert.Equal("(width + 4)", ranged.CalculationEndI.GetText());
            Assert.Equal("height", ranged.CalculationEndJ.GetText());
            Assert.Equal("depth", ranged.CalculationEndK.GetText());
            Assert.Equal("-2", ranged.OffsetI.GetText());
            Assert.Equal("0", ranged.OffsetJ.GetText());
            Assert.Equal("0", ranged.OffsetK.GetText());
            Assert.Equal("-2", ranged.OffsetX.GetText());
            Assert.Equal("0", ranged.OffsetY.GetText());
            Assert.Equal("0", ranged.OffsetZ.GetText());

            ranged = ranged.Inputs[0];
            Assert.Equal("(x - 2)", ranged.X.GetText());
            Assert.Equal("y", ranged.Y.GetText());
            Assert.Equal("z", ranged.Z.GetText());
            Assert.Equal("(x + width + 2)", ranged.OuterX.GetText());
            Assert.Equal("y + height", ranged.OuterY.GetText());
            Assert.Equal("z + depth", ranged.OuterZ.GetText());
            Assert.Equal("(width + 4)", ranged.Width.GetText());
            Assert.Equal("height", ranged.Height.GetText());
            Assert.Equal("depth", ranged.Depth.GetText());
            Assert.Equal("0", ranged.CalculationStartI.GetText());
            Assert.Equal("0", ranged.CalculationStartJ.GetText());
            Assert.Equal("0", ranged.CalculationStartK.GetText());
            Assert.Equal("(width + 4)", ranged.CalculationEndI.GetText());
            Assert.Equal("height", ranged.CalculationEndJ.GetText());
            Assert.Equal("depth", ranged.CalculationEndK.GetText());
            Assert.Equal("0", ranged.OffsetI.GetText());
            Assert.Equal("0", ranged.OffsetJ.GetText());
            Assert.Equal("0", ranged.OffsetK.GetText());
            Assert.Equal("-2", ranged.OffsetX.GetText());
            Assert.Equal("0", ranged.OffsetY.GetText());
            Assert.Equal("0", ranged.OffsetZ.GetText());
        }
Example #16
0
 public void SingleTest()
 {
     var runtime = this.CreateRuntimeLayer(new AlgorithmPerlin());
     var ranged = new RangedLayer(runtime);
     Assert.Equal("x", ranged.X.GetText());
     Assert.Equal("y", ranged.Y.GetText());
     Assert.Equal("z", ranged.Z.GetText());
     Assert.Equal("x + width", ranged.OuterX.GetText());
     Assert.Equal("y + height", ranged.OuterY.GetText());
     Assert.Equal("z + depth", ranged.OuterZ.GetText());
     Assert.Equal("width", ranged.Width.GetText());
     Assert.Equal("height", ranged.Height.GetText());
     Assert.Equal("depth", ranged.Depth.GetText());
     Assert.Equal("0", ranged.CalculationStartI.GetText());
     Assert.Equal("0", ranged.CalculationStartJ.GetText());
     Assert.Equal("0", ranged.CalculationStartK.GetText());
     Assert.Equal("width", ranged.CalculationEndI.GetText());
     Assert.Equal("height", ranged.CalculationEndJ.GetText());
     Assert.Equal("depth", ranged.CalculationEndK.GetText());
     Assert.Equal("0", ranged.OffsetI.GetText());
     Assert.Equal("0", ranged.OffsetJ.GetText());
     Assert.Equal("0", ranged.OffsetK.GetText());
     Assert.Equal("0", ranged.OffsetX.GetText());
     Assert.Equal("0", ranged.OffsetY.GetText());
     Assert.Equal("0", ranged.OffsetZ.GetText());
 }
Example #17
0
        /// <summary>
        /// Process an input runtime layer.
        /// </summary>
        /// <param name="ranged">The current ranged layer.</param>
        /// <param name="layer">The current runtime layer.</param>
        /// <param name="input">The input runtime layer.</param>
        /// <param name="idx">The index of the input layer in the parent layer.</param>
        /// <returns>The input ranged layer.</returns>
        private static RangedLayer ProcessInput(
            RangedLayer currentRanged,
            RuntimeLayer currentRuntime,
            RuntimeLayer inputRuntime,
            int idx)
        {
            // Set up the new ranged layer.
            var inputRanged = new RangedLayer();
            inputRanged.X = currentRanged.X;
            inputRanged.Y = currentRanged.Y;
            inputRanged.Z = currentRanged.Z;
            inputRanged.Width = currentRanged.Width;
            inputRanged.Height = currentRanged.Height;
            inputRanged.Depth = currentRanged.Depth;
            inputRanged.OuterX = currentRanged.OuterX;
            inputRanged.OuterY = currentRanged.OuterY;
            inputRanged.OuterZ = currentRanged.OuterZ;
            inputRanged.Layer = inputRuntime;

            // Determine if we need to adjust the width, height and depth.
            if (currentRuntime.Algorithm.InputWidthAtHalfSize[idx])
            {
                inputRanged.Width = CreateDivideByTwo(inputRanged.Width);
                inputRanged.OuterX = CreateDivideByTwo(inputRanged.OuterX);
            }

            if (currentRuntime.Algorithm.InputHeightAtHalfSize[idx])
            {
                inputRanged.Height = CreateDivideByTwo(inputRanged.Height);
                inputRanged.OuterY = CreateDivideByTwo(inputRanged.OuterY);
            }

            if (currentRuntime.Algorithm.InputDepthAtHalfSize[idx])
            {
                inputRanged.Depth = CreateDivideByTwo(inputRanged.Depth);
                inputRanged.OuterZ = CreateDivideByTwo(inputRanged.OuterZ);
            }

            // Determine if we need to adjust the X, Y or Z offsets.
            if (currentRuntime.Algorithm.RequiredXBorder[idx] > 0)
            {
                inputRanged.X = CreateSubtraction(
                    inputRanged.X,
                    currentRuntime.Algorithm.RequiredXBorder[idx]);
                inputRanged.Width = CreateAddition(
                    inputRanged.Width,
                    currentRuntime.Algorithm.RequiredXBorder[idx] * 2);
                inputRanged.OuterX = CreateAddition(
                    inputRanged.OuterX,
                    currentRuntime.Algorithm.RequiredXBorder[idx]);
            }

            if (currentRuntime.Algorithm.RequiredYBorder[idx] > 0)
            {
                inputRanged.Y = CreateSubtraction(
                    inputRanged.Y,
                    currentRuntime.Algorithm.RequiredYBorder[idx]);
                inputRanged.Height = CreateAddition(
                    inputRanged.Height,
                    currentRuntime.Algorithm.RequiredYBorder[idx] * 2);
                inputRanged.OuterY = CreateAddition(
                    inputRanged.OuterY,
                    currentRuntime.Algorithm.RequiredYBorder[idx]);
            }

            if (currentRuntime.Algorithm.RequiredZBorder[idx] > 0)
            {
                inputRanged.Z = CreateSubtraction(
                    inputRanged.Z,
                    currentRuntime.Algorithm.RequiredZBorder[idx]);
                inputRanged.Depth = CreateAddition(
                    inputRanged.Depth,
                    currentRuntime.Algorithm.RequiredZBorder[idx] * 2);
                inputRanged.OuterZ = CreateAddition(
                    inputRanged.OuterZ,
                    currentRuntime.Algorithm.RequiredZBorder[idx]);
            }

            // Process inputs recursively.
            var inputs = inputRuntime.GetInputs();
            inputRanged.Inputs = new RangedLayer[inputs.Length];
            for (var i = 0; i < inputs.Length; i++)
            {
                inputRanged.Inputs[i] =
                    inputs[i] == null
                        ? null
                        : ProcessInput(inputRanged, inputRuntime, inputs[i], i);
            }

            // Run AST visitors over the expression to simplify.
            inputRanged.X = AstHelpers.OptimizeExpression(inputRanged.X);
            inputRanged.Y = AstHelpers.OptimizeExpression(inputRanged.Y);
            inputRanged.Z = AstHelpers.OptimizeExpression(inputRanged.Z);
            inputRanged.Width = AstHelpers.OptimizeExpression(inputRanged.Width);
            inputRanged.Height = AstHelpers.OptimizeExpression(inputRanged.Height);
            inputRanged.Depth = AstHelpers.OptimizeExpression(inputRanged.Depth);
            inputRanged.OuterX = AstHelpers.OptimizeExpression(inputRanged.OuterX);
            inputRanged.OuterY = AstHelpers.OptimizeExpression(inputRanged.OuterY);
            inputRanged.OuterZ = AstHelpers.OptimizeExpression(inputRanged.OuterZ);

            // Return the new layer.
            return inputRanged;
        }
Example #18
0
        private static ProcessedResult ProcessRuntimeLayer(RuntimeLayer layer)
        {
            // Create our own processed result; a copy of our own state plus
            // somewhere to accumulate code.
            var result = new ProcessedResult();
            result.ProcessedCode = string.Empty;
            result.InitializationCode = string.Empty;

            // Get a reference to the algorithm that the runtime layer is using.
            var algorithm = layer.Algorithm;
            if (algorithm == null)
                throw new InvalidOperationException("Attempted to compile null runtime layer!");

            // Use RangedLayer to work out the metrics.
            var ranged = new RangedLayer(layer);
            Expression ix, iy, iz, iwidth, iheight, idepth, iouterx, ioutery, iouterz;
            RangedLayer.FindMaximumBounds(
                ranged,
                out ix,
                out iy,
                out iz,
                out iwidth,
                out iheight,
                out idepth,
                out iouterx,
                out ioutery,
                out iouterz);

            // Add __cwidth, __cheight and __cdepth declarations.
            result.Declarations += "int __cx = (int)(" + ix.GetText(null) + ");\n";
            result.Declarations += "int __cy = (int)(" + iy.GetText(null) + ");\n";
            result.Declarations += "int __cz = (int)(" + iz.GetText(null) + ");\n";
            result.Declarations += "int __cwidth = " + iwidth.GetText(null) + ";\n";
            result.Declarations += "int __cheight = " + iheight.GetText(null) + ";\n";
            result.Declarations += "int __cdepth = " + idepth.GetText(null) + ";\n";

            // Create the for loop that our calculations are done within.
            result.ProcessedCode +=
                "for (var k = 0; k < " + idepth.GetText(null) + @"; k++)" +
                "for (var i = 0; i < " + iwidth.GetText(null) + @"; i++)" +
                "for (var j = 0; j < " + iheight.GetText(null) + @"; j++)" +
                "{";

            // Now add the code for the layer.
            var inputResult = CompileRuntimeLayer(layer, ranged, null);
            result.ProcessedCode += inputResult.ProcessedCode;
            result.InitializationCode += inputResult.InitializationCode;
            result.OutputVariableName = inputResult.OutputVariableName;
            result.OutputVariableType = inputResult.OutputVariableType;
            result.Declarations += inputResult.Declarations;
            result.UsingStatements.AddRange(inputResult.UsingStatements);

            // Terminate the for loop and return the result.
            result.ProcessedCode += "}";
            return result;
        }