You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm getting a CancelledError when analyzing a sequence positions in a given game from a public dataset, and I'm really unsure how to debug it.
Minimal code to reproduce:
importosimportchess.engineimportnumpyasnpimportchessfromconcurrent.futuresimportThreadPoolExecutorimportpandasaspddefget_curr_board_analysis_w_root(engine_path, fen, move_uci, depths):
scores= []
board=chess.Board(fen)
move=chess.Move.from_uci(move_uci)
withchess.engine.SimpleEngine.popen_uci(engine_path) asengine:
info= [engine.analyse(board, chess.engine.Limit(depth=d), root_moves=[move]) fordindepths]
scores= [i["score"] foriininfo]
nodes= [i["nodes"] foriininfo]
analysis_dict= {"scores": scores,
"nodes": nodes}
returnanalysis_dictdefboard_analysis_with_thread_pool_w_root(sf_path, boards, moves, depths=list(range(1,15))):
mworkers=min(32, (os.cpu_count() or1) +4)
s= []
n= []
withThreadPoolExecutor(max_workers=mworkers) asexecutor:
# Using map to preserve orderanalysis_dicts=executor.map(lambdafen, move: get_curr_board_analysis_w_root(sf_path, fen, move, depths), boards, moves)
fordctinanalysis_dicts:
s.append(dct['scores'])
n.append(dct['nodes'])
returnnp.asarray(s), np.asarray(n)
defdiff_for_game(game, sf_path):
fens=list(game.board)
moves_uci=list(game.move)
s=1e=15d=list(range(s,e+1))
scores_wr, nodes_wr=board_analysis_with_thread_pool_w_root(sf_path, fens, moves_uci, depths=d)
stockfish_path=".../stockfish_14_linux_x64_avx2/stockfish_14_x64_avx2"data= {'move': ['b8c6', 'f1c4', 'e7e6', 'd2d3', 'g8e7', 'f3g5', 'd7d5', 'e4d5', 'e7d5', 'c4d5',
'd8d5', 'b1c3', 'd5f5', 'f2f3', 'h7h6', 'g2g4', 'f5e5', 'c3e2', 'h6g5', 'c1f4', 'g5f4', 'a2a3',
'e5d6', 'b2b4', 'c5b4', 'a3b4', 'd6b4','d1d2', 'b4d2', 'e1d2', 'f8b4', 'd2d1',
'c8d7', 'a1b1', 'e8g8', 'e2d4', 'c6d4', 'h1e1', 'b4e1','d1e1', 'd4f3','e1e2',
'f3h2', 'e2f2', 'h2g4','f2f3', 'g4f6', 'd3d4', 'f8d8', 'c2c3', 'd7b5', 'b1b5',
'a7a6', 'b5b7', 'a8b8', 'c3c4', 'b8b7', 'c4c5', 'd8d4'],
'board': ['rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2',
'r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 2 3',
'r1bqkbnr/pp1ppppp/2n5/2p5/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq - 3 3',
'r1bqkbnr/pp1p1ppp/2n1p3/2p5/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq - 0 4',
'r1bqkbnr/pp1p1ppp/2n1p3/2p5/2B1P3/3P1N2/PPP2PPP/RNBQK2R b KQkq - 0 4',
'r1bqkb1r/pp1pnppp/2n1p3/2p5/2B1P3/3P1N2/PPP2PPP/RNBQK2R w KQkq - 1 5',
'r1bqkb1r/pp1pnppp/2n1p3/2p3N1/2B1P3/3P4/PPP2PPP/RNBQK2R b KQkq - 2 5',
'r1bqkb1r/pp2nppp/2n1p3/2pp2N1/2B1P3/3P4/PPP2PPP/RNBQK2R w KQkq - 0 6',
'r1bqkb1r/pp2nppp/2n1p3/2pP2N1/2B5/3P4/PPP2PPP/RNBQK2R b KQkq - 0 6',
'r1bqkb1r/pp3ppp/2n1p3/2pn2N1/2B5/3P4/PPP2PPP/RNBQK2R w KQkq - 0 7',
'r1bqkb1r/pp3ppp/2n1p3/2pB2N1/8/3P4/PPP2PPP/RNBQK2R b KQkq - 0 7',
'r1b1kb1r/pp3ppp/2n1p3/2pq2N1/8/3P4/PPP2PPP/RNBQK2R w KQkq - 0 8',
'r1b1kb1r/pp3ppp/2n1p3/2pq2N1/8/2NP4/PPP2PPP/R1BQK2R b KQkq - 1 8',
'r1b1kb1r/pp3ppp/2n1p3/2p2qN1/8/2NP4/PPP2PPP/R1BQK2R w KQkq - 2 9',
'r1b1kb1r/pp3ppp/2n1p3/2p2qN1/8/2NP1P2/PPP3PP/R1BQK2R b KQkq - 0 9',
'r1b1kb1r/pp3pp1/2n1p2p/2p2qN1/8/2NP1P2/PPP3PP/R1BQK2R w KQkq - 0 10',
'r1b1kb1r/pp3pp1/2n1p2p/2p2qN1/6P1/2NP1P2/PPP4P/R1BQK2R b KQkq - 0 10',
'r1b1kb1r/pp3pp1/2n1p2p/2p1q1N1/6P1/2NP1P2/PPP4P/R1BQK2R w KQkq - 1 11',
'r1b1kb1r/pp3pp1/2n1p2p/2p1q1N1/6P1/3P1P2/PPP1N2P/R1BQK2R b KQkq - 2 11',
'r1b1kb1r/pp3pp1/2n1p3/2p1q1p1/6P1/3P1P2/PPP1N2P/R1BQK2R w KQkq - 0 12',
'r1b1kb1r/pp3pp1/2n1p3/2p1q1p1/5BP1/3P1P2/PPP1N2P/R2QK2R b KQkq - 1 12',
'r1b1kb1r/pp3pp1/2n1p3/2p1q3/5pP1/3P1P2/PPP1N2P/R2QK2R w KQkq - 0 13',
'r1b1kb1r/pp3pp1/2n1p3/2p1q3/5pP1/P2P1P2/1PP1N2P/R2QK2R b KQkq - 0 13',
'r1b1kb1r/pp3pp1/2nqp3/2p5/5pP1/P2P1P2/1PP1N2P/R2QK2R w KQkq - 1 14',
'r1b1kb1r/pp3pp1/2nqp3/2p5/1P3pP1/P2P1P2/2P1N2P/R2QK2R b KQkq - 0 14',
'r1b1kb1r/pp3pp1/2nqp3/8/1p3pP1/P2P1P2/2P1N2P/R2QK2R w KQkq - 0 15',
'r1b1kb1r/pp3pp1/2nqp3/8/1P3pP1/3P1P2/2P1N2P/R2QK2R b KQkq - 0 15',
'r1b1kb1r/pp3pp1/2n1p3/8/1q3pP1/3P1P2/2P1N2P/R2QK2R w KQkq - 0 16',
'r1b1kb1r/pp3pp1/2n1p3/8/1q3pP1/3P1P2/2PQN2P/R3K2R b KQkq - 1 16',
'r1b1kb1r/pp3pp1/2n1p3/8/5pP1/3P1P2/2PqN2P/R3K2R w KQkq - 0 17',
'r1b1kb1r/pp3pp1/2n1p3/8/5pP1/3P1P2/2PKN2P/R6R b kq - 0 17',
'r1b1k2r/pp3pp1/2n1p3/8/1b3pP1/3P1P2/2PKN2P/R6R w kq - 1 18',
'r1b1k2r/pp3pp1/2n1p3/8/1b3pP1/3P1P2/2P1N2P/R2K3R b kq - 2 18',
'r3k2r/pp1b1pp1/2n1p3/8/1b3pP1/3P1P2/2P1N2P/R2K3R w kq - 3 19',
'r3k2r/pp1b1pp1/2n1p3/8/1b3pP1/3P1P2/2P1N2P/1R1K3R b kq - 4 19',
'r4rk1/pp1b1pp1/2n1p3/8/1b3pP1/3P1P2/2P1N2P/1R1K3R w - - 5 20',
'r4rk1/pp1b1pp1/2n1p3/8/1b1N1pP1/3P1P2/2P4P/1R1K3R b - - 6 20',
'r4rk1/pp1b1pp1/4p3/8/1b1n1pP1/3P1P2/2P4P/1R1K3R w - - 0 21',
'r4rk1/pp1b1pp1/4p3/8/1b1n1pP1/3P1P2/2P4P/1R1KR3 b - - 1 21',
'r4rk1/pp1b1pp1/4p3/8/3n1pP1/3P1P2/2P4P/1R1Kb3 w - - 0 22',
'r4rk1/pp1b1pp1/4p3/8/3n1pP1/3P1P2/2P4P/1R2K3 b - - 0 22',
'r4rk1/pp1b1pp1/4p3/8/5pP1/3P1n2/2P4P/1R2K3 w - - 0 23',
'r4rk1/pp1b1pp1/4p3/8/5pP1/3P1n2/2P1K2P/1R6 b - - 1 23',
'r4rk1/pp1b1pp1/4p3/8/5pP1/3P4/2P1K2n/1R6 w - - 0 24',
'r4rk1/pp1b1pp1/4p3/8/5pP1/3P4/2P2K1n/1R6 b - - 1 24',
'r4rk1/pp1b1pp1/4p3/8/5pn1/3P4/2P2K2/1R6 w - - 0 25',
'r4rk1/pp1b1pp1/4p3/8/5pn1/3P1K2/2P5/1R6 b - - 1 25',
'r4rk1/pp1b1pp1/4pn2/8/5p2/3P1K2/2P5/1R6 w - - 2 26',
'r4rk1/pp1b1pp1/4pn2/8/3P1p2/5K2/2P5/1R6 b - - 0 26',
'r2r2k1/pp1b1pp1/4pn2/8/3P1p2/5K2/2P5/1R6 w - - 1 27',
'r2r2k1/pp1b1pp1/4pn2/8/3P1p2/2P2K2/8/1R6 b - - 0 27',
'r2r2k1/pp3pp1/4pn2/1b6/3P1p2/2P2K2/8/1R6 w - - 1 28',
'r2r2k1/pp3pp1/4pn2/1R6/3P1p2/2P2K2/8/8 b - - 0 28',
'r2r2k1/1p3pp1/p3pn2/1R6/3P1p2/2P2K2/8/8 w - - 0 29',
'r2r2k1/1R3pp1/p3pn2/8/3P1p2/2P2K2/8/8 b - - 0 29',
'1r1r2k1/1R3pp1/p3pn2/8/3P1p2/2P2K2/8/8 w - - 1 30',
'1r1r2k1/1R3pp1/p3pn2/8/2PP1p2/5K2/8/8 b - - 0 30',
'3r2k1/1r3pp1/p3pn2/8/2PP1p2/5K2/8/8 w - - 0 31',
'3r2k1/1r3pp1/p3pn2/2P5/3P1p2/5K2/8/8 b - - 0 31']
}
data_g=pd.DataFrame(data)
r=diff_for_game(data_g, stockfish_path)
Stacktrace:
CancelledError Traceback (most recent call last)
File ~/.conda/envs/chess-env/lib/python3.12/asyncio/tasks.py:520, in wait_for(fut, timeout)
519 async with timeouts.timeout(timeout):
--> 520 return await fut
File ~/.conda/envs/chess-env/lib/python3.12/site-packages/chess/engine.py:1510, in UciProtocol.initialize(self)
1508 engine.id[key] = value
-> 1510 return await self.communicate(UciInitializeCommand)
File ~/.conda/envs/chess-env/lib/python3.12/site-packages/chess/engine.py:1133, in Protocol.communicate(self, command_factory)
1131 self.command._cancel(self)
-> 1133 return await command.result
CancelledError:
Before the CancelledError, I also get the below warning:
RuntimeWarning: A loop is being detached from a child watcher with pending handlers
which repeats itself a bit more than 10 times before I eventually get a TimeoutError caused by the CancelledError. This 'CancelledError' has the following traceback:
TimeoutError Traceback (most recent call last)
Cell In[19], line 1
----> 1 r = diff_for_game(data_g, stockfish_path)
Cell In[18], line 120, in diff_for_game(game, sf_path)
117 e = 15
118 d = list(range(s,e+1))
--> 120 scores_wr, nodes_wr = board_analysis_with_thread_pool_w_root(sf_path, fens, moves_uci, depths=d)
Cell In[18], line 77, in board_analysis_with_thread_pool_w_root(sf_path, boards, moves, depths)
73 with ThreadPoolExecutor(max_workers=mworkers) as executor:
74 # Using map to preserve order
75 analysis_dicts = executor.map(lambda fen, move: get_curr_board_analysis_w_root(sf_path, fen, move, depths), boards, moves)
---> 77 for dct in analysis_dicts:
78 s.append(dct['scores'])
79 n.append(dct['nodes'])
File ~/.conda/envs/chess-env/lib/python3.12/concurrent/futures/_base.py:619, in Executor.map.<locals>.result_iterator()
616 while fs:
617 # Careful not to keep a reference to the popped future
618 if timeout is None:
--> 619 yield _result_or_cancel(fs.pop())
620 else:
621 yield _result_or_cancel(fs.pop(), end_time - time.monotonic())
File ~/.conda/envs/chess-env/lib/python3.12/concurrent/futures/_base.py:317, in _result_or_cancel(***failed resolving arguments***)
315 try:
316 try:
--> 317 return fut.result(timeout)
318 finally:
319 fut.cancel()
File ~/.conda/envs/chess-env/lib/python3.12/concurrent/futures/_base.py:449, in Future.result(self, timeout)
447 raise CancelledError()
448 elif self._state == FINISHED:
--> 449 return self.__get_result()
451 self._condition.wait(timeout)
453 if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]:
File ~/.conda/envs/chess-env/lib/python3.12/concurrent/futures/_base.py:401, in Future.__get_result(self)
399 if self._exception:
400 try:
--> 401 raise self._exception
402 finally:
403 # Break a reference cycle with the exception in self._exception
404 self = None
File ~/.conda/envs/chess-env/lib/python3.12/concurrent/futures/thread.py:58, in _WorkItem.run(self)
55 return
57 try:
---> 58 result = self.fn(*self.args, **self.kwargs)
59 except BaseException as exc:
60 self.future.set_exception(exc)
Cell In[18], line 75, in board_analysis_with_thread_pool_w_root.<locals>.<lambda>(fen, move)
72 n = []
73 with ThreadPoolExecutor(max_workers=mworkers) as executor:
74 # Using map to preserve order
---> 75 analysis_dicts = executor.map(lambda fen, move: get_curr_board_analysis_w_root(sf_path, fen, move, depths), boards, moves)
77 for dct in analysis_dicts:
78 s.append(dct['scores'])
Cell In[18], line 58, in get_curr_board_analysis_w_root(engine_path, fen, move_uci, depths)
55 board = chess.Board(fen)
56 move = chess.Move.from_uci(move_uci)
---> 58 with chess.engine.SimpleEngine.popen_uci(engine_path) as engine:
59 info = [engine.analyse(board, chess.engine.Limit(depth=d), root_moves=[move]) for d in depths]
61 scores = [i["score"] for i in info]
File ~/.conda/envs/chess-env/lib/python3.12/site-packages/chess/engine.py:3054, in SimpleEngine.popen_uci(cls, command, timeout, debug, setpgrp, **popen_args)
3048 @classmethod
3049 def popen_uci(cls, command: Union[str, List[str]], *, timeout: Optional[float] = 10.0, debug: bool = False, setpgrp: bool = False, **popen_args: Any) -> SimpleEngine:
3050 """
3051 Spawns and initializes a UCI engine.
3052 Returns a :class:`~chess.engine.SimpleEngine` instance.
3053 """
-> 3054 return cls.popen(UciProtocol, command, timeout=timeout, debug=debug, setpgrp=setpgrp, **popen_args)
File ~/.conda/envs/chess-env/lib/python3.12/site-packages/chess/engine.py:3046, in SimpleEngine.popen(cls, Protocol, command, timeout, debug, setpgrp, **popen_args)
3043 simple_engine.close()
3044 await simple_engine.shutdown_event.wait()
-> 3046 return run_in_background(background, name=f"{cls.__name__} (command={command!r})", debug=debug)
File ~/.conda/envs/chess-env/lib/python3.12/site-packages/chess/engine.py:201, in run_in_background(coroutine, name, debug, _policy_lock)
198 future.set_exception(exc)
200 threading.Thread(target=background, name=name).start()
--> 201 return future.result()
File ~/.conda/envs/chess-env/lib/python3.12/concurrent/futures/_base.py:456, in Future.result(self, timeout)
454 raise CancelledError()
455 elif self._state == FINISHED:
--> 456 return self.__get_result()
457 else:
458 raise TimeoutError()
File ~/.conda/envs/chess-env/lib/python3.12/concurrent/futures/_base.py:401, in Future.__get_result(self)
399 if self._exception:
400 try:
--> 401 raise self._exception
402 finally:
403 # Break a reference cycle with the exception in self._exception
404 self = None
File ~/.conda/envs/chess-env/lib/python3.12/site-packages/chess/engine.py:195, in run_in_background.<locals>.background()
193 def background() -> None:
194 try:
--> 195 asyncio.run(coroutine(future))
196 future.cancel()
197 except Exception as exc:
File ~/.conda/envs/chess-env/lib/python3.12/asyncio/runners.py:194, in run(main, debug, loop_factory)
190 raise RuntimeError(
191 "asyncio.run() cannot be called from a running event loop")
193 with Runner(debug=debug, loop_factory=loop_factory) as runner:
--> 194 return runner.run(main)
File ~/.conda/envs/chess-env/lib/python3.12/asyncio/runners.py:118, in Runner.run(self, coro, context)
116 self._interrupt_count = 0
117 try:
--> 118 return self._loop.run_until_complete(task)
119 except exceptions.CancelledError:
120 if self._interrupt_count > 0:
File ~/.conda/envs/chess-env/lib/python3.12/asyncio/base_events.py:685, in BaseEventLoop.run_until_complete(self, future)
682 if not future.done():
683 raise RuntimeError('Event loop stopped before Future completed.')
--> 685 return future.result()
File ~/.conda/envs/chess-env/lib/python3.12/site-packages/chess/engine.py:3038, in SimpleEngine.popen.<locals>.background(future)
3036 simple_engine = cls(transport, protocol, timeout=timeout)
3037 try:
-> 3038 await asyncio.wait_for(protocol.initialize(), timeout)
3039 future.set_result(simple_engine)
3040 returncode = await protocol.returncode
File ~/.conda/envs/chess-env/lib/python3.12/asyncio/tasks.py:519, in wait_for(fut, timeout)
516 except exceptions.CancelledError as exc:
517 raise TimeoutError from exc
--> 519 async with timeouts.timeout(timeout):
520 return await fut
File ~/.conda/envs/chess-env/lib/python3.12/asyncio/timeouts.py:115, in Timeout.__aexit__(self, exc_type, exc_val, exc_tb)
110 self._state = _State.EXPIRED
112 if self._task.uncancel() <= self._cancelling and exc_type is exceptions.CancelledError:
113 # Since there are no new cancel requests, we're
114 # handling this.
--> 115 raise TimeoutError from exc_val
116 elif self._state is _State.ENTERED:
117 self._state = _State.EXITED
TimeoutError:
Expected behavior:
The computation should go as normal, getting the score and nodes for every board position in the given game across the provided depths. For reference, this code works perfectly fine for 1400 games before this exact game.
Thanks for reporting. I've edited the script slightly to make it runnable, but I don't see the same issue, neither on Linux nor Windows 10. Do you the the issue also with the reduced script, or only in context of a larger program?
I'm getting a CancelledError when analyzing a sequence positions in a given game from a public dataset, and I'm really unsure how to debug it.
Minimal code to reproduce:
Stacktrace:
Before the CancelledError, I also get the below warning:
which repeats itself a bit more than 10 times before I eventually get a
TimeoutError
caused by theCancelledError
. This 'CancelledError' has the following traceback:Expected behavior:
The computation should go as normal, getting the score and nodes for every board position in the given game across the provided depths. For reference, this code works perfectly fine for 1400 games before this exact game.
Here's the last thing the logger gets.
The fen "r1b1kb1r/pp3pp1/2nqp3/8/1P3pP1/3P1P2/2P1N2P/R2QK2R b KQkq - 0 15" doesn't even get half way through all the board positions.
Environment:
Python version: 3.12
python-chess version: 1.10
Operating System: Windows 10 (2.4 GHz Intel Broadwell)
Chess Engine Used: Stockfish 14
The text was updated successfully, but these errors were encountered: