public Analyzer InitializeBuildSimulatorAnalyzer(AnalysisInput analysisInput) { string outputDirectory = null; var simulator = new BuildSimulatorAnalyzer(analysisInput); foreach (var opt in AnalyzerOptions) { if (opt.Name.Equals("outputDirectory", StringComparison.OrdinalIgnoreCase) || opt.Name.Equals("o", StringComparison.OrdinalIgnoreCase)) { simulator.OutputDirectory = ParseSingletonPathOption(opt, outputDirectory); } else if (opt.Name.Equals("step", StringComparison.OrdinalIgnoreCase) || opt.Name.Equals("s", StringComparison.OrdinalIgnoreCase)) { simulator.IncludedExecutionSteps[(int)ParseEnumOption <PipExecutionStep>(opt)] = true; } else { throw Error("Unknown option for build simulation analysis: {0}", opt.Name); } } return(simulator); }
public override int Analyze() { Console.WriteLine($"Analyzing"); m_block.Complete(); m_block.CompletionAsync().GetAwaiter().GetResult(); Console.WriteLine($"Writing Graph"); foreach (var pip in PipGraph.RetrieveAllPips()) { var serializedPip = pip; var nodeId = pip.PipId.ToNodeId(); bool addEdges = true; if (pip.PipType == PipType.Process) { var entry = GetEntry(pip.PipId); serializedPip = entry.Process; addEdges = !entry.AddedEdges; } if (addEdges && AddEdgesForPips) { using (var scope = m_mutableGraph.AcquireExclusiveIncomingEdgeScope(nodeId)) { foreach (var edge in DataflowGraph.GetIncomingEdges(nodeId)) { scope.AddEdge(edge.OtherNode, edge.IsLight); } } } serializedPip.ResetPipIdForTesting(); m_pipTable.Add(nodeId.Value, serializedPip); } m_mutableGraph.Seal(); CachedGraph.Serializer.SerializeToFileAsync( GraphCacheFile.DirectedGraph, m_mutableGraph.Serialize, Path.Combine(OutputFilePath, nameof(GraphCacheFile.DirectedGraph))) .GetAwaiter().GetResult(); CachedGraph.Serializer.SerializeToFileAsync( GraphCacheFile.PipTable, w => m_pipTable.Serialize(w, Environment.ProcessorCount), Path.Combine(OutputFilePath, nameof(GraphCacheFile.PipTable))) .GetAwaiter().GetResult(); CachedGraph.Serializer.SerializeToFileAsync( GraphCacheFile.PipGraphId, PipGraph.SerializeGraphId, Path.Combine(OutputFilePath, nameof(GraphCacheFile.PipGraphId))) .GetAwaiter().GetResult(); Console.WriteLine($"Simulating [Reading]"); var simulator = new BuildSimulatorAnalyzer(Input); simulator.Increment = SimulatorIncrement ?? simulator.Increment; simulator.ExecutionData.DataflowGraph = m_mutableGraph; simulator.OutputDirectory = OutputFilePath; simulator.ReadExecutionLog(); Console.WriteLine($"Simulating [Analyzing]"); simulator.Analyze(); Console.WriteLine($"Blocking Dependency Analysis"); DisplayTable <DepColumn> depTable = new DisplayTable <DepColumn>(" , "); foreach (var pipId in PipTable.Keys) { var pipType = PipTable.GetPipType(pipId); if (pipType == PipType.Process) { var entry = GetEntry(pipId); (PipId node, ulong cost)maxConsumedDependency = default; (PipId node, ulong cost)maxDependency = default; foreach (var dep in entry.PipDependencies) { var cost = simulator.ExecutionData.BottomUpAggregateCosts[dep.Key.ToNodeId()]; if (!maxDependency.node.IsValid || cost > maxDependency.cost) { maxDependency = (dep.Key, cost); } if (dep.Value != null && dep.Value.HasFlag(ContentFlag.Consumed)) { if (!maxConsumedDependency.node.IsValid || cost > maxConsumedDependency.cost) { maxConsumedDependency = (dep.Key, cost); } } } depTable.NextRow(); depTable.Set(DepColumn.Id, $"{entry.SpecFileName}-{entry.Identifier}"); depTable.Set(DepColumn.MaxConsumedDependency, ToString(maxConsumedDependency.node)); depTable.Set(DepColumn.MaxConsumedDependencyChainCost, maxConsumedDependency.cost.ToMinutes()); depTable.Set(DepColumn.MaxDependency, ToString(maxDependency.node)); depTable.Set(DepColumn.MaxDependencyChainCost, maxDependency.cost.ToMinutes()); } else if (pipType == PipType.SealDirectory && !PipTable.GetSealDirectoryKind(pipId).IsSourceSeal() && !IsSourceOnlySeal(pipId)) { var seal = (SealDirectory)GetPip(pipId); var entry = GetEntry(seal.Directory); (PipId node, ulong cost)maxDependency = default; foreach (var dep in DataflowGraph.GetIncomingEdges(pipId.ToNodeId())) { var cost = simulator.ExecutionData.BottomUpAggregateCosts[dep.OtherNode]; if (!maxDependency.node.IsValid || cost > maxDependency.cost) { maxDependency = (dep.OtherNode.ToPipId(), cost); } } depTable.NextRow(); depTable.Set(DepColumn.Id, $"{entry.SpecFileName}-{entry.Identifier} ({entry.FileCount} files)"); depTable.Set(DepColumn.MaxDependency, ToString(maxDependency.node)); depTable.Set(DepColumn.MaxDependencyChainCost, maxDependency.cost.ToMinutes()); depTable.Set(DepColumn.Directory, seal.DirectoryRoot.ToString(PathTable)); } } using (var blockAnalysisWriter = new StreamWriter(Path.Combine(OutputFilePath, "blockAnalysis.txt"))) { depTable.Write(blockAnalysisWriter); } m_writer.Dispose(); Console.WriteLine($"Analyzing complete"); return(0); }