Skip to content

Commit

Permalink
experiment 4
Browse files Browse the repository at this point in the history
  • Loading branch information
Yury Zabegaev committed Nov 14, 2023
1 parent 61a686d commit 6e13a89
Show file tree
Hide file tree
Showing 13 changed files with 3,817 additions and 164 deletions.
3,830 changes: 3,713 additions & 117 deletions examples/4/results_4_thermal.ipynb

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions examples/data_scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ def make_solve_linear_system_time(perf, converged=True):
)


def make_assemble_time(perf, converged=True):
solution_stats_converged = make_solution_stats(perf, converged=converged)
return np.array(
[y.assembly_time for x in solution_stats_converged for y in x.iterations]
)


def make_peclet_max(perf, converged=True):
predictions = make_predictions(perf, converged=converged)
return np.array([x.context.peclet_max for x in predictions])
Expand Down
33 changes: 24 additions & 9 deletions examples/mandel_model.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,14 @@
}
],
"source": [
"small = make_mandel_setup(model_size='small')\n",
"pp.plot_grid(small.porepy_setup.mdg.subdomains()[0], plot_2d=True, rgb=[1, 1, 1], fig_size=(10, 2))\n",
"print('Number of degrees of freedom:', small.porepy_setup.equation_system.num_dofs())"
"small = make_mandel_setup(model_size=\"small\")\n",
"pp.plot_grid(\n",
" small.porepy_setup.mdg.subdomains()[0],\n",
" plot_2d=True,\n",
" rgb=[1, 1, 1],\n",
" fig_size=(10, 2),\n",
")\n",
"print(\"Number of degrees of freedom:\", small.porepy_setup.equation_system.num_dofs())"
]
},
{
Expand Down Expand Up @@ -77,9 +82,14 @@
}
],
"source": [
"medium = make_mandel_setup(model_size='medium')\n",
"pp.plot_grid(medium.porepy_setup.mdg.subdomains()[0], plot_2d=True, rgb=[1, 1, 1], fig_size=(10, 2))\n",
"print('Number of degrees of freedom:', medium.porepy_setup.equation_system.num_dofs())"
"medium = make_mandel_setup(model_size=\"medium\")\n",
"pp.plot_grid(\n",
" medium.porepy_setup.mdg.subdomains()[0],\n",
" plot_2d=True,\n",
" rgb=[1, 1, 1],\n",
" fig_size=(10, 2),\n",
")\n",
"print(\"Number of degrees of freedom:\", medium.porepy_setup.equation_system.num_dofs())"
]
},
{
Expand Down Expand Up @@ -113,9 +123,14 @@
}
],
"source": [
"large = make_mandel_setup(model_size='large')\n",
"pp.plot_grid(large.porepy_setup.mdg.subdomains()[0], plot_2d=True, rgb=[1, 1, 1], fig_size=(10, 2))\n",
"print('Number of degrees of freedom:', large.porepy_setup.equation_system.num_dofs())"
"large = make_mandel_setup(model_size=\"large\")\n",
"pp.plot_grid(\n",
" large.porepy_setup.mdg.subdomains()[0],\n",
" plot_2d=True,\n",
" rgb=[1, 1, 1],\n",
" fig_size=(10, 2),\n",
")\n",
"print(\"Number of degrees of freedom:\", large.porepy_setup.equation_system.num_dofs())"
]
}
],
Expand Down
2 changes: 1 addition & 1 deletion examples/solvers_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

import numpy as np
import petsc4py
import pyamg
from petsc4py import PETSc
from scipy.sparse import csr_matrix
from scipy.sparse.linalg import LinearOperator, gmres, spsolve
import pyamg

from solver_selector.simulation_runner import SimulationModel
from solver_selector.solver_space import KrylovSolverNode, SolverConfigNode
Expand Down
4 changes: 2 additions & 2 deletions examples/spe10_data/spe10.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,8 @@
"\n",
"perm_large = mirrored(perm_med)\n",
"phi_large = mirrored(phi_med)\n",
"np.save('spe10_l3_mirrored_perm.npy', perm_large)\n",
"np.save('spe10_l3_mirrored_phi.npy', phi_large)\n",
"np.save(\"spe10_l3_mirrored_perm.npy\", perm_large)\n",
"np.save(\"spe10_l3_mirrored_phi.npy\", phi_large)\n",
"print(perm_large.shape)\n",
"print(phi_large.shape)"
]
Expand Down
1 change: 1 addition & 0 deletions examples/thermal_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@ def enthalpy_dirichlet(boundary_grids):
result = self.fluid_enthalpy(boundary_grids)
result *= self.mobility_rho(boundary_grids)
return result

boundary_operator_enthalpy = (
self._combine_boundary_operators( # type: ignore[call-arg]
subdomains=subdomains,
Expand Down
23 changes: 14 additions & 9 deletions examples/thermal_solvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
ConstantNode,
ForkNode,
KrylovSolverNode,
NumericalParameter,
ParametersNode,
SolverConfigNode,
SplittingNode,
NumericalParameter,
)

if TYPE_CHECKING:
Expand Down Expand Up @@ -71,7 +71,12 @@ def __init__(
self.primary_variable: SolverConfigNode = primary_variable

self.splitting = SplittingNode.from_solvers_list(solver_nodes=solver_nodes)
super().__init__(children=[self.splitting, self.primary_variable])
super().__init__(
children=[
self.splitting,
# self.primary_variable,
]
)

def copy(self):
return SplittingNodeCPR(
Expand Down Expand Up @@ -110,7 +115,11 @@ def __init__(
self.method = method

super().__init__(
children=[splitting, primary_variable, method],
children=[
splitting,
# primary_variable,
method,
],
)

def copy(self):
Expand Down Expand Up @@ -226,8 +235,6 @@ def __init__(
thermal_problem: "ThermalSimulationModel",
config: Optional[dict] = None,
):
for param in ["primary_variable"]:
assert param in config
self.linear_solver_primary: LinearSolver = linear_solver_primary
self.linear_solver_secondary: LinearSolver = linear_solver_secondary
self.thermal_problem: "ThermalSimulationModel" = thermal_problem
Expand All @@ -236,7 +243,7 @@ def __init__(
def update(self, mat):
super().update(mat)
prim_ind, sec_ind = self.thermal_problem.get_primary_secondary_indices(
self.config["primary_variable"]
primary_variable="pressure"
)
self.primary_ind = prim_ind
mat_00 = mat[prim_ind[:, None], prim_ind]
Expand Down Expand Up @@ -264,14 +271,12 @@ def __init__(
config: dict,
):
self.thermal_problem: "ThermalSimulationModel" = thermal_problem
for param in ["primary_variable"]:
assert param in config
super().__init__(linear_solver_primary, linear_solver_secondary, config)

def update(self, mat):
super().update(mat)
prim_ind, sec_ind = self.thermal_problem.get_primary_secondary_indices(
self.config["primary_variable"]
primary_variable="pressure"
)
self.primary_ind = prim_ind
self.secondary_ind = sec_ind
Expand Down
7 changes: 3 additions & 4 deletions src/solver_selector/performance_predictor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@
import numpy as np
from sklearn.base import BaseEstimator, RegressorMixin
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process import kernels
from sklearn.linear_model import Ridge, Lasso
from sklearn.gaussian_process import GaussianProcessRegressor, kernels
from sklearn.linear_model import Ridge
from sklearn.neural_network import MLPRegressor
from sklearn.pipeline import make_pipeline, Pipeline
from sklearn.pipeline import Pipeline, make_pipeline
from sklearn.preprocessing import StandardScaler

from solver_selector.data_structures import (
Expand Down
1 change: 0 additions & 1 deletion src/solver_selector/simulation_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
ProblemContext,
SolverSelectionData,
)

from solver_selector.solver_selector import (
RewardPicker,
SolverSelector,
Expand Down
37 changes: 24 additions & 13 deletions src/solver_selector/solver_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,18 @@ def __init__(
self,
solver_space: SolverConfigNode,
predictors: Sequence[PerformancePredictor],
solver_templates: Optional[Sequence[DecisionTemplate]] = None,
):
if solver_templates is None:
solver_templates = solver_space.get_all_solvers()

self.solver_space: SolverConfigNode = solver_space
self.all_solvers: Sequence[
DecisionTemplate
] = self.solver_space.get_all_solvers()
self.solver_templates: Sequence[DecisionTemplate] = solver_templates
self.memory: list[SolverSelectionData] = []
self.predictors: Sequence[PerformancePredictor] = predictors

def show_all_solvers(self) -> None:
for i, solver_template in enumerate(self.all_solvers):
for i, solver_template in enumerate(self.solver_templates):
default_solver = solver_template.use_defaults()
config = self.solver_space.config_from_decision(default_solver)
print(f"{i}:", self.solver_space.format_config(config))
Expand Down Expand Up @@ -117,39 +119,48 @@ def learn_performance_offline(
rewards=selection_data.rewards,
work_time=selection_data.work_time,
)
decision_idx = self._get_solver_idx(decision)
datasets_for_predictors[decision_idx].append(new_selection_data)

try:
decision_idx = self._get_solver_idx(decision)
except ValueError:
pass
else:
datasets_for_predictors[decision_idx].append(new_selection_data)
num_used_points = sum([len(x) for x in datasets_for_predictors])
print(f"Used {num_used_points} / {len(selection_dataset)} data points.")
for dataset, predictor in zip(datasets_for_predictors, self.predictors):
predictor.offline_update(dataset)

def _get_solver_idx(self, decision: Decision) -> int:
for idx, solver in enumerate(self.all_solvers):
for idx, solver in enumerate(self.solver_templates):
if solver.subsolvers == decision.subsolvers:
return idx
raise ValueError("Index not found.")


def make_solver_selector(
solver_space: SolverConfigNode, params: Optional[dict] = None
solver_space: SolverConfigNode,
params: Optional[dict] = None,
solver_templates: Optional[Sequence[DecisionTemplate]] = None,
) -> SolverSelector:
params = params or {}
all_solvers = solver_space.get_all_solvers()
print(f"Selecting from {len(all_solvers)} solvers.")
for i, solver_template in enumerate(all_solvers):
if solver_templates is None:
solver_templates = solver_space.get_all_solvers()
print(f"Selecting from {len(solver_templates)} solvers.")
for i, solver_template in enumerate(solver_templates):
default = solver_template.use_defaults()
conf = solver_space.config_from_decision(decision=default, optimized_only=True)
print(i, solver_space.format_config(conf))

predictors = []
for solver_template in all_solvers:
for solver_template in solver_templates:
predictors.append(
make_performance_predictor(params=params, solver_template=solver_template)
)

solver_selector = SolverSelector(
solver_space=solver_space,
predictors=predictors,
solver_templates=solver_templates,
)

load_statistics_paths: Sequence[str]
Expand Down
1 change: 1 addition & 0 deletions tests/test_performance_predictor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import warnings

import numpy as np
import pytest
from tests_common import DummpyProblemContext, generate_synthetic_data
Expand Down
3 changes: 1 addition & 2 deletions tests/test_simulation_runner.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from pytest import raises

from tests_common import DummpyProblemContext

from solver_selector.data_structures import (
Expand Down Expand Up @@ -114,4 +113,4 @@ def test_simulation_runner_bad_solver():

if __name__ == "__main__":
test_simulation_runner()
test_simulation_runner_bad_solver()
test_simulation_runner_bad_solver()
32 changes: 26 additions & 6 deletions tests/test_solver_selector.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from typing import Sequence

import numpy as np
import pytest
from tests_common import DummpyProblemContext, generate_synthetic_data

from solver_selector.data_structures import SolverSelectionData
Expand All @@ -8,6 +11,7 @@
)
from solver_selector.solver_selector import SolverSelector
from solver_selector.solver_space import (
DecisionTemplate,
ForkNode,
KrylovSolverNode,
NumericalParameter,
Expand Down Expand Up @@ -46,10 +50,15 @@ def make_solver_space():
return solver_space


def make_solver_selector(solver_space: SolverConfigNode):
all_solvers = solver_space.get_all_solvers()
def make_solver_selector(
solver_space: SolverConfigNode,
solver_templates: Sequence[DecisionTemplate] | None = None,
):
if solver_templates is None:
solver_templates = solver_space.get_all_solvers()

predictors: list[PerformancePredictor] = []
for solver_template in all_solvers:
for solver_template in solver_templates:
predictors.append(
PerformancePredictorEpsGreedy(
decision_template=solver_template, exploration=0
Expand All @@ -58,6 +67,7 @@ def make_solver_selector(solver_space: SolverConfigNode):
return SolverSelector(
solver_space=solver_space,
predictors=predictors,
solver_templates=solver_templates,
)


Expand Down Expand Up @@ -92,12 +102,22 @@ def test_sovler_selector():
prediction_offline = solver_selector_offline.select_solver(context)

assert prediction.score == prediction_offline.score
config = solver_space.config_from_decision(
prediction.decision
)
config = solver_space.config_from_decision(prediction.decision)
new_config = new_solver_space.config_from_decision(prediction_offline.decision)
assert config == new_config


def test_subset_of_solvers():
solver_space = make_solver_space()
solvers = solver_space.get_all_solvers()
solver_selector = make_solver_selector(solver_space, solver_templates=solvers[1:])

solver_id = solver_selector._get_solver_idx(solvers[1].use_defaults())
assert solver_id == 0
with pytest.raises(ValueError):
solver_id = solver_selector._get_solver_idx(solvers[0].use_defaults())


if __name__ == "__main__":
test_sovler_selector()
test_subset_of_solvers()

0 comments on commit 6e13a89

Please sign in to comment.