Exemple #1
0
        /// <summary>
        /// Runs CPU benchmark and outputs summary results,
        /// with an overall statistic provided (index to 100 on a Intel Skylake 6142).
        /// </summary>
        /// <returns>Relative CPU index (baseline 100)</returns>
        static int DumpCPUBenchmark()
        {
            Console.WriteLine("-----------------------------------------------------------------------------------");
            Console.WriteLine("CPU BENCHMARK");

            Position             ps = Position.StartPosition;
            EncodedPositionBoard zb = default;
            MGMove nmove            = ConverterMGMoveEncodedMove.EncodedMoveToMGChessMove(new EncodedMove("e2e4"), MGChessPositionConverter.MGChessPositionFromFEN(ps.FEN));

            float ops1 = Benchmarking.DumpOperationTimeAndMemoryStats(() => MGPosition.FromPosition(ps), "MGPosition.FromPosition");
            float ops2 = Benchmarking.DumpOperationTimeAndMemoryStats(() => MGChessPositionConverter.MGChessPositionFromFEN(ps.FEN), "MGChessPositionFromFEN");
            float ops3 = Benchmarking.DumpOperationTimeAndMemoryStats(() => ConverterMGMoveEncodedMove.MGChessMoveToEncodedMove(nmove), "MGChessMoveToLZPositionMove");
            float ops4 = Benchmarking.DumpOperationTimeAndMemoryStats(() => EncodedBoardZobrist.ZobristHash(zb), "ZobristHash");

            // Performance metric is against a baseline system (Intel Skylake 6142)
            const float REFERENCE_BM1_OPS = 2160484;
            const float REFERENCE_BM2_OPS = 448074;
            const float REFERENCE_BM3_OPS = 157575582;
            const float REFERENCE_BM4_OPS = 112731351;

            float relative1 = ops1 / REFERENCE_BM1_OPS;
            float relative2 = ops2 / REFERENCE_BM2_OPS;
            float relative3 = ops3 / REFERENCE_BM3_OPS;
            float relative4 = ops4 / REFERENCE_BM4_OPS;

            float avg = StatUtils.Average(relative1, relative2, relative3, relative4);

            Console.WriteLine();
            Console.WriteLine($"CERES CPU BENCHMARK SCORE: {avg*100,4:F0}");

            return((int)MathF.Round(avg * 100, 0));
        }
Exemple #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="node"></param>
        /// <param name="parentAnnotation">optionally a precomputed parent annotation (otherwise computed)</param>
        /// <returns></returns>
        public unsafe void Annotate(MCTSNode node)
        {
            if (node.Annotation.IsInitialized)
            {
                return;
            }

            NumAnnotations++;

            // Get the position corresponding to this node
            MGPosition newPos;

            if (!node.IsRoot)
            {
                // Apply move for this node to the prior position
                node.Parent.Annotate();
                newPos = node.Parent.Annotation.PosMG;
                newPos.MakeMove(ConverterMGMoveEncodedMove.EncodedMoveToMGChessMove(node.PriorMove, in newPos, true));
            }
            else
            {
                newPos = PriorMoves.FinalPosMG;
            }

            MGMove priorMoveMG = default;

            if (!node.IsRoot)
            {
                priorMoveMG = ConverterMGMoveEncodedMove.EncodedMoveToMGChessMove(node.PriorMove, in node.Parent.Annotation.PosMG, true);
            }

            bool isRoot = node.IsRoot;

            Position newPosAsPos = newPos.ToPosition;

            // Create history, with prepended move representing this move
            Span <Position> posHistory = GetPriorHistoryPositions(node.Parent, in newPosAsPos, PosScratchBuffer,
                                                                  node.Context.ParamsSearch.DrawByRepetitionLookbackPlies, true);

            // Determine the set (possibly a subset) of positions over which to compute hash
            Span <Position> posHistoryForCaching  = posHistory;
            int             numCacheHashPositions = node.Context.EvaluatorDef.NumCacheHashPositions;

            if (posHistory.Length > numCacheHashPositions)
            {
                posHistoryForCaching = posHistory.Slice(posHistory.Length - numCacheHashPositions, numCacheHashPositions);
            }

            // Compute the actual hash
            ulong zobristHashForCaching = EncodedBoardZobrist.ZobristHash(posHistoryForCaching, node.Context.EvaluatorDef.HashMode);

            node.LastAccessedSequenceCounter = node.Context.Tree.SEQUENCE_COUNTER++;
            node.Annotation.PriorMoveMG      = priorMoveMG;

            node.Annotation.Pos   = posHistory[^ 1]; // this will have had its repetition count set
Exemple #3
0
        /// <summary>
        /// Attempts to find a subnode by following specified moves from root.
        /// </summary>
        /// <param name="priorRoot"></param>
        /// <param name="movesMade"></param>
        /// <returns></returns>
        static MCTSNode FollowMovesToNode(MCTSNode priorRoot, IEnumerable <MGMove> movesMade)
        {
            PositionWithHistory startingPriorMove = priorRoot.Context.StartPosAndPriorMoves;
            MGPosition          position          = startingPriorMove.FinalPosMG;
            MCTSIterator        context           = priorRoot.Context;

            // Advance root node and update prior moves
            MCTSNode newRoot = priorRoot;

            foreach (MGMove moveMade in movesMade)
            {
                bool foundChild = false;

                // Find this new root node (after these moves)
                foreach (MCTSNodeStructChild child in newRoot.Ref.Children)
                {
                    if (child.IsExpanded)
                    {
                        MGMove thisChildMove = ConverterMGMoveEncodedMove.EncodedMoveToMGChessMove(child.Move, in position);
                        if (thisChildMove == moveMade)
                        {
                            // Advance new root to reflect this move
                            newRoot = context.Tree.GetNode(child.ChildIndex, newRoot);

                            // Advance position
                            position.MakeMove(thisChildMove);

                            // Done looking for match
                            foundChild = true;
                            break;
                        }
                    }
                }

                if (!foundChild)
                {
                    return(null);
                }
            }

            // Found it
            return(newRoot);
        }