Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

👌 IMP: Use threadpooling #339

Merged
merged 1 commit into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ goober = { git = "https://github.com/jw1912/goober/", rev = "32b9b52" }
nohash-hasher = "=0.2.0"
memmap = "=0.7.0"
once_cell = "=1.19.0"
scoped_threadpool = "=0.1.9"

[features]
no-policy-net = []
Expand Down
6 changes: 3 additions & 3 deletions bin/Dockerfile.fastchess
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ FROM debian:bullseye
RUN apt-get update \
&& apt-get install -y curl git build-essential unzip

RUN git clone https://github.com/Disservin/fast-chess.git \
&& cd fast-chess \
RUN git clone https://github.com/Disservin/fastchess.git \
&& cd fastchess \
&& make

RUN mkdir /books
Expand All @@ -15,4 +15,4 @@ RUN curl -ssL https://github.com/AndyGrant/openbench-books/raw/master/8moves_v3.
RUN unzip /books/4moves_noob.epd.zip -d /books
RUN unzip /books/8moves_v3.epd.zip -d /books

ENTRYPOINT ["fast-chess/fast-chess"]
ENTRYPOINT ["fastchess/fastchess"]
18 changes: 9 additions & 9 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ services:

-each proto=uci tc=8+0.08
option.SyzygyPath=/syzygy option.Hash=128 option.Threads=1
-randomseed -openings file=/books/8moves_v3.epd format=epd order=random
-openings file=/books/8moves_v3.epd format=epd order=random
-games 2 -repeat -rounds 500
-recover -ratinginterval 10 -concurrency 6
volumes:
Expand All @@ -29,7 +29,7 @@ services:

-each proto=uci tc=inf nodes=1
option.SyzygyPath=/syzygy option.Hash=128 option.Threads=1
-randomseed -openings file=/books/8moves_v3.epd format=epd order=random
-openings file=/books/8moves_v3.epd format=epd order=random
-games 2 -repeat -rounds 2500
-recover -ratinginterval 10 -concurrency 6
volumes:
Expand All @@ -48,7 +48,7 @@ services:
-each proto=uci tc=8+0.08
option.SyzygyPath=/syzygy option.Hash=128 option.Threads=1
-sprt elo0=0 elo1=5 alpha=0.05 beta=0.1
-randomseed -openings file=/books/4moves_noob.epd format=epd order=random
-openings file=/books/4moves_noob.epd format=epd order=random
-games 2 -repeat -rounds 7500
-recover -ratinginterval 10 -concurrency 6
volumes:
Expand All @@ -67,7 +67,7 @@ services:
-each proto=uci tc=inf nodes=5000
option.SyzygyPath=/syzygy option.Hash=128 option.Threads=1
-sprt elo0=0 elo1=5 alpha=0.05 beta=0.1
-randomseed -openings file=/books/4moves_noob.epd format=epd order=random
-openings file=/books/4moves_noob.epd format=epd order=random
-games 2 -repeat -rounds 2500
-recover -ratinginterval 10 -concurrency 6
volumes:
Expand All @@ -86,7 +86,7 @@ services:
-each proto=uci tc=40+0.4
option.SyzygyPath=/syzygy option.Hash=128 option.Threads=1
-sprt elo0=0 elo1=5 alpha=0.1 beta=0.2
-randomseed -openings file=/books/4moves_noob.epd format=epd order=random
-openings file=/books/4moves_noob.epd format=epd order=random
-games 2 -repeat -rounds 7500
-recover -ratinginterval 10 -concurrency 6
-resign movecount=3 score=500 twosided=true
Expand All @@ -107,7 +107,7 @@ services:
-each proto=uci tc=8+0.08
option.SyzygyPath=/syzygy option.Hash=128 option.Threads=1
-sprt elo0=-5 elo1=0 alpha=0.05 beta=0.1
-randomseed -openings file=/books/4moves_noob.epd format=epd order=random
-openings file=/books/4moves_noob.epd format=epd order=random
-games 2 -repeat -rounds 7500
-recover -ratinginterval 10 -concurrency 6
volumes:
Expand All @@ -125,7 +125,7 @@ services:

-each proto=uci tc=inf nodes=5000
option.Hash=128 option.Threads=1
-randomseed -openings file=/books/8moves_v3.epd format=epd order=random
-openings file=/books/8moves_v3.epd format=epd order=random
-rounds 100000
-recover -ratinginterval 100 -concurrency 6
-pgnout /pgn/self_play-0.15.0.pgn min fi
Expand All @@ -143,7 +143,7 @@ services:

-each proto=uci tc=8+0.08
option.SyzygyPath=/syzygy option.Hash=128 option.Threads=1
-randomseed -openings file=/books/8moves_v3.epd format=epd order=random
-openings file=/books/8moves_v3.epd format=epd order=random
-debug -rounds 1
-pgnout /pgn/debug.pgn
volumes:
Expand All @@ -163,7 +163,7 @@ services:
-each proto=uci tc=inf nodes=5000
option.SyzygyPath=/syzygy option.Hash=128 option.Threads=1
-tournament gauntlet
-randomseed -openings file=/books/4moves_noob.epd format=epd order=random
-openings file=/books/4moves_noob.epd format=epd order=random
-games 2 -repeat -rounds 250
-recover -ratinginterval 100 -concurrency 6
volumes:
Expand Down
8 changes: 4 additions & 4 deletions src/options.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use once_cell::sync::Lazy;
use std::cmp::max;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering};
use std::sync::RwLock;

static NUM_THREADS: AtomicUsize = AtomicUsize::new(1);
static NUM_THREADS: AtomicU32 = AtomicU32::new(1);
static HASH_SIZE_MB: AtomicUsize = AtomicUsize::new(16);
static MULTI_PV: AtomicUsize = AtomicUsize::new(1);

Expand All @@ -16,11 +16,11 @@ static POLICY_TEMPERATURE_ROOT: Lazy<RwLock<f32>> = Lazy::new(|| RwLock::new(14.
static CHESS960: AtomicBool = AtomicBool::new(false);
static POLICY_ONLY: AtomicBool = AtomicBool::new(false);

pub fn set_num_threads(threads: usize) {
pub fn set_num_threads(threads: u32) {
NUM_THREADS.store(threads, Ordering::Relaxed);
}

pub fn get_num_threads() -> usize {
pub fn get_num_threads() -> u32 {
max(1, NUM_THREADS.load(Ordering::Relaxed))
}

Expand Down
31 changes: 17 additions & 14 deletions src/search.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use scoped_threadpool::Pool;
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::{Duration, Instant};

use crate::chess::{Color, Move};
use crate::evaluation;
use crate::options::{get_num_threads, get_policy_temperature, is_policy_only};
use crate::options::{get_policy_temperature, is_policy_only};
use crate::search_tree::{MoveEdge, PositionNode, SearchTree};
use crate::state::State;
use crate::tablebase;
Expand Down Expand Up @@ -128,7 +129,7 @@ impl Search {
.map(Duration::from_millis)
}

pub fn go(&self, mut tokens: Tokens, next_line: &mut Option<String>) {
pub fn go(&self, threads: &mut Pool, mut tokens: Tokens, next_line: &mut Option<String>) {
let state = self.search_tree.root_state();
let stm = state.side_to_move();

Expand Down Expand Up @@ -227,32 +228,33 @@ impl Search {

think_time.set_node_limit(node_limit);

self.playout_parallel(get_num_threads(), think_time, next_line);
self.playout_parallel(threads, think_time, next_line);
}

fn playout_parallel(
&self,
num_threads: usize,
threads: &mut Pool,
time_management: TimeManagement,
next_line: &mut Option<String>,
) {
let stop_signal = AtomicBool::new(false);
let thread_count = threads.thread_count();

let run_search_thread = |tm: &TimeManagement| {
let mut tld = ThreadData::create(&self.search_tree);
while self.search_tree.playout(&mut tld, tm, &stop_signal) {}
};

std::thread::scope(|s| {
s.spawn(|| {
threads.scoped(|s| {
s.execute(|| {
run_search_thread(&time_management);
self.search_tree.print_info(&time_management);
stop_signal.store(true, Ordering::Relaxed);
println!("bestmove {}", self.best_move().to_uci());
});

for _ in 0..(num_threads - 1) {
s.spawn(|| {
for _ in 0..(thread_count - 1) {
s.execute(|| {
run_search_thread(&TimeManagement::infinite());
});
}
Expand Down Expand Up @@ -307,13 +309,14 @@ impl Search {
let reward = mov.reward();

println!(
"info string {:7} M: {:5} P: {:>6} V: {:7} E: {:>6} ({:>8})",
format!("{}", mov.get_move().to_uci()),
format!("{:3.2}", e * 100.),
format!("{:3.2}", f32::from(mov.policy()) / SCALE * 100.),
"info string {:7} M: {:>5.2} P: {:>5.2} V: {:7} ({:>5.2}%) E: {:>7.2} ({:>8})",
mov.get_move().to_uci(),
e * 100.,
f32::from(mov.policy()) / SCALE * 100.,
mov.visits(),
format!("{:3.2}", reward.average as f32 / (SCALE / 100.)),
format!("{:3.2}", eval_in_cp(reward.average as f32 / SCALE))
mov.visits() as f32 / root_node.visits() as f32 * 100.,
reward.average as f32 / (SCALE / 100.),
eval_in_cp(reward.average as f32 / SCALE)
);
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/search_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ impl PositionNode {
unsafe { &*(self.hots) }
}

pub fn visits(&self) -> u64 {
self.hots().iter().map(|x| u64::from(x.visits())).sum()
}

pub fn clear_children_links(&self) {
let hots = unsafe { &*(self.hots.cast_mut()) };

Expand Down
14 changes: 11 additions & 3 deletions src/uci.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use scoped_threadpool::Pool;
use std::io::stdin;
use std::str::{FromStr, SplitWhitespace};

use crate::options::{
set_chess960, set_cpuct, set_cpuct_tau, set_cvisits_selection, set_hash_size_mb, set_multi_pv,
set_num_threads, set_policy_only, set_policy_temperature, set_policy_temperature_root,
get_num_threads, set_chess960, set_cpuct, set_cpuct_tau, set_cvisits_selection,
set_hash_size_mb, set_multi_pv, set_num_threads, set_policy_only, set_policy_temperature,
set_policy_temperature_root,
};
use crate::search::Search;
use crate::search_tree::print_size_list;
Expand All @@ -19,6 +21,7 @@ const VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION");

pub fn main() {
let mut search = Search::new(State::default(), LRTable::empty());
let mut search_threads = Pool::new(1);

let mut next_line: Option<String> = None;

Expand Down Expand Up @@ -53,7 +56,12 @@ pub fn main() {
}
}
"quit" => return,
"go" => search.go(tokens, &mut next_line),
"go" => {
if search_threads.thread_count() != get_num_threads() {
search_threads = Pool::new(get_num_threads());
}
search.go(&mut search_threads, tokens, &mut next_line);
}
"movelist" => search.print_move_list(),
"sizelist" => print_size_list(),
"eval" => search.print_eval(),
Expand Down
Loading