private void GenerateReports(SolverState state, ISolver solver)
        {
            var r = state.Command.Report;

            if (r == null)
            {
                return;
            }

            var renderer   = new MapToReportingRendererText();
            var finalStats = solver.Statistics;

            if (finalStats != null)
            {
                r.WriteLine("### Statistics ###");


                MapToReporting.Create <SolverStatistics>()
                .AddColumn("Name", x => x.Name)
                .AddColumn("Nodes", x => x.TotalNodes)
                .AddColumn("Avg. Speed", x => x.NodesPerSec)
                .AddColumn("Duration (sec)", x => x.DurationInSec)
                .AddColumn("Duplicates", x => x.Duplicates < 0 ? null : (int?)x.Duplicates)
                .AddColumn("Dead", x => x.TotalDead < 0 ? null : (int?)x.TotalDead)
                .AddColumn("Current Depth", x => x.DepthCurrent < 0 ? null : (int?)x.DepthCurrent)
                .RenderTo(finalStats, renderer, Report);
            }

            var repDepth = MapToReporting.Create <SolverHelper.DepthLineItem>()
                           .AddColumn("Depth", x => x.Depth)
                           .AddColumn("Total", x => x.Total)
                           .AddColumn("UnEval", x => x.UnEval)
                           .AddColumn("Complete", x => (x.Total - x.UnEval) * 100 / x.Total, c => c.ColumnInfo.AsPercentage());

            if (state is MultiThreadedSolverState multi)
            {
                r.WriteLine("### Forward Tree ###");
                repDepth.RenderTo(SolverHelper.ReportDepth(multi.Root), renderer, r);

                r.WriteLine("### Reverse Tree ###");
                repDepth.RenderTo(SolverHelper.ReportDepth(multi.RootReverse), renderer, r);
            }
        }
        public int SolverRun(BatchArgs batchArgs, SolverRun run)
        {
            var args =
                new FluentString(" ")
                .Append(batchArgs.Puzzle).Sep()
                .Append($"--solver {batchArgs.Solver}").Sep()
                .Append($"--pool {batchArgs.Pool}").Sep()
                .If(batchArgs.Min > 0, $"--min {batchArgs.Min}").Sep()
                .If(batchArgs.Sec > 0, $"--sec {batchArgs.Sec}").Sep()
                .If(batchArgs.MinR > 0, $"--min-rating {batchArgs.MinR}").Sep()
                .If(batchArgs.MaxR < 2000, $"--min-rating {batchArgs.MaxR}");

            batchArgs.Console.WriteLine($"Arguments: {args}");

            var           exitRequested = false;
            SolverCommand?executing     = null;

            // Setup: Report and cancellation
            var benchId   = DateTime.Now.ToString("s").Replace(':', '-');
            var outFile   = $"./benchmark--{benchId}.txt";
            var outTele   = $"./telemetry--{benchId}.csv";
            var outFolder = "./results/";

            if (!Directory.Exists(outFolder))
            {
                Directory.CreateDirectory(outFolder);
            }
            var info = new FileInfo(System.IO.Path.Combine(outFolder, outFile));
            var tele = new FileInfo(System.IO.Path.Combine(outFolder, outTele));


            using var report  = File.CreateText(info.FullName);
            using var repTele = File.CreateText(tele.FullName);

            System.Console.CancelKeyPress += (o, e) =>
            {
                report.Flush();
                batchArgs.Console.WriteLine("Ctrl+C detected; cancel requested");

                if (executing != null)
                {
                    executing.ExitConditions.ExitRequested = true;
                }
                exitRequested = true;
            };

            ISokobanSolutionRepository?solutionRepo = File.Exists("./solutions.json") && !DevHelper.IsDebug()
                ? new JsonSokobanSolutionRepository("./solutions.json")
                : null;
            ISolverRunTracking?runTracking = null;

            var results    = new List <(Strategy, List <SolverResultSummary>)>();
            var perm       = GetPermutations(batchArgs.Solver, batchArgs.Pool).ToList();
            var countStrat = 0;

            foreach (var strat in perm)
            {
                countStrat++;
                batchArgs.Console.WriteLine($"(Strategy {countStrat}/{perm.Count}) {strat}");

                var ioc = new SolverContainerByType(new Dictionary <Type, Func <Type, object> >()
                {
                    { typeof(ISolverPool), _ => PoolFactory(strat.Pool) },
                    { typeof(ISolverQueue), _ => new SolverQueueConcurrent() },
                    { typeof(ISolverRunTracking), _ => runTracking },
                    { typeof(ISokobanSolutionRepository), _ => solutionRepo },
                });
                var solverCommand = new SolverCommand
                {
                    ServiceProvider = ioc,
                    ExitConditions  = new ExitConditions()
                    {
                        Duration       = TimeSpan.FromMinutes(batchArgs.Min).Add(TimeSpan.FromSeconds(batchArgs.Sec)),
                        MemAvail       = DevHelper.GiB_1 / 2, // Stops the machine hanging / swapping to death
                        StopOnSolution = true,
                    },
                    AggProgress = new ConsoleProgressNotifier(repTele),
                    CheckAbort  = x => exitRequested,
                };


                var runner = new SingleSolverBatchSolveComponent(
                    new TextWriterAdapter(report),
                    batchArgs.Console,
                    solutionRepo,
                    runTracking,
                    5,
                    false);

                var solverInstance = SolverFactory(strat.Solver, ioc);
                var summary        = runner.Run(run, solverCommand, solverInstance, false, batchArgs);
                results.Add((strat, summary));
            }

            // Header
            var extras = new Dictionary <string, string>()
            {
                { "Args", args },
                { "Report", info.FullName }
            };

            DevHelper.WriteFullDevelopmentContext(report, extras);
            DevHelper.WriteFullDevelopmentContext(System.Console.Out, extras);

            // Body
            var reportRow = GenerateReport(results).ToList();

            MapToReporting.Create <SummaryLine>()
            .AddColumn("Solver", x => x.Strategy.Solver)
            .AddColumn("Pool", x => x.Strategy.Pool)
            .AddColumn("Puzzle", x => x.Result.Puzzle.Ident)
            .AddColumn("State", x => x.Result.Exited)
            .AddColumn("Solutions", x => (x.Result.Solutions?.Count ?? 0) == 0 ? null : (int?)x.Result.Solutions.Count)
            .AddColumn("Statistics", x =>
                       x.Result.Exited == ExitConditions.Conditions.Error
                                  ? x.Result.Exited.ToString()
                                  : x.Result.Statistics?.ToString(false, true)
                       )
            .RenderTo(reportRow, new MapToReportingRendererText(), report)
            .RenderTo(reportRow, new MapToReportingRendererText(), System.Console.Out);

            return(results.Any(x => x.Item2.Any(y => y.Exited == ExitConditions.Conditions.Error)) ? -1 : 0); // All exceptions
        }
示例#3
0
        public static void Run(string file, string report)
        {
            System.Console.WriteLine($"<file> {file} --report {report}");


            var ser = new BinaryNodeSerializer();

            if (report == "depth")
            {
                using (var f = System.IO.File.OpenRead(file))
                {
                    using (var br = new BinaryReader(f))
                    {
                        System.Console.WriteLine($"Reading File...");
                        var root = ser.AssembleTree(br);



                        var repDepth = MapToReporting.Create <SolverHelper.DepthLineItem>()
                                       .AddColumn("Depth", x => x.Depth)
                                       .AddColumn("Total", x => x.Total)
                                       .AddColumn("Growth Rate", x => x.GrowthRate)
                                       .AddColumn("UnEval", x => x.UnEval)
                                       .AddColumn("Complete", x => (x.Total - x.UnEval) * 100 / x.Total, c => c.ColumnInfo.AsPercentage());
                        repDepth.RenderTo(SolverHelper.ReportDepth(root), new MapToReportingRendererText(), System.Console.Out);
                    }
                }
            }
            else if (report == "clash")
            {
                using (var f = File.OpenRead(file))
                {
                    var writer = new BinaryNodeSerializer();
                    var nodes  = writer.ReadAll(new BinaryReader(f));

                    Dictionary <int, ClashLineItem> hash = new Dictionary <int, ClashLineItem>();
                    foreach (var n in nodes)
                    {
                        if (hash.TryGetValue(n.HashCode, out var c))
                        {
                            c.Count++;

                            if (c.First.CrateMap.Equals(n.CrateMap) && c.First.MoveMap.Equals(n.MoveMap))
                            {
                                c.Dups++;
                            }
                        }
                        else
                        {
                            hash[n.HashCode] = new ClashLineItem()
                            {
                                Hash  = n.HashCode,
                                Count = 1,
                                First = n
                            };
                        }
                    }

                    var items = hash.Where(x => x.Value.Count > 1).OrderByDescending(x => x.Value.Dups).ThenByDescending(x => x.Value.Count).Take(50).Select(x => x.Value);
                    MapToReporting.Create <ClashLineItem>()
                    .AddColumn("Hash", x => x.Hash)
                    .AddColumn("Count", x => x.Count)
                    .AddColumn("Dups", x => x.Dups)
                    .RenderTo(items, new MapToReportingRendererText(), System.Console.Out);


                    System.Console.WriteLine($"Total Dups: {hash.Values.Sum(x=>x.Dups)}");
                }
            }
            else if (report == "dump")
            {
                using (var f = File.OpenRead(file))
                {
                    var writer = new BinaryNodeSerializer();
                    using (var br = new BinaryReader(f))
                    {
                        foreach (var node in writer.ReadAll(br).OrderBy(x => x.SolverNodeId).Take(20))
                        {
                            System.Console.WriteLine(node);
                        }
                    }
                }
            }
            else
            {
                throw new Exception($"Unknown Report: {report}");
            }
        }