vectorize mutation

This commit is contained in:
mos 2025-01-11 13:51:03 +01:00
parent 2e1f524476
commit 89b3e6e983
3 changed files with 41 additions and 30 deletions

4
Cargo.lock generated
View File

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
version = 4
[[package]]
name = "anstream"
@ -53,7 +53,7 @@ dependencies = [
[[package]]
name = "bano"
version = "0.1.0"
version = "0.2.0"
dependencies = [
"clap",
"rand",

View File

@ -1,9 +1,12 @@
[package]
name = "bano"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
[dependencies]
clap = { version = "4.5.19", features = ["derive"] }
rand = "0.8.5"
rayon = "1.10.0"
[features]
simd = []

View File

@ -1,5 +1,8 @@
#![cfg_attr(feature = "simd", feature(portable_simd))]
use rayon::prelude::*;
use std::ops::{Add, Index, IndexMut, Sub};
#[cfg(feature = "simd")]
use std::simd::{u32x8, Simd};
pub enum ReadError {
BadSymbol,
@ -15,14 +18,6 @@ pub enum Error {
type Result<T> = std::result::Result<T, Error>;
#[derive(PartialEq, Copy, Clone)]
enum Direction {
U,
D,
L,
R,
}
#[derive(PartialEq, Copy, Clone)]
enum Cell {
Wall,
@ -249,13 +244,8 @@ impl State {
Ok((false, false))
}
fn move_dir(&mut self, dir: Direction) -> Result<(bool, bool)> {
match dir {
Direction::U => self.move_pos(Self::DIR_POS[0]),
Direction::D => self.move_pos(Self::DIR_POS[1]),
Direction::L => self.move_pos(Self::DIR_POS[2]),
Direction::R => self.move_pos(Self::DIR_POS[3]),
}
fn move_dir(&mut self, dir: u32) -> Result<(bool, bool)> {
self.move_pos(Self::DIR_POS[dir as usize])
}
fn test_box(&self, pos: Pos, bt: bool) -> bool {
@ -337,7 +327,7 @@ impl State {
#[derive(Clone)]
struct Agent {
state: State,
dna: Vec<Direction>,
dna: Vec<u32>,
score: f32,
dir: usize,
goal: Solution,
@ -357,14 +347,14 @@ impl Agent {
const INACTIVE_PENALTY: f32 = 0.0010;
const BOX_DIFF: f32 = 1024.0;
const DIR_TABLE: &'static [Direction] =
&[Direction::U, Direction::D, Direction::L, Direction::R];
const DIR_TABLE: &'static [u32] = &[0, 1, 2, 3];
const DIR_STR: &[&str] = &["U", "D", "L", "R"];
fn chromo() -> Direction {
fn chromo() -> u32 {
Self::DIR_TABLE[rnd!(Self::DIR_TABLE.len())]
}
fn with_dna(state: State, dna: Vec<Direction>) -> Self {
fn with_dna(state: State, dna: Vec<u32>) -> Self {
Self {
state,
dna,
@ -375,7 +365,7 @@ impl Agent {
}
fn new(state: State, size: usize) -> Self {
let dna: Vec<Direction> = (0..size).map(|_| Self::chromo()).collect();
let dna: Vec<u32> = (0..size).map(|_| Self::chromo()).collect();
Self::with_dna(state, dna)
}
@ -386,6 +376,29 @@ impl Agent {
self.dna[..ratio].copy_from_slice(&seed.dna[..ratio]);
}
#[cfg(feature = "simd")]
fn mutate(&mut self, max: usize) {
let len = self.dna.len();
let (ni, nd) = (rnd!(max) + 8, rnd!(len));
for x in 0..ni / 8 {
let d = u32x8::from_array([Agent::chromo(); 8]);
let si = Simd::from_array([
nd + x,
nd + x + 1,
nd + x + 2,
nd + x + 3,
nd + x + 4,
nd + x + 5,
nd + x + 6,
nd + x + 7,
]);
d.scatter(&mut self.dna, si);
}
}
#[cfg(not(feature = "simd"))]
fn mutate(&mut self, max: usize) {
let len = self.dna.len();
let (ni, nd) = (rnd!(max), rnd!(len));
@ -443,12 +456,7 @@ impl Agent {
fn solution(&self) -> String {
(0..self.dir)
.map(|i| match self.dna[i] {
Direction::U => "U",
Direction::D => "D",
Direction::L => "L",
Direction::R => "R",
})
.map(|i| Self::DIR_STR[self.dna[i] as usize])
.collect()
}
}