Exemplo n.º 1
0
        private void SearchRangeAttributes(Range range)
        {
            IVariableDeclaration ivd = range.GetIndexDeclaration();

            foreach (ICompilerAttribute attr in range.GetAttributes <ICompilerAttribute>())
            {
                if (attr is ParallelSchedule ps)
                {
                    toSearch.Push(ps.scheduleExpression);
                    var attr2 = new ParallelScheduleExpression(ps.scheduleExpression.GetExpression());
                    Attributes.Set(ivd, attr2);
                }
                else if (attr is DistributedSchedule ds)
                {
                    toSearch.Push(ds.commExpression);
                    if (ds.scheduleExpression != null)
                    {
                        toSearch.Push(ds.scheduleExpression);
                    }
                    if (ds.schedulePerThreadExpression != null)
                    {
                        toSearch.Push(ds.schedulePerThreadExpression);
                    }
                    var attr2 = new DistributedScheduleExpression(ds.commExpression.GetExpression(), ds.scheduleExpression?.GetExpression(), ds.schedulePerThreadExpression?.GetExpression());
                    Attributes.Set(ivd, attr2);
                }
                else
                {
                    Attributes.Set(ivd, attr);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Search all variables referred to by a Range.
        /// </summary>
        /// <param name="range"></param>
        private void SearchRange(Range range)
        {
            if (searched.Contains(range))
            {
                return;
            }
            string name = ((IModelExpression)range).Name;

            foreach (IModelExpression expr in searched)
            {
                if (name.Equals(expr.Name))
                {
                    throw new InferCompilerException("Model contains multiple items with the name '" + name + "'.  Names must be unique.");
                }
            }
            searched.Add(range);
            toSearch.Push(range.Size);
            IVariableDeclaration ivd = range.GetIndexDeclaration();

            foreach (ICompilerAttribute attr in range.GetAttributes <ICompilerAttribute>())
            {
                if (attr is ParallelSchedule)
                {
                    var ps = (ParallelSchedule)attr;
                    toSearch.Push(ps.scheduleExpression);
                    var attr2 = new ParallelScheduleExpression(ps.scheduleExpression.GetExpression());
                    Attributes.Set(ivd, attr2);
                }
                else if (attr is DistributedSchedule)
                {
                    var ds = (DistributedSchedule)attr;
                    toSearch.Push(ds.commExpression);
                    if (ds.scheduleExpression != null)
                    {
                        toSearch.Push(ds.scheduleExpression);
                    }
                    if (ds.schedulePerThreadExpression != null)
                    {
                        toSearch.Push(ds.schedulePerThreadExpression);
                    }
                    var attr2 = new DistributedScheduleExpression(ds.commExpression.GetExpression(), ds.scheduleExpression?.GetExpression(), ds.schedulePerThreadExpression?.GetExpression());
                    Attributes.Set(ivd, attr2);
                }
                else
                {
                    Attributes.Set(ivd, attr);
                }
            }
        }
        /// <summary>
        /// Converts 'for' loops with ParallelSchedule attributes into parallel for loops.
        /// </summary>
        /// <param name="ifs">The for loop to convert</param>
        /// <returns>The converted statement</returns>
        protected override IStatement ConvertFor(IForStatement ifs)
        {
            if (context.InputAttributes.Has <ConvergenceLoop>(ifs) || (ifs is IBrokenForStatement))
            {
                return(base.ConvertFor(ifs));
            }
            IVariableDeclaration       loopVar = Recognizer.LoopVariable(ifs);
            ParallelScheduleExpression pse     = context.InputAttributes.Get <ParallelScheduleExpression>(loopVar);

            if (pse != null)
            {
                return(ConvertForWithParallelSchedule(ifs, loopVar, pse));
            }
            DistributedScheduleExpression dse = context.InputAttributes.Get <DistributedScheduleExpression>(loopVar);

            if (dse != null)
            {
                return(ConvertForWithDistributedSchedule(ifs, loopVar, dse));
            }
            return(base.ConvertFor(ifs));
        }
        private IForStatement ConvertForWithParallelSchedule(IForStatement ifs, IVariableDeclaration loopVar, ParallelScheduleExpression pse)
        {
            // Convert this loop into for(block) Parallel.For(thread) for(indexInBlock)
            IVariableDeclaration loopVarBlock   = VariableInformation.GenerateLoopVar(context, loopVar.Name + "_Block");
            Sequential           sequentialAttr = new Sequential();

            context.OutputAttributes.Set(loopVarBlock, sequentialAttr);
            IVariableDeclaration loopVarInBlock = VariableInformation.GenerateLoopVar(context, loopVar.Name + "_inBlock");

            context.OutputAttributes.Set(loopVarInBlock, sequentialAttr);
            string paramName   = VariableInformation.GenerateName(context, loopVar.Name + "_thread");
            var    threadParam = Builder.Param(paramName, typeof(int));

            if (!pse.scheduleExpression.GetExpressionType().Equals(typeof(int[][][])))
            {
                Error("argument to ParallelSchedule attribute is not of type int[][][]");
            }
            IExpression   itemsInThread    = Builder.ArrayIndex(pse.scheduleExpression, Builder.ParamRef(threadParam));
            IExpression   itemsInBlock     = Builder.ArrayIndex(itemsInThread, Builder.VarRefExpr(loopVarBlock));
            IExpression   itemCountInBlock = Builder.PropRefExpr(itemsInBlock, typeof(int[]), "Length");
            IExpression   threadCount      = Builder.PropRefExpr(pse.scheduleExpression, typeof(int[][][]), "Length");
            IExpression   zero             = Builder.LiteralExpr(0);
            IExpression   blockCount       = Builder.PropRefExpr(Builder.ArrayIndex(pse.scheduleExpression, zero), typeof(int[][]), "Length");
            IForStatement loopInBlock      = Builder.ForStmt(loopVarInBlock, itemCountInBlock);
            bool          isBackwardLoop   = !Recognizer.IsForwardLoop(ifs);

            if (isBackwardLoop)
            {
                Recognizer.ReverseLoopDirection(loopInBlock);
            }
            var assignLoopVar = Builder.AssignStmt(Builder.VarDeclExpr(loopVar), Builder.ArrayIndex(itemsInBlock, Builder.VarRefExpr(loopVarInBlock)));

            loopInBlock.Body.Statements.Add(assignLoopVar);
            ConvertStatements(loopInBlock.Body.Statements, ifs.Body.Statements);
            //loopInBlock.Body.Statements.AddRange(ifs.Body.Statements);
            IAnonymousMethodExpression bodyDelegate = Builder.AnonMethodExpr(typeof(Action <int>));

            bodyDelegate.Body = Builder.BlockStmt();
            bodyDelegate.Body.Statements.Add(loopInBlock);
            bodyDelegate.Parameters.Add(threadParam);
            Delegate d = new Func <int, int, Action <int>, ParallelLoopResult>(Parallel.For);
            IMethodInvokeExpression parallelFor = Builder.StaticMethod(d, zero, threadCount, bodyDelegate);
            IStatement    loopThread            = Builder.ExprStatement(parallelFor);
            IForStatement loopBlock             = Builder.ForStmt(loopVarBlock, blockCount);

            loopBlock.Body.Statements.Add(loopThread);
            if (isBackwardLoop)
            {
                Recognizer.ReverseLoopDirection(loopBlock);
            }
            return(loopBlock);
        }