Skip to content

Commit

Permalink
address newest clippy warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
brunocodutra committed Nov 2, 2024
1 parent 89e2216 commit 24d2a33
Show file tree
Hide file tree
Showing 12 changed files with 95 additions and 105 deletions.
26 changes: 16 additions & 10 deletions lib/chess/bitboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::chess::{File, Perspective, Rank, Square};
use crate::util::{Assume, Integer};
use derive_more::{Debug, *};
use std::fmt::{self, Write};
use std::mem::MaybeUninit;
use std::{cell::SyncUnsafeCell, mem::MaybeUninit};

/// A set of squares on a chess board.
#[derive(
Expand Down Expand Up @@ -119,33 +119,36 @@ impl Bitboard {
/// ```
#[inline(always)]
pub fn line(whence: Square, whither: Square) -> Self {
static mut LINES: [[Bitboard; 64]; 64] = unsafe { MaybeUninit::zeroed().assume_init() };
static LINES: SyncUnsafeCell<[[Bitboard; 64]; 64]> =
unsafe { MaybeUninit::zeroed().assume_init() };

#[cold]
#[ctor::ctor]
#[optimize(size)]
#[inline(never)]
unsafe fn init() {
let lines = LINES.get().as_mut_unchecked();

for wc in Square::iter() {
for wt in Square::iter() {
let df = wt.file() - wc.file();
let dr = wt.rank() - wc.rank();
if df == 0 && dr == 0 {
LINES[wc as usize][wt as usize] = wc.bitboard();
lines[wc as usize][wt as usize] = wc.bitboard();
} else if df == 0 {
LINES[wc as usize][wt as usize] = wc.file().bitboard();
lines[wc as usize][wt as usize] = wc.file().bitboard();
} else if dr == 0 {
LINES[wc as usize][wt as usize] = wc.rank().bitboard();
lines[wc as usize][wt as usize] = wc.rank().bitboard();
} else if df.abs() == dr.abs() {
let steps = [(df.signum(), dr.signum()), (-df.signum(), -dr.signum())];
let bb = Bitboard::fill(wc, &steps, Bitboard::empty());
LINES[wc as usize][wt as usize] = bb;
lines[wc as usize][wt as usize] = bb;
}
}
}
}

unsafe { LINES[whence as usize][whither as usize] }
unsafe { LINES.get().as_ref_unchecked()[whence as usize][whither as usize] }
}

/// Bitboard with squares in the open segment between two squares.
Expand All @@ -160,27 +163,30 @@ impl Bitboard {
/// ```
#[inline(always)]
pub fn segment(whence: Square, whither: Square) -> Self {
static mut SEGMENTS: [[Bitboard; 64]; 64] = unsafe { MaybeUninit::zeroed().assume_init() };
static SEGMENTS: SyncUnsafeCell<[[Bitboard; 64]; 64]> =
unsafe { MaybeUninit::zeroed().assume_init() };

#[cold]
#[ctor::ctor]
#[optimize(size)]
#[inline(never)]
unsafe fn init() {
let segments = SEGMENTS.get().as_mut_unchecked();

for wc in Square::iter() {
for wt in Square::iter() {
let df = wt.file() - wc.file();
let dr = wt.rank() - wc.rank();
if df == 0 || dr == 0 || df.abs() == dr.abs() {
let steps = [(df.signum(), dr.signum())];
let bb = Bitboard::fill(wc, &steps, wt.bitboard());
SEGMENTS[wc as usize][wt as usize] = bb.without(wc).without(wt);
segments[wc as usize][wt as usize] = bb.without(wc).without(wt);
}
}
}
}

unsafe { SEGMENTS[whence as usize][whither as usize] }
unsafe { SEGMENTS.get().as_ref_unchecked()[whence as usize][whither as usize] }
}

/// The number of [`Square`]s in the set.
Expand Down
2 changes: 1 addition & 1 deletion lib/chess/board.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl Board {
/// Toggles a piece on a square.
#[inline(always)]
pub fn toggle(&mut self, p: Piece, sq: Square) {
debug_assert!(!self[sq].is_some_and(|q| p != q));
debug_assert!(self[sq].is_none_or(|q| p == q));
self.colors[p.color() as usize] ^= sq.bitboard();
self.roles[p.role() as usize] ^= sq.bitboard();
}
Expand Down
22 changes: 13 additions & 9 deletions lib/chess/castles.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::chess::{Color, Perspective, Piece, Role, Square};
use crate::util::{Bits, Integer};
use derive_more::{Debug, *};
use std::{fmt, mem::MaybeUninit, str::FromStr};
use std::{cell::SyncUnsafeCell, fmt, mem::MaybeUninit, str::FromStr};

/// The castling rights in a chess [`Position`][`crate::chess::Position`].
#[derive(
Expand Down Expand Up @@ -37,6 +37,7 @@ impl Castles {
}

/// A unique number the represents this castling rights configuration.
#[inline(always)]
pub fn index(&self) -> u8 {
self.0.get()
}
Expand Down Expand Up @@ -84,22 +85,25 @@ impl Default for Castles {
impl From<Square> for Castles {
#[inline(always)]
fn from(sq: Square) -> Self {
static mut CASTLES: [Castles; 64] = unsafe { MaybeUninit::zeroed().assume_init() };
static CASTLES: SyncUnsafeCell<[Castles; 64]> =
unsafe { MaybeUninit::zeroed().assume_init() };

#[cold]
#[ctor::ctor]
#[optimize(size)]
#[inline(never)]
unsafe fn init() {
CASTLES[Square::A1 as usize] = Castles(Bits::new(0b0010));
CASTLES[Square::H1 as usize] = Castles(Bits::new(0b0001));
CASTLES[Square::E1 as usize] = Castles(Bits::new(0b0011));
CASTLES[Square::A8 as usize] = Castles(Bits::new(0b1000));
CASTLES[Square::H8 as usize] = Castles(Bits::new(0b0100));
CASTLES[Square::E8 as usize] = Castles(Bits::new(0b1100));
let castles = CASTLES.get().as_mut_unchecked();

castles[Square::A1 as usize] = Castles(Bits::new(0b0010));
castles[Square::H1 as usize] = Castles(Bits::new(0b0001));
castles[Square::E1 as usize] = Castles(Bits::new(0b0011));
castles[Square::A8 as usize] = Castles(Bits::new(0b1000));
castles[Square::H8 as usize] = Castles(Bits::new(0b0100));
castles[Square::E8 as usize] = Castles(Bits::new(0b1100));
}

unsafe { CASTLES[sq as usize] }
unsafe { CASTLES.get().as_ref_unchecked()[sq as usize] }
}
}

Expand Down
6 changes: 3 additions & 3 deletions lib/chess/move.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ impl Move {
#[inline(always)]
pub fn set_whence(&mut self, whence: Square) {
let bits = self.0.get() & 0b0000001111111111 | ((whence as u16) << 10);
self.0 = NonZeroU16::new(bits).assume();
self.0 = <NonZeroU16 as Integer>::new(bits);
}

/// The destination [`Square`].
Expand All @@ -83,7 +83,7 @@ impl Move {
#[inline(always)]
pub fn set_whither(&mut self, whither: Square) {
let bits = (self.0.get() & 0b1111110000001111) | ((whither as u16) << 4);
self.0 = NonZeroU16::new(bits).assume();
self.0 = <NonZeroU16 as Integer>::new(bits);
}

/// The promotion specifier.
Expand All @@ -101,7 +101,7 @@ impl Move {
pub fn set_promotion(&mut self, promotion: Role) {
debug_assert!(self.is_promotion());
let bits = (self.0.get() & 0b1111111111111100) | (promotion as u16 - 1);
self.0 = NonZeroU16::new(bits).assume();
self.0 = <NonZeroU16 as Integer>::new(bits);
}

/// Whether this is a castling move.
Expand Down
33 changes: 18 additions & 15 deletions lib/chess/piece.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::chess::{Bitboard, Color, Magic, Perspective, Role, Square};
use crate::util::{Assume, Integer};
use derive_more::{Display, Error};
use std::{mem::MaybeUninit, str::FromStr};
use std::{cell::SyncUnsafeCell, mem::MaybeUninit, str::FromStr};

/// A chess [piece][`Role`] of a certain [`Color`].
#[derive(Debug, Display, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
Expand Down Expand Up @@ -37,45 +37,48 @@ pub enum Piece {
impl Piece {
#[inline(always)]
fn bitboard(idx: usize) -> Bitboard {
static mut BITBOARDS: [Bitboard; 88772] = unsafe { MaybeUninit::zeroed().assume_init() };
static BITBOARDS: SyncUnsafeCell<[Bitboard; 88772]> =
unsafe { MaybeUninit::zeroed().assume_init() };

#[cold]
#[ctor::ctor]
#[optimize(size)]
#[inline(never)]
unsafe fn init() {
let bitboard = BITBOARDS.get().as_mut_unchecked();

for whence in Square::iter() {
let (attacks, quiets) = Magic::pawn(whence);
let steps = [(-1, 1), (1, 1)];
let idx = attacks.offset();
let moves = Bitboard::fill(whence, &steps, Bitboard::full()).without(whence);
debug_assert!(BITBOARDS[idx] == moves || BITBOARDS[idx] == Bitboard::empty());
BITBOARDS[idx] = moves;
debug_assert!(bitboard[idx] == moves || bitboard[idx] == Bitboard::empty());
bitboard[idx] = moves;

for bb in quiets.mask().subsets() {
let blks = bb | !quiets.mask();
let moves = Bitboard::fill(whence, &[(0, 1)], blks).without(whence) & !blks;
let idx = (bb.wrapping_mul(quiets.factor()) >> 62) as usize + quiets.offset();
debug_assert!(BITBOARDS[idx] == moves || BITBOARDS[idx] == Bitboard::empty());
BITBOARDS[idx] = moves;
debug_assert!(bitboard[idx] == moves || bitboard[idx] == Bitboard::empty());
bitboard[idx] = moves;
}

let magic = Magic::knight(whence);
#[rustfmt::skip]
let steps = [(-2, 1), (-1, 2), (1, 2), (2, 1), (2, -1), (1, -2), (-1, -2), (-2, -1)];
let moves = Bitboard::fill(whence, &steps, Bitboard::full()).without(whence);
let idx = magic.offset();
debug_assert!(BITBOARDS[idx] == moves || BITBOARDS[idx] == Bitboard::empty());
BITBOARDS[idx] = moves;
debug_assert!(bitboard[idx] == moves || bitboard[idx] == Bitboard::empty());
bitboard[idx] = moves;

let magic = Magic::bishop(whence);
for bb in magic.mask().subsets() {
let blks = bb | !magic.mask();
let steps = [(-1, 1), (1, 1), (1, -1), (-1, -1)];
let moves = Bitboard::fill(whence, &steps, blks).without(whence);
let idx = (bb.wrapping_mul(magic.factor()) >> 55) as usize + magic.offset();
debug_assert!(BITBOARDS[idx] == moves || BITBOARDS[idx] == Bitboard::empty());
BITBOARDS[idx] = moves;
debug_assert!(bitboard[idx] == moves || bitboard[idx] == Bitboard::empty());
bitboard[idx] = moves;
}

let magic = Magic::rook(whence);
Expand All @@ -84,21 +87,21 @@ impl Piece {
let steps = [(-1, 0), (0, 1), (1, 0), (0, -1)];
let moves = Bitboard::fill(whence, &steps, blks).without(whence);
let idx = (bb.wrapping_mul(magic.factor()) >> 52) as usize + magic.offset();
debug_assert!(BITBOARDS[idx] == moves || BITBOARDS[idx] == Bitboard::empty());
BITBOARDS[idx] = moves;
debug_assert!(bitboard[idx] == moves || bitboard[idx] == Bitboard::empty());
bitboard[idx] = moves;
}

let magic = Magic::king(whence);
#[rustfmt::skip]
let steps = [(-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1)];
let moves = Bitboard::fill(whence, &steps, Bitboard::full()).without(whence);
let idx = magic.offset();
debug_assert!(BITBOARDS[idx] == moves || BITBOARDS[idx] == Bitboard::empty());
BITBOARDS[idx] = moves;
debug_assert!(bitboard[idx] == moves || bitboard[idx] == Bitboard::empty());
bitboard[idx] = moves;
}
}

unsafe { *BITBOARDS.get(idx).assume() }
*unsafe { BITBOARDS.get().as_ref_unchecked().get(idx).assume() }
}

/// Constructs [`Piece`] from a pair of [`Color`] and [`Role`].
Expand Down
27 changes: 15 additions & 12 deletions lib/chess/zobrist.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::chess::*;
use crate::util::{Bits, Integer};
use crate::util::{Assume, Bits, Integer};
use rand::prelude::*;
use rand_pcg::Pcg64;
use std::mem::MaybeUninit;
use std::{cell::SyncUnsafeCell, mem::MaybeUninit};

/// A type representing a [`Position`]'s [zobrist hash].
///
Expand All @@ -17,39 +17,42 @@ pub struct ZobristNumbers {
turn: u64,
}

static mut ZOBRIST: ZobristNumbers = unsafe { MaybeUninit::zeroed().assume_init() };
static ZOBRIST: SyncUnsafeCell<ZobristNumbers> = unsafe { MaybeUninit::zeroed().assume_init() };

#[cold]
#[ctor::ctor]
#[optimize(size)]
#[inline(never)]
unsafe fn init() {
let zobrist = ZOBRIST.get().as_mut_unchecked();
let mut rng = Pcg64::seed_from_u64(0x980E8CE238E3B114);

ZOBRIST.pieces = rng.gen();
ZOBRIST.castles = rng.gen();
ZOBRIST.en_passant = rng.gen();
ZOBRIST.turn = rng.gen();
zobrist.pieces = rng.gen();
zobrist.castles = rng.gen();
zobrist.en_passant = rng.gen();
zobrist.turn = rng.gen();
}

impl ZobristNumbers {
#[inline(always)]
pub fn psq(color: Color, role: Role, sq: Square) -> Zobrist {
unsafe { Zobrist::new(ZOBRIST.pieces[color as usize][role as usize][sq as usize]) }
let psq = unsafe { &ZOBRIST.get().as_ref_unchecked().pieces };
Zobrist::new(psq[color as usize][role as usize][sq as usize])
}

#[inline(always)]
pub fn castling(castles: Castles) -> Zobrist {
unsafe { Zobrist::new(ZOBRIST.castles[castles.index() as usize]) }
let castling = unsafe { &ZOBRIST.get().as_ref_unchecked().castles };
Zobrist::new(*castling.get(castles.index() as usize).assume())
}

#[inline(always)]
pub fn en_passant(file: File) -> Zobrist {
unsafe { Zobrist::new(ZOBRIST.en_passant[file as usize]) }
let en_passant = unsafe { &ZOBRIST.get().as_ref_unchecked().en_passant };
Zobrist::new(en_passant[file as usize])
}

#[inline(always)]
pub fn turn() -> Zobrist {
unsafe { Zobrist::new(ZOBRIST.turn) }
Zobrist::new(unsafe { ZOBRIST.get().as_ref_unchecked().turn })
}
}
9 changes: 8 additions & 1 deletion lib/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
#![cfg_attr(target_arch = "x86_64", feature(stdarch_x86_mm_shuffle))]
#![feature(array_chunks, coverage_attribute, new_zeroed_alloc, optimize_attribute)]
#![feature(
array_chunks,
coverage_attribute,
new_zeroed_alloc,
optimize_attribute,
ptr_as_ref_unchecked,
sync_unsafe_cell
)]

/// Chess domain types.
pub mod chess;
Expand Down
16 changes: 10 additions & 6 deletions lib/nnue.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::util::Assume;
use byteorder::{LittleEndian, ReadBytesExt};
use ruzstd::StreamingDecoder;
use std::cell::SyncUnsafeCell;
use std::io::{self, Read};
use std::mem::{transmute, MaybeUninit};

Expand Down Expand Up @@ -31,7 +33,7 @@ struct Nnue {
hidden: [Hidden<{ Positional::LEN }>; Material::LEN],
}

static mut NNUE: Nnue = unsafe { MaybeUninit::zeroed().assume_init() };
static NNUE: SyncUnsafeCell<Nnue> = unsafe { MaybeUninit::zeroed().assume_init() };

#[cold]
#[ctor::ctor]
Expand All @@ -40,7 +42,7 @@ static mut NNUE: Nnue = unsafe { MaybeUninit::zeroed().assume_init() };
unsafe fn init() {
let encoded = include_bytes!("nnue/nn.zst").as_slice();
let decoder = StreamingDecoder::new(encoded).expect("failed to initialize zstd decoder");
NNUE.load(decoder).expect("failed to load the NNUE");
Nnue::load(NNUE.get().as_mut_unchecked(), decoder).expect("failed to load the NNUE");
}

impl Nnue {
Expand Down Expand Up @@ -73,17 +75,19 @@ impl Nnue {
Ok(())
}

#[inline(always)]
fn psqt() -> &'static Transformer<i32, { Material::LEN }> {
unsafe { &NNUE.psqt }
unsafe { &NNUE.get().as_ref_unchecked().psqt }
}

#[inline(always)]
fn ft() -> &'static Transformer<i16, { Positional::LEN }> {
unsafe { &NNUE.ft }
unsafe { &NNUE.get().as_ref_unchecked().ft }
}

#[inline(always)]
fn hidden(phase: usize) -> &'static Hidden<{ Positional::LEN }> {
debug_assert!(phase < Positional::LEN);
unsafe { NNUE.hidden.get_unchecked(phase) }
unsafe { NNUE.get().as_ref_unchecked().hidden.get(phase).assume() }
}
}

Expand Down
Loading

0 comments on commit 24d2a33

Please sign in to comment.