Skip to content

Commit

Permalink
👌 IMP: Use threadpooling
Browse files Browse the repository at this point in the history
  • Loading branch information
ianagbip1oti committed Aug 23, 2024
1 parent 8eb40a6 commit 56532d5
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 33 deletions.
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

0 comments on commit 56532d5

Please sign in to comment.