classic search: introduce SearchTree overlay and move n_in_flight out of Node#11
Draft
Copilot wants to merge 3 commits into
Draft
classic search: introduce SearchTree overlay and move n_in_flight out of Node#11Copilot wants to merge 3 commits into
Copilot wants to merge 3 commits into
Conversation
Add SearchTree as a lightweight per-search overlay keyed by Node*. The
overlay owns search-local bookkeeping that should not live in the
persistent Node tree.
In this first commit the overlay takes ownership of the shared collision
path bookkeeping (previously stored as Search::shared_collisions_). The
SearchTree class and its per-node SearchTreeNode struct are defined in
the new files src/search/classic/search_tree.{h,cc}.
Changes:
- New src/search/classic/search_tree.h: SearchTreeNode struct (n_in_flight
placeholder) and SearchTree class with collision bookkeeping and
n_in_flight API stubs for the next commit.
- New src/search/classic/search_tree.cc: implementation.
- meson.build: add search_tree.cc to the build.
- search.h: include search_tree.h, add search_tree_ member, remove
shared_collisions_ (moved into SearchTree).
- search.cc: initialise search_tree_ in constructor; delegate
CancelSharedCollisions() and CollectCollisions() to search_tree_.
Agent-Logs-Url: https://github.com/borg323/lc0/sessions/a12b09e2-9933-49f1-8fd7-127528dd6d83
Co-authored-by: borg323 <39573933+borg323@users.noreply.github.com>
Remove n_in_flight_ from the persistent Node and move all virtual-loss
/ in-flight accounting into SearchTree (introduced in the previous
commit).
Changes:
- node.h: remove n_in_flight_ field, GetNInFlight(), GetNStarted(),
TryStartScoreUpdate(), CancelScoreUpdate(), IncrementNInFlight().
Update EdgeAndNode::GetU() to take an explicit nstarted parameter
(callers now compute it via search_tree_->GetNStarted()).
Simplify VisitedNode_Iterator: now stops at the first N=0 node;
the n_in_flight-based early-exit optimisation is replaced by a
simpler N==0 check (equivalent for the common case).
Update static_assert: sizeof(Node) 64 → 56.
- node.cc: remove TryStartScoreUpdate/CancelScoreUpdate
implementations. Update FinalizeScoreUpdate to no longer decrement
n_in_flight_. Update MakeSolid to remove n_in_flight safety checks
(function is still disabled via #if 0 in the backup path).
- search_tree.h / search_tree.cc: add full n_in_flight API:
TryStartScoreUpdate, CancelScoreUpdate, IncrementNInFlight,
FinalizeScoreUpdate, GetNInFlight, GetNStarted.
- search.cc: update all call sites:
* PickNodesToExtendTask: TryStartScoreUpdate, IncrementNInFlight,
GetNStarted → search_tree_ equivalents.
* GatherMinibatch OOO: CancelScoreUpdate, IncrementNInFlight →
search_tree_.
* DoBackupUpdateSingleNode: add search_tree_->FinalizeScoreUpdate.
* GetVerboseStats: GetNInFlight/GetNStarted → search_tree_.
* PrefetchIntoCache: GetNStarted → search_tree_->GetNStarted.
Build validated: ninja build passes cleanly on both commits.
Agent-Logs-Url: https://github.com/borg323/lc0/sessions/a12b09e2-9933-49f1-8fd7-127528dd6d83
Co-authored-by: borg323 <39573933+borg323@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Refactor classic search by introducing search-local tree overlay
classic search: introduce SearchTree overlay and move n_in_flight out of Node
Apr 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Nodemixes persistent game-tree state with ephemeral search-local state (n_in_flight_, collision bookkeeping). This PR separates them across two commits without removingNode::parent_.Commit 1 — Introduce
SearchTreeoverlayNew
src/search/classic/search_tree.{h,cc}provides a lightweight per-search overlay keyed byNode*. In this commit it takes ownership ofshared_collisions_(previously a rawstd::vectoronSearch):Search::shared_collisions_is replaced bystd::unique_ptr<SearchTree> search_tree_, initialised in the constructor.CancelSharedCollisions()andCollectCollisions()delegate to it.Commit 2 — Move
n_in_flight_/ virtual loss intoSearchTreeNode: removen_in_flight_field and all derived APIs (GetNInFlight,GetNStarted,TryStartScoreUpdate,CancelScoreUpdate,IncrementNInFlight).FinalizeScoreUpdateno longer decrements n_in_flight.sizeof(Node)shrinks from 64 → 56 bytes.SearchTree: gains the full virtual-loss API (TryStartScoreUpdate,CancelScoreUpdate,IncrementNInFlight,FinalizeScoreUpdate,GetNInFlight,GetNStarted).search.cc: all call sites updated — selection (PickNodesToExtendTask), OOO collision handling (GatherMinibatch), backup (DoBackupUpdateSingleNode), verbose stats, and prefetch.EdgeAndNode::GetU: now takes an explicitnstartedargument; callers obtain it viasearch_tree_->GetNStarted(node).VisitedNode_Iterator: then_in_flight-based early-exit optimisation is replaced by a simpler N==0 stop (functionally equivalent for the common case; iterator does not have SearchTree access).Node::parent_,GetParent(), andGetOwnEdge()are intentionally preserved — ancestry reconstruction migration is deferred to a future step.Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
gitlab.com/home/REDACTED/.local/bin/meson meson setup /tmp/lc0build --wipe -Dgtest=false(dns block)wrapdb.mesonbuild.com/home/REDACTED/.local/bin/meson meson setup /tmp/lc0build --wipe -Dgtest=false(dns block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
Implement the first two stages of refactoring classic search search-local state in
borg323/lc0.Repository:
borg323/lc0Base ref:
backprop3Context:
Node::parent_for active search path handling.SearchTree) keyed to the persistentNodetree, to own search-local path / ancestry / collision bookkeeping as appropriate.n_in_flight_/ virtual-loss accounting out ofNodeand into that search-local tree / overlay.Node::parent_/ fully migrating all ancestry reconstruction) should NOT be done in this PR.Requirements:
Node::parent_.n_in_flight_/ virtual loss accounting out ofNodeinto the search-local tree/overlay and update selection / collision / verbose stats / prefetch / backup related code accordingly.Nodeas the persistent game-tree state holder for long-lived data such as edges,n_,wl_,d_,m_, bounds, terminal flags, etc.Node::parent_,GetParent(), orGetOwnEdge()in this PR.src/search/classic/search.h,src/search/classic/search.cc,src/search/classic/node.h, andsrc/search/classic/node.cc, and add new files if appropriate.n_in_flight_and related APIs fromNodeonly in the second commit, after the search-local replacement exists.Suggested design direction:
SearchTreeshould be a lightweight per-search overlay keyed byNode*, rather than a duplicated ownership tree.Node.Node::parent_may remain as-is unless there is a clear benefit to routing through the new overlay.Please make the commit boundaries clean and explain them clearly in the PR description.
The following is the prior conversation context from the user's chat exploration (may be truncated):
User: This branch keeps track of the node path during the search and avoids use of the parent pointer in the
Node. I would like to make those paths into some kind of a local tree (saySearchTree) and also move then_in_flight_counter out of theNodeand into this tree as it logically belongs in the search.Assistant: Yes — the refactor direction makes sense, and the current code is already halfway there.
The cleanest design is:
Nodeas persistent game-tree state only,SearchTreethat owns:n_in_flight/ virtual-loss accounting,SearchTreeentries while still storing long-lived stats (n_,wl_,d_,m_, bounds, children/edges) inNode.Why this is a good split
Right now
Nodemixes two concerns:n_, eval aggregates, bounds, edges, child storageparent_usage during search,n_in_flight_, collision path bookkeepingYour branch already started separating path tracking from
Node::parent_by carrying full paths inNodeToProcessand task workspaces:NodeToProcess::pathinsearch.hTaskWorkspace::full_pathinsearch.hPickTask::start_pathinsearch.hSo introducing a
SearchTreeis a natural next step rather than a conceptual jump.The strongest reason to move
n_in_flight_out ofNoden_in_flight_is not really a property of the reused game tree; it's a property of the currently running search.That shows up in several ways:
CancelSharedCollisions)Nodehas search-time synchronization couplingMakeSolid()because “in flight” state is embedded in the persistent nodesSo movin...
This pull request was created from Copilot chat.