Parcourir la source

warn user when algebraic loop optimizer is used on multiple variants

Claudio Gomes il y a 5 ans
Parent
commit
1286a2c3f9
1 fichiers modifiés avec 16 ajouts et 10 suppressions
  1. 16 10
      HintCOEngine/src/ua/ansymo/hintco/CandidatesGenerator.xtend

+ 16 - 10
HintCOEngine/src/ua/ansymo/hintco/CandidatesGenerator.xtend

@@ -23,19 +23,25 @@ class CandidatesGenerator {
 		processor = p
 	}
 	
+	/*
+	 * Recursively goes through every path on the variant diagram and creates the necessary precedence constraints, cleaning up after the function call (that's why we use a stack to keep groups of constraints together).
+	 * Optimization: when optimizeAlgebraicLoops==false, check if there is a cycle every time there are a new edge is created. Then abort that function call, as any children of the variant tree will not be valid. Possible paper that addresses this: https://dl.acm.org/citation.cfm?id=1033207
+	 * The simple solution to find a cycle is to check if there already is a path connecting those two ports being connected.
+	 * (Not done) A better way is to compute transitive closure for quicker reachable computation after adding multiple edges. This result is passed down function calls, and cleaned up as well.
+	 * For now, we just check whether there is a single path passing through all nodes, in a DFS, and return the first such path (mark it on the model, and call semantic adaptation code generation).
+	 * 
+	 * When optimizeAlgebraicLoops==true, we have to continue the recursion, and add constraints as needed. When a variant is fully specified, we launch the algebraic loop optimizer in order to find a schedule for the cosim scenario.
+	 */
 	def generateVariants(HintConfiguration cs, int maxVariants, boolean optimizeAlgebraicLoops){
-		 /*
-		  * Recursively goes through every path on the variant diagram and creates the necessary precedence constraints, cleaning up after the function call.
-		 Optimizations: check if there is a cycle every time there are a new edge is created. Then abort that function call, as any children of the variant tree will not be valid. Possible paper that addresses this: https://dl.acm.org/citation.cfm?id=1033207
-		 Simple solution is to check if there already is a path connecting those two ports being connected.
-		 (Not done) Compute transitive closure for quicker reachable computation after adding multiple edges. This result is passed down function calls, and cleaned up as well.
-		 The base case, for now, is to check whether there is a single path passing through all nodes, in a DFS, and return the first such path (mark it on the model, and call semantic adaptation code generation).
-		  */
 		
 		// Assumes that there is a variant diagram created.
 		Assert.isTrue(cs.root !== null)
 		
-		val genVariants = recGenerateVariants(newLinkedList(cs.root), cs, new ConstraintsStack(), maxVariants)
+		if (optimizeAlgebraicLoops && maxVariants > 1) {
+			logger.warn("Multiple variants chosen with algebraic loop optimizer enabled. This will cause the optimizer to be used for every variant, and might be slow.")
+		}
+		
+		val genVariants = recGenerateVariants(newLinkedList(cs.root), cs, new ConstraintsStack(), maxVariants, optimizeAlgebraicLoops)
 		return genVariants
 	}
 	
@@ -119,7 +125,7 @@ class CandidatesGenerator {
 	// Leave the recursive calls here!
 	def private int recGenerateVariants(Deque<VariantDiagram> ns, 
 										HintConfiguration cs, 
-										ConstraintsStack constraints, int maxVariants) {
+										ConstraintsStack constraints, int maxVariants, boolean optimizeAlgebraicLoops) {
 		// Store size of stack for assertion
 		val callDepth = constraints.size
 		
@@ -285,7 +291,7 @@ class CandidatesGenerator {
 				for (c : n.children) {
 					if (numGenVariants < maxVariants && variantValidator.validVariant(c, n.children.filter[a | a!==c], ns)){
 						ns.push(c)
-						val childGenVariants = recGenerateVariants(ns, cs, constraints, maxVariants-numGenVariants)
+						val childGenVariants = recGenerateVariants(ns, cs, constraints, maxVariants-numGenVariants, optimizeAlgebraicLoops)
 						numGenVariants = numGenVariants + childGenVariants
 						ns.pop()	
 					}