use std::sync::Arc;
use crate::search::plugin::{
AdaptModifier, CodingModifier, Method, OptionKind, OptionSpec, Plugin, Registry, Scope,
StartCtx,
};
use crate::search::SearchState;
use super::{run, run_warm, WARM_ITERS};
struct Nrpa;
impl Method for Nrpa {
fn id(&self) -> &'static str {
"nrpa"
}
fn label_key(&self) -> &'static str {
"algo-nrpa"
}
fn spawn(&self, ctx: StartCtx, search: Arc<SearchState>) {
let StartCtx {
initial,
level,
warm_seq,
..
} = ctx;
match warm_seq {
Some(seq) => {
std::thread::spawn(move || run_warm(&initial, search, level, &seq, WARM_ITERS));
}
None => {
std::thread::spawn(move || run(&initial, search, level));
}
}
}
fn method_desc(&self, ctx: &StartCtx) -> String {
if ctx.warm_seq.is_some() {
format!(
"nrpa-seeded L{} warm-from={} warm={}",
ctx.level, ctx.seed_len, WARM_ITERS
)
} else {
format!("nrpa L{}", ctx.level)
}
}
fn checkpoint_kind(&self) -> Option<&'static str> {
Some("nrpa")
}
}
static NRPA: Nrpa = Nrpa;
pub struct NrpaPlugin;
impl Plugin for NrpaPlugin {
fn id(&self) -> &'static str {
"nrpa"
}
fn register(&self, reg: &mut Registry) {
reg.add_method(&NRPA);
reg.add_option(OptionSpec {
key: "level",
label_key: "opt-level",
help_key: "opt-level-hint",
help: "NRPA nesting level (recursion depth). 3 is the fast default; 4+ \
searches more deeply but only pays off over long runs.",
kind: OptionKind::Int {
default: 3,
min: 1,
max: 6,
},
scope: Scope::NrpaFamily,
});
}
}
pub static NRPA_PLUGIN: NrpaPlugin = NrpaPlugin;
struct CoreAdapt;
impl AdaptModifier for CoreAdapt {}
static CORE_ADAPT: CoreAdapt = CoreAdapt;
pub struct AdaptPlugin;
impl Plugin for AdaptPlugin {
fn id(&self) -> &'static str {
"adapt"
}
fn register(&self, reg: &mut Registry) {
reg.add_adapt(&CORE_ADAPT);
reg.add_option(OptionSpec {
key: "clamp",
label_key: "opt-clamp",
help_key: "opt-clamp-hint",
help: "Stabilized-NRPA logit clamp C (default 3; 0 disables clamping). The \
tight sweet spot for record hunting; only re-tune for experiments.",
kind: OptionKind::Float {
default: 3.0,
min: 0.0,
max: 10.0,
step: 0.5,
},
scope: Scope::NrpaFamily,
});
reg.add_option(OptionSpec {
key: "alpha",
label_key: "opt-alpha",
help_key: "opt-alpha-hint",
help: "Policy adaptation step size α (default 1.0).",
kind: OptionKind::Float {
default: 1.0,
min: 0.1,
max: 3.0,
step: 0.05,
},
scope: Scope::NrpaFamily,
});
}
}
pub static ADAPT_PLUGIN: AdaptPlugin = AdaptPlugin;
struct CoreCoding;
impl CodingModifier for CoreCoding {}
static CORE_CODING: CoreCoding = CoreCoding;
pub struct SymmetryPlugin;
impl Plugin for SymmetryPlugin {
fn id(&self) -> &'static str {
"symmetry"
}
fn register(&self, reg: &mut Registry) {
reg.add_coding(&CORE_CODING);
reg.add_option(OptionSpec {
key: "symmetry",
label_key: "opt-symmetry",
help_key: "opt-symmetry-hint",
help: "Drop symmetry-invariant move coding (identity frame only): ~+16% \
throughput at neutral score — recommended for cold record runs \
without warm-start. (The flag is `--no-symmetry`.)",
kind: OptionKind::Toggle { default: true },
scope: Scope::NrpaFamily,
});
}
}
pub static SYMMETRY_PLUGIN: SymmetryPlugin = SymmetryPlugin;