diff --git a/config/default.ini b/config/default.ini index f7333e4f18..4e0ccf61a2 100644 --- a/config/default.ini +++ b/config/default.ini @@ -59,6 +59,8 @@ eval_bot_games = 0 # Ladder rungs, weakest first: the [env] bot_policy ids the env's header # defines. Required when eval_bot_games > 0, e.g. eval_bots = 3,4,5,6. eval_bots = 0 +eval_bot_envs = 8192 +eval_bot_threads = 0 # Per-rung [env] overrides for the bot ladder, as full section.key = value # lines (e.g. env.dr = 0). Env-owned so core needs no per-env knowledge. diff --git a/src/constellation.c b/src/constellation.c index 81e52678e6..a65a22520c 100644 --- a/src/constellation.c +++ b/src/constellation.c @@ -654,7 +654,6 @@ PlotArgs DEFAULT_PLOT_ARGS = { .z_label = "Train/Learning Rate", }; - Table* dataset_table(Dataset *data, char *env) { for (int i = 0; i < data->n; i++) { if (strcmp(data->tables[i].name, env) == 0) { diff --git a/src/pufferl.cu b/src/pufferl.cu index 48247e879f..745bf78ae5 100644 --- a/src/pufferl.cu +++ b/src/pufferl.cu @@ -2513,12 +2513,6 @@ typedef struct { #define SELFPLAY_MAX_HIST 8 #define SELFPLAY_MAX_LADDER 16 #define SELFPLAY_PATH_MAX 4096 -// Bot-ladder parallelism, held fixed so rung scores stay comparable across -// sweep trials that vary vec.total_agents. selfplay.eval_bot_games / this is -// the games each env plays; scripted bots keep their kNN across episodes, so -// one game per env measures only cold bots. -#define SELFPLAY_LADDER_ENVS 8192 - // One historical opponent ↔ policies[policy_idx] (env tag == policy_idx). typedef struct { int policy_idx; @@ -2899,8 +2893,9 @@ static EvalResult eval_loop(Ini* ini, PuffeRL* p, int mode, int verbose, if (verbose) { puf_dashboard_print(ini, p, show, board ? epoch : 0); } + DictItem* m = dict_find(&el, metric_key); result.score = match ? dict_get(&el, "env/policy_0_score") - : dict_get(&el, metric_key); + : (m ? m->value : dict_get(&el, "env/score")); result.perf = dict_get(&el, "env/perf"); if (match) { result.draw = dict_get(&el, "env/draw_rate"); @@ -3304,11 +3299,17 @@ TrainResult run_train(Ini* ini, TrainContext* ctx) { puf_ini_put(ini, ek, over->str); } // Fixed parallelism; ignore swept train total_agents. Each env plays - // bot_games / SELFPLAY_LADDER_ENVS games, so bots face a warmed-up kNN - // rather than being re-measured cold once per env. + // bot_games / ladder_envs games, so bots face a warmed-up kNN rather + // than being re-measured cold once per env. char nbuf[32]; - snprintf(nbuf, sizeof(nbuf), "%d", SELFPLAY_LADDER_ENVS); + long envs = puf_ini_get(ini, "selfplay", "eval_bot_envs"); + snprintf(nbuf, sizeof(nbuf), "%ld", envs); puf_ini_put(ini, "vec.total_agents", nbuf); + long threads = puf_ini_get(ini, "selfplay", "eval_bot_threads"); + if (threads > 0) { + snprintf(nbuf, sizeof(nbuf), "%ld", threads); + puf_ini_put(ini, "vec.num_threads", nbuf); + } double ladder[SELFPLAY_MAX_LADDER]; int rungs = puf_ini_get_list(ini, "selfplay", "eval_bots", ladder, SELFPLAY_MAX_LADDER);