/// <summary> /// Replaces the given action by a new action instance with a search plan adapted /// to the current analysis data of the associated graph. /// </summary> /// <param name="actionName">The name of the action to be replaced.</param> /// <returns>The new action instance.</returns> public LGSPAction GenerateAction(String actionName) { LGSPAction action = (LGSPAction)GetAction(actionName); if (action == null) { throw new ArgumentException("\"" + actionName + "\" is not the name of an action!\n"); } return(GenerateAction(action)); }
/// <summary> /// Replaces the given action by a new action instance with a search plan adapted /// to the current analysis data of the associated graph. /// </summary> /// <param name="action">The action to be replaced.</param> /// <returns>The new action instance.</returns> public LGSPAction GenerateAction(LGSPAction action) { matcherGenerator.LazyNegativeIndependentConditionEvaluation = LazyNIC; matcherGenerator.InlineIndependents = InlineIndependents; matcherGenerator.Profile = Profile; LGSPAction newAction = matcherGenerator.GenerateAction(graph, modelAssemblyName, actionsAssemblyName, (LGSPAction)action); actions[action.Name] = newAction; return(newAction); }
/// <summary> /// Replaces the given actions by new action instances with a search plan adapted /// to the current analysis data of the associated graph. /// </summary> /// <param name="actionNames">An array of names of actions to be replaced.</param> /// <returns>An array with the new action instances.</returns> public LGSPAction[] GenerateActions(params String[] actionNames) { LGSPAction[] oldActions = new LGSPAction[actionNames.Length]; for (int i = 0; i < oldActions.Length; i++) { oldActions[i] = (LGSPAction)GetAction((String)actionNames[i]); if (oldActions[i] == null) { throw new ArgumentException("\"" + (String)actionNames[i] + "\"' is not the name of an action!"); } } return(GenerateActions(oldActions)); }
/// <summary> /// Does action-backend dependent stuff. /// </summary> /// <param name="args">Any kind of parameters for the stuff to do</param> public override void Custom(params object[] args) { if(args.Length == 0) goto invalidCommand; switch((String) args[0]) { case "gen_searchplan": { if(graph.statistics.edgeCounts == null) throw new ArgumentException("Graph not analyzed yet!\nPlease execute 'custom graph analyze'!"); LGSPAction[] oldActions; if(args.Length == 1) { oldActions = new LGSPAction[actions.Count]; int i = 0; foreach(LGSPAction action in actions.Values) { oldActions[i] = action; ++i; } } else { oldActions = new LGSPAction[args.Length - 1]; for(int i = 0; i < oldActions.Length; i++) { oldActions[i] = (LGSPAction)GetAction((String)args[i + 1]); if(oldActions[i] == null) throw new ArgumentException("'" + (String)args[i + 1] + "' is not the name of an action!\n" + "Please use 'show actions' to get a list of the available names."); } } int startticks = Environment.TickCount; matcherGenerator.LazyNegativeIndependentConditionEvaluation = LazyNIC; matcherGenerator.InlineIndependents = InlineIndependents; matcherGenerator.Profile = Profile; LGSPAction[] newActions = matcherGenerator.GenerateActions(graph, modelAssemblyName, actionsAssemblyName, oldActions); int stopticks = Environment.TickCount; Console.Write("Searchplans for actions "); for(int i = 0; i < oldActions.Length; i++) { actions[oldActions[i].Name] = newActions[i]; if(i != 0) Console.Write(", "); Console.Write("'" + oldActions[i].Name + "'"); } Console.WriteLine(" generated in " + (stopticks - startticks) + " ms."); return; } case "dump_sourcecode": if(args.Length != 2) throw new ArgumentException("Usage: dump_sourcecode <bool>\n" + "If <bool> == true, C# files will be dumped for new searchplans."); if(!bool.TryParse((String) args[1], out matcherGenerator.DumpDynSourceCode)) throw new ArgumentException("Illegal bool value specified: \"" + (String) args[1] + "\""); return; case "dump_searchplan": if(args.Length != 2) throw new ArgumentException("Usage: dump_searchplan <bool>\n" + "If <bool> == true, VCG and TXT files will be dumped for new searchplans."); if(!bool.TryParse((String) args[1], out matcherGenerator.DumpSearchPlan)) throw new ArgumentException("Illegal bool value specified: \"" + (String) args[1] + "\""); return; case "explain": { if(args.Length != 2) throw new ArgumentException("Usage: explain <name>\n" + "Explains the searchplan of the given action."); LGSPAction action = (LGSPAction)GetAction((String)args[1]); if(action == null) throw new ArgumentException("'" + (String)args[1] + "' is not the name of an action!\n" + "Please use 'show actions' to get a list of the available names."); if(action.patternGraph.schedules[0] == null) { LGSPGraphStatistics graphStatistics = null; if(StatisticsPath != null) { Console.WriteLine("static search plans from " + StatisticsPath); graphStatistics = new LGSPGraphStatistics(graph.Model); graphStatistics.Parse(StatisticsPath); } else Console.WriteLine("static search plans"); LGSPMatcherGenerator matcherGen = new LGSPMatcherGenerator(graph.Model); matcherGen.FillInStaticSearchPlans(graphStatistics, InlineIndependents, action); } SourceBuilder sb = new SourceBuilder(); foreach(KeyValuePair<LGSPMatchingPattern, LGSPMatchingPattern> usedSubpattern in action.rulePattern.patternGraph.usedSubpatterns) { usedSubpattern.Key.patternGraph.Explain(sb, graph.Model); } action.patternGraph.Explain(sb, graph.Model); Console.WriteLine(sb.ToString()); return; } } invalidCommand: throw new ArgumentException("Possible commands:\n" + "- gen_searchplan: Generates a new searchplan for a given action\n" + " depending on a previous graph analysis\n" + "- explain: explains the searchplan in use for a given action\n" + "- dump_sourcecode: Sets dumping of C# files for new searchplans\n" + "- dump_searchplan: Sets dumping of VCG and TXT files of new\n" + " searchplans (with some intermediate steps)"); }
/// <summary> /// Replaces a given action by another one. /// For internal use. /// </summary> /// <param name="actionName">The name of the action to be replaced.</param> /// <param name="newAction">The new action.</param> public void ReplaceAction(String actionName, LGSPAction newAction) { actions[actionName] = newAction; }
/// <summary> /// Replaces the given actions by new action instances with a search plan adapted /// to the current analysis data of the associated graph. /// </summary> /// <param name="actionNames">An array of names of actions to be replaced.</param> /// <returns>An array with the new action instances.</returns> public LGSPAction[] GenerateActions(params String[] actionNames) { LGSPAction[] oldActions = new LGSPAction[actionNames.Length]; for(int i = 0; i < oldActions.Length; i++) { oldActions[i] = (LGSPAction) GetAction((String) actionNames[i]); if(oldActions[i] == null) throw new ArgumentException("\"" + (String) actionNames[i] + "\"' is not the name of an action!"); } return GenerateActions(oldActions); }
/// <summary> /// Replaces the given action by a new action instance with a search plan adapted /// to the current analysis data of the associated graph. /// </summary> /// <param name="action">The action to be replaced.</param> /// <returns>The new action instance.</returns> public LGSPAction GenerateAction(LGSPAction action) { matcherGenerator.LazyNegativeIndependentConditionEvaluation = LazyNIC; matcherGenerator.InlineIndependents = InlineIndependents; matcherGenerator.Profile = Profile; LGSPAction newAction = matcherGenerator.GenerateAction(graph, modelAssemblyName, actionsAssemblyName, (LGSPAction) action); actions[action.Name] = newAction; return newAction; }
/// <summary> /// Does action-backend dependent stuff. /// </summary> /// <param name="args">Any kind of parameters for the stuff to do; first parameter has to be the command</param> public override void Custom(params object[] args) { if (args.Length == 0) { throw new ArgumentException("No command given"); } String command = (String)args[0]; switch (command) { case "gen_searchplan": { if (graph.statistics.edgeCounts == null) { throw new ArgumentException("Graph not analyzed yet!\nPlease execute 'custom graph analyze'!"); } LGSPAction[] oldActions; if (args.Length == 1) { oldActions = new LGSPAction[actions.Count]; int i = 0; foreach (LGSPAction action in actions.Values) { oldActions[i] = action; ++i; } } else { oldActions = new LGSPAction[args.Length - 1]; for (int i = 0; i < oldActions.Length; i++) { oldActions[i] = (LGSPAction)GetAction((String)args[i + 1]); if (oldActions[i] == null) { throw new ArgumentException("'" + (String)args[i + 1] + "' is not the name of an action!\n" + "Please use 'show actions' to get a list of the available names."); } } } int startticks = Environment.TickCount; matcherGenerator.LazyNegativeIndependentConditionEvaluation = LazyNIC; matcherGenerator.InlineIndependents = InlineIndependents; matcherGenerator.Profile = Profile; LGSPAction[] newActions = matcherGenerator.GenerateActions(graph, modelAssemblyName, actionsAssemblyName, oldActions); int stopticks = Environment.TickCount; Console.Write("Searchplans for actions "); for (int i = 0; i < oldActions.Length; i++) { actions[oldActions[i].Name] = newActions[i]; if (i != 0) { Console.Write(", "); } Console.Write("'" + oldActions[i].Name + "'"); } Console.WriteLine(" generated in " + (stopticks - startticks) + " ms."); return; } case "dump_sourcecode": if (args.Length != 2) { throw new ArgumentException("Usage: dump_sourcecode <bool>\n" + "If <bool> == true, C# files will be dumped for new searchplans."); } if (!bool.TryParse((String)args[1], out matcherGenerator.DumpDynSourceCode)) { throw new ArgumentException("Illegal bool value specified: \"" + (String)args[1] + "\""); } return; case "dump_searchplan": if (args.Length != 2) { throw new ArgumentException("Usage: dump_searchplan <bool>\n" + "If <bool> == true, VCG and TXT files will be dumped for new searchplans."); } if (!bool.TryParse((String)args[1], out matcherGenerator.DumpSearchPlan)) { throw new ArgumentException("Illegal bool value specified: \"" + (String)args[1] + "\""); } return; case "explain": { if (args.Length != 2) { throw new ArgumentException("Usage: explain <name>\n" + "Explains the searchplan of the given action."); } LGSPAction action = (LGSPAction)GetAction((String)args[1]); if (action == null) { throw new ArgumentException("'" + (String)args[1] + "' is not the name of an action!\n" + "Please use 'show actions' to get a list of the available names."); } if (action.patternGraph.schedules[0] == null) { LGSPGraphStatistics graphStatistics = null; if (StatisticsPath != null) { Console.WriteLine("static search plans from " + StatisticsPath); graphStatistics = new LGSPGraphStatistics(graph.Model); GraphStatisticsParserSerializer parserSerializer = new GraphStatisticsParserSerializer(graphStatistics); parserSerializer.Parse(StatisticsPath); } else { Console.WriteLine("static search plans"); } LGSPMatcherGenerator matcherGen = new LGSPMatcherGenerator(graph.Model); matcherGen.FillInStaticSearchPlans(graphStatistics, InlineIndependents, action); } SourceBuilder sb = new SourceBuilder(); foreach (KeyValuePair <LGSPMatchingPattern, LGSPMatchingPattern> usedSubpattern in action.rulePattern.patternGraph.usedSubpatterns) { usedSubpattern.Key.patternGraph.Explain(sb, graph.Model); } action.patternGraph.Explain(sb, graph.Model); Console.WriteLine(sb.ToString()); return; } default: throw new ArgumentException("Unknown command: " + command); } }
/// <summary> /// Generate a new action for the given action, doing the same work, /// but hopefully faster by taking graph analysis information into account /// </summary> public LGSPAction GenerateAction(LGSPGraph graph, String modelAssemblyName, String actionsAssemblyName, LGSPAction action) { return GenerateActions(graph, modelAssemblyName, actionsAssemblyName, action)[0]; }
/// <summary> /// Generate new actions for the given actions, doing the same work, /// but hopefully faster by taking graph analysis information into account /// </summary> public LGSPAction[] GenerateActions(LGSPGraph graph, String modelAssemblyName, String actionsAssemblyName, params LGSPAction[] actions) { if(actions.Length == 0) throw new ArgumentException("No actions provided!"); SourceBuilder sourceCode = new SourceBuilder(CommentSourceCode); GenerateFileHeaderForActionsFile(sourceCode, model.GetType().Namespace, actions[0].rulePattern.GetType().Namespace); // use domain of dictionary as set with rulepatterns of the subpatterns of the actions, get them from pattern graph Dictionary<LGSPMatchingPattern, LGSPMatchingPattern> subpatternMatchingPatterns = new Dictionary<LGSPMatchingPattern, LGSPMatchingPattern>(); foreach (LGSPAction action in actions) { foreach (KeyValuePair<LGSPMatchingPattern, LGSPMatchingPattern> usedSubpattern in action.rulePattern.patternGraph.usedSubpatterns) { subpatternMatchingPatterns[usedSubpattern.Key] = usedSubpattern.Value; } } // generate code for subpatterns foreach (KeyValuePair<LGSPMatchingPattern, LGSPMatchingPattern> subpatternMatchingPattern in subpatternMatchingPatterns) { LGSPMatchingPattern smp = subpatternMatchingPattern.Key; GenerateScheduledSearchPlans(smp.patternGraph, graph, true, false, null); MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(smp.patternGraph); ParallelizeAsNeeded(smp); GenerateActionAndMatcher(sourceCode, smp, false); } // generate code for actions foreach(LGSPAction action in actions) { GenerateScheduledSearchPlans(action.rulePattern.patternGraph, graph, false, false, null); MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(action.rulePattern.patternGraph); ParallelizeAsNeeded(action.rulePattern); GenerateActionAndMatcher(sourceCode, action.rulePattern, false); } // close namespace sourceCode.Append("}"); if(DumpDynSourceCode) { using(StreamWriter writer = new StreamWriter("dynamic_" + actions[0].Name + ".cs")) writer.Write(sourceCode.ToString()); } // set up compiler CSharpCodeProvider compiler = new CSharpCodeProvider(); CompilerParameters compParams = GetDynCompilerSetup(modelAssemblyName, actionsAssemblyName); // compile generated code CompilerResults compResults = compiler.CompileAssemblyFromSource(compParams, sourceCode.ToString()); if(compResults.Errors.HasErrors) { String errorMsg = compResults.Errors.Count + " Errors:"; foreach(CompilerError error in compResults.Errors) errorMsg += Environment.NewLine + "Line: " + error.Line + " - " + error.ErrorText; throw new ArgumentException("Internal error: Illegal dynamic C# source code produced: " + errorMsg); } // create action instances LGSPAction[] newActions = new LGSPAction[actions.Length]; for(int i = 0; i < actions.Length; i++) { newActions[i] = (LGSPAction) compResults.CompiledAssembly.CreateInstance( "de.unika.ipd.grGen.lgspActions.DynAction_" + actions[i].Name); if(newActions[i] == null) throw new ArgumentException("Internal error: Generated assembly does not contain action '" + actions[i].Name + "'!"); } return newActions; }
/// <summary> /// Generates an LGSPAction object for the given scheduled search plan. /// </summary> /// <param name="action">Needed for the rule pattern and the name</param> /// <param name="sourceOutputFilename">null if no output file needed</param> public LGSPAction GenerateAction(ScheduledSearchPlan scheduledSearchPlan, LGSPAction action, String modelAssemblyLocation, String actionAssemblyLocation, String sourceOutputFilename) { SourceBuilder sourceCode = new SourceBuilder(CommentSourceCode); GenerateFileHeaderForActionsFile(sourceCode, model.GetType().Namespace, action.rulePattern.GetType().Namespace); // can't generate new subpattern matchers due to missing scheduled search plans for them / missing graph analyze data Debug.Assert(action.rulePattern.patternGraph.embeddedGraphsPlusInlined.Length == 0); GenerateActionAndMatcher(sourceCode, action.rulePattern, false); // close namespace sourceCode.Append("}"); // write generated source to file if requested if(sourceOutputFilename != null) { StreamWriter writer = new StreamWriter(sourceOutputFilename); writer.Write(sourceCode.ToString()); writer.Close(); } // set up compiler CSharpCodeProvider compiler = new CSharpCodeProvider(); CompilerParameters compParams = GetDynCompilerSetup(modelAssemblyLocation, actionAssemblyLocation); // Stopwatch compilerWatch = Stopwatch.StartNew(); // compile generated code CompilerResults compResults = compiler.CompileAssemblyFromSource(compParams, sourceCode.ToString()); if(compResults.Errors.HasErrors) { String errorMsg = compResults.Errors.Count + " Errors:"; foreach(CompilerError error in compResults.Errors) errorMsg += Environment.NewLine + "Line: " + error.Line + " - " + error.ErrorText; throw new ArgumentException("Illegal dynamic C# source code produced for actions \"" + action.Name + "\": " + errorMsg); } // create action instance Object obj = compResults.CompiledAssembly.CreateInstance("de.unika.ipd.grGen.lgspActions.DynAction_" + action.Name); // long compSourceTicks = compilerWatch.ElapsedTicks; // Console.WriteLine("GenMatcher: Compile source: {0} us", compSourceTicks / (Stopwatch.Frequency / 1000000)); return (LGSPAction) obj; }