Skip to content

Commit

Permalink
add a test and a little doc for the scenario lp writer extension
Browse files Browse the repository at this point in the history
  • Loading branch information
DLWoodruff committed Dec 15, 2024
1 parent f230d61 commit dfac003
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 1 deletion.
16 changes: 16 additions & 0 deletions doc/src/extensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ extension can be included in some applications, but not others.
There are a number of extensions, particularly for PH, that are provided
with ``mpi-sppy`` and they provide examples that can be used for the
creation of more. Extensions can be found in ``mpisppy.extensions``.
Note that some things (e.g. some xhatters) can be used as a cylinder
or as an extension. A few other things (e.g., cross scenario cuts) need
both an extension and a cylinder.

Many extensions are supported in :ref:`generic_cylinders`. The rest of
this help file describes extensions released with mpisppy along with
some hints for including them in your own cylinders driver program.

Multiple Extensions
-------------------
Expand Down Expand Up @@ -266,3 +273,12 @@ If some variables have zero probability in all scenarios, then you will need to
``do_not_check_variable_probabilities`` to True in the options for ``spbase``. This will result in skipping the checks for
all variable probabilities! So you might want to set this to False to verify that the probabilities sum to one
only for the Vars you expect before setting it to True.

Scenario_lpwriter
-----------------

This extension writes an lp file with the model and json file with (a) list(s) of
scenario tree node names and nonanticaptive variables for each scenario before
the iteration zero solve of PH or APH. Note that for two-stage problems, all
json files will be the same. See ``mpisppy.generic_cylinders.py``
for an example of use.
2 changes: 1 addition & 1 deletion examples/generic_cylinders.bash
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ echo "^^^ unpickle the sizes bundles and write the lp and nonant files ^^^"
cd sizes
python ../../mpisppy/generic_cylinders.py --module-name sizes --num-scens 10 --default-rho 1 --solver-name ${SOLVER} --max-iterations 0 --scenario-lpfiles --unpickle-bundles-dir sizes_pickles --scenarios-per-bundle 5
cd ..
echo "xxx also write a test?"
echo "xxxx Early exit. xxxx"
exit

echo "^^^ pickle the scenarios ^^^"
Expand Down
40 changes: 40 additions & 0 deletions mpisppy/tests/test_ef_ph.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import os
import glob
import json
import unittest
import pandas as pd
import pyomo.environ as pyo
Expand Down Expand Up @@ -379,6 +380,45 @@ def test_xhat_extension(self):
xhatobj1 = round_pos_sig(ph.extobject._xhat_looper_obj_final, 1)
self.assertEqual(xhatobj1, 200000)


@unittest.skipIf(not pyo.SolverFactory('glpk').available(),
"glpk is not available")
def test_scenario_lpwriter_extension(self):
print("test scenarip_lpwriter")
from mpisppy.extensions.scenario_lpfiles import Scenario_lpfiles
options = self._copy_of_base_options()
options["iter0_solver_options"] = {"mipgap": 0.1}
options["PHIterLimit"] = 0
options["solver_name"] = "glpk"
options["tee_rank0_solves"] = True

ph = mpisppy.opt.ph.PH(
options,
self.all3_scenario_names,
scenario_creator,
scenario_denouement,
scenario_creator_kwargs={"scenario_count": 3},
extensions=Scenario_lpfiles,
)
conv, basic_obj, tbound = ph.ph_main()
# The idea is to detect a change in Pyomo's writing of lp files
with open("Scenario1_nonants.json", "r") as jfile:
nonants_by_node = json.load(jfile)
vname = nonants_by_node["ROOT"][0] # first name in the file
gotit = False
with open("Scenario1.lp", 'r') as lpfile:
for line in lpfile:
if vname in line:
gotit = True
break
assert gotit, f"The first nonant in Scenario1_nonants.json ({vname}) not found in Scenario1.lp"
print(" deleting Scenario*.p and Scenario*_nonants.json")
for fn in glob.glob("Scenario*.lp"):
os.remove(fn)
for fn in glob.glob("Scenario*_nonants.json"):
os.remove(fn)


@unittest.skipIf(not solver_available,
"no solver is available")
def test_wtracker_extension(self):
Expand Down

0 comments on commit dfac003

Please sign in to comment.