private Containers GetContainers() { var containers = new Containers(); foreach (var container in openContainers.Reverse()) { containers.Add(Containers.CreateContainer(container)); } return(containers); }
/// <summary> /// Converts each statement, analyses their containers, then merges them /// </summary> /// <param name="outputs"></param> /// <param name="inputs"></param> protected override void ConvertStatements(IList <IStatement> outputs, IEnumerable <IStatement> inputs) { if (loopMergingInfo == null || !isTopLevel) { base.ConvertStatements(outputs, inputs); return; } OpenOutputBlock(outputs); List <IStatement> converted = new List <IStatement>(); foreach (IStatement ist in inputs) { bool isConvergenceLoop = context.InputAttributes.Has <ConvergenceLoop>(ist); bool isFirstIterPost = context.InputAttributes.Has <FirstIterationPostProcessingBlock>(ist); if (!(isConvergenceLoop || isFirstIterPost)) { isTopLevel = false; } IStatement st = ConvertStatement(ist); if (st != null) { converted.Add(st); } FinishConvertStatement(); isTopLevel = true; } // a container is represented by the first statement that had the container openContainers.Clear(); List <IStatement> newContainers = new List <IStatement>(); List <int> newPriority = new List <int>(); // determine the size of each container, ignoring nesting constraints Func <IStatement, int> getStmtIndex = delegate(IStatement ist) { bool cannotMerge = context.InputAttributes.Has <ConvergenceLoop>(ist) || context.InputAttributes.Has <FirstIterationPostProcessingBlock>(ist) || (ist is ICommentStatement); int stmtIndex = cannotMerge ? -1 : loopMergingInfo.GetIndexOf(ist); return(stmtIndex); }; foreach (IStatement ist in converted) { int stmtIndex = getStmtIndex(ist); IList <IStatement> core = UnwrapStatement(ist, newContainers, newPriority, stmtIndex, keepNested: false); openContainers.AddRange(newContainers); foreach (IStatement container in openContainers) { Set <int> stmts; if (!stmtsOfContainer.TryGetValue(container, out stmts)) { stmts = new Set <int>(); stmtsOfContainer[container] = stmts; } stmts.Add(stmtIndex); } } openContainers.Clear(); stmtsOfContainer.Clear(); List <IStatement> outputContainers = new List <IStatement>(); // merge containers, obeying nesting constraints foreach (IStatement ist in converted) { int stmtIndex = getStmtIndex(ist); IList <IStatement> core = UnwrapStatement(ist, newContainers, newPriority, stmtIndex, keepNested: true); RemoveLast(outputContainers, openContainers.Count); openContainers.AddRange(newContainers); // create output statements for the new containers foreach (IStatement container in newContainers) { IStatement outputContainer = Containers.CreateContainer(container); context.InputAttributes.CopyObjectAttributesTo(container, context.OutputAttributes, outputContainer); AddToLastContainer(outputs, outputContainers, outputContainer); outputContainers.Add(outputContainer); } foreach (IStatement st in core) { AddToLastContainer(outputs, outputContainers, st); } int i = 0; foreach (IStatement container in openContainers) { Set <int> stmts; if (!stmtsOfContainer.TryGetValue(container, out stmts)) { stmts = new Set <int>(); stmtsOfContainer[container] = stmts; } if (!context.InputAttributes.Has <HasOffsetIndices>(outputContainers[i]) && HasOffsetToContainer(container, stmtIndex)) { context.OutputAttributes.Set(outputContainers[i], new HasOffsetIndices()); // for ParallelForTransform } stmts.Add(stmtIndex); i++; } } CloseOutputBlock(); }
private ICollection <IStatement> TransformContainers(IEnumerable <IStatement> containers) { this.isTransformingContainer = true; // must put a dummy statement inside each container so that conversion doesn't prune them. var dummySt = Builder.CommentStmt(); var result = containers.Select(c => ConvertStatement(Containers.WrapWithContainers(dummySt, new[] { Containers.CreateContainer(c) }))).ToList(); this.isTransformingContainer = false; return(result); }