Skip to content

Commit

Permalink
Merge branch 'main' into name_equals
Browse files Browse the repository at this point in the history
  • Loading branch information
DLWoodruff authored Sep 13, 2024
2 parents 3415d04 + 9aee0f5 commit 92ebdb1
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 5 deletions.
11 changes: 11 additions & 0 deletions examples/generic_cylinders.bash
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@

SOLVER="cplex"

# sslp EF
echo "^^^ sslp ef ^^^"
cd sslp
python ../../mpisppy/generic_cylinders.py --module-name sslp --sslp-data-path ./data --EF --instance-name sslp_15_45_10 --EF-solver-name ${SOLVER}
cd ..

echo "^^^ sslp bounds ^^^"
cd sslp
mpiexec -np 3 python -m mpi4py ../../mpisppy/generic_cylinders.py --module-name sslp --sslp-data-path ./data --instance-name sslp_15_45_10 --solver-name ${SOLVER} --max-iterations 10 --max-solver-threads 4 --default-rho 1 --lagrangian --xhatshuffle --rel-gap 0.01
cd ..

# netdes EF
echo "^^^ netdes ef ^^^"
cd netdes
Expand Down
72 changes: 71 additions & 1 deletion examples/sslp/sslp.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,85 @@ def scenario_creator(scenario_name, data_dir=None):
"ROOT", 1.0, 1, model.FirstStageCost, [model.FacilityOpen], model
)
]
model._mpisppy_probability = "uniform"

return model


def scenario_denouement(rank, scenario_name, scenario):
pass


########## helper functions ########

#=========
def scenario_names_creator(num_scens,start=None):
# one-based scenarios
# if start!=None, the list starts with the 'start' labeled scenario
if (start is None) :
start=1
return [f"Scenario{i}" for i in range(start,start+num_scens)]


#=========
def inparser_adder(cfg):
# add options unique to sizes
# we don't want num_scens from the command line
cfg.mip_options()
cfg.add_to_config("instance_name",
description="sslp instance name (e.g., sslp_15_45_10)",
domain=str,
default=None)
cfg.add_to_config("sslp_data_path",
description="path to sslp data (e.g., ./data)",
domain=str,
default=None)


#=========
def kw_creator(cfg):
# linked to the scenario_creator and inparser_adder
# side-effect is dealing with num_scens
inst = cfg.instance_name
ns = int(inst.split("_")[-1])
if hasattr(cfg, "num_scens"):
if cfg.num_scens != ns:
raise RuntimeError(f"Argument num-scens={cfg.num_scens} does not match the number "
"implied by instance name={ns} "
"\n(--num-scens is not needed for sslp)")
else:
cfg.add_and_assign("num_scens","number of scenarios", int, None, ns)
data_dir = os.path.join(cfg.sslp_data_path, inst, "scenariodata")
kwargs = {"data_dir": data_dir}
return kwargs


def sample_tree_scen_creator(sname, stage, sample_branching_factors, seed,
given_scenario=None, **scenario_creator_kwargs):
""" Create a scenario within a sample tree. Mainly for multi-stage and simple for two-stage.
(this function supports zhat and confidence interval code)
Args:
sname (string): scenario name to be created
stage (int >=1 ): for stages > 1, fix data based on sname in earlier stages
sample_branching_factors (list of ints): branching factors for the sample tree
seed (int): To allow random sampling (for some problems, it might be scenario offset)
given_scenario (Pyomo concrete model): if not None, use this to get data for ealier stages
scenario_creator_kwargs (dict): keyword args for the standard scenario creator funcion
Returns:
scenario (Pyomo concrete model): A scenario for sname with data in stages < stage determined
by the arguments
"""
# Since this is a two-stage problem, we don't have to do much.
sca = scenario_creator_kwargs.copy()
sca["seedoffset"] = seed
sca["num_scens"] = sample_branching_factors[0] # two-stage problem
return scenario_creator(sname, **sca)

######## end helper functions #########

# special helper function
def id_fix_list_fct(s):
""" specify tuples used by the fixer.
""" specify tuples used by the classic (non-RC-based) fixer.
Args:
s (ConcreteModel): the sizes instance.
Expand Down
23 changes: 19 additions & 4 deletions mpisppy/generic_cylinders.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def _parse_args(m):
argparse=True)
assert hasattr(m, "inparser_adder"), "The model file must have an inparser_adder function"
cfg.add_to_config(name="solution_base_name",
description="The string used fo a directory of ouput along with a csv and an npv file (default None, which means no soltion output)",
description="The string used for a directory of ouput along with a csv and an npv file (default None, which means no soltion output)",
domain=str,
default=None)
cfg.add_to_config(name="run_async",
Expand Down Expand Up @@ -60,6 +60,7 @@ def _parse_args(m):
cfg.tracking_args()
cfg.gradient_args()
cfg.dynamic_gradient_args()
cfg.reduced_costs_args()

cfg.parse_command_line(f"mpi-sppy for {cfg.module_name}")
return cfg
Expand Down Expand Up @@ -138,11 +139,12 @@ def _do_decomp(module, cfg, scenario_creator, scenario_creator_kwargs, scenario_
}

if cfg.fixer: # cfg_vanilla takes care of the fixer_tol?
assert hasattr(module, "id_fix_list_fct"), "id_fix_list_fct required for --fixer"
ext_classes.append(Fixer)
hub_dict["opt_kwargs"]["options"]["fixeroptions"] = {
"verbose": cfg.verbose,
"boundtol": cfg.fixer_tol,
"id_fix_list_fct": uc.id_fix_list_fct,
"id_fix_list_fct": module.id_fix_list_fct,
}
if cfg.grad_rho_setter:
ext_classes.append(Gradient_extension)
Expand Down Expand Up @@ -205,10 +207,20 @@ def _do_decomp(module, cfg, scenario_creator, scenario_creator_kwargs, scenario_
xhatxbar_spoke = vanilla.xhatxbar_spoke(*beans,
scenario_creator_kwargs=scenario_creator_kwargs,
all_nodenames=all_nodenames)


# reduced cost fixer options setup
if cfg.reduced_costs:
vanilla.add_reduced_costs_fixer(hub_dict, cfg)

# reduced cost fixer
if cfg.reduced_costs:
reduced_costs_spoke = vanilla.reduced_costs_spoke(*beans,
scenario_creator_kwargs=scenario_creator_kwargs,
rho_setter = None)


# special code for multi-stage (e.g., hydro)
if cfg.get("stage2EFsolvern") is not None:
print("debug foo")
assert cfg.get("xhatshuffle"), "xhatshuffle is required for stage2EFsolvern"
xhatshuffle_spoke["opt_kwargs"]["options"]["stage2EFsolvern"] = cfg["stage2EFsolvern"]
xhatshuffle_spoke["opt_kwargs"]["options"]["branching_factors"] = cfg["branching_factors"]
Expand All @@ -226,6 +238,9 @@ def _do_decomp(module, cfg, scenario_creator, scenario_creator_kwargs, scenario_
list_of_spoke_dict.append(xhatshuffle_spoke)
if cfg.xhatxbar:
list_of_spoke_dict.append(xhatxbar_spoke)
if cfg.reduced_costs:
list_of_spoke_dict.append(reduced_costs_spoke)


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

0 comments on commit 92ebdb1

Please sign in to comment.