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); }
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)); }
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)); }
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)); }
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, "")); } } } }
public override Block TrueCopy(DFG <Block> dfg) { VariableBlock operandCopy = (VariableBlock)OperandBlock.TrueCopy(dfg); dfg.AddNode(operandCopy); return(new SetNumberVariable(operandCopy, OutputVariable, BlockID)); }
public override FluidInput TrueCopy(DFG <Block> dfg) { VariableBlock indexCopy = (VariableBlock)IndexBlock.TrueCopy(dfg); dfg.AddNode(indexCopy); return(new GetArrayFluid(indexCopy, ArrayName, ID, AmountInML, UseAllFluid)); }
public override Block TrueCopy(DFG <Block> dfg) { VariableBlock arrayLengthCopy = (VariableBlock)ArrayLengthBlock.TrueCopy(dfg); dfg.AddNode(arrayLengthCopy); return(new NumberArray(ArrayName, arrayLengthCopy, BlockID)); }
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); }
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)); }
public override Block TrueCopy(DFG <Block> dfg) { VariableBlock numberCopy = (VariableBlock)NumberBlock.TrueCopy(dfg); dfg.AddNode(numberCopy); return(new RoundOP(numberCopy, OutputVariable, RoundType, BlockID, CanBeScheduled)); }
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)); }
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)); }
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); }
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 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)); }
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)); }
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)); }
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); }
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)); }
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)); }
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]]}."); } } }
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); }