File size: 1,728 Bytes
590a501
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
"""GP mining configuration loader."""

from __future__ import annotations

import os
from pathlib import Path
from typing import Any

import yaml

PROJECT_ROOT = Path(__file__).resolve().parents[2]
DEFAULT_GP_CONFIG = PROJECT_ROOT / "config" / "gp_mining.yaml"
DEFAULT_BASE_CONFIG = PROJECT_ROOT / "config" / "base.yaml"


def load_gp_config(
    gp_config_path: str | Path | None = None,
    base_config_path: str | Path | None = None,
) -> dict[str, Any]:
    gp_path = Path(gp_config_path) if gp_config_path else DEFAULT_GP_CONFIG
    base_path = Path(base_config_path) if base_config_path else DEFAULT_BASE_CONFIG

    with open(gp_path, encoding="utf-8") as f:
        gp_cfg = yaml.safe_load(f)["gp_mining"]
    with open(base_path, encoding="utf-8") as f:
        base_cfg = yaml.safe_load(f)

    cfg = {"gp": gp_cfg, "base": base_cfg}

    # Allow runtime overrides via environment variables
    env_int_keys = {
        "POPULATION_SIZE": "population_size",
        "GENERATIONS_PER_RUN": "generations_per_run",
        "MAX_INIT_DEPTH": "max_init_depth",
        "TOP_K_EXPORT": "top_k_export",
    }
    for env_key, cfg_key in env_int_keys.items():
        if env_key in os.environ:
            gp_cfg[cfg_key] = int(os.environ[env_key])

    if "SEED" in os.environ:
        gp_cfg["seed"] = int(os.environ["SEED"])

    run_id = os.environ.get("RUN_ID", gp_cfg.get("run_id", "qlib_gp_run_0"))
    output_root = Path(base_cfg.get("output", {}).get("root", "outputs"))
    if not output_root.is_absolute():
        output_root = PROJECT_ROOT / output_root

    cfg["output_dir"] = output_root / "gp_mining" / run_id
    cfg["output_dir"].mkdir(parents=True, exist_ok=True)
    cfg["run_id"] = run_id
    return cfg