static void MCTSProgressCallback(MCTSManager manager) { int numUpdatesSent = 0; DateTime now = DateTime.Now; float timeSinceLastUpdate = (float)(now - lastInfoUpdate).TotalSeconds; bool isFirstUpdate = numUpdatesSent == 0; float UPDATE_INTERVAL_SECONDS = 1;// isFirstUpdate ? 0.1f : 3f; if (timeSinceLastUpdate > UPDATE_INTERVAL_SECONDS && manager.Root.N > 0) { Console.WriteLine(UCIManager.UCIInfoString(manager)); lastInfoUpdate = now; } }
public SuiteTestResultItem(MCTSManager manager, MGMove bestMove) { using (new SearchContextExecutionBlock(manager.Context)) { if (manager.TablebaseImmediateBestMove != default(MGMove)) { Q = 1.0; BestMove = manager.TablebaseImmediateBestMove; PickedNonTopNMoveStr = " "; } else { Q = manager.Root.Q; UCIInfoString = UCIManager.UCIInfoString(manager); // SearchPrincipalVariation pv1 = new SearchPrincipalVariation(worker1.Root); BestMove = bestMove; N = manager.Context.Root.N; NumNodesWhenChoseTopNNode = manager.NumNodesWhenChoseTopNNode; NumNNBatches = manager.Context.NumNNBatches; NumNNNodes = manager.Context.NumNNNodes; TopNNodeN = manager.TopNNode.N; FractionNumNodesWhenChoseTopNNode = manager.FractionNumNodesWhenChoseTopNNode; AvgDepth = manager.Context.AvgDepth; MAvg = manager.Context.Root.MAvg; NodeSelectionYieldFrac = manager.Context.NodeSelectionYieldFrac; // TODO: try removing this, clean up try { PickedNonTopNMoveStr = !manager.Root.BestMove(false).Equals(manager.Root.ChildWithLargestValue(node => node.N)) ? "!" : " "; } catch (Exception excp) { // TODO: resolve this PickedNonTopNMoveStr = "?"; } } } }
public static void Analyze(string fen, SearchLimit searchLimit, NNEvaluatorDef evaluatorDef, bool forceDisablePruning, LC0Engine lc0Engine = null, GameEngine comparisonEngine = null, bool verbose = false) { Console.WriteLine("============================================================================="); Console.WriteLine("Analyzing FEN : " + fen); Console.WriteLine("Search limit : " + searchLimit.ToString()); Console.WriteLine("Ceres evaluator : " + evaluatorDef.ToString()); if (comparisonEngine != null) { Console.WriteLine("Opponent : " + comparisonEngine.ToString()); } Console.WriteLine(); Console.WriteLine(); NNEvaluatorSet nnEvaluators = new NNEvaluatorSet(evaluatorDef); // Warmup (in parallel) lc0Engine?.DoSearchPrepare(); Parallel.Invoke( () => nnEvaluators.Warmup(true), () => comparisonEngine?.Warmup()); bool ceresDone = false; lastInfoUpdate = DateTime.Now; UCISearchInfo lastCeresInfo = null; // Launch Ceres MCTSearch ceresResults = null; Task searchCeres = Task.Run(() => { ParamsSearch searchParams = new ParamsSearch(); searchParams.FutilityPruningStopSearchEnabled = !forceDisablePruning; PositionWithHistory positionWithHistory = PositionWithHistory.FromFENAndMovesUCI(fen, null); ceresResults = new MCTSearch(); ceresResults.Search(nnEvaluators, new ParamsSelect(), searchParams, null, null, null, positionWithHistory, searchLimit, verbose, DateTime.Now, null, manager => lastCeresInfo = new UCISearchInfo(UCIManager.UCIInfoString(manager), null, null), false, true); }); // Possibly launch search for other engine Task searchComparison = null; if (lc0Engine != null || comparisonEngine != null) { searchComparison = Task.Run(() => { if (lc0Engine != null) { lc0Engine.DoSearchPrepare(); lc0Engine.AnalyzePositionFromFENAndMoves(fen, null, fen, searchLimit); } else { // TODO: someday enable passing in of moves here comparisonEngine.Search(PositionWithHistory.FromFENAndMovesUCI(fen, null), searchLimit, verbose: true); } }); } ; while (!searchCeres.IsCompleted || (searchComparison != null && !searchComparison.IsCompleted)) { Thread.Sleep(1000); //Console.WriteLine(DateTime.Now + " --> " + lastCeresInfo?.PVString + " OTHER " + comparisonEngine?.UCIInfo?.RawString); int numCharactersSame = int.MaxValue; if (lastCeresInfo?.PVString != null || comparisonEngine?.UCIInfo?.RawString != null) { if (lastCeresInfo != null && comparisonEngine?.UCIInfo != null) { numCharactersSame = 0; string pv1 = lastCeresInfo.PVString; UCISearchInfo lastComparisonInfo = comparisonEngine.UCIInfo; string pv2 = lastComparisonInfo.PVString; while (pv1.Length > numCharactersSame && pv2.Length > numCharactersSame && pv1[numCharactersSame] == pv2[numCharactersSame]) { numCharactersSame++; } } } if (lastCeresInfo != null) { WriteUCI("Ceres", lastCeresInfo, numCharactersSame); } if (comparisonEngine != null) { WriteUCI(comparisonEngine.ID, comparisonEngine.UCIInfo, numCharactersSame); } Console.WriteLine(); } searchCeres.Wait(); searchComparison?.Wait(); string infoUpdate = UCIManager.UCIInfoString(ceresResults.Manager); double q2 = ceresResults.BestMoveRoot.Q; //SearchPrincipalVariation pv2 = new SearchPrincipalVariation(worker2.Root); MCTSPosTreeNodeDumper.DumpPV(ceresResults.Manager.Context.StartPosAndPriorMoves, ceresResults.BestMoveRoot, true, null); }