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)); } }
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); }
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); }
internal static DFG <Block> ParseDFG(XmlNode node, ParserInfo parserInfo, bool allowDeclarationBlocks = false, bool canFirstBlockBeControlFlow = true) { parserInfo.EnterDFG(); try { IControlBlock controlBlock = null; var dfg = new DFG <Block>(); while (true) { if (IsDFGBreaker(node, dfg) && canFirstBlockBeControlFlow) { controlBlock = ParseDFGBreaker(node, dfg, parserInfo); break; } canFirstBlockBeControlFlow = true; Block block = null; try { block = ParseAndAddNodeToDFG(node, dfg, parserInfo, allowDeclarationBlocks); } catch (ParseException e) { parserInfo.ParseExceptions.Add(e); } allowDeclarationBlocks = block is DeclarationBlock && allowDeclarationBlocks; //move on to the next node or exit if none node = node.TryGetNodeWithName("next"); if (node == null) { break; } node = node.FirstChild; } if (parserInfo.ParseExceptions.Count == 0) { dfg.FinishDFG(); } parserInfo.cdfg.AddNode(controlBlock, dfg); parserInfo.LeftDFG(); return(dfg); } catch (ParseException e) { parserInfo.ParseExceptions.Add(e); parserInfo.LeftDFG(); return(null); } }
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); } } }
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); }
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); }
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); }