private static string RunRepair(string scheduleString, params Action <IStatement[], DependencyInformation[]>[] dependencies) { var scheduleParts = scheduleString.Split(",".ToCharArray()).ToArray(); var schedule = scheduleParts.Select(int.Parse).ToArray(); var numStmts = schedule.Max() + 1; var stmts = Enumerable.Range(0, numStmts).Select(i => CodeBuilder.Instance.CommentStmt(i.ToString(CultureInfo.InvariantCulture))).ToArray(); var context = new BasicTransformContext(); var depInfos = stmts.Select(i => new DependencyInformation()).ToArray(); schedule.ForEach(i => { if (!context.InputAttributes.Has <DependencyInformation>(stmts[i])) { context.InputAttributes.Set(stmts[i], depInfos[i]); } }); schedule.ForEach(i => { if (!context.InputAttributes.Has <OperatorStatement>(stmts[i])) { context.InputAttributes.Set(stmts[i], new OperatorStatement()); } }); dependencies.ForEach(dep => dep(stmts, depInfos)); var dg = new DependencyGraph(context, stmts); var invalid = new Set <int>(); var stale = new Set <DependencyGraph.TargetIndex>(); var initialized = new Set <int>(); var repaired = dg.RepairSchedule(schedule, invalid, stale, initialized); return(string.Join(",", repaired.Select(i => i.ToString(CultureInfo.InvariantCulture)))); }
internal static Containers GetContainersNeededForExpression(BasicTransformContext context, IExpression expr, int excludeAncestorIndex) { Containers containers = GetContainersNeededForExpression(context, expr); containers.OrderByContext(context, excludeAncestorIndex + 1); return(containers); }
internal static Containers SortStochasticConditionals(Containers containers, BasicTransformContext context) { Containers result = new Containers(); Containers conditionals = new Containers(); for (int i = 0; i < containers.inputs.Count; i++) { IStatement container = containers.inputs[i]; if (container is IConditionStatement) { IConditionStatement ics = (IConditionStatement)container; if (CodeRecognizer.IsStochastic(context, ics.Condition)) { conditionals.inputs.Add(container); conditionals.outputs.Add(containers.outputs[i]); continue; } } result.inputs.Add(container); result.outputs.Add(containers.outputs[i]); } for (int i = 0; i < conditionals.inputs.Count; i++) { result.inputs.Add(conditionals.inputs[i]); result.outputs.Add(conditionals.outputs[i]); } return(result); }
internal TaskGraphView(ITypeDeclaration itd, BasicTransformContext context) { pretasks = Builder.StmtCollection(); looptasks = Builder.StmtCollection(); foreach (IMethodDeclaration imd in itd.Methods) { if (!context.InputAttributes.Has <OperatorMethod>(imd)) { continue; } foreach (IStatement ist in imd.Body.Statements) { if (ist is IWhileStatement) { looptasks.AddRange(((IWhileStatement)ist).Body.Statements); continue; } if (context.InputAttributes.Has <OperatorStatement>(ist)) { pretasks.Add(ist); } } // if (imd.Name == "Initialise") pretasks.AddRange(((IBlockStatement)imd.Body).Statements); //if (imd.Name == "Update") looptasks.AddRange(((IBlockStatement)imd.Body).Statements); } this.context = context; OnTasksChanged(); }
/// <summary> /// Get the minimal set of containers needed for all variables in an expression to be declared. /// </summary> /// <param name="context"></param> /// <param name="expr"></param> /// <returns></returns> internal static Containers GetContainersNeededForExpression(BasicTransformContext context, IExpression expr) { Containers containers = new Containers(); containers.AddContainersNeededForExpression(context, expr); return(containers); }
public static Set <IVariableDeclaration> GetConditionedLoopVariables(BasicTransformContext context) { Set <IVariableDeclaration> loopVars = new Set <IVariableDeclaration>(); foreach (IConditionStatement ics in context.FindAncestors <IConditionStatement>()) { ConditionBinding binding = new ConditionBinding(ics.Condition); if (binding.lhs is IVariableReferenceExpression) { IVariableReferenceExpression ivre = (IVariableReferenceExpression)binding.lhs; if (Recognizer.GetLoopForVariable(context, ivre) != null) { loopVars.Add(Recognizer.GetVariableDeclaration(ivre)); } } if (binding.rhs is IVariableReferenceExpression) { IVariableReferenceExpression ivre = (IVariableReferenceExpression)binding.rhs; if (Recognizer.GetLoopForVariable(context, ivre) != null) { loopVars.Add(Recognizer.GetVariableDeclaration(ivre)); } } } return(loopVars); }
public static IVariableDeclaration GenerateLoopVar(BasicTransformContext context, string prefix) { IVariableDeclaration ivd = Builder.VarDecl(GenerateName(context, prefix), typeof(int)); //VariableInformation.GetVariableInformation(context, ivd); return(ivd); }
/// <summary> /// Remove loops (and their dependent containers) that are not needed to evaluate the expression. /// </summary> /// <param name="containers"></param> /// <param name="context"></param> /// <param name="needed"></param> /// <returns></returns> internal static Containers RemoveUnusedLoops(Containers containers, BasicTransformContext context, Containers needed) { Containers result = new Containers(); Set <IVariableDeclaration> allowedVars = Containers.GetConditionedLoopVariables(context); allowedVars.Clear(); // for ReplicateWithConditionedIndexTest for (int i = 0; i < containers.inputs.Count; i++) { IStatement container = containers.inputs[i]; if (container is IForStatement) { IForStatement ifs = container as IForStatement; IVariableDeclaration loopVar = Recognizer.LoopVariable(ifs); if (!allowedVars.Contains(loopVar) && !needed.Contains(container)) { continue; } } result.inputs.Add(container); result.outputs.Add(containers.outputs[i]); } // Removing unused loops may have left us with containers that refer to the removed loop index. We must remove these also. // Note this routine could be merged with RemoveUnusedLoops. result = Containers.RemoveInvalidConditions(result, context); return(result); }
/// <summary> /// Gets the VariableInformation attribute of ivd, or creates one if it doesn't already exist /// </summary> internal static VariableInformation GetVariableInformation(BasicTransformContext context, object target) { IVariableDeclaration ivd = null; if (target is IVariableDeclaration) { ivd = (IVariableDeclaration)target; } else if (target is IParameterDeclaration) { IParameterDeclaration ipd = (IParameterDeclaration)target; ivd = Builder.VarDecl(ipd.Name, ipd.ParameterType); } else if (target is IFieldDeclaration) { IFieldDeclaration ifd = (IFieldDeclaration)target; ivd = Builder.VarDecl(ifd.Name, ifd.FieldType); } else { throw new ArgumentException("target is not a variable or parameter"); } VariableInformation vi = context.InputAttributes.Get <VariableInformation>(target); if (vi == null) { vi = new VariableInformation(ivd); context.InputAttributes.Set(target, vi); } return(vi); }
/// <summary> /// Returns true if expr can be evaluated in the given containers, i.e. all local variables are declared. /// </summary> /// <param name="containers"></param> /// <param name="context"></param> /// <param name="expr"></param> /// <returns></returns> internal static bool ContainsExpression(List <IStatement> containers, BasicTransformContext context, IExpression expr) { return(Recognizer.GetVariables(expr).All(ivd => { Containers c = context.InputAttributes.Get <Containers>(ivd); // does containers contain all of c? return c.inputs.TrueForAll(st => Containers.ListContains(containers, st, allowBrokenLoops: true, ignoreLoopDirection: true)); })); }
public IExpression Replace(BasicTransformContext context, IExpression expr) { if (copyMap.ContainsKey(expr)) { var cc = copyMap[expr]; if (cc.IsValidContext(context)) { return(cc.Expression); } } if (expr is IArrayIndexerExpression) { IArrayIndexerExpression iaie = (IArrayIndexerExpression)expr; if (copiedInEveryElementMap.ContainsKey(iaie.Target)) { var cc = copiedInEveryElementMap[iaie.Target]; if (cc.IsValidContext(context)) { return(cc.Expression); } } if (copyAtIndexMap.ContainsKey(iaie.Target)) { var cc = copyAtIndexMap[iaie.Target]; if (cc.Depth == 1 && cc.IsValidContext(context)) { return(cc.ExpressionAtIndex(new[] { iaie.Indices })); } } if (iaie.Target is IArrayIndexerExpression) { var iaie2 = (IArrayIndexerExpression)iaie.Target; if (copyAtIndexMap.ContainsKey(iaie2.Target)) { var cc = copyAtIndexMap[iaie2.Target]; if (cc.Depth == 2 && cc.IsValidContext(context)) { return(cc.ExpressionAtIndex(new[] { iaie2.Indices, iaie.Indices })); } } if (iaie2.Target is IArrayIndexerExpression) { var iaie3 = (IArrayIndexerExpression)iaie2.Target; if (copyAtIndexMap.ContainsKey(iaie3.Target)) { var cc = copyAtIndexMap[iaie3.Target]; if (cc.Depth == 3 && cc.IsValidContext(context)) { return(cc.ExpressionAtIndex(new[] { iaie3.Indices, iaie2.Indices, iaie.Indices })); } } } } } return(null); }
/// <summary> /// Gets the VariableInformation attribute of a declaration object, or creates one if it doesn't already exist /// </summary> internal static VariableInformation GetVariableInformation(BasicTransformContext context, object declaration) { VariableInformation vi = context.InputAttributes.Get <VariableInformation>(declaration); if (vi == null) { vi = new VariableInformation(declaration); context.InputAttributes.Set(declaration, vi); } return(vi); }
/// <summary> /// The first index in the input stack matching the given container, or -1 if not found. /// </summary> /// <param name="context"></param> /// <param name="ancestor">A container</param> /// <returns></returns> internal static int GetAncestorIndex(BasicTransformContext context, IStatement ancestor) { for (int i = 0; i < context.InputStack.Count; i++) { IStatement anc = context.InputStack[i].inputElement as IStatement; if (ContainersAreEqual(anc, ancestor)) { return(i); } } return(-1); }
internal static Containers RemoveInvalidConditions(Containers containers, BasicTransformContext context) { Containers result = new Containers(); for (int i = 0; i < containers.inputs.Count; i++) { IStatement container = containers.inputs[i]; if (container is IConditionStatement ics) { IExpression condition = ics.Condition; if (condition is IBinaryExpression ibe && ibe.Operator == BinaryOperator.BooleanAnd) { // split the condition into conjuncts List <IExpression> conditions = new List <IExpression>(); IExpression newCondition = null; bool changed = false; ForEachConjunct(condition, delegate(IExpression expr) { if (ContainsExpression(containers.inputs, context, expr)) { if (newCondition == null) { newCondition = expr; } else { newCondition = Builder.BinaryExpr(BinaryOperator.BooleanAnd, newCondition, expr); } } else { changed = true; } }); if (changed) { if (newCondition != null) { IConditionStatement cs = Builder.CondStmt(newCondition, Builder.BlockStmt()); result.inputs.Add(cs); result.outputs.Add(cs); } continue; } } else { if (!ContainsExpression(containers.inputs, context, condition)) { continue; } } }
internal Containers(BasicTransformContext context, int count) { for (int i = 0; i < count; i++) { TransformInfo ti = context.InputStack[i]; IStatement inputElement = ti.inputElement as IStatement; if (IsContainer(inputElement) && !context.InputAttributes.Has <ConvergenceLoop>(inputElement)) { inputs.Add(CreateContainer(inputElement)); outputs.Add((IStatement)ti.PrimaryOutput); } } }
internal bool IsValidContext(BasicTransformContext context) { var containers = new Containers(context); foreach (var ics in ConditionContext) { if (!containers.Contains(ics)) { return(false); } } return(true); }
internal int GetMaxAncestorIndex(BasicTransformContext context) { int ancIndex = -1; foreach (IStatement container in inputs) { int ancIndex2 = GetAncestorIndex(context, container); if (ancIndex2 > ancIndex) { ancIndex = ancIndex2; } } return(ancIndex); }
public static void setAllGroupRoots(BasicTransformContext context, IVariableDeclaration ivd, bool isRoot) { IList <GroupMember> gmas = context.OutputAttributes.GetAll <GroupMember>(ivd); if (gmas != null) { context.OutputAttributes.Remove <GroupMember>(ivd); foreach (GroupMember gma in gmas) { GroupMember gmanew = new GroupMember(gma.Group, isRoot); context.OutputAttributes.Add(ivd, gmanew); } } }
internal void AddContainersNeededForExpression(BasicTransformContext context, IExpression expr) { foreach (var ivd in Recognizer.GetVariables(expr)) { Containers c = context.InputAttributes.Get <Containers>(ivd); if (c == null) { context.Error("Containers not found for '" + ivd.Name + "'."); return; } Add(c); } this.OrderByContext(context); }
public void DefineSizesUpToDepth(BasicTransformContext context, int arrayDepth) { IExpression sourceArray = GetExpression(); for (int depth = 0; depth < arrayDepth; depth++) { bool notLast = (depth < arrayDepth - 1); int rank; Type arrayType = sourceArray.GetExpressionType(); Util.GetElementType(arrayType, out rank); if (sizes.Count <= depth) { sizes.Add(new IExpression[rank]); } IExpression[] indices = new IExpression[rank]; for (int i = 0; i < rank; i++) { if (sizes.Count <= depth || sizes[depth][i] == null) { if (rank == 1) { sizes[depth][i] = Builder.PropRefExpr(sourceArray, arrayType, arrayType.IsArray ? "Length" : "Count", typeof(int)); } else { sizes[depth][i] = Builder.Method(sourceArray, typeof(Array).GetMethod("GetLength"), Builder.LiteralExpr(i)); } } if (notLast) { if (indexVars.Count <= depth) { indexVars.Add(new IVariableDeclaration[rank]); } IVariableDeclaration v = indexVars[depth][i]; if (v == null) { v = GenerateLoopVar(context, "_iv"); indexVars[depth][i] = v; } indices[i] = Builder.VarRefExpr(v); } } if (notLast) { sourceArray = Builder.ArrayIndex(sourceArray, indices); } } }
/// <summary> /// The containers of the current transform context. /// </summary> /// <param name="context"></param> /// <param name="loopVarsHaveOneContainer"></param> internal Containers(BasicTransformContext context, bool loopVarsHaveOneContainer = true) // : this(FindContainers(context)) { if (loopVarsHaveOneContainer) { int ancIndex2 = Recognizer.GetAncestorIndexOfLoopBeingInitialized(context); if (ancIndex2 != -1) { // For a loop variable, the loop is the only container. // This is needed to allow re-ordering nested loops. Otherwise, the inner loop variable would always require the outer loop around it. // It is also useful for ignoring conditioned loops. TransformInfo ti = context.InputStack[ancIndex2]; IForStatement ifs = (IForStatement)ti.inputElement; IStatement container = CreateContainer(ifs); inputs.Add(container); #if ignoreOutput outputs.Add(container); #else outputs.Add((IStatement)ti.PrimaryOutput); #endif var loopVar = Recognizer.LoopVariable(ifs); bool mustRemove = false; if (!context.InputAttributes.Has <Containers>(loopVar)) { context.InputAttributes.Set(loopVar, this); mustRemove = true; } var initExpr = ((IExpressionStatement)ifs.Initializer).Expression; this.AddContainersNeededForExpression(context, initExpr); this.AddContainersNeededForExpression(context, ifs.Condition); if (mustRemove) { context.InputAttributes.Remove <Containers>(loopVar); } return; } } // exclude the current statement. int ancIndex = context.FindAncestorIndex <IStatement>(); for (int i = 0; i < ancIndex; i++) { TransformInfo ti = context.InputStack[i]; IStatement inputElement = ti.inputElement as IStatement; if (IsContainer(inputElement) && !context.InputAttributes.Has <ConvergenceLoop>(inputElement)) { inputs.Add(CreateContainer(inputElement)); outputs.Add((IStatement)ti.PrimaryOutput); } } }
public static string GenerateName(BasicTransformContext context, string prefix) { int ancIndex = context.FindAncestorIndex <ITypeDeclaration>(); object input = context.GetAncestor(ancIndex); NameGenerator ng = context.InputAttributes.Get <NameGenerator>(input); if (ng == null) { ng = new NameGenerator(); context.InputAttributes.Set(input, ng); object output = context.GetOutputForAncestorIndex <object>(ancIndex); context.OutputAttributes.Set(output, ng); } return(ng.GenerateName(prefix)); }
/// <summary> /// Get the minimal set of containers needed to evaluate an expression, along with the first index in the context stack at which the expression's variables are all declared. /// </summary> /// <param name="context">The transform context</param> /// <param name="expr">Any expression</param> /// <param name="ancIndex">On exit, the first index in the context stack at which the expression's variables are all declared.</param> /// <returns>The minimal set of containers needed to evaluate expr</returns> internal static Containers GetContainersNeededForExpression(BasicTransformContext context, IExpression expr, out int ancIndex) { Containers containers = GetContainersNeededForExpression(context, expr); if (containers == null) { ancIndex = -1; return(null); } ancIndex = containers.GetMatchingAncestorIndex(context); // append any conditionals with constant conditions //List<IStatement> loopsMissing = Containers.GetLoopsNeededForExpression(context, expr, ancIndex-1, true); //containers = Containers.Append(containers, loopsMissing); //containers.OrderByContext(context); return(containers); }
internal static Containers InsideOf(BasicTransformContext context, int exclude) { Containers containers = new Containers(); for (int i = exclude + 1; i < context.InputStack.Count; i++) { TransformInfo ti = context.InputStack[i]; IStatement inputElement = ti.inputElement as IStatement; if (IsContainer(inputElement) && !context.InputAttributes.Has <ConvergenceLoop>(inputElement)) { containers.inputs.Add(CreateContainer(inputElement)); containers.outputs.Add((IStatement)ti.PrimaryOutput); } } return(containers); }
/// <summary> /// Collect all containers that are not in the context at the given index. /// </summary> /// <param name="context"></param> /// <param name="ancestorIndex">If 0, all containers are returned.</param> /// <returns></returns> internal Containers GetContainersNotInContext(BasicTransformContext context, int ancestorIndex) { Containers result = new Containers(); for (int i = 0; i < inputs.Count; i++) { IStatement container = inputs[i]; int index = GetAncestorIndex(context, container); if (index == -1 || index >= ancestorIndex) { result.inputs.Add(container); result.outputs.Add(outputs[i]); } } return(result); }
internal IExpression GetMarginalPrototypeExpression(BasicTransformContext context, IExpression prototypeExpression, IList <IList <IExpression> > indices, IList <IList <IExpression> > wildcardVars = null) { IExpression original = prototypeExpression; int replaceCount = 0; prototypeExpression = ReplaceIndexVars(context, prototypeExpression, indices, wildcardVars, ref replaceCount); int mpDepth = Util.GetArrayDepth(varType, Distribution.GetDomainType(prototypeExpression.GetExpressionType())); int indexingDepth = indices.Count; int wildcardBracket = 0; for (int depth = mpDepth; depth < indexingDepth; depth++) { IList <IExpression> indexCollection = Builder.ExprCollection(); int wildcardCount = 0; for (int i = 0; i < indices[depth].Count; i++) { if (Recognizer.IsStaticMethod(indices[depth][i], new Func <int>(GateAnalysisTransform.AnyIndex))) { indexCollection.Add(wildcardVars[wildcardBracket][wildcardCount]); wildcardCount++; } else { indexCollection.Add(indices[depth][i]); } } if (indexCollection.Count > 0) { if (wildcardCount > 0) { wildcardBracket++; } prototypeExpression = Builder.ArrayIndex(prototypeExpression, indexCollection); replaceCount++; } } if (replaceCount > 0) { return(prototypeExpression); } else { return(original); } }
public List <IList <IExpression> > GetIndexExpressions(BasicTransformContext context, int depth) { DefineIndexVarsUpToDepth(context, depth); List <IList <IExpression> > indexExprs = new List <IList <IExpression> >(); for (int d = 0; d < depth; d++) { IList <IExpression> bracketExprs = Builder.ExprCollection(); for (int i = 0; i < indexVars[d].Length; i++) { IVariableDeclaration indexVar = indexVars[d][i]; bracketExprs.Add(Builder.VarRefExpr(indexVar)); } indexExprs.Add(bracketExprs); } return(indexExprs); }
internal static List <ConditionBinding> GetBindings(BasicTransformContext context, IEnumerable <IStatement> containers) { List <ConditionBinding> bindings = new List <ConditionBinding>(); foreach (IStatement st in containers) { if (st is IConditionStatement) { IConditionStatement ics = (IConditionStatement)st; if (!CodeRecognizer.IsStochastic(context, ics.Condition)) { ConditionBinding binding = new ConditionBinding(ics.Condition); bindings.Add(binding); } } } return(bindings); }
public void DefineIndexVarsUpToDepth(BasicTransformContext context, int depth) { for (int d = 0; d < depth; d++) { for (int i = 0; i < sizes[d].Length; i++) { IVariableDeclaration v = (indexVars.Count <= d) ? null : indexVars[d][i]; if (v == null) { v = GenerateLoopVar(context, "_iv"); } if (indexVars.Count == d) { indexVars.Add(new IVariableDeclaration[sizes[d].Length]); } indexVars[d][i] = v; } } }
/// <summary> /// Replace all indexVars which appear in expr with the given indices. /// </summary> /// <param name="context"></param> /// <param name="expr">Any expression</param> /// <param name="indices">A list of lists of index expressions (one list for each indexing bracket).</param> /// <param name="wildcardIndices">Expressions used to replace wildcards. May be null if there are no wildcards.</param> /// <param name="replaceCount">The number of replacements.</param> /// <returns>A new expression.</returns> internal IExpression ReplaceIndexVars(BasicTransformContext context, IExpression expr, IList <IList <IExpression> > indices, IList <IList <IExpression> > wildcardIndices, out int replaceCount) { replaceCount = 0; Dictionary <IVariableDeclaration, IExpression> replacedIndexVars = new Dictionary <IVariableDeclaration, IExpression>(); int wildcardBracket = 0; for (int depth = 0; depth < indices.Count; depth++) { if (indexVars.Count > depth) { int wildcardCount = 0; for (int i = 0; i < indices[depth].Count; i++) { if (indexVars[depth].Length > i) { IVariableDeclaration indexVar = indexVars[depth][i]; if (indexVar != null) { IExpression actualIndex = indices[depth][i]; if (Recognizer.IsStaticMethod(actualIndex, new Func <int>(GateAnalysisTransform.AnyIndex))) { actualIndex = wildcardIndices[wildcardBracket][wildcardCount]; wildcardCount++; } IExpression formalIndex = Builder.VarRefExpr(indexVar); if (!formalIndex.Equals(actualIndex)) { expr = Builder.ReplaceExpression(expr, formalIndex, actualIndex, ref replaceCount); replacedIndexVars.Add(indexVar, actualIndex); } } } } if (wildcardCount > 0) { wildcardBracket++; } } } CheckReplacements(context, expr, replacedIndexVars); return(expr); }