GP_for_TO / scripts /common.py
OneScience's picture
Upload folder using huggingface_hub
6c3f19f verified
Raw
History Blame Contribute Delete
4.99 kB
import json
import os
import sys
from pathlib import Path
import torch
import yaml
PROJECT_ROOT = Path(__file__).resolve().parents[1]
CONFIG_PATH = PROJECT_ROOT / "conf" / "config.yaml"
PROBLEMS = ("doublepipe", "diffuser", "rugby", "pipebend")
def ensure_onescience_path(explicit_src=None):
candidates = []
if explicit_src:
candidates.append(Path(explicit_src).expanduser())
if os.environ.get("ONESCIENCE_SRC"):
candidates.append(Path(os.environ["ONESCIENCE_SRC"]).expanduser())
for parent in (PROJECT_ROOT, *PROJECT_ROOT.parents):
candidates.append(parent / "refactor" / "onescience" / "src")
candidates.append(parent / "onescience" / "src")
for candidate in candidates:
if (candidate / "onescience").is_dir():
path = str(candidate.resolve())
if path not in sys.path:
sys.path.insert(0, path)
return candidate.resolve()
return None
def load_config():
with CONFIG_PATH.open("r", encoding="utf-8") as f:
return yaml.safe_load(f)["root"]
def resolve_path(path_value):
path = Path(path_value)
return path if path.is_absolute() else PROJECT_ROOT / path
def select_device(section):
requested = section.get("device", "auto")
gpu = int(section.get("gpu", 0))
if requested == "auto":
return torch.device(f"cuda:{gpu}" if torch.cuda.is_available() else "cpu")
if requested.startswith("cuda") and not torch.cuda.is_available():
print(f"Requested {requested}, but CUDA is not available. Falling back to CPU.")
return torch.device("cpu")
return torch.device(requested)
def dtype_from_config(name):
mapping = {
"float32": torch.float32,
"float": torch.float32,
"float64": torch.float64,
"double": torch.float64,
}
if name not in mapping:
raise ValueError(f"Unsupported dtype: {name}")
return mapping[name]
def set_nested(cfg, section, key, value):
if value is not None:
cfg[section][key] = value
def build_models(cfg, device, *, n_col_domain=None, n_train_per_bc=None, problem=None):
ensure_onescience_path(cfg.get("runtime", {}).get("onescience_src"))
from model import GPPLUS
from onescience.utils.GP_TO import get_data_fluid, set_seed
problem = problem or cfg["problem"]
n_col_domain = int(n_col_domain or cfg["data"]["n_col_domain"])
n_train_per_bc = int(n_train_per_bc or cfg["data"]["n_train_per_bc"])
dtype = dtype_from_config(cfg["model"].get("dtype", "float32"))
set_seed(int(cfg["seed"]))
x_col, x_train, sol_train = get_data_fluid(
problem=problem,
N_col_domain=n_col_domain,
N_train=n_train_per_bc,
)
collocation_x = x_col.to(device=device, dtype=dtype).clone().requires_grad_(True)
models = []
for i, name in enumerate(cfg["output_names"]):
model = GPPLUS(
train_x=x_train[i].type(dtype),
train_y=sol_train[i].type(dtype),
collocation_x=collocation_x,
basis=cfg["model"]["mean_function"],
NN_layers_base=cfg["model"]["nn_layers_base"],
name_output=name,
device=device,
dtype=dtype,
).to(device=device, dtype=dtype)
models.append(model)
return models, {
"problem": problem,
"n_col_domain": n_col_domain,
"n_train_per_bc": n_train_per_bc,
"x_col_shape": tuple(x_col.shape),
"x_train_shapes": [tuple(x.shape) for x in x_train],
"sol_train_shapes": [tuple(y.shape) for y in sol_train],
}
def save_checkpoint(path, model_list, cfg, metadata, loss_history):
path = resolve_path(path)
path.parent.mkdir(parents=True, exist_ok=True)
torch.save(
{
"model_state_dicts": [model.state_dict() for model in model_list],
"config": cfg,
"metadata": metadata,
"loss_history": loss_history,
},
path,
)
return path
def load_checkpoint(path, model_list, device):
path = resolve_path(path)
if not path.is_file():
raise FileNotFoundError(f"Missing checkpoint: {path}. Run scripts/train.py first.")
try:
checkpoint = torch.load(path, map_location=device, weights_only=False)
except TypeError:
checkpoint = torch.load(path, map_location=device)
state_dicts = checkpoint.get("model_state_dicts")
if state_dicts is None:
raise KeyError(f"Checkpoint does not contain model_state_dicts: {path}")
for model, state_dict in zip(model_list, state_dicts):
model.load_state_dict(state_dict)
return checkpoint
def dump_json(data, path):
path = resolve_path(path)
path.parent.mkdir(parents=True, exist_ok=True)
with path.open("w", encoding="utf-8") as f:
json.dump(data, f, indent=2)
return path
def tensor_to_numpy_dict(fields):
return {key: value.detach().cpu().numpy() for key, value in fields.items()}