about summary refs log tree commit diff stats
path: root/archive/2024/winter/bsc_dichler/scripts/experiments.py
blob: c3779f7e106d2d4371ed320dd7b67c75677f6b9d (plain) (blame)
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
from typing import Callable, Literal
import matplotlib as mpl
import matplotlib.pyplot as plt
from pathlib import Path

import importlib
import importlib.util

Experiments = Literal[
    "cas",
    "contiguous",
    "non_contiguous",
    "contiguous_tagging",
    "malloc",
    "parallel_non_contiguous",
]
PlottingFunction = Callable[[Path, str], None]
experiments: dict[str, PlottingFunction] | None = None


def set_experiments(discovered_experiments: dict[str, PlottingFunction]):
    global experiments
    experiments = discovered_experiments


def plot(output_root: Path, experiment: Experiments, format: Literal["pdf", "png"]):
    assert experiment, "invalid state, experiment discovery was not executed"
    rcParams = {
        "font.family": "serif",
        "font.size": 11,
        "pgf.rcfonts": False,
    }

    if format == "pdf":
        mpl.use("pdf")
        plt.rcParams["text.latex.preamble"] = r"\renewcommand{\mathdefault}[1][]{}"
        rcParams["pgf.texsystem"] = "pdflatex"

    mpl.rcParams.update(rcParams)
    experiments[experiment](output_root, format)


def verify_experiment(experiment_base: Path, experiment_name: str) -> None:
    experiment_directory = experiment_base / Path(experiment_name)
    if not experiment_directory.exists():
        raise Exception(f"Invalid state - cannot find experiment '{experiment_name}'.")

    makefile = experiment_directory / Path("Makefile")
    if not makefile.exists():
        raise Exception(
            f"Invalid state - cannot find Makefile for '{experiment_name}'."
        )

    evaluation_script = (
        Path(__file__).parent / Path("plot") / Path(f"{experiment_name}.py")
    )
    if not evaluation_script.exists():
        raise Exception(
            f"Invalid state - cannot find evaluation script for '{experiment_name}'."
        )


def discover_experiments(base: Path):
    experiments = {}

    evaluation_script = Path(__file__).parent / Path("plot")
    for file in evaluation_script.glob("*.py"):
        if file.name == "__init__.py":
            continue
        module_name = file.stem
        spec = importlib.util.spec_from_file_location(module_name, file)
        module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(module)
        if hasattr(module, "plot"):
            experiments[module_name] = module.plot
        else:
            print("foo")

    experiment_source = set()
    for experiment in base.iterdir():
        if experiment.is_dir():
            experiment_source.add(experiment.name)

    return {k: v for k, v in experiments.items() if k in experiment_source}