Example #1
0
        public void TestCorrectIntialReadyOperationsParallelDFG()
        {
            TestBlock operation1 = new TestBlock(new List <FluidBlock> {
            }, null, new TestModule());
            TestBlock operation2 = new TestBlock(new List <FluidBlock> {
            }, null, new TestModule());
            TestBlock operation3 = new TestBlock(new List <FluidBlock> {
            }, null, new TestModule());
            TestBlock operation4 = new TestBlock(new List <FluidBlock> {
            }, null, new TestModule());

            DFG <Block> dfg = new DFG <Block>();

            dfg.AddNode(operation1);
            dfg.AddNode(operation2);
            dfg.AddNode(operation3);
            dfg.AddNode(operation4);
            dfg.FinishDFG();

            Assay assay = new Assay(dfg);

            Assert.AreEqual(assay.GetReadyOperations().Count, dfg.Nodes.Count);
            foreach (var node in dfg.Nodes)
            {
                //Even the pointers should be the same.
                Assert.IsTrue(assay.GetReadyOperations().Contains(node.value));
            }
        }
Example #2
0
        public void TestCopyCDFG()
        {
            DFG <Block> dfg1 = new DFG <Block>();

            dfg1.AddNode(new Constant(3, "a", "", false));
            dfg1.AddNode(new SetNumberVariable((VariableBlock)dfg1.Nodes[0].value, "b", ""));
            dfg1.AddNode(new Constant(6, "g", "", false));
            dfg1.AddNode(new Constant(6, "h", "", false));
            dfg1.AddNode(new BoolOP((VariableBlock)dfg1.Nodes[2].value, (VariableBlock)dfg1.Nodes[3].value, "i", BoolOPTypes.EQ, "", true));
            dfg1.FinishDFG();

            DFG <Block> dfg2 = new DFG <Block>();

            dfg2.AddNode(new Constant(6, "c", "", false));
            dfg2.AddNode(new GetNumberVariable("b", "d", "", false));
            dfg2.AddNode(new ArithOP((VariableBlock)dfg2.Nodes[0].value, (VariableBlock)dfg2.Nodes[1].value, "e", ArithOPTypes.ADD, "", false));
            dfg2.AddNode(new SetNumberVariable((VariableBlock)dfg2.Nodes[2].value, "f", ""));
            dfg2.FinishDFG();

            CDFG original = new CDFG();

            original.AddNode(new While(new Conditional((VariableBlock)dfg1.Nodes[4].value, dfg2, null)), dfg1);
            original.AddNode(null, dfg2);
            original.StartDFG = dfg1;

            CDFG copy1 = original.Copy();

            CheckCopyCDFG(original, copy1);

            CDFG copy2 = original.Copy();

            CheckCopyCDFG(original, copy2);
        }
Example #3
0
        public void TestUpdateReadyOperationsMultiDependecy()
        {
            TestBlock operation1 = new TestBlock(new List <FluidBlock> {
            }, "op1", new TestModule());
            TestBlock operation3 = new TestBlock(new List <FluidBlock> {
            }, "op3", new TestModule());
            TestBlock operation2 = new TestBlock(new List <FluidBlock> {
                operation1, operation3
            }, "op2", new TestModule());
            TestBlock operation4 = new TestBlock(new List <FluidBlock> {
            }, "op4", new TestModule());

            DFG <Block> dfg = new DFG <Block>();

            dfg.AddNode(operation1);
            dfg.AddNode(operation3);
            dfg.AddNode(operation2);
            dfg.AddNode(operation4);
            dfg.FinishDFG();

            //Now the operations associated with node 1,
            //should wait for the operation assocaited with node 0 and 2.

            Assay assay = new Assay(dfg);

            //Remove first dependecy

            assay.UpdateReadyOperations(dfg.Nodes[2].value);

            Assert.AreEqual(assay.GetReadyOperations().Count, dfg.Nodes.Count - 2);

            Assert.IsTrue(assay.GetReadyOperations().Contains(dfg.Nodes[0].value));
            Assert.IsTrue(assay.GetReadyOperations().Contains(dfg.Nodes[3].value));
            Assert.IsFalse(assay.GetReadyOperations().Contains(dfg.Nodes[1].value));
            Assert.IsFalse(assay.GetReadyOperations().Contains(dfg.Nodes[2].value));

            Assert.IsFalse(dfg.Nodes[0].value.IsDone);
            Assert.IsFalse(dfg.Nodes[1].value.IsDone);
            Assert.IsTrue(dfg.Nodes[2].value.IsDone);
            Assert.IsFalse(dfg.Nodes[3].value.IsDone);

            //remove last dependecy
            assay.UpdateReadyOperations(dfg.Nodes[0].value);

            Assert.AreEqual(assay.GetReadyOperations().Count, dfg.Nodes.Count - 2);

            Assert.IsTrue(assay.GetReadyOperations().Contains(dfg.Nodes[1].value));
            Assert.IsTrue(assay.GetReadyOperations().Contains(dfg.Nodes[3].value));
            Assert.IsFalse(assay.GetReadyOperations().Contains(dfg.Nodes[0].value));
            Assert.IsFalse(assay.GetReadyOperations().Contains(dfg.Nodes[2].value));

            Assert.IsTrue(dfg.Nodes[0].value.IsDone);
            Assert.IsFalse(dfg.Nodes[1].value.IsDone);
            Assert.IsTrue(dfg.Nodes[2].value.IsDone);
            Assert.IsFalse(dfg.Nodes[3].value.IsDone);
        }
Example #4
0
        public override Block TrueCopy(DFG <Block> dfg)
        {
            VariableBlock indexCopy  = (VariableBlock)IndexBlock.TrueCopy(dfg);
            VariableBlock numberCopy = (VariableBlock)NumberBlock.TrueCopy(dfg);

            dfg.AddNode(indexCopy);
            dfg.AddNode(numberCopy);

            return(new SetArrayNumber(indexCopy, numberCopy, ArrayName, BlockID, CanBeScheduled));
        }
Example #5
0
        public override Block TrueCopy(DFG <Block> dfg)
        {
            VariableBlock leftCopy  = (VariableBlock)LeftBlock.TrueCopy(dfg);
            VariableBlock rightCopy = (VariableBlock)RightBlock.TrueCopy(dfg);

            dfg.AddNode(leftCopy);
            dfg.AddNode(rightCopy);

            return(new BoolOP(leftCopy, rightCopy, OutputVariable, OPType, BlockID, CanBeScheduled));
        }
Example #6
0
        public static Block Parse(XmlNode node, DFG <Block> dfg, ParserInfo parserInfo, bool canBeScheduled)
        {
            string      id     = ParseTools.ParseID(node);
            BoolOPTypes opType = BoolOP.StringToBoolOPType(id, ParseTools.ParseString(node, OPTypeFieldName));

            VariableBlock leftBoolBlock = ParseTools.ParseBlock <VariableBlock>(node, dfg, parserInfo, id, LeftBoolFieldName,
                                                                                new MissingBlockException(id, "Left side of boolean operator is missing a block."));
            VariableBlock rightBoolBlock = ParseTools.ParseBlock <VariableBlock>(node, dfg, parserInfo, id, RightBoolFieldName,
                                                                                 new MissingBlockException(id, "Right side of boolean operator is missing a block."));

            dfg.AddNode(leftBoolBlock);
            dfg.AddNode(rightBoolBlock);

            return(new BoolOP(leftBoolBlock, rightBoolBlock, parserInfo.GetUniqueAnonymousName(), opType, id, canBeScheduled));
        }
Example #7
0
        private static void AddWasteBlocks(List <string> fluidsOutOfScope, DFG <Block> bigDFG, Dictionary <string, string> renamer, Dictionary <string, BoardFluid> fluidLocations, List <StaticDeclarationBlock> staticModuleDeclarations)
        {
            foreach (string wasteFluidName in fluidsOutOfScope)
            {
                if (!fluidLocations.ContainsKey(wasteFluidName))
                {
                    continue;
                }

                if (staticModuleDeclarations.Any(x => x.OutputVariable == wasteFluidName))
                {
                    continue;
                }

                if (renamer.TryGetValue(wasteFluidName, out string correctedName))
                {
                    int dropletCount = fluidLocations[wasteFluidName].GetNumberOfDropletsAvailable();
                    if (dropletCount > 0)
                    {
                        List <FluidInput> fluidInputs = new List <FluidInput>();
                        fluidInputs.Add(new BasicInput("none", correctedName, dropletCount, false));

                        bigDFG.AddNode(new WasteUsage(Schedule.WASTE_MODULE_NAME, fluidInputs, null, ""));
                    }
                }
            }
        }
Example #8
0
        public override Block TrueCopy(DFG <Block> dfg)
        {
            VariableBlock operandCopy = (VariableBlock)OperandBlock.TrueCopy(dfg);

            dfg.AddNode(operandCopy);

            return(new SetNumberVariable(operandCopy, OutputVariable, BlockID));
        }
Example #9
0
        public override FluidInput TrueCopy(DFG <Block> dfg)
        {
            VariableBlock indexCopy = (VariableBlock)IndexBlock.TrueCopy(dfg);

            dfg.AddNode(indexCopy);

            return(new GetArrayFluid(indexCopy, ArrayName, ID, AmountInML, UseAllFluid));
        }
Example #10
0
        public override Block TrueCopy(DFG <Block> dfg)
        {
            VariableBlock arrayLengthCopy = (VariableBlock)ArrayLengthBlock.TrueCopy(dfg);

            dfg.AddNode(arrayLengthCopy);

            return(new NumberArray(ArrayName, arrayLengthCopy, BlockID));
        }
Example #11
0
        internal static Block ParseAndAddNodeToDFG(XmlNode node, DFG <Block> dfg, ParserInfo parserInfo, bool allowDeclarationBlocks = false)
        {
            Block block = ParseBlock(node, dfg, parserInfo, allowDeclarationBlocks);

            dfg.AddNode(block);

            return(block);
        }
Example #12
0
        public override Block TrueCopy(DFG <Block> dfg)
        {
            VariableBlock indexCopy = (VariableBlock)IndexBlock.TrueCopy(dfg);

            dfg.AddNode(indexCopy);

            return(new SetArrayFluid(indexCopy, ArrayName, InputFluids.Copy(dfg), BlockID));
        }
Example #13
0
        public override Block TrueCopy(DFG <Block> dfg)
        {
            VariableBlock numberCopy = (VariableBlock)NumberBlock.TrueCopy(dfg);

            dfg.AddNode(numberCopy);

            return(new RoundOP(numberCopy, OutputVariable, RoundType, BlockID, CanBeScheduled));
        }
Example #14
0
        public static Block Parse(XmlNode node, DFG <Block> dfg, ParserInfo parserInfo, bool canBeScheduled)
        {
            string id        = ParseTools.ParseID(node);
            string arrayName = ParseTools.ParseString(node, ARRAY_NAME_FIELD_NAME);

            parserInfo.CheckVariable(id, VariableType.NUMBER_ARRAY, arrayName);

            VariableBlock indexBlock = ParseTools.ParseBlock <VariableBlock>(node, dfg, parserInfo, id, INDEX_FIELD_NAME,
                                                                             new MissingBlockException(id, "Missing block to define the variables value."));

            VariableBlock numberInput = ParseTools.ParseBlock <VariableBlock>(node, dfg, parserInfo, id, INPUT_NUMBER_FIELD_NAME,
                                                                              new MissingBlockException(id, "Mixer is missing input fluid block."));

            dfg.AddNode(indexBlock);
            dfg.AddNode(numberInput);

            return(new SetArrayNumber(indexBlock, numberInput, arrayName, id, canBeScheduled));
        }
Example #15
0
        public static Block Parse(XmlNode node, DFG <Block> dfg, ParserInfo parserInfo, bool canBeScheduled)
        {
            string       id        = ParseTools.ParseID(node);
            RoundOPTypes roundType = StringToRoundOPType(id, ParseTools.ParseString(node, OPTypeFieldName));

            VariableBlock numberBlock = ParseTools.ParseBlock <VariableBlock>(node, dfg, parserInfo, id, NUMBER_FIELD_NAME,
                                                                              new MissingBlockException(id, "Number defining block is missing."));

            dfg.AddNode(numberBlock);

            return(new RoundOP(numberBlock, parserInfo.GetUniqueAnonymousName(), roundType, id, canBeScheduled));
        }
Example #16
0
        private void CheckCopySingleBlock <T>(T original) where T : Block
        {
            DFG <Block> dfg  = new DFG <Block>();
            Block       copy = original.TrueCopy(dfg);

            dfg.AddNode(copy);
            CompareToOriginal(original, copy, 1);

            Node <Block> oCopy = dfg.Nodes.Single(x => x.value is T);

            Assert.AreEqual(1, dfg.Nodes.Count);
            Assert.AreEqual(0, oCopy.GetIngoingEdges().Count);
        }
Example #17
0
        public void TestCorrectIntialReadyOperationsNonParallelDFG()
        {
            TestBlock operation1 = new TestBlock(new List <FluidBlock> {
            }, "op1", new TestModule());
            TestBlock operation2 = new TestBlock(new List <FluidBlock> {
                operation1
            }, "op2", new TestModule());
            TestBlock operation3 = new TestBlock(new List <FluidBlock> {
            }, "op3", new TestModule());
            TestBlock operation4 = new TestBlock(new List <FluidBlock> {
            }, "op4", new TestModule());

            DFG <Block> dfg = new DFG <Block>();

            dfg.AddNode(operation1);
            dfg.AddNode(operation2);
            dfg.AddNode(operation3);
            dfg.AddNode(operation4);
            dfg.FinishDFG();

            //Now the operations associated with node 1,
            //should wait for the operation assocaited with node 0.

            Assay assay = new Assay(dfg);

            Assert.AreEqual(assay.GetReadyOperations().Count, dfg.Nodes.Count - 1);
            for (int i = 0; i < dfg.Nodes.Count; i++)
            {
                bool containsOperation = assay.GetReadyOperations().Contains(dfg.Nodes[i].value);
                if (i == 1)
                {
                    Assert.IsFalse(containsOperation);
                }
                else
                {
                    Assert.IsTrue(containsOperation);
                }
            }
        }
Example #18
0
        public static Block Parse(XmlNode node, DFG <Block> dfg, ParserInfo parserInfo)
        {
            string id     = ParseTools.ParseID(node);
            string output = ParseTools.ParseString(node, VARIABLE_FIELD_NAME);

            parserInfo.AddVariable(id, VariableType.NUMBER, output);

            VariableBlock operandBlock = ParseTools.ParseBlock <VariableBlock>(node, dfg, parserInfo, id, INPUT_VARIABLE_FIELD_NAME,
                                                                               new MissingBlockException(id, "Missing block to define the variables value."));

            dfg.AddNode(operandBlock);

            return(new SetNumberVariable(operandBlock, output, id));
        }
Example #19
0
        public static Block Parse(XmlNode node, DFG <Block> dfg, ParserInfo parserInfo, bool canBeScheduled)
        {
            string id        = ParseTools.ParseID(node);
            string arrayName = ParseTools.ParseString(node, ARRAY_NAME_FIELD_NAME);

            parserInfo.CheckVariable(id, VariableType.NUMBER_ARRAY, arrayName);

            VariableBlock indexBlock = ParseTools.ParseBlock <VariableBlock>(node, dfg, parserInfo, id, INDEX_FIELD_NAME,
                                                                             new MissingBlockException(id, "Missing block which define the index into the array."));

            dfg.AddNode(indexBlock);

            return(new GetArrayNumber(indexBlock, arrayName, parserInfo.GetUniqueAnonymousName(), id, canBeScheduled));
        }
Example #20
0
        public static Block Parse(XmlNode node, DFG <Block> dfg, ParserInfo parserInfo)
        {
            string id        = ParseTools.ParseID(node);
            string arrayName = ParseTools.ParseString(node, ARRAY_NAME_FIELD_NAME);

            parserInfo.AddVariable(id, VariableType.NUMBER_ARRAY, arrayName);

            VariableBlock arrayLengthBlock = ParseTools.ParseBlock <VariableBlock>(node, dfg, parserInfo, id, ARRAY_LENGTH_FIELD_NAME,
                                                                                   new MissingBlockException(id, "Missing block which define the length of the array."));

            dfg.AddNode(arrayLengthBlock);

            return(new NumberArray(arrayName, arrayLengthBlock, id));
        }
Example #21
0
        public void TestCreateNonEmptyAssay()
        {
            Block op1 = new InputDeclaration("cake", 10, "");
            Block op2 = new InputDeclaration("cookies", 7, "");
            Block op3 = new Mixer(new List <FluidInput>()
            {
                new BasicInput("", "cake", 1, false), new BasicInput("", "cookie", 1, false)
            }, "mash", "");
            Block op4 = new Mixer(new List <FluidInput>()
            {
                new BasicInput("", "mash", 1, false), new BasicInput("", "cookie", 1, false)
            }, "trash", "");

            DFG <Block> dfg = new DFG <Block>();

            dfg.AddNode(op1);
            dfg.AddNode(op2);
            dfg.AddNode(op3);
            dfg.AddNode(op4);
            dfg.FinishDFG();

            Assay assay = new Assay(dfg);
        }
Example #22
0
        public static FluidInput Parse(XmlNode node, DFG <Block> dfg, ParserInfo parserInfo, bool doVariableCheck = true)
        {
            string id        = ParseTools.ParseID(node);
            string arrayName = ParseTools.ParseString(node, ARRAY_NAME_FIELD_NAME);

            if (doVariableCheck)
            {
                parserInfo.CheckVariable(id, VariableType.FLUID_ARRAY, arrayName);
            }

            float amountInML  = ParseTools.ParseFloat(node, parserInfo, id, FLUID_AMOUNT_FIELD_NAME);
            bool  useAllFluid = FluidInput.StringToBool(ParseTools.ParseString(node, USE_ALL_FLUID_FIELD_NAME));

            VariableBlock indexBlock = ParseTools.ParseBlock <VariableBlock>(node, dfg, parserInfo, id, INDEX_FIELD_NAME,
                                                                             new MissingBlockException(id, "Missing block which define the index into the array."));

            dfg.AddNode(indexBlock);

            return(new GetArrayFluid(indexBlock, arrayName, id, amountInML, useAllFluid));
        }
Example #23
0
        public static Block Parse(XmlNode node, DFG <Block> dfg, ParserInfo parserInfo)
        {
            string id        = ParseTools.ParseID(node);
            string arrayName = ParseTools.ParseString(node, ARRAY_NAME_FIELD_NAME);

            parserInfo.CheckVariable(id, VariableType.FLUID_ARRAY, arrayName);

            VariableBlock indexBlock = ParseTools.ParseBlock <VariableBlock>(node, dfg, parserInfo, id, INDEX_FIELD_NAME,
                                                                             new MissingBlockException(id, "Missing block to define the index."));

            FluidInput fluidInput = ParseTools.ParseFluidInput(node, dfg, parserInfo, id, INPUT_FLUID_FIELD_NAME,
                                                               new MissingBlockException(id, "Missing input fluid block."));


            dfg.AddNode(indexBlock);

            List <FluidInput> inputFluids = new List <FluidInput>();

            inputFluids.Add(fluidInput);

            return(new SetArrayFluid(indexBlock, arrayName, inputFluids, id));
        }
Example #24
0
        private void CheckCopyMultiBlock(Block original, Block[] blocks, int[][] dependencyGraph)
        {
            DFG <Block> dfg  = new DFG <Block>();
            Block       copy = original.TrueCopy(dfg);

            dfg.AddNode(copy);
            CompareToOriginal(original, copy, blocks.Length);

            Assert.AreEqual(blocks.Length, dfg.Nodes.Count, "Not all blocks were copied.");
            Assert.AreEqual(blocks.Length, dependencyGraph.Length, "Dependency graph and blocks array need to match.");
            for (int i = 0; i < blocks.Length; i++)
            {
                Node <Block> node = dfg.Nodes.SingleOrDefault(x => x.value.Equals(blocks[i]));

                Assert.IsNotNull(node, $"Can't find a copie block that matches the block: {blocks[i].GetType()}");
                Assert.AreEqual(dependencyGraph[i].Length, node.GetIngoingEdges().Count, "DFG does not meatch the dependency graph.");
                for (int y = 0; y < dependencyGraph[i].Length; y++)
                {
                    Assert.IsTrue(node.GetIngoingEdges().Any(z => z.value.Equals(blocks[dependencyGraph[i][y]])),
                                  $"Block {node.value.GetType()} does not depend on block {blocks[dependencyGraph[i][y]]}.");
                }
            }
        }
Example #25
0
        private void TransformDFGToFunctionDFG(DFG <Block> dfg, InlineProgramInfo programInfo)
        {
            //New blocks are crerated which requires new dependencies
            //and dependencies are created when they are inserted into
            //the dfg, so a new dfg is created to create the correct
            //dependencies.
            //The given dfg is still used as the corrected result is then
            //copied into the given dfg.
            DFG <Block> correctOrder = new DFG <Block>();
            Dictionary <string, string> namesToReplace = new Dictionary <string, string>();

            programInfo.InputsFromTo.ForEach(x => namesToReplace.Add(x.Key, x.Value.OriginalFluidName));

            foreach (Node <Block> node in dfg.Nodes)
            {
                Block block = node.value;

                foreach (FluidInput input in block.InputFluids)
                {
                    if (namesToReplace.ContainsKey(input.OriginalFluidName))
                    {
                        input.OriginalFluidName = namesToReplace[input.OriginalFluidName];
                    }
                }

                if (namesToReplace.ContainsKey(block.OutputVariable))
                {
                    namesToReplace.Remove(block.OutputVariable);
                }

                if (block is VariableBlock varBlock)
                {
                    if (!varBlock.CanBeScheduled)
                    {
                        continue;
                    }
                }

                if (block is InputDeclaration)
                {
                    //string newName = block.OutputVariable;
                    //string oldName = InputsFromTo[block.OutputVariable].OriginalFluidName;
                    //correctOrder.AddNode(new FluidRef(newName, oldName));
                }
                else if (block is OutputDeclaration output)
                {
                    string name = programInfo.OutputsFromTo[output.ModuleName];
                    correctOrder.AddNode(new Fluid(new List <FluidInput>()
                    {
                        new BasicInput("", name, 0, true)
                    }, name, ""));
                }
                else if (//block is WasteDeclaration ||
                    block is HeaterDeclaration /*||
                                                * block is SensorDeclaration*/)
                {
                    //remove these blocks which is the same as not adding them
                }
                else if (block is OutputUsage outputUsage)
                {
                    List <FluidInput> inputs = new List <FluidInput>()
                    {
                        block.InputFluids[0].TrueCopy(correctOrder),
                        block.InputFluids[0].TrueCopy(correctOrder)
                    };

                    inputs[1].OriginalFluidName = programInfo.OutputsFromTo[outputUsage.ModuleName];
                    inputs[1].UseAllFluid       = true;

                    correctOrder.AddNode(new Union(inputs, programInfo.OutputsFromTo[outputUsage.ModuleName], block.BlockID));
                }
                else if (block is ImportVariable import)
                {
                    VariableBlock asdqwd = (VariableBlock)programInfo.VariablesFromTo[import.VariableName].TrueCopy(correctOrder);

                    correctOrder.AddNode(asdqwd);

                    correctOrder.AddNode(new SetNumberVariable(asdqwd, import.VariableName, block.BlockID));
                }
                else
                {
                    List <Block> blocks = block.GetBlockTreeList(new List <Block>());
                    blocks.Reverse();
                    foreach (Block blockTreeBlock in blocks)
                    {
                        correctOrder.AddNode(blockTreeBlock);
                    }
                }
            }
            correctOrder.FinishDFG();

            dfg.Nodes.Clear();
            dfg.Input.Clear();
            dfg.Output.Clear();

            dfg.Nodes.AddRange(correctOrder.Nodes);
            dfg.Input.AddRange(correctOrder.Input);
            dfg.Output.AddRange(correctOrder.Output);
        }
Example #26
0
        public static DFG <Block> OptimizeCDFG <T>(int width, int height, CDFG graph, CancellationToken keepRunning, bool useGC)
        {
            DFG <Block>            runningGraph    = graph.StartDFG;
            Stack <IControlBlock>  controlStack    = new Stack <IControlBlock>();
            Stack <List <string> > scopedVariables = new Stack <List <string> >();

            controlStack.Push(null);
            scopedVariables.Push(new List <string>());

            DFG <Block> bigDFG = new DFG <Block>();
            Dictionary <string, string> renamer           = new Dictionary <string, string>();
            Dictionary <string, string> variablePostfixes = new Dictionary <string, string>();

            Schedule scheduler = new Schedule(width, height);

            scheduler.SHOULD_DO_GARBAGE_COLLECTION = useGC;
            List <StaticDeclarationBlock> staticModuleDeclarations = runningGraph.Nodes.Where(node => node.value is StaticDeclarationBlock)
                                                                     .Select(node => node.value as StaticDeclarationBlock)
                                                                     .ToList();

            if (staticModuleDeclarations.Count > 0)
            {
                scheduler.PlaceStaticModules(staticModuleDeclarations);
                scopedVariables.Peek().AddRange(scheduler.NewVariablesCreatedInThisScope.Distinct());
            }

            int nameID = 0;

            while (runningGraph != null)
            {
                int time = scheduler.ListScheduling <T>(runningGraph, null);
                scopedVariables.Peek().AddRange(scheduler.NewVariablesCreatedInThisScope.Distinct().Where(x => !x.Contains("#@#Index")));
                runningGraph.Nodes.ForEach(x => x.value.IsDone = false);

                Assay fisk = new Assay(runningGraph);
                foreach (Block toCopy in fisk)
                {
                    if (toCopy is FluidBlock fluidBlockToCopy)
                    {
                        if (!variablePostfixes.ContainsKey(toCopy.OutputVariable))
                        {
                            variablePostfixes.Add(toCopy.OutputVariable, $"##{nameID++}");
                        }

                        Block copy = fluidBlockToCopy.CopyBlock(bigDFG, renamer, variablePostfixes[toCopy.OutputVariable]);

                        bigDFG.AddNode(copy);
                    }

                    fisk.UpdateReadyOperations(toCopy);
                }

                runningGraph.Nodes.ForEach(x => x.value.Reset());

                var           dropPositionsCopy = scheduler.FluidVariableLocations.ToDictionary();
                List <string> variablesOutOfScope;
                (runningGraph, variablesOutOfScope) = GetNextGraph(graph, runningGraph, null, scheduler.Variables, controlStack, scopedVariables, scheduler.FluidVariableLocations);

                if (useGC)
                {
                    AddWasteBlocks(variablesOutOfScope, bigDFG, renamer, dropPositionsCopy, staticModuleDeclarations);
                }

                foreach (var item in variablesOutOfScope)
                {
                    renamer.Remove(item);
                    variablePostfixes.Remove(item);
                }

                if (keepRunning.IsCancellationRequested)
                {
                    return(null);
                }
            }

            if (useGC)
            {
                AddWasteBlocks(scopedVariables.Pop(), bigDFG, renamer, scheduler.FluidVariableLocations, staticModuleDeclarations);
            }

            bigDFG.FinishDFG();
            return(bigDFG);
        }