Beispiel #1
0
 internal void ShowBrowser(TransformerChain tc, string folder, string name)
 {
     if (InferenceEngine.Visualizer?.TransformerChainVisualizer != null)
     {
         InferenceEngine.Visualizer.TransformerChainVisualizer.VisualizeTransformerChain(tc, folder, name);
     }
 }
        /// <summary>
        /// Get the abstract syntax tree for the generated code.
        /// </summary>
        /// <param name="itd"></param>
        /// <param name="method"></param>
        /// <param name="inputAttributes"></param>
        /// <returns></returns>
        internal List <ITypeDeclaration> GetTransformedDeclaration(ITypeDeclaration itd, MethodBase method, AttributeRegistry <object, ICompilerAttribute> inputAttributes)
        {
            TransformerChain        tc = ConstructTransformChain(method);
            List <ITypeDeclaration> output;

            try
            {
                Compiling?.Invoke(this, new CompileEventArgs());
                bool trackTransform = (BrowserMode != BrowserMode.Never);
                List <TransformError> warnings;
                output = tc.TransformToDeclaration(itd, inputAttributes, trackTransform, ShowProgress, out warnings, CatchExceptions, TreatWarningsAsErrors);
                OnCompiled(new CompileEventArgs()
                {
                    Warnings = warnings
                });
                if (BrowserMode == BrowserMode.Always)
                {
                    ShowBrowser(tc, GeneratedSourceFolder, output[0].Name);
                }
                else if (BrowserMode == BrowserMode.WriteFiles)
                {
                    tc.WriteAllOutputs(Path.Combine(GeneratedSourceFolder, output[0].Name + " Transforms"));
                }
                if (ShowSchedule && InferenceEngine.Visualizer?.TaskGraphVisualizer != null)
                {
                    foreach (CodeTransformer ct in tc.transformers)
                    {
                        DeadCodeTransform bst = ct.Transform as DeadCodeTransform;
                        //SchedulingTransform bst = ct.Transform as SchedulingTransform;
                        if (bst != null)
                        {
                            foreach (ITypeDeclaration itd2 in ct.transformMap.Values)
                            {
                                InferenceEngine.Visualizer.TaskGraphVisualizer.VisualizeTaskGraph(itd2, (BasicTransformContext)bst.Context);
                            }
                        }
                    }
                }
            }
            catch (TransformFailedException ex)
            {
                OnCompiled(new CompileEventArgs()
                {
                    Exception = ex
                });
                if (BrowserMode != BrowserMode.Never)
                {
                    ShowBrowser(tc, GeneratedSourceFolder, itd.Name);
                }
                throw new CompilationFailedException(ex.Results, ex.Message);
            }
            return(output);
        }
Beispiel #3
0
        /// <summary>
        /// Construct the transform chain for the given method
        /// </summary>
        /// <param name="method">The method</param>
        /// <returns></returns>
        private TransformerChain ConstructTransformChain(MethodBase method)
        {
            if (algorithm == null)
            {
                throw new InferCompilerException("No algorithm was specified, please specify one before compiling.");
            }
            TransformerChain tc = new TransformerChain();

            //if (args != null) tc.AddTransform(new ParameterInsertionTransform(method,args));
            if (UnrollLoops)
            {
                tc.AddTransform(new LoopUnrollingTransform(method));
            }
            bool useVariableTransform = !(algorithm is GibbsSampling);
            bool useDepthCloning      = useVariableTransform;

            tc.AddTransform(new IsolateModelTransform(method));
            tc.AddTransform(new ExternalVariablesTransform());
            tc.AddTransform(new IntermediateVariableTransform());
            tc.AddTransform(new ModelAnalysisTransform());
            tc.AddTransform(new ArrayAnalysisTransform());
            tc.AddTransform(new EqualityPropagationTransform());
            tc.AddTransform(new StocAnalysisTransform(true));
            tc.AddTransform(new MarginalAnalysisTransform());

            tc.AddTransform(new GateTransform(algorithm));
            tc.AddTransform(new IndexingTransform());
            if (useDepthCloning)
            {
                // DepthCloningTransform needs two passes since the first pass may create new code that needs to be transformed.
                // See SwitchDeepArrayCopyTest.
                //tc.AddTransform(new DepthCloningTransform(false));
                // Unfortunately this breaks ArrayUsedAtManyDepths2.
                tc.AddTransform(new DepthCloningTransform(true));
                tc.AddTransform(new ReplicationTransform());
                // IfCutting must be between Depth and Replication because loops are added
                tc.AddTransform(new IfCuttingTransform());
            }
            tc.AddTransform(new DerivedVariableTransform());
            tc.AddTransform(new PowerTransform());
            tc.AddTransform(new ReplicationTransform());
            if (useVariableTransform)
            {
                tc.AddTransform(new VariableTransform(algorithm));
                if (useDepthCloning)
                {
                    tc.AddTransform(new Channel2Transform(useDepthCloning, false));
                }
            }
            // IfCutting must be after Variable because Variable factors send evidence
            tc.AddTransform(new IfCuttingTransform());
            if (useVariableTransform)
            {
                // must do Replication here since Channel2 could have created new loops (see ArrayUsedAtManyDepths3)
                if (useDepthCloning)
                {
                    tc.AddTransform(new ReplicationTransform());
                }
                tc.AddTransform(new Channel2Transform(useDepthCloning, true));
                tc.AddTransform(new PointMassAnalysisTransform());
            }
            else
            {
                tc.AddTransform(new ChannelTransform(algorithm));
            }
            if (algorithm is GibbsSampling)
            {
                tc.AddTransform(new GroupTransform(algorithm));
            }
            //   tc.AddTransform(new HybridAlgorithmTransform(engine.Algorithm));
            tc.AddTransform(new MessageTransform(this, algorithm, factorManager, this.AllowDerivedParents));
            tc.AddTransform(new IncrementTransform(this));
            if (OptimiseInferenceCode)
            {
                // LoopCutting must precede CopyPropagation because you can have situations such as:
                // for(N) {
                //   bool local = ...;
                //   array[N] = Copy(local);
                // }
                // SomeFactor(array);
                var lct = new LoopCuttingTransform(false);
                tc.AddTransform(lct);
                tc.AddTransform(lct); // run again to catch uses before declaration
                // TODO: fix CopyPropagation so it only needs to run once.
                tc.AddTransform(new CopyPropagationTransform());
                tc.AddTransform(new CopyPropagationTransform());
                tc.AddTransform(new CopyPropagationTransform());
                tc.AddTransform(new HoistingTransform(this));
                // LoopCutting must follow Hoisting since new hoist variables can be loop locals
            }
            var lct2 = new LoopCuttingTransform(true);

            tc.AddTransform(lct2);
            tc.AddTransform(lct2); // run again to catch uses before declaration
            if (OptimiseInferenceCode)
            {
                // must run after HoistingTransform
                tc.AddTransform(new LoopRemovalTransform());
            }
            tc.AddTransform(new DependencyAnalysisTransform());
            tc.AddTransform(new PruningTransform());
            tc.AddTransform(new IterationTransform(this));
            tc.AddTransform(new IncrementPruningTransform());
            tc.AddTransform(new InitializerTransform(this));
            if (UseSerialSchedules && !UseExperimentalSerialSchedules)
            {
                tc.AddTransform(new ForwardBackwardTransform(this));
            }
            tc.AddTransform(new SchedulingTransform(this));
            tc.AddTransform(new UniquenessTransform());
            tc.AddTransform(new DependencyPruningTransform());
            if (OptimiseInferenceCode)
            {
                tc.AddTransform(new LoopReversalTransform());
            }
            tc.AddTransform(new LocalAllocationTransform(this));
            tc.AddTransform(new DeadCodeTransform(this, true));
            // add any extra transforms provided by the user
            if (this.ExtraTransforms != null)
            {
                foreach (var transform in this.ExtraTransforms)
                {
                    tc.AddTransform(transform());
                }
            }
            tc.AddTransform(new IterativeProcessTransform(this, algorithm));
            // LoopMerging is required to support offset indexing (see GateModelTests.CaseLoopIndexTest2)
            tc.AddTransform(new LoopMergingTransform());
            tc.AddTransform(new IsIncreasingTransform());
            // Local is required for DistributedTests
            tc.AddTransform(new LocalTransform(this));
            if (OptimiseInferenceCode)
            {
                tc.AddTransform(new DeadCode2Transform(this));
            }
            tc.AddTransform(new ParallelScheduleTransform());
            // All messages after each iteration will be logged to csv files in a folder named with the model name.
            // Use MatlabWriter.WriteFromCsvFolder to convert these to a mat file.
            bool useTracingTransform = false;

            if (TraceAllMessages && useTracingTransform)
            {
                tc.AddTransform(new TracingTransform());
            }
            bool useArraySizeTracing = false;

            if (useArraySizeTracing)
            {
                // This helps isolate memory performance issues.
                tc.AddTransform(new ArraySizeTracingTransform());
            }
            if (UseParallelForLoops)
            {
                tc.AddTransform(new ParallelForTransform());
            }
            tc.AddTransform(new LoggingTransform(this));
            return(tc);
        }