Skip to content

Commit

Permalink
Global config (#246)
Browse files Browse the repository at this point in the history
* getting started on software to convert base_parsers to the Pyomo config system

* config.py is realy for testing

* making progress on config; hyro_cylinders_confi.py is a partial example; can't figure out list of int for branching factors yet

* minor improvments, but I stil don't know how to work with ListOf(int)

* work on config

* add some notes

* create cfg_vanilla to replace vanilla and create a hydro driver that uses it

* add a comma to a comment
  • Loading branch information
DLWoodruff authored May 3, 2022
1 parent 6472d4f commit b9c8b37
Show file tree
Hide file tree
Showing 5 changed files with 1,229 additions and 0 deletions.
10 changes: 10 additions & 0 deletions examples/hydro/cfg.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash
# runs the version that uses config.py

SOLVERNAME=cplex

mpiexec --oversubscribe --np 3 python -m mpi4py hydro_cylinders_config.py --branching-factors "3 3" --bundles-per-rank=0 --max-iterations=100 --default-rho=1 --xhatshuffle --lagrangian --solver-name=${SOLVERNAME} --stage2EFsolvern=${SOLVERNAME}
#--tee-rank0-solves

# including this option will cause the upper bounder to solve the EF since there are only three ranks in total.
#--stage2EFsolvern=${SOLVERNAME}
116 changes: 116 additions & 0 deletions examples/hydro/hydro_cylinders_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Copyright 2020 by B. Knueven, D. Mildebrath, C. Muir, J-P Watson, and D.L. Woodruff
# This software is distributed under the 3-clause BSD License.
# general example driver for the hydro example with cylinders
# Modfied April 2022 by DLW to illustrate config.py

import hydro

import mpisppy.utils.sputils as sputils

from mpisppy.spin_the_wheel import WheelSpinner
from mpisppy.utils import config
import mpisppy.utils.cfg_vanilla as vanilla

import mpisppy.cylinders as cylinders

# For this problem, the subproblems are
# small and take no time to solve. The
# default SPOKE_SLEEP_TIME of 0.01 *causes*
# synchronization issues in this case, so
# we reduce it so as not to dominate the
# time spent for cylinder synchronization
SPOKE_SLEEP_TIME = 0.0001

write_solution = True

def _parse_args():
# update config.global_config
config.multistage()
config.two_sided_args()
config.xhatlooper_args()
config.xhatshuffle_args()
config.lagrangian_args()
config.xhatspecific_args()

config.add_to_config(name ="stage2EFsolvern",
description="Solver to use for xhatlooper stage2ef option (default None)",
domain = str,
default=None)

parser = config.create_parser("hydro")
args = parser.parse_args() # from the command line
args = config.global_config.import_argparse(args)


def main():
cfg = config.global_config # typing aid

_parse_args() # updates cfg

BFs = cfg["branching_factors"]
if len(BFs) != 2:
raise RuntimeError("Hydro is a three stage problem, so it needs 2 BFs")

xhatshuffle = cfg["xhatshuffle"]
lagrangian = cfg["lagrangian"]

# This is multi-stage, so we need to supply node names
all_nodenames = sputils.create_nodenames_from_branching_factors(BFs)

ScenCount = BFs[0] * BFs[1]
scenario_creator_kwargs = {"branching_factors": BFs}
all_scenario_names = [f"Scen{i+1}" for i in range(ScenCount)]
scenario_creator = hydro.scenario_creator
scenario_denouement = hydro.scenario_denouement
rho_setter = None

# Things needed for vanilla cylinders
beans = (cfg, scenario_creator, scenario_denouement, all_scenario_names)

# Vanilla PH hub
hub_dict = vanilla.ph_hub(*beans,
scenario_creator_kwargs=scenario_creator_kwargs,
ph_extensions=None,
rho_setter = rho_setter,
all_nodenames = all_nodenames,
spoke_sleep_time = SPOKE_SLEEP_TIME)

# Standard Lagrangian bound spoke
if lagrangian:
lagrangian_spoke = vanilla.lagrangian_spoke(*beans,
scenario_creator_kwargs=scenario_creator_kwargs,
rho_setter = rho_setter,
all_nodenames = all_nodenames,
spoke_sleep_time = SPOKE_SLEEP_TIME)


# xhat looper bound spoke

if xhatshuffle:
xhatshuffle_spoke = vanilla.xhatshuffle_spoke(*beans,
all_nodenames=all_nodenames,
scenario_creator_kwargs=scenario_creator_kwargs,
spoke_sleep_time = SPOKE_SLEEP_TIME)

list_of_spoke_dict = list()
if lagrangian:
list_of_spoke_dict.append(lagrangian_spoke)
if xhatshuffle:
list_of_spoke_dict.append(xhatshuffle_spoke)

if cfg.stage2EFsolvern is not None:
xhatshuffle_spoke["opt_kwargs"]["options"]["stage2EFsolvern"] = cfg["stage2EFsolvern"]
xhatshuffle_spoke["opt_kwargs"]["options"]["branching_factors"] = cfg["branching_factors"]

wheel = WheelSpinner(hub_dict, list_of_spoke_dict)
wheel.spin()

if wheel.global_rank == 0: # we are the reporting hub rank
print(f"BestInnerBound={wheel.BestInnerBound} and BestOuterBound={wheel.BestOuterBound}")

if write_solution:
wheel.write_first_stage_solution('hydro_first_stage.csv')
wheel.write_tree_solution('hydro_full_solution')

if __name__ == "__main__":
main()
Loading

0 comments on commit b9c8b37

Please sign in to comment.