diff --git a/.github/workflows/test_pr_and_main.yml b/.github/workflows/test_pr_and_main.yml index 2d84c99f5..825ccb4ae 100644 --- a/.github/workflows/test_pr_and_main.yml +++ b/.github/workflows/test_pr_and_main.yml @@ -17,9 +17,17 @@ defaults: shell: bash -l {0} jobs: + ruff: + name: Ruff Linting + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: chartboost/ruff-action@v1 + nompi4py: name: no mpi4py runs-on: ubuntu-latest + needs: [ruff] steps: - uses: actions/checkout@v3 - uses: conda-incubator/setup-miniconda@v2 @@ -45,6 +53,7 @@ jobs: regression: name: Basic regression tests runs-on: ubuntu-latest + needs: [ruff] steps: - uses: actions/checkout@v3 @@ -86,6 +95,9 @@ jobs: name: run_all.py runs-on: ubuntu-latest timeout-minutes: 15 + # this takes the most time, so we'll start it + # without waiting on the linting and other checks + # needs: [ruff] steps: - uses: actions/checkout@v3 @@ -117,6 +129,7 @@ jobs: schur-complement: name: schur-complement runs-on: ubuntu-latest + needs: [ruff] strategy: matrix: python-version: [3.8, 3.9] @@ -151,6 +164,7 @@ jobs: straight-tests: name: straight_tests.py runs-on: ubuntu-latest + needs: [ruff] steps: - uses: actions/checkout@v3 @@ -176,6 +190,7 @@ jobs: admm-wrapper: name: admm wrapper tests runs-on: ubuntu-latest + needs: [ruff] steps: - uses: actions/checkout@v3 @@ -205,6 +220,7 @@ jobs: aph: name: aph tests runs-on: ubuntu-latest + needs: [ruff] steps: - uses: actions/checkout@v3 @@ -232,6 +248,7 @@ jobs: pickled-bundles: name: pickled bundles tests runs-on: ubuntu-latest + needs: [ruff] steps: - uses: actions/checkout@v3 @@ -259,6 +276,7 @@ jobs: confidence-intervals: name: confidence intervals tests runs-on: ubuntu-latest + needs: [ruff] steps: - uses: actions/checkout@v3 @@ -291,6 +309,7 @@ jobs: test-generic-pyomo-released: name: generic_tester.py runs-on: ubuntu-latest + needs: [ruff] timeout-minutes: 15 steps: @@ -323,6 +342,7 @@ jobs: test-gradient-rho: name: gradient and rho tests runs-on: ubuntu-latest + needs: [ruff] steps: - uses: actions/checkout@v3 @@ -354,7 +374,6 @@ jobs: test-headers: name: header test - runs-on: ubuntu-latest steps: @@ -381,8 +400,8 @@ jobs: test-pysp: name: pysp tests - runs-on: ubuntu-latest + needs: [ruff] steps: - uses: actions/checkout@v3 @@ -415,8 +434,8 @@ jobs: test-cylinders: name: tests on some cylinders - runs-on: ubuntu-latest + needs: [ruff] steps: - uses: actions/checkout@v3 diff --git a/.ruff.toml b/.ruff.toml new file mode 100644 index 000000000..046214475 --- /dev/null +++ b/.ruff.toml @@ -0,0 +1,7 @@ +# ignore old Pyomo models +extend-exclude = [ + "ReferenceModel*.py", + "./mpisppy/utils/callbacks/termination/tests/markshare2.py", + "./mpisppy/tests/examples/hydro/hydro.py", + "./examples/hydro/hydro.py", +] diff --git a/examples/acopf3/ACtree.py b/examples/acopf3/ACtree.py index 93f8a6dbe..61a185891 100644 --- a/examples/acopf3/ACtree.py +++ b/examples/acopf3/ACtree.py @@ -149,11 +149,9 @@ def __init__(self, Parent, TreeInfo, ScenarioList, Name, CondProb, acstream): self.kids = [] if self.stage < TreeInfo.NumStages: bf = TreeInfo.BFs[self.stage-1] - snstr = "_sn"+str(self.sn) self.sn += 1 # serial number for non-leaf, non-ROOT nodes else: bf = 1 # leaf node - snstr = "" for b in range(bf): # divide up the scenario list plist = self.ScenarioList # typing aid diff --git a/examples/acopf3/ccopf2wood.py b/examples/acopf3/ccopf2wood.py index e97a774cd..3aaf1f52a 100644 --- a/examples/acopf3/ccopf2wood.py +++ b/examples/acopf3/ccopf2wood.py @@ -23,8 +23,7 @@ # the problem import ACtree as etree from ccopf_multistage import pysp2_callback,\ - scenario_denouement, _md_dict, FixFast, FixNever, FixGaussian -import rho_setter + scenario_denouement, _md_dict, FixFast import pyomo.environ as pyo import socket diff --git a/examples/acopf3/ccopf_multistage.py b/examples/acopf3/ccopf_multistage.py index 5885d4bf8..9d0989c8d 100644 --- a/examples/acopf3/ccopf_multistage.py +++ b/examples/acopf3/ccopf_multistage.py @@ -11,7 +11,6 @@ import egret import egret.models.acopf as eac import egret.models.ac_relaxations as eac_relax -from egret.data.model_data import ModelData from egret.parsers.matpower_parser import create_ModelData import mpisppy.scenario_tree as scenario_tree import mpisppy.utils.sputils as sputils @@ -22,9 +21,7 @@ import sys import copy import scipy -import socket import numpy as np -import datetime as dt import mpisppy.MPI as mpi import pyomo.environ as pyo @@ -57,10 +54,10 @@ def FixGaussian(minutes, acstream, mu, sigma): #======= end repair functions ===== def _md_dict(epath): - p = str(egret.__path__) - l = p.find("'") - r = p.find("'", l+1) - egretrootpath = p[l+1:r] + path = str(egret.__path__) + left = path.find("'") + right = path.find("'", left+1) + egretrootpath = path[left+1:right] if epath[0] != os.sep: test_case = os.path.join(egretrootpath, epath) else: @@ -262,9 +259,10 @@ def scenario_denouement(rank, scenario_name, scenario): print("GEN: %4s PG:" % gen, end="") + previous_val = None for stage in stages: current_val = pyo.value(getattr(scenario, "stage_models_"+str(stage)).pg[gen]) - if stage == stages[0]: + if previous_val is None: print("%6.2f -->> " % current_val, end=" ") else: print("%6.2f" % (current_val-previous_val), end=" ") @@ -273,9 +271,10 @@ def scenario_denouement(rank, scenario_name, scenario): print("GEN: %4s QG:" % gen, end="") + previous_val = None for stage in stages: current_val = pyo.value(getattr(scenario, "stage_models_"+str(stage)).qg[gen]) - if stage == stages[0]: + if previous_val is None: print("%6.2f -->> " % current_val, end=" ") else: print("%6.2f" % (current_val-previous_val), end=" ") diff --git a/examples/acopf3/fourstage.py b/examples/acopf3/fourstage.py index f4e5283a6..86cab0600 100644 --- a/examples/acopf3/fourstage.py +++ b/examples/acopf3/fourstage.py @@ -23,7 +23,7 @@ # the problem import ACtree as etree from ccopf_multistage import pysp2_callback,\ - scenario_denouement, _md_dict, FixFast, FixNever, FixGaussian + scenario_denouement, _md_dict, FixFast import rho_setter import pyomo.environ as pyo diff --git a/examples/aircond/aircond_cylinders.py b/examples/aircond/aircond_cylinders.py index 2dc6999c8..bc467ff9c 100644 --- a/examples/aircond/aircond_cylinders.py +++ b/examples/aircond/aircond_cylinders.py @@ -10,9 +10,6 @@ # Use bundle_pickler.py to create bundle pickles # NOTE: As of 3 March 2022, you can't compare pickle bundle problems with non-pickled. See _demands_creator in aircondB.py for more discusion. -import sys -import os -import copy import numpy as np import itertools from mpisppy import global_toc @@ -101,7 +98,7 @@ def make_nodenames_balanced(BFs, leaf_nodes=False, root = True): 0, 1, 2, ..., BFs[0], 0_0, 0_1, ..., 0_BFs[1], 1_0, 1_1, ... , 1_BFs[1], ... , BFs[0]_BFs[1], ... , BFs[0]...BFs[-2] """ - if leaf_nodes == False: + if not leaf_nodes: BFs = BFs[:-1] # exclude leaf nodes # Constructs all nodenames @@ -156,7 +153,7 @@ def _parse_args(): domain=bool, default=False) # special "proper" bundle arguments - parser = pickle_bundle.pickle_bundle_parser(cfg) + pickle_bundle.pickle_bundle_config(cfg) cfg.add_to_config("EF_directly", description="Solve the EF directly instead of using cylinders (default False)", @@ -211,7 +208,6 @@ def main(): all_scenario_names = [f"Bundle_{bn*bsize}_{(bn+1)*bsize-1}" for bn in range(numbuns)] refmodule = aircondB primal_rho_setter = None - dual_rho_setter = None global_toc("WARNING: not using rho setters with proper bundles") else: @@ -219,7 +215,6 @@ def main(): all_scenario_names = [f"scen{i}" for i in range(ScenCount)] #Scens are 0-based refmodule = aircond primal_rho_setter = refmodule.primal_rho_setter - dual_rho_setter = refmodule.dual_rho_setter xhat_scenario_dict = make_node_scenario_dict_balanced(BFs) all_nodenames = list(xhat_scenario_dict.keys()) @@ -243,8 +238,8 @@ def main(): ama = amalgamator.from_module(refmodule, cfg, use_command_line=False) ama.run() - print(f"EF inner bound=", ama.best_inner_bound) - print(f"EF outer bound=", ama.best_outer_bound) + print("EF inner bound=", ama.best_inner_bound) + print("EF outer bound=", ama.best_outer_bound) quit() # if we are still here, we are running cylinders diff --git a/examples/aircond/aircond_ef.py b/examples/aircond/aircond_ef.py index 51364f3bd..a1cad0d5a 100644 --- a/examples/aircond/aircond_ef.py +++ b/examples/aircond/aircond_ef.py @@ -7,11 +7,9 @@ # full copyright and license information. ############################################################################### # multistage (4-stage) example using aircond model. Can be any number of stages, does not support unbalanced trees -import pyomo.environ as pyo import numpy as np import mpisppy.utils.sputils as sputils import mpisppy.utils.amalgamator as amalgamator -from mpisppy import global_toc # Use this random stream: aircondstream = np.random.RandomState() @@ -42,8 +40,8 @@ ama = amalgamator.from_module(refmodel, ama_options,use_command_line=False) ama.run() - print(f"inner bound=", ama.best_inner_bound) - print(f"outer bound=", ama.best_outer_bound) + print("inner bound=", ama.best_inner_bound) + print("outer bound=", ama.best_outer_bound) print ("quitting early") quit() from mpisppy.confidence_intervals.mmw_ci import MMWConfidenceIntervals diff --git a/examples/aircond/aircond_seqsampling.py b/examples/aircond/aircond_seqsampling.py index 99db45c19..d134e3070 100644 --- a/examples/aircond/aircond_seqsampling.py +++ b/examples/aircond/aircond_seqsampling.py @@ -9,14 +9,8 @@ # Use the aircond model to illustrate how to use sequential sampling. # -import sys import numpy as np -import argparse import mpisppy.tests.examples.aircond as aircond -import pyomo.environ as pyo -import pyomo.common.config as pyofig -import mpisppy.utils.sputils as sputils -import mpisppy.utils.amalgamator as amalgamator import mpisppy.confidence_intervals.multi_seqsampling as multi_seqsampling import mpisppy.confidence_intervals.confidence_config as conf_config from mpisppy.utils import config @@ -29,19 +23,10 @@ def main(cfg): results (dict): the solution, gap confidence interval and T """ refmodelname = "mpisppy.tests.examples.aircond" - scenario_creator = aircond.scenario_creator BFs = cfg.branching_factors num_scens = np.prod(BFs) - scenario_creator_kwargs = {"num_scens" : num_scens, - "branching_factors": BFs, - "mu_dev": cfg.mu_dev, - "sigma_dev": cfg.sigma_dev, - "start_ups": cfg.start_ups, - "start_seed": cfg.seed, - } - scenario_names = ['Scenario' + str(i) for i in range(num_scens)] xhat_gen_kwargs = {"scenario_names": scenario_names, @@ -114,7 +99,7 @@ def _parse_args(): if cfg.BM_vs_BPL is None: raise RuntimeError("--BM-vs-BPL must be given.") if cfg.BM_vs_BPL != "BM" and cfg.BM_vs_BPL != "BPL": - raise RuntimeError(f"--BM-vs-BPL must be BM or BPL (you gave {args.BM_vs_BMPL})") + raise RuntimeError(f"--BM-vs-BPL must be BM or BPL (you gave {cfg.BM_vs_BPL})") return cfg @@ -124,7 +109,7 @@ def _parse_args(): cfg.quick_assign("EF_mstage", bool, True) results = main(cfg) - print(f"Final gap confidence interval results:", results) + print("Final gap confidence interval results:", results) if cfg.xhat1_file is not None: print(f"Writing xhat1 to {cfg.xhat1_file}.npy") diff --git a/examples/aircond/bundle_pickler.py b/examples/aircond/bundle_pickler.py index 552b92fb9..9076951ad 100644 --- a/examples/aircond/bundle_pickler.py +++ b/examples/aircond/bundle_pickler.py @@ -11,11 +11,7 @@ # see try_pickles.bash # parallel version -import sys -import os -import copy import numpy as np -import itertools import mpisppy.tests.examples.aircondB as aircondB from mpisppy.utils import config from mpisppy.utils import pickle_bundle @@ -31,7 +27,7 @@ def _parse_args(): cfg = config.Config() cfg.multistage() - pickle_bundle.pickle_bundle_parser(cfg) + pickle_bundle.pickle_bundle_config(cfg) aircondB.inparser_adder(cfg) cfg.parse_command_line("bundle_pickler for aircond") @@ -55,8 +51,6 @@ def main(): bsize = int(cfg.scenarios_per_bundle) numbuns = ScenCount // bsize - # we won't actually use all names - all_bundle_names = [f"Bundle_{bn*bsize}_{(bn+1)*bsize-1}" for bn in range(numbuns)] if numbuns < n_proc: raise RuntimeError( diff --git a/examples/battery/battery.py b/examples/battery/battery.py index bbe0bbcf7..05b9fbb84 100644 --- a/examples/battery/battery.py +++ b/examples/battery/battery.py @@ -23,7 +23,7 @@ import mpisppy.scenario_tree as stree def scenario_creator( - scenario_name, solar_filname=None, use_LP=False, lam=None, + scenario_name, solar_filename=None, use_LP=False, lam=None, ): """ Args: @@ -80,7 +80,8 @@ def big_M_constraint_rule(model, t): + data['disc'] * pyo.quicksum(model.q) + lam * model.z[0], sense=pyo.minimize) - fscr = lambda model: pyo.dot_product(data['rev'], model.y) + def fscr(model): + return pyo.dot_product(data["rev"], model.y) model.first_stage_cost = pyo.Expression(rule=fscr) model._mpisppy_node_list = [ diff --git a/examples/distr/distr.py b/examples/distr/distr.py index 91a381a97..0a30ce086 100644 --- a/examples/distr/distr.py +++ b/examples/distr/distr.py @@ -8,7 +8,6 @@ ############################################################################### # Network Flow - various formulations import pyomo.environ as pyo -import mpisppy.utils.sputils as sputils import distr_data import time @@ -196,12 +195,12 @@ def consensus_vars_creator(num_scens, inter_region_dict, all_scenario_names): vstr = f"flow[{arc}]" #variable name as string #adds inter region arcs in the source region - if not region_source in consensus_vars: #initiates consensus_vars[region_source] + if region_source not in consensus_vars: #initiates consensus_vars[region_source] consensus_vars[region_source] = list() consensus_vars[region_source].append(vstr) #adds inter region arcs in the target region - if not region_target in consensus_vars: #initiates consensus_vars[region_target] + if region_target not in consensus_vars: #initiates consensus_vars[region_target] consensus_vars[region_target] = list() consensus_vars[region_target].append(vstr) for region in all_scenario_names: diff --git a/examples/distr/distr_admm_cylinders.py b/examples/distr/distr_admm_cylinders.py index 06fec9770..82ead40dc 100644 --- a/examples/distr/distr_admm_cylinders.py +++ b/examples/distr/distr_admm_cylinders.py @@ -10,17 +10,16 @@ import mpisppy.utils.admmWrapper as admmWrapper import distr_data import distr -import mpisppy.cylinders from mpisppy.spin_the_wheel import WheelSpinner import mpisppy.utils.sputils as sputils from mpisppy.utils import config import mpisppy.utils.cfg_vanilla as vanilla from mpisppy import MPI -global_rank = MPI.COMM_WORLD.Get_rank() - import time +global_rank = MPI.COMM_WORLD.Get_rank() + write_solution = False def _parse_args(): @@ -170,4 +169,4 @@ def main(): if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/examples/distr/distr_data.py b/examples/distr/distr_data.py index 580f5ceb4..d27b610a1 100644 --- a/examples/distr/distr_data.py +++ b/examples/distr/distr_data.py @@ -14,6 +14,10 @@ # First there is a hard wired data_set, then there is a scalable dataset # Hardwired data sets +import json +import re +import numpy as np + def inter_region_dict_creator(num_scens): """Creates the oriented arcs between the regions, with their capacities and costs. \n @@ -184,7 +188,6 @@ def _is_partition(L, *lists): return region_dict -import json if __name__ == "__main__": #creating the json files for num_scens in range(2,5): @@ -206,9 +209,6 @@ def _is_partition(L, *lists): ######################################################################################################################## # Scalable datasets -import re -import numpy as np - def parse_node_name(name): """ decomposes the name, for example "DC1_2 gives" "DC",1,2 Args: @@ -413,4 +413,4 @@ def scalable_region_dict_creator(scenario_name, all_nodes_dict=None, cfg=None, d arc = (node_1, node_2) _intra_arc_creator(region_dict, node_1, node_2, cfg, arc, arc_params, my_seed=count, intra=True) count += 1 - return region_dict \ No newline at end of file + return region_dict diff --git a/examples/distr/distr_ef.py b/examples/distr/distr_ef.py index 053e9bb66..935e4e687 100644 --- a/examples/distr/distr_ef.py +++ b/examples/distr/distr_ef.py @@ -13,7 +13,6 @@ import mpisppy.utils.admmWrapper as admmWrapper import distr import distr_data -import mpisppy.cylinders import pyomo.environ as pyo import mpisppy.utils.sputils as sputils diff --git a/examples/farmer/cs_farmer.py b/examples/farmer/cs_farmer.py index 079269bc6..b7f006660 100644 --- a/examples/farmer/cs_farmer.py +++ b/examples/farmer/cs_farmer.py @@ -9,7 +9,6 @@ import datetime import logging import sys -import os import mpisppy.MPI as mpi import copy diff --git a/examples/farmer/farmer.py b/examples/farmer/farmer.py index 70cf2ae80..2d620b68f 100644 --- a/examples/farmer/farmer.py +++ b/examples/farmer/farmer.py @@ -23,9 +23,7 @@ import pyomo.environ as pyo import numpy as np -import mpisppy.scenario_tree as scenario_tree import mpisppy.utils.sputils as sputils -from mpisppy.utils import config # Use this random stream: farmerstream = np.random.RandomState() diff --git a/examples/farmer/farmer_cylinders.py b/examples/farmer/farmer_cylinders.py index 5a3220748..11d516676 100644 --- a/examples/farmer/farmer_cylinders.py +++ b/examples/farmer/farmer_cylinders.py @@ -9,7 +9,6 @@ # general example driver for farmer with cylinders import farmer -import mpisppy.cylinders # Make it all go from mpisppy.spin_the_wheel import WheelSpinner @@ -18,7 +17,6 @@ from mpisppy.utils import config import mpisppy.utils.cfg_vanilla as vanilla -from mpisppy.extensions.extension import MultiExtension from mpisppy.extensions.norm_rho_updater import NormRhoUpdater from mpisppy.convergers.norm_rho_converger import NormRhoConverger from mpisppy.convergers.primal_dual_converger import PrimalDualConverger @@ -93,7 +91,6 @@ def main(): "crops_multiplier": crops_multiplier, 'sense': pyo.minimize } - scenario_names = [f"Scenario{i+1}" for i in range(num_scen)] # Things needed for vanilla cylinders beans = (cfg, scenario_creator, scenario_denouement, all_scenario_names) diff --git a/examples/farmer/farmer_ef.py b/examples/farmer/farmer_ef.py index c86df4618..df4edb58b 100644 --- a/examples/farmer/farmer_ef.py +++ b/examples/farmer/farmer_ef.py @@ -80,6 +80,8 @@ def main_with_cfg(): results = solver.solve(tee=True) else: results = solver.solve(ef, tee=True, symbolic_solver_labels=True,) + if not pyo.check_optimal_termination(results): + print("Warning: solver reported non-optimal termination status") return ef diff --git a/examples/farmer/farmer_lshapedhub.py b/examples/farmer/farmer_lshapedhub.py index 255e077d8..f16c88b09 100644 --- a/examples/farmer/farmer_lshapedhub.py +++ b/examples/farmer/farmer_lshapedhub.py @@ -95,10 +95,6 @@ def main(): # FWPH spoke if fwph: fw_spoke = vanilla.fwph_spoke(*beans, scenario_creator_kwargs=scenario_creator_kwargs) - - # xhat looper bound spoke -- any scenario will do for - # lshaped (they're all the same) - xhat_scenario_dict = {"ROOT": all_scenario_names[0]} if xhatlshaped: xhatlshaped_spoke = vanilla.xhatlshaped_spoke(*beans, scenario_creator_kwargs=scenario_creator_kwargs) diff --git a/examples/farmer/farmer_rho_demo.py b/examples/farmer/farmer_rho_demo.py index a50df0ab8..99c21322b 100644 --- a/examples/farmer/farmer_rho_demo.py +++ b/examples/farmer/farmer_rho_demo.py @@ -13,9 +13,7 @@ # Edited by DLW Oct 2023 # Note: norm_rho_updater is the Gabe thing -import time import farmer -import mpisppy.cylinders # Make it all go from mpisppy.spin_the_wheel import WheelSpinner @@ -28,9 +26,6 @@ from mpisppy.extensions.norm_rho_updater import NormRhoUpdater from mpisppy.convergers.norm_rho_converger import NormRhoConverger -import mpisppy.utils.gradient as grad -import mpisppy.utils.find_rho as find_rho -from mpisppy.utils.wxbarwriter import WXBarWriter from mpisppy.extensions.gradient_extension import Gradient_extension write_solution = False @@ -80,7 +75,6 @@ def main(): cfg = _parse_args() - num_scen = cfg.num_scens crops_multiplier = cfg.crops_mult rho_setter = None # non-grad rho setter? @@ -104,7 +98,6 @@ def main(): 'use_integer': False, "crops_multiplier": crops_multiplier, } - scenario_names = [f"Scenario{i+1}" for i in range(num_scen)] # Things needed for vanilla cylinders beans = (cfg, scenario_creator, scenario_denouement, all_scenario_names) diff --git a/examples/farmer/farmer_seqsampling.py b/examples/farmer/farmer_seqsampling.py index 3d5a434a9..2a4eacd25 100644 --- a/examples/farmer/farmer_seqsampling.py +++ b/examples/farmer/farmer_seqsampling.py @@ -14,11 +14,8 @@ # the command line parameters for both (so either way, # many command line parameters will be ignored). -import sys import numpy as np -import argparse import farmer -import pyomo.environ as pyo from mpisppy.utils import config import mpisppy.utils.sputils as sputils import mpisppy.utils.amalgamator as amalgamator @@ -91,7 +88,6 @@ def main(cfg): results (dict): the solution, gap confidence interval and T """ refmodelname = "farmer" - scenario_creator = farmer.scenario_creator scen_count = cfg.num_scens assert cfg.EF_solver_name is not None @@ -193,7 +189,7 @@ def _parse_args(): cfg = _parse_args() results = main(cfg) - print(f"Final gap confidence interval results:", results) + print("Final gap confidence interval results:", results) if cfg.xhat1_file is not None: print(f"Writing xhat1 to {cfg.xhat1_file}.npy") diff --git a/examples/farmer/from_pysp/abstract.py b/examples/farmer/from_pysp/abstract.py index 0385b75ca..685f0ab23 100644 --- a/examples/farmer/from_pysp/abstract.py +++ b/examples/farmer/from_pysp/abstract.py @@ -29,7 +29,7 @@ def _print_usage(): if not solver_avail: print(f"Cannot find solver {solver_name}") sys.exit() -except: +except Exception: print(f"Cannot find solver {solver_name}") _print_usage() sys.exit() diff --git a/examples/farmer/from_pysp/concrete_ampl.py b/examples/farmer/from_pysp/concrete_ampl.py index 1ad72adb5..28fc44764 100644 --- a/examples/farmer/from_pysp/concrete_ampl.py +++ b/examples/farmer/from_pysp/concrete_ampl.py @@ -25,7 +25,7 @@ def _print_usage(): if not solver_avail: print(f"Cannot find solver {sys.argv[1]}") sys.exit() -except: +except Exception: print(f"Cannot find solver {sys.argv[1]}") _print_usage() sys.exit() diff --git a/examples/farmer/schur_complement.py b/examples/farmer/schur_complement.py index b654cc545..1fa923552 100644 --- a/examples/farmer/schur_complement.py +++ b/examples/farmer/schur_complement.py @@ -6,13 +6,12 @@ # All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md for # full copyright and license information. ############################################################################### -import pyomo.environ as pe import farmer -import mpisppy.utils.sputils as sputils from mpisppy.opt import ef, sc import logging from mpisppy import MPI import sys +import pyomo.environ as pyo if MPI.COMM_WORLD.Get_rank() == 0: @@ -38,6 +37,8 @@ def solve_with_extensive_form(scen_count): scenario_creator=farmer.scenario_creator, scenario_creator_kwargs=scenario_kwargs) results = opt.solve_extensive_form() + if not pyo.check_optimal_termination(results): + print("Warning: solver reported non-optimal termination status") opt.report_var_values_at_rank0() return opt @@ -55,6 +56,7 @@ def solve_with_sc(scen_count, linear_solver=None): scenario_creator=farmer.scenario_creator, scenario_creator_kwargs=scenario_kwargs) results = opt.solve() + print(f"SchurComplement solver status: {results}") opt.report_var_values_at_rank0() return opt diff --git a/examples/generic_tester.py b/examples/generic_tester.py index 07579eb7b..69c337e6e 100644 --- a/examples/generic_tester.py +++ b/examples/generic_tester.py @@ -54,13 +54,13 @@ def egret_avail(): try: import egret - except: + except Exception: return False - p = str(egret.__path__) - l = p.find("'") - r = p.find("'", l+1) - egretrootpath = p[l+1:r] + path = str(egret.__path__) + left = path.find("'") + right = path.find("'", left+1) + egretrootpath = path[left+1:right] egret_thirdparty_path = os.path.join(egretrootpath, "thirdparty") if os.path.exists(os.path.join(egret_thirdparty_path, "pglib-opf-master")): diff --git a/examples/hydro/hydro_cylinders.py b/examples/hydro/hydro_cylinders.py index 16623f1b1..3e43a80c2 100644 --- a/examples/hydro/hydro_cylinders.py +++ b/examples/hydro/hydro_cylinders.py @@ -17,7 +17,6 @@ from mpisppy.utils import config import mpisppy.utils.cfg_vanilla as vanilla -import mpisppy.cylinders as cylinders write_solution = True diff --git a/examples/hydro/hydro_cylinders_pysp.py b/examples/hydro/hydro_cylinders_pysp.py index fe752f10e..8955cce80 100644 --- a/examples/hydro/hydro_cylinders_pysp.py +++ b/examples/hydro/hydro_cylinders_pysp.py @@ -8,15 +8,12 @@ ############################################################################### # general example driver for the hydro example with cylinders -import hydro import hydro_cylinders from mpisppy.spin_the_wheel import WheelSpinner -from mpisppy.utils import config import mpisppy.utils.cfg_vanilla as vanilla from mpisppy.utils.pysp_model import PySPModel -import mpisppy.cylinders as cylinders write_solution = True diff --git a/examples/netdes/netdes_cylinders.py b/examples/netdes/netdes_cylinders.py index a974d51e0..232a775aa 100644 --- a/examples/netdes/netdes_cylinders.py +++ b/examples/netdes/netdes_cylinders.py @@ -6,9 +6,6 @@ # All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md for # full copyright and license information. ############################################################################### -import sys -import os -import copy import netdes from mpisppy.spin_the_wheel import WheelSpinner diff --git a/examples/netdes/netdes_ef.py b/examples/netdes/netdes_ef.py index 0975ce401..d0748bfcc 100644 --- a/examples/netdes/netdes_ef.py +++ b/examples/netdes/netdes_ef.py @@ -34,6 +34,8 @@ def main(): scenario_creator_kwargs={"path": path}, ) results = ef.solve_extensive_form(tee=True) + if not pyo.check_optimal_termination(results): + print("Warning: solver reported non-optimal termination status") print("Netdes objective value:", pyo.value(ef.ef.EF_Obj)) if __name__=="__main__": diff --git a/examples/netdes/netdes_extension.py b/examples/netdes/netdes_extension.py index 25da4ca6c..eb752866c 100644 --- a/examples/netdes/netdes_extension.py +++ b/examples/netdes/netdes_extension.py @@ -6,7 +6,6 @@ # All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md for # full copyright and license information. ############################################################################### -import numpy as np import pyomo.environ as pyo import mpisppy.utils.sputils as sputils from mpisppy.extensions.extension import Extension diff --git a/examples/netdes/netdes_ph.py b/examples/netdes/netdes_ph.py index 6bdb17e37..4a4d5162d 100644 --- a/examples/netdes/netdes_ph.py +++ b/examples/netdes/netdes_ph.py @@ -10,7 +10,6 @@ ''' from netdes import scenario_creator, scenario_denouement from mpisppy.opt.ph import PH -from netdes_extension import NetworkDesignTracker from mpisppy.convergers.primal_dual_converger import PrimalDualConverger from mpisppy.extensions.xhatclosest import XhatClosest import os diff --git a/examples/run_all.py b/examples/run_all.py index 884bf6132..e36d4851d 100644 --- a/examples/run_all.py +++ b/examples/run_all.py @@ -45,13 +45,13 @@ def egret_avail(): try: import egret - except: + except Exception: return False - p = str(egret.__path__) - l = p.find("'") - r = p.find("'", l+1) - egretrootpath = p[l+1:r] + path = str(egret.__path__) + left = path.find("'") + right = path.find("'", left+1) + egretrootpath = path[left+1:right] egret_thirdparty_path = os.path.join(egretrootpath, "thirdparty") if os.path.exists(os.path.join(egret_thirdparty_path, "pglib-opf-master")): @@ -106,6 +106,8 @@ def time_one(ID, dirname, progname, np, argstring): if (i % 2) == 0: foo = i * i bar = str(i)+"!" + del foo + del bar finish = dt.now() refsecs = (finish-start).total_seconds() diff --git a/examples/sizes/sizes.py b/examples/sizes/sizes.py index 5aef3005d..538d97ddb 100644 --- a/examples/sizes/sizes.py +++ b/examples/sizes/sizes.py @@ -20,7 +20,7 @@ def scenario_creator(scenario_name, scenario_count=None): datadir = os.sep.join((sizes_dir, f"SIZES{scenario_count}")) try: fname = datadir + os.sep + scenario_name + ".dat" - except: + except Exception: print("FAIL: datadir=", datadir, " scenario_name=", scenario_name) model = ref.model.create_instance(fname) @@ -57,7 +57,7 @@ def inparser_adder(cfg): def kw_creator(cfg): # (for Amalgamator): linked to the scenario_creator and inparser_adder if cfg.num_scens not in (3, 10): - raise RuntimeError(f"num_scen must the 3 or 10; was {num_scen}") + raise RuntimeError(f"num_scen must the 3 or 10; was {cfg.num_scen}") kwargs = {"scenario_count": cfg.num_scens} return kwargs diff --git a/examples/sizes/sizes_cylinders.py b/examples/sizes/sizes_cylinders.py index f4e475075..293480c96 100644 --- a/examples/sizes/sizes_cylinders.py +++ b/examples/sizes/sizes_cylinders.py @@ -6,8 +6,6 @@ # All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md for # full copyright and license information. ############################################################################### -import sys -import copy import sizes from mpisppy.utils import config diff --git a/examples/sizes/sizes_demo.py b/examples/sizes/sizes_demo.py index b5cc77375..972c271bb 100644 --- a/examples/sizes/sizes_demo.py +++ b/examples/sizes/sizes_demo.py @@ -9,17 +9,14 @@ # updated 23 April 2020 # Serial (not cylinders) -import os import sys import pyomo.environ as pyo import mpisppy.phbase import mpisppy.opt.ph -import mpisppy.scenario_tree as scenario_tree from mpisppy.extensions.extension import MultiExtension from mpisppy.extensions.fixer import Fixer from mpisppy.extensions.mipgapper import Gapper -from mpisppy.extensions.xhatlooper import XhatLooper -from mpisppy.extensions.xhatclosest import XhatClosest +from mpisppy.extensions.avgminmaxer import MinMaxAvg from mpisppy.extensions.wtracker_extension import Wtracker_extension from sizes import scenario_creator, \ scenario_denouement, \ @@ -120,7 +117,6 @@ #quit() ############ test W and xbar writers and special joint reader ############ - from mpisppy.utils.wxbarwriter import WXBarWriter newph = mpisppy.opt.ph.PH( options, @@ -135,7 +131,6 @@ conv, obj, tbound = newph.ph_main() ##### - from mpisppy.utils.wxbarreader import WXBarReader newph = mpisppy.opt.ph.PH( options, @@ -198,7 +193,6 @@ ) ph.options["PHIterLimit"] = 3 - from mpisppy.extensions.avgminmaxer import MinMaxAvg options["avgminmax_name"] = "FirstStageCost" conv, obj, bnd = ph.ph_main() diff --git a/examples/sizes/sizes_ef.py b/examples/sizes/sizes_ef.py index 9c1855757..bc403d677 100644 --- a/examples/sizes/sizes_ef.py +++ b/examples/sizes/sizes_ef.py @@ -25,8 +25,8 @@ scenario_creator, scenario_creator_kwargs={"scenario_count": ScenCount}, ) -if 'persistent' in options["solver_name"]: +if 'persistent' in solver.name: solver.set_instance(ef, symbolic_solver_labels=True) solver.options["mipgap"] = 0.0001 -results = solver.solve(ef, tee=options["verbose"]) -print('EF objective value:', pyo.value(ef.EF_Obj)) \ No newline at end of file +results = solver.solve(ef, tee=True) +print('EF objective value:', pyo.value(ef.EF_Obj)) diff --git a/examples/sizes/sizes_ph.py b/examples/sizes/sizes_ph.py index 6489e0ac4..8068bc377 100644 --- a/examples/sizes/sizes_ph.py +++ b/examples/sizes/sizes_ph.py @@ -10,7 +10,6 @@ # Serial (not cylinders) import sys -import os import mpisppy.phbase import mpisppy.opt.ph from mpisppy.convergers.primal_dual_converger import PrimalDualConverger diff --git a/examples/sizes/sizes_pysp.py b/examples/sizes/sizes_pysp.py index 825e4bb09..59eec904b 100644 --- a/examples/sizes/sizes_pysp.py +++ b/examples/sizes/sizes_pysp.py @@ -27,7 +27,7 @@ def _print_usage(): if not solver_avail: print(f"Cannot find solver {sys.argv[2]}") sys.exit() -except: +except Exception: print(f"Cannot find solver {sys.argv[2]}") _print_usage() sys.exit() diff --git a/examples/sizes/special_cylinders.py b/examples/sizes/special_cylinders.py index f9a0ab4f2..6efc51e5b 100644 --- a/examples/sizes/special_cylinders.py +++ b/examples/sizes/special_cylinders.py @@ -7,8 +7,6 @@ # full copyright and license information. ############################################################################### # ** special ** -import sys -import copy import special_sizes as sizes from mpisppy.spin_the_wheel import WheelSpinner diff --git a/examples/sizes/special_sizes.py b/examples/sizes/special_sizes.py index 24b9cd03e..8bacb2d91 100644 --- a/examples/sizes/special_sizes.py +++ b/examples/sizes/special_sizes.py @@ -21,7 +21,7 @@ def scenario_creator(scenario_name, scenario_count=None): datadir = os.sep.join((sizes_dir, f"SIZES{scenario_count}")) try: fname = datadir + os.sep + scenario_name + ".dat" - except: + except Exception: print("FAIL: datadir=", datadir, " scenario_name=", scenario_name) model = ref.model.create_instance(fname) diff --git a/examples/sslp/sslp.py b/examples/sslp/sslp.py index b097bfaff..1daa836d0 100644 --- a/examples/sslp/sslp.py +++ b/examples/sslp/sslp.py @@ -13,7 +13,6 @@ import sys import socket import datetime as dt -import pyomo.environ as pyo import mpisppy.opt.ph import mpisppy.scenario_tree as scenario_tree import mpisppy.utils.sputils as sputils @@ -161,17 +160,17 @@ def id_fix_list_fct(s): quit() try: bunper = int(sys.argv[2]) - except: + except Exception: print(msg, "\n bad number of bundles per rank=", sys.argv[2]) quit() try: maxit = int(sys.argv[3]) - except: + except Exception: print(msg, "\n bad max iterations=", sys.argv[3]) quit() try: rho = int(sys.argv[4]) - except: + except Exception: print(msg, "\n bad rho=", sys.argv[4]) quit() diff --git a/examples/sslp/sslp_cylinders.py b/examples/sslp/sslp_cylinders.py index 2e61f0a4a..638004240 100644 --- a/examples/sslp/sslp_cylinders.py +++ b/examples/sslp/sslp_cylinders.py @@ -6,9 +6,6 @@ # All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md for # full copyright and license information. ############################################################################### -import sys -import os -import copy import sslp from mpisppy.spin_the_wheel import WheelSpinner diff --git a/examples/sslp/sslp_ef.py b/examples/sslp/sslp_ef.py index e33e867bf..10f536d35 100644 --- a/examples/sslp/sslp_ef.py +++ b/examples/sslp/sslp_ef.py @@ -37,6 +37,8 @@ def main(): scenario_creator_kwargs={"data_dir": data_dir}, ) results = ef.solve_extensive_form() + if not pyo.check_optimal_termination(results): + print("Warning: Non-optimal termination condition from Pyomo") print("sslp objective value:", pyo.value(ef.ef.EF_Obj)) if __name__=="__main__": diff --git a/examples/stoch_distr/stoch_distr.py b/examples/stoch_distr/stoch_distr.py index 6d93e057b..bcf645a5b 100644 --- a/examples/stoch_distr/stoch_distr.py +++ b/examples/stoch_distr/stoch_distr.py @@ -11,7 +11,6 @@ import mpisppy.utils.sputils as sputils import examples.distr.distr_data as distr_data import numpy as np -import re # In this file, we create a (linear) inter-region minimal cost distribution problem. # Our data, gives the constraints inside each in region in region_dict_creator @@ -234,12 +233,12 @@ def consensus_vars_creator(admm_subproblem_names, stoch_scenario_name, inter_reg vstr = f"flow[{arc}]" #variable name as string, y is the slack #adds inter_region_arcs in the source region - if not region_source in consensus_vars: #initiates consensus_vars[region_source] + if region_source not in consensus_vars: #initiates consensus_vars[region_source] consensus_vars[region_source] = list() consensus_vars[region_source].append((vstr,2)) #adds inter_region_arcs in the target region - if not region_target in consensus_vars: #initiates consensus_vars[region_target] + if region_target not in consensus_vars: #initiates consensus_vars[region_target] consensus_vars[region_target] = list() consensus_vars[region_target].append((vstr,2)) @@ -258,7 +257,7 @@ def consensus_vars_creator(admm_subproblem_names, stoch_scenario_name, inter_reg model = scenario_creator(admm_stoch_subproblem_scenario_name, inter_region_dict=inter_region_dict, cfg=cfg, data_params=data_params, all_nodes_dict=all_nodes_dict) for node in model._mpisppy_node_list: for var in node.nonant_list: - if not var.name in consensus_vars[admm_subproblem_name]: + if var.name not in consensus_vars[admm_subproblem_name]: consensus_vars[admm_subproblem_name].append((var.name, node.stage)) return consensus_vars @@ -321,7 +320,7 @@ def split_admm_stoch_subproblem_scenario_name(admm_stoch_subproblem_scenario_nam """ # Method specific to our example and because the admm_subproblem_name and stoch_scenario_name don't include "_" splitted = admm_stoch_subproblem_scenario_name.split('_') - assert (len(splitted) == 4), f"no underscore should be attached to admm_subproblem_name nor stoch_scenario_name" + assert (len(splitted) == 4), "no underscore should be attached to admm_subproblem_name nor stoch_scenario_name" admm_subproblem_name = splitted[2] stoch_scenario_name = splitted[3] return admm_subproblem_name, stoch_scenario_name diff --git a/examples/stoch_distr/stoch_distr_admm_cylinders.py b/examples/stoch_distr/stoch_distr_admm_cylinders.py index cb825ff0b..507ecddbb 100644 --- a/examples/stoch_distr/stoch_distr_admm_cylinders.py +++ b/examples/stoch_distr/stoch_distr_admm_cylinders.py @@ -13,7 +13,6 @@ import examples.distr.distr_data as distr_data import stoch_distr -import mpisppy.cylinders from mpisppy.spin_the_wheel import WheelSpinner import mpisppy.utils.sputils as sputils diff --git a/examples/stoch_distr/stoch_distr_ef.py b/examples/stoch_distr/stoch_distr_ef.py index 23662ee26..ec5d9aa7d 100644 --- a/examples/stoch_distr/stoch_distr_ef.py +++ b/examples/stoch_distr/stoch_distr_ef.py @@ -14,7 +14,6 @@ import stoch_distr import stoch_distr_admm_cylinders import examples.distr.distr_data as distr_data -import mpisppy.cylinders import pyomo.environ as pyo import mpisppy.utils.sputils as sputils diff --git a/examples/uc/cs_uc.py b/examples/uc/cs_uc.py index 0541b32d0..c2734375d 100644 --- a/examples/uc/cs_uc.py +++ b/examples/uc/cs_uc.py @@ -9,7 +9,6 @@ import datetime import logging import sys -import os import mpisppy.MPI as mpi # Hub and spoke SPBase classes @@ -68,7 +67,7 @@ def _usage(): ScenCount = int(sys.argv[1]) bundles_per_rank = int(sys.argv[2]) PHIterLimit = int(sys.argv[3]) - except: + except Exception: _usage() if sys.argv[4] == "fixer": usefixer = True @@ -118,7 +117,7 @@ def _usage(): }, "cross_scen_options":{"valid_eta_bound": {i:0 for i in all_scenario_names}}, } - if usefixer == True: + if usefixer: multi_ext = {"ext_classes": [Fixer, Gapper]} else: multi_ext = {"ext_classes": [Gapper]} diff --git a/examples/uc/gradient_uc_cylinders.py b/examples/uc/gradient_uc_cylinders.py index 52d1f8014..03898d52a 100644 --- a/examples/uc/gradient_uc_cylinders.py +++ b/examples/uc/gradient_uc_cylinders.py @@ -12,7 +12,6 @@ # There is manipulation of the mip gap, # so we need modifications of the vanilla dicts. # Notice also that this uses MutliExtensions -import sys import json import uc_funcs as uc @@ -97,6 +96,8 @@ def main(): all_scenario_names = [f"Scenario{i+1}" for i in range(num_scen)] if cfg.use_cost_based_rho: rho_setter = uc._rho_setter + else: + rho_setter = None # Things needed for vanilla cylinders beans = (cfg, scenario_creator, scenario_denouement, all_scenario_names) @@ -106,12 +107,12 @@ def main(): hub_dict = vanilla.aph_hub(*beans, scenario_creator_kwargs=scenario_creator_kwargs, ph_extensions=MultiExtension, - rho_setter = None) + rho_setter = rho_setter) else: hub_dict = vanilla.ph_hub(*beans, scenario_creator_kwargs=scenario_creator_kwargs, ph_extensions=MultiExtension, - rho_setter = None) + rho_setter = rho_setter) # Extend and/or correct the vanilla dictionary ext_classes = [Gapper] @@ -169,7 +170,7 @@ def main(): if lagrangian: lagrangian_spoke = vanilla.lagrangian_spoke(*beans, scenario_creator_kwargs=scenario_creator_kwargs, - rho_setter = None) + rho_setter = rho_setter) # xhat looper bound spoke if xhatlooper: @@ -179,7 +180,7 @@ def main(): if cfg.ph_ob: ph_ob_spoke = vanilla.ph_ob_spoke(*beans, scenario_creator_kwargs=scenario_creator_kwargs, - rho_setter = uc._rho_setter) + rho_setter = rho_setter) # xhat shuffle bound spoke if xhatshuffle: diff --git a/examples/uc/rhoconfig10.py b/examples/uc/rhoconfig10.py index caf683f65..f833c68e4 100644 --- a/examples/uc/rhoconfig10.py +++ b/examples/uc/rhoconfig10.py @@ -6,7 +6,7 @@ # All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md for # full copyright and license information. ############################################################################### -from pyomo.environ import * +from pyomo.environ import value # TBD - we can't get the rho scale factor into the callback easily, so we hard-code for now. rho_scale_factor = 1.0 @@ -26,17 +26,13 @@ def ph_rhosetter_callback(ph, scenario_tree, scenario): for g in sorted(scenario_instance.ThermalGeneratorsAtBus[b]): - max_capacity = value(scenario_instance.MaximumPowerOutput[g]) min_power = value(scenario_instance.MinimumPowerOutput[g]) max_power = value(scenario_instance.MaximumPowerOutput[g]) avg_power = min_power + ((max_power - min_power) / 2.0) min_cost = value(scenario_instance.MinimumProductionCost[g]) - fuel_cost = value(scenario_instance.FuelCost[g]) - avg_cost = scenario_instance.ComputeProductionCosts(scenario_instance, g, t, avg_power) + min_cost - max_cost = scenario_instance.ComputeProductionCosts(scenario_instance, g, t, max_power) + min_cost rho = rho_scale_factor * avg_cost diff --git a/examples/uc/simple_ef.py b/examples/uc/simple_ef.py index 88bd0f3aa..4f445c08f 100644 --- a/examples/uc/simple_ef.py +++ b/examples/uc/simple_ef.py @@ -11,7 +11,6 @@ import pyomo.environ as pyo import mpisppy.utils.sputils as sputils -from mpisppy.opt.ef import ExtensiveForm """ UC """ assert len(sys.argv) == 2, "Supply the solver name as the first argument" diff --git a/examples/uc/uc3wood.py b/examples/uc/uc3wood.py index dd3f48a4b..c603e00ad 100644 --- a/examples/uc/uc3wood.py +++ b/examples/uc/uc3wood.py @@ -12,15 +12,12 @@ import datetime import logging import sys -import os import mpisppy.MPI as mpi # Hub and spoke SPBase classes from mpisppy.phbase import PHBase from mpisppy.opt.ph import PH -from mpisppy.fwph.fwph import FWPH # Hub and spoke SPCommunicator classes -from mpisppy.cylinders.fwph_spoke import FrankWolfeOuterBound from mpisppy.cylinders.lagrangian_bounder import LagrangianOuterBound from mpisppy.cylinders.xhatlooper_bounder import XhatLooperInnerBound from mpisppy.cylinders.hub import PHHub @@ -65,7 +62,7 @@ def _usage(): ScenCount = int(sys.argv[1]) bundles_per_rank = int(sys.argv[2]) PHIterLimit = int(sys.argv[3]) - except: + except Exception: _usage() if sys.argv[4] == "fixer": usefixer = True @@ -113,7 +110,7 @@ def _usage(): "mipgapdict": dict() , # Setting this changes iter0_solver_options }, } - if usefixer==True: + if usefixer: multi_ext = {"ext_classes": [Fixer, Gapper]} else: multi_ext = {"ext_classes": [Gapper]} diff --git a/examples/uc/uc4wood.py b/examples/uc/uc4wood.py index b1e996807..bfba16e1f 100644 --- a/examples/uc/uc4wood.py +++ b/examples/uc/uc4wood.py @@ -13,7 +13,6 @@ import datetime import logging import sys -import os import mpisppy.MPI as mpi # Hub and spoke SPBase classes @@ -66,7 +65,7 @@ def _usage(): ScenCount = int(sys.argv[1]) bundles_per_rank = int(sys.argv[2]) PHIterLimit = int(sys.argv[3]) - except: + except Exception: _usage() if sys.argv[4] == "fixer": usefixer = True @@ -113,7 +112,7 @@ def _usage(): "mipgapdict": dict() , # Setting this changes iter0_solver_options }, } - if usefixer==True: + if usefixer: multi_ext = {"ext_classes": [Fixer, Gapper]} else: multi_ext = {"ext_classes": [Gapper]} diff --git a/examples/uc/uc_cylinders.py b/examples/uc/uc_cylinders.py index eadf3986a..7c1413864 100644 --- a/examples/uc/uc_cylinders.py +++ b/examples/uc/uc_cylinders.py @@ -12,7 +12,6 @@ # There is manipulation of the mip gap, # so we need modifications of the vanilla dicts. # Notice also that this uses MutliExtensions -import sys import json import uc_funcs as uc @@ -150,7 +149,7 @@ def main(): hub_dict["opt_kwargs"]["options"]["defaultPHrho"] = 1 ### end ph spoke ### - if cfg.reduced_costs: + if reduced_costs: vanilla.add_reduced_costs_fixer(hub_dict, cfg) # FWPH spoke @@ -175,7 +174,7 @@ def main(): if cross_scenario_cuts: cross_scenario_cuts_spoke = vanilla.cross_scenario_cuts_spoke(*beans, scenario_creator_kwargs=scenario_creator_kwargs) - if cfg.reduced_costs: + if reduced_costs: reduced_costs_spoke = vanilla.reduced_costs_spoke(*beans, scenario_creator_kwargs=scenario_creator_kwargs, rho_setter = None) @@ -191,7 +190,7 @@ def main(): list_of_spoke_dict.append(xhatshuffle_spoke) if cross_scenario_cuts: list_of_spoke_dict.append(cross_scenario_cuts_spoke) - if cfg.reduced_costs: + if reduced_costs: list_of_spoke_dict.append(reduced_costs_spoke) wheel = WheelSpinner(hub_dict, list_of_spoke_dict) diff --git a/examples/uc/uc_ef.py b/examples/uc/uc_ef.py index cc4dc3267..1b12fccf1 100644 --- a/examples/uc/uc_ef.py +++ b/examples/uc/uc_ef.py @@ -28,5 +28,5 @@ results = ef.solve_extensive_form(tee=True) print(f"{scen_count}-scenario UC objective value:", pyo.value(ef.ef.EF_Obj)) if ef.tree_solution_available: - print(f"Writing tree solution") + print("Writing tree solution") ef.write_tree_solution(f"{scen_count}scenario_EF_solution", uc.scenario_tree_solution_writer) diff --git a/examples/uc/uc_funcs.py b/examples/uc/uc_funcs.py index e820353ad..1a36af031 100644 --- a/examples/uc/uc_funcs.py +++ b/examples/uc/uc_funcs.py @@ -15,8 +15,6 @@ from pyomo.dataportal import DataPortal -import mpisppy.scenario_tree as scenario_tree -from mpisppy.utils import config import pyomo.environ as pyo import mpisppy.utils.sputils as sputils @@ -64,12 +62,6 @@ def pysp_instance_creation_callback(scenario_name, path=None, scenario_count=Non def scenario_creator(scenario_name, scenario_count=None, path=None, num_scens=None, seedoffset=0): - - # Do some calculations that might be needed by confidence interval software - scennum = sputils.extract_num(scenario_name) - newnum = scennum + seedoffset - newname = f"Scenario{newnum}" - return pysp2_callback(scenario_name, scenario_count=scenario_count, path=path, num_scens=num_scens, seedoffset=seedoffset) @@ -125,7 +117,6 @@ def scenario_rhos(scenario_instance, rho_scale_factor=0.1): computed_rhos = [] for t in scenario_instance.TimePeriods: for g in scenario_instance.ThermalGenerators: - max_capacity = pyo.value(scenario_instance.MaximumPowerOutput[g,t]) min_power = pyo.value(scenario_instance.MinimumPowerOutput[g,t]) max_power = pyo.value(scenario_instance.MaximumPowerOutput[g,t]) avg_power = min_power + ((max_power - min_power) / 2.0) @@ -158,7 +149,7 @@ def scenario_rhos_trial_from_file(scenario_instance, rho_scale_factor=0.01, rho_scale_factor=rho_scale_factor) try: trial_rhos = _get_saved_rhos(fname) - except: + except Exception: raise RuntimeError('Formatting issue in specified rho file ' + fname + '. Format should be (variable_name,rho_value) for ' 'each row, with no blank lines, and no ' @@ -169,7 +160,6 @@ def scenario_rhos_trial_from_file(scenario_instance, rho_scale_factor=0.01, for t in sorted(scenario_instance.TimePeriods): for g in sorted(scenario_instance.ThermalGeneratorsAtBus[b]): var = scenario_instance.UnitOn[g,t] - computed_rho = computed_rhos[index] try: trial_rho = trial_rhos[var.name] except KeyError: diff --git a/mpisppy/MPI.py b/mpisppy/MPI.py index 71f75d27d..a265777cb 100644 --- a/mpisppy/MPI.py +++ b/mpisppy/MPI.py @@ -8,8 +8,8 @@ ############################################################################### try: - from mpi4py.MPI import * - _haveMPI = True + from mpi4py.MPI import * # noqa: F403 + haveMPI = True except ImportError: import numpy as _np @@ -22,7 +22,7 @@ LOR = _np.logical_or DOUBLE = _np.double INT = _np.intc - _haveMPI = False + haveMPI = False class _MockMPIComm: @@ -81,9 +81,9 @@ def _set_data(sendbuf, recvbuf): recv_data, recv_size, recv_type = _process_BufSpec(recvbuf) if send_size != recv_size: - raise RuntimeError(f"Send and receive buffers should be of the same size") + raise RuntimeError("Send and receive buffers should be of the same size") if send_type != recv_type: - raise RuntimeError(f"Send and receive buffers should be of the same type") + raise RuntimeError("Send and receive buffers should be of the same type") recv_data[:] = send_data diff --git a/mpisppy/__init__.py b/mpisppy/__init__.py index a58efecf8..ff2bbe7c4 100644 --- a/mpisppy/__init__.py +++ b/mpisppy/__init__.py @@ -7,15 +7,16 @@ # full copyright and license information. ############################################################################### from pyomo.common.timing import TicTocTimer as _TTT -# Register numpy types in Pyomo, see https://github.com/Pyomo/pyomo/issues/3091 from pyomo.common.dependencies import numpy_available as _np_avail -bool(_np_avail) -from mpisppy.MPI import COMM_WORLD, _haveMPI as haveMPI +from mpisppy.MPI import COMM_WORLD, haveMPI as haveMPI +# Register numpy types in Pyomo, see https://github.com/Pyomo/pyomo/issues/3091 +bool(_np_avail) tt_timer = _TTT() _global_rank = COMM_WORLD.rank -global_toc = lambda msg, cond=(_global_rank==0) : tt_timer.toc(msg, delta=False) if cond else None +def global_toc(msg, cond=_global_rank == 0): + return tt_timer.toc(msg, delta=False) if cond else None global_toc("Initializing mpi-sppy") diff --git a/mpisppy/confidence_intervals/ciutils.py b/mpisppy/confidence_intervals/ciutils.py index c08a85eca..286d4313c 100644 --- a/mpisppy/confidence_intervals/ciutils.py +++ b/mpisppy/confidence_intervals/ciutils.py @@ -271,7 +271,7 @@ def gap_estimators(xhat_one, ''' global_toc("Enter gap_estimators") if solving_type not in ["EF_2stage","EF_mstage"]: - print(f"solving type=", solving_type) + print("solving type=", solving_type) raise RuntimeError("Only EF solve for the approximate problem is supported yet.") else: is_multi = (solving_type=="EF_mstage") @@ -398,7 +398,7 @@ def gap_estimators(xhat_one, all_nodenames = all_nodenames,mpicomm=mpicomm) #Evaluating xhat and xstar and getting the value of the objective function #for every (local) scenario - zn_hat=ev.evaluate(xhats) + ev.evaluate(xhats) objs_at_xhat = ev.objs_dict zn_star=ev.evaluate(xstars) objs_at_xstar = ev.objs_dict diff --git a/mpisppy/confidence_intervals/mmw_ci.py b/mpisppy/confidence_intervals/mmw_ci.py index 276d30178..e44c20869 100644 --- a/mpisppy/confidence_intervals/mmw_ci.py +++ b/mpisppy/confidence_intervals/mmw_ci.py @@ -10,21 +10,17 @@ # Code to evaluate a given x-hat given as a nonant-cache, and the MMW confidence interval. import mpisppy.MPI as mpi -import argparse import numpy as np import scipy.stats import importlib -import os from mpisppy import global_toc -fullcomm = mpi.COMM_WORLD -global_rank = fullcomm.Get_rank() - import mpisppy.utils.amalgamator as ama -import mpisppy.utils.xhat_eval as xhat_eval -import mpisppy.utils.sputils as sputils import mpisppy.confidence_intervals.ciutils as ciutils +fullcomm = mpi.COMM_WORLD +global_rank = fullcomm.Get_rank() + def remove_None(d): if d is None: return {} diff --git a/mpisppy/confidence_intervals/mmw_conf.py b/mpisppy/confidence_intervals/mmw_conf.py index 541e2d997..887e66e3e 100644 --- a/mpisppy/confidence_intervals/mmw_conf.py +++ b/mpisppy/confidence_intervals/mmw_conf.py @@ -57,10 +57,10 @@ mname = sys.argv[1] # will be assigned to the model_module_name config arg try: m = import_file(mname) - except: + except Exception: try: m = import_file(f"{mname}.py") - except: + except Exception: raise RuntimeError(f"Could not import module: {mname}") @@ -68,7 +68,7 @@ # the inprser_adder might want num_scens, but mmw contols the number of scenarios try: del cfg["num_scens"] - except: + except Exception: pass parser = cfg.create_parser("mmw_conf") @@ -98,7 +98,7 @@ # Read xhats from xhatpath xhat = ciutils.read_xhat(cfg.xhatpath) - if cfg.MMW_batch_size == None: + if cfg.MMW_batch_size is None: raise RuntimeError("mmw_conf requires MMW_batch_size") refmodel = modelpath #Change this path to use a different model diff --git a/mpisppy/confidence_intervals/multi_seqsampling.py b/mpisppy/confidence_intervals/multi_seqsampling.py index 7f04b830d..c2da535d2 100644 --- a/mpisppy/confidence_intervals/multi_seqsampling.py +++ b/mpisppy/confidence_intervals/multi_seqsampling.py @@ -10,27 +10,23 @@ # This extension of SeqSampling works for multistage, using independent # scenarios instead of a single scenario tree. -import pyomo.environ as pyo import pyomo.common.config as pyofig import mpisppy.MPI as mpi import mpisppy.utils.sputils as sputils import mpisppy.confidence_intervals.confidence_config as confidence_config from mpisppy.utils import config import numpy as np -import scipy.stats -import importlib from mpisppy import global_toc -fullcomm = mpi.COMM_WORLD -global_rank = fullcomm.Get_rank() - import mpisppy.utils.amalgamator as amalgamator import mpisppy.utils.xhat_eval as xhat_eval import mpisppy.confidence_intervals.ciutils as ciutils from mpisppy.confidence_intervals.seqsampling import SeqSampling from mpisppy.tests.examples.aircond import xhat_generator_aircond import mpisppy.confidence_intervals.sample_tree as sample_tree -import mpisppy.confidence_intervals.ciutils as ciutils + +fullcomm = mpi.COMM_WORLD +global_rank = fullcomm.Get_rank() class IndepScens_SeqSampling(SeqSampling): def __init__(self, @@ -114,7 +110,6 @@ def run(self, maxit=200): #----------------------------Step 3 -------------------------------------# k+=1 nk_m1 = nk #n_{k-1} - mk_m1 = mk lower_bound_k = self.sample_size(k, Gk, sk, nk_m1) #Computing m_k and associated scenario names diff --git a/mpisppy/confidence_intervals/sample_tree.py b/mpisppy/confidence_intervals/sample_tree.py index 4b23aa66a..a2ef658b5 100644 --- a/mpisppy/confidence_intervals/sample_tree.py +++ b/mpisppy/confidence_intervals/sample_tree.py @@ -15,7 +15,6 @@ import mpisppy.utils.sputils as sputils import mpisppy.utils.amalgamator as amalgamator import mpisppy.confidence_intervals.ciutils as ciutils -from mpisppy import global_toc fullcomm = mpi.COMM_WORLD global_rank = fullcomm.Get_rank() diff --git a/mpisppy/confidence_intervals/seqsampling.py b/mpisppy/confidence_intervals/seqsampling.py index ccb33aacf..43c5178eb 100644 --- a/mpisppy/confidence_intervals/seqsampling.py +++ b/mpisppy/confidence_intervals/seqsampling.py @@ -13,7 +13,6 @@ # see also multi_seqsampling.py, which has a class derived from this class -import pyomo.environ as pyo import mpisppy.MPI as mpi import mpisppy.utils.sputils as sputils import numpy as np @@ -23,14 +22,13 @@ from mpisppy.utils import config import mpisppy.utils.solver_spec as solver_spec -fullcomm = mpi.COMM_WORLD -global_rank = fullcomm.Get_rank() - import mpisppy.utils.amalgamator as amalgamator -import mpisppy.utils.xhat_eval as xhat_eval import mpisppy.confidence_intervals.ciutils as ciutils import mpisppy.confidence_intervals.confidence_config as confidence_config +fullcomm = mpi.COMM_WORLD +global_rank = fullcomm.Get_rank() + print("\nTBD: check seqsampling for start vs start_seed") @@ -52,7 +50,7 @@ def is_needed(cfg, needed_things, message=""): def add_options(cfg, optional_things): # allow for defaults on options that Bayraksan et al establish for i,v in optional_things.items(): - if not i in cfg: + if i not in cfg: # there must be a better way... if isinstance(v, str): cfg.quick_assign(i, str, v) @@ -197,7 +195,7 @@ def __init__(self, """ if self.stochastic_sampling : - add_options(options, ["n0min"], [50]) + add_options(cfg, {"n0min": 50}) if self.stopping_criterion == "BM": diff --git a/mpisppy/confidence_intervals/zhat4xhat.py b/mpisppy/confidence_intervals/zhat4xhat.py index 1d9cb4a4a..a564985c7 100644 --- a/mpisppy/confidence_intervals/zhat4xhat.py +++ b/mpisppy/confidence_intervals/zhat4xhat.py @@ -9,7 +9,6 @@ # script to estimate zhat from a given xhat for a given model import sys -import argparse import importlib import numpy as np import scipy.stats @@ -180,14 +179,14 @@ def _main_body(model_module, cfg): raise ValueError(f"Module name should not end in .py ({mname})") try: model_module = importlib.import_module(mname) - except: + except Exception: raise RuntimeError(f"Could not import module: {mname}") model_module.inparser_adder(cfg) # TBD xxxx the inprser_adder might want num_scens, but zhat4xhat contols the number of scenarios # see if this works: try: del cfg.num_scens - except: + except Exception: pass parser = cfg.create_parser("zhat4zhat") diff --git a/mpisppy/convergers/norms_and_residuals.py b/mpisppy/convergers/norms_and_residuals.py index 7bb191913..29a6bfc33 100644 --- a/mpisppy/convergers/norms_and_residuals.py +++ b/mpisppy/convergers/norms_and_residuals.py @@ -7,36 +7,9 @@ # full copyright and license information. ############################################################################### -import sys -import os -import inspect -import pyomo.environ as pyo -from pyomo.opt import SolverFactory, SolutionStatus, TerminationCondition -import logging import numpy as np -import math -import importlib -import csv -import inspect -import typing -import copy -import time - -import mpisppy.log -from mpisppy import global_toc + from mpisppy import MPI -import mpisppy.utils.sputils as sputils -import mpisppy.spopt -from mpisppy.utils import config -import mpisppy.utils.cfg_vanilla as vanilla -from mpisppy.utils.wxbarwriter import WXBarWriter -from mpisppy.spin_the_wheel import WheelSpinner -import mpisppy.confidence_intervals.ciutils as ciutils -from pyomo.contrib.pynumero.interfaces.pyomo_nlp import PyomoNLP -import mpisppy.utils.wxbarutils as wxbarutils -import mpisppy.utils.rho_utils as rho_utils -import mpisppy.utils.find_rho as find_rho -import mpisppy.phbase as phbase ############################################################################ diff --git a/mpisppy/cylinders/hub.py b/mpisppy/cylinders/hub.py index 08b6962ce..5347c6910 100644 --- a/mpisppy/cylinders/hub.py +++ b/mpisppy/cylinders/hub.py @@ -9,7 +9,6 @@ import numpy as np import abc import logging -import time import mpisppy.log from mpisppy.opt.aph import APH @@ -174,7 +173,7 @@ def hub_finalize(self): if self.global_rank == 0: self.print_init = True - global_toc(f"Statistics at termination", True) + global_toc("Statistics at termination", True) self.screen_trace() def receive_innerbounds(self): diff --git a/mpisppy/cylinders/lagranger_bounder.py b/mpisppy/cylinders/lagranger_bounder.py index db7712346..b4a893dbd 100644 --- a/mpisppy/cylinders/lagranger_bounder.py +++ b/mpisppy/cylinders/lagranger_bounder.py @@ -9,7 +9,6 @@ # Indepedent Lagrangian that takes x values as input and # updates its own W. -import time import json import csv import numpy as np @@ -35,7 +34,6 @@ def lagrangian_prep(self): self.opt._save_nonants() def _lagrangian(self, iternum): - verbose = self.opt.options['verbose'] # see if rho should be rescaled if self.rho_rescale_factors is not None\ and iternum in self.rho_rescale_factors: @@ -82,10 +80,6 @@ def _update_weights_and_solve(self, iternum): return self._lagrangian(iternum) def main(self): - # The rho_setter should be attached to the opt object - rho_setter = None - if hasattr(self.opt, 'rho_setter'): - rho_setter = self.opt.rho_setter extensions = self.opt.extensions is not None self.lagrangian_prep() diff --git a/mpisppy/cylinders/lagrangian_bounder.py b/mpisppy/cylinders/lagrangian_bounder.py index 91e819c51..6a5e5d2c3 100644 --- a/mpisppy/cylinders/lagrangian_bounder.py +++ b/mpisppy/cylinders/lagrangian_bounder.py @@ -11,7 +11,6 @@ class _LagrangianMixin: def lagrangian_prep(self): - verbose = self.opt.options['verbose'] # Split up PH_Prep? Prox option is important for APH. # Seems like we shouldn't need the Lagrangian stuff, so attach_prox=False # Scenarios are created here @@ -59,12 +58,8 @@ def _set_weights_and_solve(self): return self.lagrangian() def main(self): - # The rho_setter should be attached to the opt object - rho_setter = None - if hasattr(self.opt, 'rho_setter'): - rho_setter = self.opt.rho_setter - extensions = self.opt.extensions is not None verbose = self.opt.options['verbose'] + extensions = self.opt.extensions is not None self.lagrangian_prep() diff --git a/mpisppy/cylinders/lshaped_bounder.py b/mpisppy/cylinders/lshaped_bounder.py index dee891eb5..b4bc9c406 100644 --- a/mpisppy/cylinders/lshaped_bounder.py +++ b/mpisppy/cylinders/lshaped_bounder.py @@ -6,16 +6,9 @@ # All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md for # full copyright and license information. ############################################################################### -import logging -import time -import random -import mpisppy.log -import mpisppy.utils.sputils as sputils import mpisppy.cylinders.spoke as spoke from math import inf -from pyomo.opt import SolverFactory, SolverStatus, TerminationCondition -from mpisppy.phbase import PHBase from mpisppy.utils.xhat_eval import Xhat_Eval class XhatLShapedInnerBound(spoke.InnerBoundNonantSpoke): diff --git a/mpisppy/cylinders/ph_ob.py b/mpisppy/cylinders/ph_ob.py index 9616e713e..e22d0ee6f 100644 --- a/mpisppy/cylinders/ph_ob.py +++ b/mpisppy/cylinders/ph_ob.py @@ -12,14 +12,11 @@ # - use rho rescale factors written in a json file # - use gradient-based rho (to be tested) -import time import json -import csv import mpisppy.cylinders.spoke import mpisppy.utils.find_rho as find_rho import mpisppy.utils.gradient as grad from mpisppy.utils.wtracker import WTracker -from mpisppy import global_toc class PhOuterBound(mpisppy.cylinders.spoke.OuterBoundSpoke): """Updates its own W and x using its own rho. @@ -27,7 +24,6 @@ class PhOuterBound(mpisppy.cylinders.spoke.OuterBoundSpoke): converger_spoke_char = 'B' def ph_ob_prep(self): - verbose = self.opt.options['verbose'] # Scenarios are created here self.opt.PH_Prep(attach_prox=True) self.opt._reenable_W() @@ -43,7 +39,7 @@ def ph_ob_prep(self): # use gradient rho self.use_gradient_rho = False if "ph_ob_gradient_rho" in self.opt.options: - assert self.opt.options["ph_ob_gradient_rho"]["cfg"] != None, "You need to give a cfg to use gradient rho." + assert self.opt.options["ph_ob_gradient_rho"]["cfg"] is not None, "You need to give a cfg to use gradient rho." self.use_gradient_rho = True print("PH Outer Bounder uses an iterative gradient-based rho setter") self.cfg = self.opt.options["ph_ob_gradient_rho"]["cfg"] @@ -150,11 +146,6 @@ def _update_weights_and_solve(self, iternum): return bound def main(self): - # The rho_setter should be attached to the opt object - rho_setter = None - if hasattr(self.opt, 'rho_setter'): - rho_setter = self.opt.rho_setter - self.ph_ob_prep() self._rescale_rho(self.opt.options["ph_ob_initial_rho_rescale_factor"] ) diff --git a/mpisppy/cylinders/reduced_costs_spoke.py b/mpisppy/cylinders/reduced_costs_spoke.py index e0f4b80df..d504e1ba7 100644 --- a/mpisppy/cylinders/reduced_costs_spoke.py +++ b/mpisppy/cylinders/reduced_costs_spoke.py @@ -6,9 +6,7 @@ # All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md for # full copyright and license information. ############################################################################### -import math import pyomo.environ as pyo -from pyomo.common.collections import ComponentSet import numpy as np from mpisppy.cylinders.spcommunicator import communicator_array from mpisppy.cylinders.lagrangian_bounder import LagrangianOuterBound @@ -68,7 +66,6 @@ def lagrangian_prep(self): same as base class, but relax the integer variables and attach the reduced cost suffix """ - verbose = self.opt.options['verbose'] # Split up PH_Prep? Prox option is important for APH. # Seems like we shouldn't need the Lagrangian stuff, so attach_prox=False # Scenarios are created here @@ -137,4 +134,4 @@ def extract_and_store_reduced_costs(self, outer_bound): rcg = np.zeros(self.nonant_length) self.cylinder_comm.Allreduce(rc, rcg, op=MPI.SUM) - self.rc = rcg \ No newline at end of file + self.rc = rcg diff --git a/mpisppy/cylinders/slam_heuristic.py b/mpisppy/cylinders/slam_heuristic.py index 743b730c7..54f938118 100644 --- a/mpisppy/cylinders/slam_heuristic.py +++ b/mpisppy/cylinders/slam_heuristic.py @@ -8,18 +8,13 @@ ############################################################################### import abc import logging -import time -import random -import logging import mpisppy.log import mpisppy.utils.sputils as sputils import mpisppy.cylinders.spoke as spoke import mpisppy.MPI as mpi -import pyomo.environ as pyo import numpy as np from mpisppy.utils.xhat_eval import Xhat_Eval -from math import inf # Could also pass, e.g., sys.stdout instead of a filename mpisppy.log.setup_logger("mpisppy.cylinders.slam_heuristic", diff --git a/mpisppy/cylinders/spoke.py b/mpisppy/cylinders/spoke.py index 7dd95035d..1d59e58cb 100644 --- a/mpisppy/cylinders/spoke.py +++ b/mpisppy/cylinders/spoke.py @@ -9,12 +9,10 @@ import numpy as np import abc import enum -import logging import time import os import math -import mpisppy.utils.sputils as sputils from pyomo.environ import ComponentMap, Var from mpisppy import MPI @@ -231,7 +229,7 @@ def make_windows(self): raise RuntimeError("Provided SPBase object does not have local_scenarios attribute") if len(self.opt.local_scenarios) == 0: - raise RuntimeError(f"Rank has zero local_scenarios") + raise RuntimeError("Rank has zero local_scenarios") vbuflen = 2 for s in self.opt.local_scenarios.values(): diff --git a/mpisppy/cylinders/subgradient_bounder.py b/mpisppy/cylinders/subgradient_bounder.py index 4212e59f9..fc125c23b 100644 --- a/mpisppy/cylinders/subgradient_bounder.py +++ b/mpisppy/cylinders/subgradient_bounder.py @@ -14,10 +14,6 @@ class SubgradientOuterBound(_LagrangianMixin, mpisppy.cylinders.spoke.OuterBound converger_spoke_char = 'G' def main(self): - # The rho_setter should be attached to the opt object - rho_setter = None - if hasattr(self.opt, 'rho_setter'): - rho_setter = self.opt.rho_setter extensions = self.opt.extensions is not None verbose = self.opt.options['verbose'] diff --git a/mpisppy/cylinders/xhatlooper_bounder.py b/mpisppy/cylinders/xhatlooper_bounder.py index 8877da638..cfe5623dc 100644 --- a/mpisppy/cylinders/xhatlooper_bounder.py +++ b/mpisppy/cylinders/xhatlooper_bounder.py @@ -25,7 +25,6 @@ class XhatLooperInnerBound(spoke.InnerBoundNonantSpoke): converger_spoke_char = 'X' def xhatlooper_prep(self): - verbose = self.opt.options['verbose'] if "bundles_per_rank" in self.opt.options\ and self.opt.options["bundles_per_rank"] != 0: raise RuntimeError("xhat spokes cannot have bundles (yet)") @@ -56,7 +55,6 @@ def xhatlooper_prep(self): return xhatter def main(self): - verbose = self.opt.options["verbose"] # typing aid logger.debug(f"Entering main on xhatlooper spoke rank {self.global_rank}") xhatter = self.xhatlooper_prep() diff --git a/mpisppy/cylinders/xhatshufflelooper_bounder.py b/mpisppy/cylinders/xhatshufflelooper_bounder.py index a106c217a..764eff1a3 100644 --- a/mpisppy/cylinders/xhatshufflelooper_bounder.py +++ b/mpisppy/cylinders/xhatshufflelooper_bounder.py @@ -6,12 +6,9 @@ # All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md for # full copyright and license information. ############################################################################### -import os -import time import logging import random import mpisppy.log -import mpisppy.utils.sputils as sputils import mpisppy.cylinders.spoke as spoke from mpisppy.utils.xhat_eval import Xhat_Eval @@ -29,7 +26,6 @@ class XhatShuffleInnerBound(spoke.InnerBoundNonantSpoke): def xhatbase_prep(self): - verbose = self.opt.options['verbose'] if "bundles_per_rank" in self.opt.options\ and self.opt.options["bundles_per_rank"] != 0: raise RuntimeError("xhat spokes cannot have bundles (yet)") @@ -92,7 +88,6 @@ def _vb(msg): return update def main(self): - verbose = self.opt.options["verbose"] # typing aid logger.debug(f"Entering main on xhatshuffle spoke rank {self.global_rank}") self.xhatbase_prep() diff --git a/mpisppy/cylinders/xhatspecific_bounder.py b/mpisppy/cylinders/xhatspecific_bounder.py index ceb26251e..2add79d3f 100644 --- a/mpisppy/cylinders/xhatspecific_bounder.py +++ b/mpisppy/cylinders/xhatspecific_bounder.py @@ -40,7 +40,6 @@ def ib_prep(self): if not isinstance(self.opt, Xhat_Eval): raise RuntimeError("XhatShuffleInnerBound must be used with Xhat_Eval.") - verbose = self.opt.options['verbose'] xhatter = XhatSpecific(self.opt) # somehow deal with the prox option .... TBD .... important for aph APH @@ -71,7 +70,6 @@ def main(self): """ dtm = logging.getLogger(f'dtm{global_rank}') - verbose = self.opt.options["verbose"] # typing aid logging.debug("Enter xhatspecific main on rank {}".format(global_rank)) # What to try does not change, but the data in the scenarios should @@ -81,7 +79,6 @@ def main(self): xhatter = self.ib_prep() ib_iter = 1 # ib is for inner bound - got_kill_signal = False while (not self.got_kill_signal()): logging.debug(' IB loop iter={} on global rank {}'.\ format(ib_iter, global_rank)) diff --git a/mpisppy/cylinders/xhatxbar_bounder.py b/mpisppy/cylinders/xhatxbar_bounder.py index 558856a06..38621a3be 100644 --- a/mpisppy/cylinders/xhatxbar_bounder.py +++ b/mpisppy/cylinders/xhatxbar_bounder.py @@ -52,7 +52,6 @@ def ib_prep(self): if not isinstance(self.opt, Xhat_Eval): raise RuntimeError("XhatXbarInnerBound must be used with Xhat_Eval.") - verbose = self.opt.options['verbose'] xhatter = XhatXbar(self.opt) # somehow deal with the prox option .... TBD .... important for aph APH @@ -80,13 +79,11 @@ def main(self): """ dtm = logging.getLogger(f'dtm{global_rank}') - verbose = self.opt.options["verbose"] # typing aid logging.debug("Enter xhatxbar main on rank {}".format(global_rank)) xhatter = self.ib_prep() ib_iter = 1 # ib is for inner bound - got_kill_signal = False while (not self.got_kill_signal()): logging.debug(' IB loop iter={} on global rank {}'.\ format(ib_iter, global_rank)) diff --git a/mpisppy/extensions/cross_scen_extension.py b/mpisppy/extensions/cross_scen_extension.py index 0b94e7acd..9fe4ca718 100644 --- a/mpisppy/extensions/cross_scen_extension.py +++ b/mpisppy/extensions/cross_scen_extension.py @@ -10,7 +10,6 @@ from mpisppy.utils.sputils import find_active_objective from pyomo.repn.standard_repn import generate_standard_repn from pyomo.core.expr.numeric_expr import LinearExpression -from mpisppy import global_toc from mpisppy.cylinders.cross_scen_spoke import CrossScenarioCutSpoke import pyomo.environ as pyo @@ -166,7 +165,6 @@ def make_cuts(self, coefs): row_len = 1+1+self.nonant_len outer_iter = int(coefs[-1]) - bundling = opt.bundling if opt.bundling: for bn,b in opt.local_subproblems.items(): persistent_solver = sputils.is_persistent(b._solver_plugin) @@ -284,11 +282,14 @@ def post_iter0(self): _eta_init = { k: -v for k,v in valid_eta_bound.items() } else: _eta_init = valid_eta_bound - _eta_bounds = lambda m,k : (_eta_init[k], None) + def _eta_bounds(m, k): + return _eta_init[k], None else: lb = (-sys.maxsize - 1) * 1. / len(opt.all_scenario_names) - _eta_init = lambda m,k : lb - _eta_bounds = lambda m,k : (lb, None) + def _eta_init(m, k): + return lb + def _eta_bounds(m, k): + return lb, None # eta is attached to each subproblem, regardless of bundles bundling = opt.bundling diff --git a/mpisppy/extensions/fixer.py b/mpisppy/extensions/fixer.py index e7f90a99a..ab2963336 100644 --- a/mpisppy/extensions/fixer.py +++ b/mpisppy/extensions/fixer.py @@ -6,6 +6,11 @@ # All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md for # full copyright and license information. ############################################################################### + +import pyomo.environ as pyo +import mpisppy.utils.sputils as sputils +import mpisppy.extensions.extension + """ Code for WW style fixing of integers. This can be used as the only extension, but it could be called from a "multi" extension. @@ -19,10 +24,6 @@ For other iters, use count; None is also how you avoid. """ -import pyomo.environ as pyo -import mpisppy.utils.sputils as sputils -import mpisppy.extensions.extension - def Fixer_tuple(xvar, th=None, nb=None, lb=None, ub=None): """ Somewhat self-documenting way to make a fixer tuple. For use in/by/for the so-called Reference Model. @@ -118,7 +119,6 @@ def _dp(self, str): print ("(rank0) " + str) def _update_fix_counts(self): - nodesdone = [] # avoid multiple updates of a node's Vars for k,s in self.local_scenarios.items(): for ndn_i, xvar in s._mpisppy_data.nonant_indices.items(): if xvar.is_fixed(): @@ -148,7 +148,6 @@ def iter0(self, local_scenarios): if solver_is_persistent: vars_to_update = {} - fixoptions = self.fixeroptions # modelers might have already fixed variables - count those up and output the result raw_fixed_on_arrival = 0 raw_fixed_this_iter = 0 @@ -244,7 +243,6 @@ def iterk(self, PHIter): if solver_is_persistent: vars_to_update = {} - fixoptions = self.fixeroptions raw_fixed_this_iter = 0 self._update_fix_counts() for sname,s in self.local_scenarios.items(): @@ -260,7 +258,6 @@ def iterk(self, PHIter): except: print ("Are you trying to fix a Var that is not nonant?") raise - tolval = self.threshold[(ndn, i)] xvar = s._mpisppy_data.nonant_indices[ndn,i] if not xvar.is_fixed(): xb = pyo.value(s._mpisppy_model.xbars[(ndn,i)]) diff --git a/mpisppy/extensions/gradient_extension.py b/mpisppy/extensions/gradient_extension.py index c9dba8466..236e9b016 100644 --- a/mpisppy/extensions/gradient_extension.py +++ b/mpisppy/extensions/gradient_extension.py @@ -8,15 +8,11 @@ ############################################################################### import os -import time import numpy as np -import pyomo.environ as pyo -import mpisppy.MPI as MPI import mpisppy.extensions.extension import mpisppy.utils.gradient as grad import mpisppy.utils.find_rho as find_rho -import mpisppy.utils.sputils as sputils from mpisppy.utils.wtracker import WTracker from mpisppy import global_toc diff --git a/mpisppy/extensions/mipgapper.py b/mpisppy/extensions/mipgapper.py index c74e5ba52..ded606ee7 100644 --- a/mpisppy/extensions/mipgapper.py +++ b/mpisppy/extensions/mipgapper.py @@ -11,7 +11,6 @@ extension. """ -import pyomo.environ as pyo import mpisppy.extensions.extension class Gapper(mpisppy.extensions.extension.Extension): diff --git a/mpisppy/extensions/mult_rho_updater.py b/mpisppy/extensions/mult_rho_updater.py index 60eb8db62..b1e465265 100644 --- a/mpisppy/extensions/mult_rho_updater.py +++ b/mpisppy/extensions/mult_rho_updater.py @@ -11,11 +11,8 @@ # but only update when convergence improves # Preference given to user-supplied converger -import math import mpisppy.extensions.extension -import numpy as np -import mpisppy.MPI as MPI # for ph.options['mult_rho_options']: _mult_rho_defaults = { 'convergence_tolerance' : 1e-4, @@ -59,7 +56,7 @@ def _set_options(self): def _attach_rho_ratio_data(self, ph, conv): - if conv == None or conv == self._tol: + if conv is None or conv == self._tol: return self.first_c = conv if not self.ph.multistage: diff --git a/mpisppy/extensions/reduced_costs_fixer.py b/mpisppy/extensions/reduced_costs_fixer.py index 7cb82305d..6b36f053a 100644 --- a/mpisppy/extensions/reduced_costs_fixer.py +++ b/mpisppy/extensions/reduced_costs_fixer.py @@ -7,9 +7,7 @@ # full copyright and license information. ############################################################################### import numpy as np -import pandas as pd -from pyomo.common.collections import ComponentSet, ComponentMap from mpisppy.extensions.extension import Extension from mpisppy.cylinders.reduced_costs_spoke import ReducedCostsSpoke @@ -46,7 +44,7 @@ def __init__(self, spobj): if not (self._use_rc_bt or self._use_rc_fixer) and \ self.opt.cylinder_rank == 0: - print(f"Warning: ReducedCostsFixer will be idle. Enable use_rc_bt or use_rc_fixer in options.") + print("Warning: ReducedCostsFixer will be idle. Enable use_rc_bt or use_rc_fixer in options.") #self._options = rc_options @@ -99,7 +97,7 @@ def reduced_costs_bounds_tightening(self, reduced_costs, this_outer_bound): is_minimizing = self.opt.is_minimizing if np.isinf(inner_bound) or np.isinf(outer_bound): if self.opt.cylinder_rank == 0 and self.verbose: - print(f"Bounds tightened by reduced cost: 0 (inner or outer bound not available)") + print("Bounds tightened by reduced cost: 0 (inner or outer bound not available)") return for sub in self.opt.local_subproblems.values(): diff --git a/mpisppy/extensions/test_extension.py b/mpisppy/extensions/test_extension.py index 8f6d4ea11..d25c58f3d 100644 --- a/mpisppy/extensions/test_extension.py +++ b/mpisppy/extensions/test_extension.py @@ -10,9 +10,7 @@ # Not all extension points are guaranteed to be here (see the parent class) -import mpisppy.utils.sputils as sputils import mpisppy.extensions.xhatbase -import mpisppy.phbase as phbase class TestExtension(mpisppy.extensions.extension.Extension): """ diff --git a/mpisppy/extensions/wtracker_extension.py b/mpisppy/extensions/wtracker_extension.py index 709e37899..429521316 100644 --- a/mpisppy/extensions/wtracker_extension.py +++ b/mpisppy/extensions/wtracker_extension.py @@ -7,11 +7,9 @@ # full copyright and license information. ############################################################################### -import pyomo.environ as pyo import mpisppy.extensions.extension import mpisppy.utils.wtracker as wtracker -import mpisppy.utils.sputils as sputils class Wtracker_extension(mpisppy.extensions.extension.Extension): diff --git a/mpisppy/extensions/xhatbase.py b/mpisppy/extensions/xhatbase.py index 23d16272a..023a7f83f 100644 --- a/mpisppy/extensions/xhatbase.py +++ b/mpisppy/extensions/xhatbase.py @@ -35,8 +35,6 @@ def __init__(self, opt): self.n_proc = self.opt.n_proc self.verbose = self.opt.options["verbose"] - scen_count = len(opt.all_scenario_names) - self.scenario_name_to_rank = opt.scenario_names_to_rank # dict: scenario names --> LOCAL rank number (needed mainly for xhat) diff --git a/mpisppy/extensions/xhatspecific.py b/mpisppy/extensions/xhatspecific.py index 914896039..8149bbf59 100644 --- a/mpisppy/extensions/xhatspecific.py +++ b/mpisppy/extensions/xhatspecific.py @@ -47,7 +47,6 @@ def _vb(msg): print(" xhat_specific: " + msg) obj = None - sname = None _vb("Enter XhatSpecific.xhat_tryit to try: "+str(xhat_scenario_dict)) diff --git a/mpisppy/extensions/xhatxbar.py b/mpisppy/extensions/xhatxbar.py index 5875d77f3..563bb9d25 100644 --- a/mpisppy/extensions/xhatxbar.py +++ b/mpisppy/extensions/xhatxbar.py @@ -77,7 +77,6 @@ def _vb(msg): print(" xhat_xbar: " + msg) obj = None - sname = None _vb("Enter XhatXbar.xhat_tryit") @@ -100,7 +99,7 @@ def _vb(msg): self.opt._restore_nonants() return None else: - if verbose and src_rank == self.cylinder_rank: + if verbose and self.cylinder_rank == 0: print(" Feasible xhat found at xbar") obj = self.opt.Eobjective(verbose=verbose) if restore_nonants: diff --git a/mpisppy/fwph/fwph.py b/mpisppy/fwph/fwph.py index 7855db8de..ac3c29c0a 100644 --- a/mpisppy/fwph/fwph.py +++ b/mpisppy/fwph/fwph.py @@ -48,7 +48,6 @@ import pyomo.environ as pyo import time import re # For manipulating scenario names -from mpisppy import global_toc from mpisppy import MPI from pyomo.repn.standard_repn import generate_standard_repn @@ -85,7 +84,7 @@ def __init__( ph_converger=ph_converger, rho_setter=rho_setter, ) - assert (variable_probability == None), "variable probability is not allowed with fwph" + assert (variable_probability is None), "variable probability is not allowed with fwph" self._init(FW_options) def _init(self, FW_options): @@ -110,7 +109,7 @@ def fw_prep(self): if (check): self._check_initial_points() self._create_solvers() - self._use_rho_setter(verbose and self.cylinder_rank==0) + self._use_rho_setter(self.options['verbose'] and self.cylinder_rank==0) self._initialize_MIP_var_values() best_bound = -np.inf if self.is_minimizing else np.inf else: @@ -202,7 +201,6 @@ def fwph_main(self): secs = time.time() - self.t0 self._output(itr+1, self._local_bound, best_bound, diff, secs) self.Update_W(self.options['verbose']) - timed_out = self._is_timed_out() if (self._is_timed_out()): if (self.cylinder_rank == 0 and self.vb): print('Timeout.') @@ -430,7 +428,7 @@ def _attach_MIP_vars(self): leaf_var_dict = {(scenario_name, 'LEAF', ix): var for ix, var in enumerate(self._get_leaf_vars(mip))} EF.leaf_vars.update(leaf_var_dict) - EF.num_leaf_vars[scenario_name] = len(leaf_vars_dict) + EF.num_leaf_vars[scenario_name] = len(leaf_var_dict) # Reference variables are already attached: EF.ref_vars # indexed by (node_name, index) else: @@ -466,7 +464,6 @@ def _check_initial_points(self): points = {key: value for block in init_pts for (key, value) in block.items()} scenario_names = points.keys() - num_scenarios = len(points) # Some index sets we will need.. conv_ix = [(scenario_name, var_name) diff --git a/mpisppy/generic_cylinders.py b/mpisppy/generic_cylinders.py index 3d9c6a37e..95200edbc 100644 --- a/mpisppy/generic_cylinders.py +++ b/mpisppy/generic_cylinders.py @@ -17,6 +17,8 @@ import mpisppy.utils.cfg_vanilla as vanilla import mpisppy.utils.config as config import mpisppy.utils.sputils as sputils +from mpisppy.convergers.norm_rho_converger import NormRhoConverger +from mpisppy.convergers.primal_dual_converger import PrimalDualConverger from mpisppy.extensions.extension import MultiExtension from mpisppy.extensions.fixer import Fixer from mpisppy.extensions.mipgapper import Gapper @@ -107,8 +109,6 @@ def _do_decomp(module, cfg, scenario_creator, scenario_creator_kwargs, scenario_ else: ph_converger = None - fwph = cfg.fwph - all_scenario_names, all_nodenames = _name_lists(module, cfg) # Things needed for vanilla cylinders @@ -282,6 +282,8 @@ def _do_EF(module, cfg, scenario_creator, scenario_creator_kwargs, scenario_deno results = solver.solve(tee=cfg.tee_EF) else: results = solver.solve(ef, tee=cfg.tee_EF, symbolic_solver_labels=True,) + if not pyo.check_optimal_termination(results): + print("Warning: non-optimal solver termination") global_toc(f"EF objective: {pyo.value(ef.EF_Obj)}") if cfg.solution_base_name is not None: @@ -297,8 +299,8 @@ def _bad_news(): "--module-name foo\n" "or\n" "--module-name=foo") - def _len_check(l): - if len(sys.argv) <= l: + def _len_check(needed_length): + if len(sys.argv) <= needed_length: _bad_news() else: return True @@ -327,7 +329,8 @@ def _len_check(l): # TBD: when agnostic is merged, use the function and delete the code lines # module = sputils.module_name_to_module(model_fname) # TBD: do the sys.path.append trick in sputils - import importlib, inspect + import importlib + import inspect if inspect.ismodule(model_fname): module = model_fname else: diff --git a/mpisppy/log.py b/mpisppy/log.py index 1c1d5d3c9..bd1398dce 100644 --- a/mpisppy/log.py +++ b/mpisppy/log.py @@ -61,13 +61,13 @@ def setup_logger(name, out, level=logging.DEBUG, mode='w', fmt=None): ''' if fmt is None: fmt = "(%(asctime)s) %(message)s" - l = logging.getLogger(name) - l.setLevel(level) - l.propagate = False + log = logging.getLogger(name) + log.setLevel(level) + log.propagate = False formatter = logging.Formatter(fmt) if out in (sys.stdout, sys.stderr): handler = logging.StreamHandler(out) else: # out is a filename handler = logging.FileHandler(out, mode=mode) handler.setFormatter(formatter) - l.addHandler(handler) + log.addHandler(handler) diff --git a/mpisppy/opt/aph.py b/mpisppy/opt/aph.py index 44d66fdf9..9539c9c5d 100644 --- a/mpisppy/opt/aph.py +++ b/mpisppy/opt/aph.py @@ -13,15 +13,11 @@ import collections import time import logging -import datetime as dt -import mpisppy import mpisppy.MPI as mpi import pyomo.environ as pyo -from pyomo.opt import SolverFactory, SolverStatus import mpisppy.utils.listener_util.listener_util as listener_util import mpisppy.phbase as ph_base import mpisppy.utils.sputils as sputils -import mpisppy.utils.wxbarutils as wxbarutils fullcomm = mpi.COMM_WORLD global_rank = fullcomm.Get_rank() @@ -245,8 +241,6 @@ def _calculate_APHgamma(self, synchro): uk = self.global_pusqnorm vk = self.global_pvsqnorm - wk = self.global_pwsqnorm - zk = self.global_pzsqnorm # Note June, 2023: We are waiting until we get values greater # than 0 for the norms. Iteration 3 is arbitrary @@ -847,7 +841,7 @@ def _print_conv_detail(self): if pwnorm > 0 and pznorm > 0: print(f" scaled U term={punorm / pwnorm}; scaled V term={pvnorm / pznorm}") else: - print(f" ! convergence metric cannot be computed due to zero-divide") + print(" ! convergence metric cannot be computed due to zero-divide") #======== @@ -943,7 +937,6 @@ def APH_iterk(self, spcomm): break if have_converger: if self.convobject.is_converged(): - converged = True if self.cylinder_rank == 0: print("User-supplied converger determined termination criterion reached") break @@ -954,7 +947,7 @@ def APH_iterk(self, spcomm): self.extobject.miditer() teeme = ("tee-rank0-solves" in self.options) \ - and (self.options["tee-rank0-solves"] == True + and (self.options["tee-rank0-solves"] and self.cylinder_rank == 0) # Let the solve loop deal with persistent solvers & signal handling # Aug2020 switch to a partial loop xxxxx maybe that is enough..... diff --git a/mpisppy/opt/lshaped.py b/mpisppy/opt/lshaped.py index dfcb141d7..c79a8a21c 100644 --- a/mpisppy/opt/lshaped.py +++ b/mpisppy/opt/lshaped.py @@ -20,7 +20,7 @@ from mpisppy.utils.lshaped_cuts import LShapedCutGenerator from mpisppy.spopt import set_instance_retry from pyomo.core import ( - Objective, SOSConstraint, Constraint, Var + SOSConstraint, Constraint, Var ) from pyomo.core.expr.visitor import identify_variables from pyomo.repn.standard_repn import generate_standard_repn @@ -126,7 +126,7 @@ def __init__( self.has_root_scens = self.root_scenarios is not None if self.store_subproblems: - self.subproblems = dict.fromkeys(scenario_names) + self.subproblems = {} def options_check(self): """ Check to ensure that the user-specified options are valid. Requried diff --git a/mpisppy/opt/ph.py b/mpisppy/opt/ph.py index 2d768f5ea..d08373105 100644 --- a/mpisppy/opt/ph.py +++ b/mpisppy/opt/ph.py @@ -136,12 +136,11 @@ def ph_main(self, finalize=True): try: shutil.rmtree("delme_diagdir") print ("...deleted delme_diagdir") - except: + except Exception: pass ph.options["diagnoser_options"] = {"diagnoser_outdir": "delme_diagdir"} conv, obj, bnd = ph.ph_main() - import mpisppy.extensions.avgminmaxer as minmax_extension from mpisppy.extensions.avgminmaxer import MinMaxAvg ph = PH(PHopt, all_scenario_names, scenario_creator, scenario_denouement, extensions=MinMaxAvg, diff --git a/mpisppy/phbase.py b/mpisppy/phbase.py index 04108ed2f..d0f8b18bf 100644 --- a/mpisppy/phbase.py +++ b/mpisppy/phbase.py @@ -15,7 +15,6 @@ import pyomo.environ as pyo import mpisppy.utils.sputils as sputils -import mpisppy.utils.listener_util.listener_util as listener_util import mpisppy.spopt from mpisppy.utils.prox_approx import ProxApproxManager @@ -909,7 +908,6 @@ def _vb(msg): for ndn_i, _ in scenario._mpisppy_data.nonant_indices.items(): scenario._mpisppy_model.p[ndn_i] *= scenario._mpisppy_model.rho[ndn_i] - converged = False if have_converger: # Call the constructor of the converger object self.convobject = self.ph_converger(self) @@ -991,12 +989,10 @@ def iterk_loop(self): # latest data, even at termination if have_converger: if self.convobject.is_converged(): - converged = True global_toc("User-supplied converger determined termination criterion reached", self.cylinder_rank == 0) break elif self.conv is not None: if self.conv < self.options["convthresh"]: - converged = True global_toc("Convergence metric=%f dropped below user-supplied threshold=%f" % (self.conv, self.options["convthresh"]), self.cylinder_rank == 0) break diff --git a/mpisppy/scenario_tree.py b/mpisppy/scenario_tree.py index 56ad03939..febc2ffd0 100644 --- a/mpisppy/scenario_tree.py +++ b/mpisppy/scenario_tree.py @@ -9,11 +9,12 @@ # scenario_tree.py; PySP 2.0 scenario structure # ALL INDEXES ARE ZERO-BASED import logging -logger = logging.getLogger('mpisppy.scenario_tree') import pyomo.environ as pyo from pyomo.core.base.indexed_component_slice import IndexedComponent_slice +logger = logging.getLogger('mpisppy.scenario_tree') + def build_vardatalist(self, model, varlist=None): """ Convert a list of pyomo variables to a list of SimpleVar and _GeneralVarData. If varlist is none, builds a diff --git a/mpisppy/spbase.py b/mpisppy/spbase.py index f2475e087..5de8203b7 100644 --- a/mpisppy/spbase.py +++ b/mpisppy/spbase.py @@ -12,9 +12,7 @@ import time import logging import weakref -import math import numpy as np -import re import pyomo.environ as pyo import mpisppy.utils.sputils as sputils from mpisppy import global_toc @@ -517,7 +515,7 @@ def _look_and_leap(self): scenario._mpisppy_model = pyo.Block(name="For mpi-sppy Pyomo additions to the scenario model") if hasattr(scenario, "PySP_prob"): - raise RuntimeError(f"PySP_prob is deprecated; use _mpisppy_probability") + raise RuntimeError("PySP_prob is deprecated; use _mpisppy_probability") pspec = scenario._mpisppy_probability if hasattr(scenario, "_mpisppy_probability") else None if pspec is None or pspec == "uniform": prob = 1./len(self.all_scenario_names) @@ -627,7 +625,7 @@ def report_var_values_at_rank0(self, header="", print_zero_prob_values=False): print("{0: ^{width}s}".format("-", width=value_field_len), end='') else: this_var_value = var_values[this_scenario, this_var] - if (this_var_value == None) and (not print_zero_prob_values): + if (this_var_value is None) and (not print_zero_prob_values): print("{0: ^{width}s}".format("-", width=value_field_len), end='') else: print("{0: {width}.4f}".format(this_var_value, width=value_field_len), end='') diff --git a/mpisppy/spopt.py b/mpisppy/spopt.py index ea1deb3fd..2032d9fe5 100644 --- a/mpisppy/spopt.py +++ b/mpisppy/spopt.py @@ -20,7 +20,6 @@ import pyomo.environ as pyo from pyomo.opt import SolverFactory -from mpisppy import global_toc from mpisppy.spbase import SPBase import mpisppy.utils.sputils as sputils @@ -89,7 +88,7 @@ def _check_staleness(self, s): else: try: float(pyo.value(v)) - except: + except Exception: raise RuntimeError( f"Non-anticipative variable {v.name} on scenario {s.name} " "reported as stale. This usually means this variable " @@ -749,7 +748,7 @@ def _restore_original_nonants(self): for ci, vardata in enumerate(s._mpisppy_data.nonant_indices.values()): vardata._value = s._mpisppy_data.original_nonants[ci] vardata.fixed = s._mpisppy_data.original_fixedness[ci] - if persistent_solver != None: + if persistent_solver is not None: persistent_solver.update_var(vardata) @@ -922,7 +921,7 @@ def set_instance_retry(subproblem, solver_plugin, subproblem_name): break # pyomo presently has no general way to trap a license acquisition # error - so we're stuck with trapping on "any" exception. not ideal. - except: + except Exception: if num_retry_attempts == 0: print("Failed to acquire solver license (call to set_instance() for scenario=%s) after first attempt" % (sname)) else: diff --git a/mpisppy/tests/examples/aircond.py b/mpisppy/tests/examples/aircond.py index 99b841c6e..11c36eab0 100644 --- a/mpisppy/tests/examples/aircond.py +++ b/mpisppy/tests/examples/aircond.py @@ -17,7 +17,6 @@ import mpisppy.utils.sputils as sputils import mpisppy.utils.amalgamator as amalgamator import argparse -from mpisppy import global_toc from mpisppy.utils import config import pyomo.common.config as pyofig @@ -193,8 +192,6 @@ def aircond_model_creator(demands, **kwargs): # create a single aircond model for the given demands # branching_factors=None, num_scens=None, mu_dev=0, sigma_dev=40, start_seed=0, start_ups=None): # typing aids... - start_seed = kwargs["start_seed"] - start_ups = kwargs.get("start_ups", parms["start_ups"][1]) model = pyo.ConcreteModel() @@ -311,7 +308,6 @@ def MakeNodesforScen(model,nodenames,branching_factors,starting_stage=1): def scenario_creator(sname, **kwargs): - start_seed = kwargs['start_seed'] if "branching_factors" not in kwargs: raise RuntimeError("scenario_creator for aircond needs branching_factors in kwargs") branching_factors = kwargs["branching_factors"] @@ -358,7 +354,7 @@ def sample_tree_scen_creator(sname, stage, sample_branching_factors, seed, if stage == 1: past_demands = [starting_d] else: - raise RuntimeError(f"sample_tree_scen_creator for aircond needs a 'given_scenario' argument if the starting stage is greater than 1") + raise RuntimeError("sample_tree_scen_creator for aircond needs a 'given_scenario' argument if the starting stage is greater than 1") else: past_demands = [given_scenario.stage_models[t].Demand for t in given_scenario.T if t<=stage] @@ -594,8 +590,8 @@ def xhat_generator_aircond(scenario_names, solver_name=None, solver_options=None print('start ups costs: ', start_ups) print('branching factors: ', bfs) print('run time: ', time.time()-t0) - print(f"inner bound =", ama.best_inner_bound) - print(f"outer bound =", ama.best_outer_bound) + print("inner bound =", ama.best_inner_bound) + print("outer bound =", ama.best_outer_bound) xhat = sputils.nonant_cache_from_ef(ama.ef) print('xhat_one = ', xhat['ROOT']) diff --git a/mpisppy/tests/examples/aircondB.py b/mpisppy/tests/examples/aircondB.py index 65cf217bf..4a1805cba 100644 --- a/mpisppy/tests/examples/aircondB.py +++ b/mpisppy/tests/examples/aircondB.py @@ -13,16 +13,11 @@ # exccept Last Inventory cost, which should be negative. import os import numpy as np -import time import pyomo.environ as pyo -import mpisppy.scenario_tree as scenario_tree import mpisppy.utils.sputils as sputils -import mpisppy.utils.amalgamator as amalgamator import mpisppy.utils.pickle_bundle as pickle_bundle import mpisppy.tests.examples.aircond as base_aircond from mpisppy.utils.sputils import attach_root_node -from mpisppy.utils import config -from mpisppy import global_toc # Use this random stream: aircondstream = np.random.RandomState() @@ -201,7 +196,7 @@ def scenario_names_creator(num_scens,start=None): def inparser_adder(cfg): base_aircond.inparser_adder(cfg) # special "proper" bundle arguments - pickle_bundle.pickle_bundle_parser(cfg) + pickle_bundle.pickle_bundle_config(cfg) #========= diff --git a/mpisppy/tests/examples/distr.py b/mpisppy/tests/examples/distr.py index 95fd7dfdb..c6f81a7fd 100644 --- a/mpisppy/tests/examples/distr.py +++ b/mpisppy/tests/examples/distr.py @@ -368,12 +368,12 @@ def consensus_vars_creator(num_scens): vstr = f"y[{dummy_node}]" #variable name as string, y is the slack #adds dummy_node in the source region - if not region_source in consensus_vars: #initiates consensus_vars[region_source] + if region_source not in consensus_vars: #initiates consensus_vars[region_source] consensus_vars[region_source] = list() consensus_vars[region_source].append(vstr) #adds dummy_node in the target region - if not region_target in consensus_vars: #initiates consensus_vars[region_target] + if region_target not in consensus_vars: #initiates consensus_vars[region_target] consensus_vars[region_target] = list() consensus_vars[region_target].append(vstr) return consensus_vars @@ -401,7 +401,7 @@ def kw_creator(cfg): """ kwargs = {"num_scens" : cfg.get('num_scens', None), } - if not kwargs["num_scens"] in [2, 3, 4]: + if kwargs["num_scens"] not in [2, 3, 4]: RuntimeError (f"unexpected number of regions {cfg.num_scens}, whould be in [2, 3, 4]") return kwargs diff --git a/mpisppy/tests/examples/farmer.py b/mpisppy/tests/examples/farmer.py index 1113115b0..ce0dc47a7 100644 --- a/mpisppy/tests/examples/farmer.py +++ b/mpisppy/tests/examples/farmer.py @@ -25,7 +25,6 @@ import numpy as np import mpisppy.scenario_tree as scenario_tree import mpisppy.utils.sputils as sputils -from mpisppy.utils import config # Use this random stream: farmerstream = np.random.RandomState() diff --git a/mpisppy/tests/examples/gbd/gbd.py b/mpisppy/tests/examples/gbd/gbd.py index 86c0c4f6f..9ced77d94 100644 --- a/mpisppy/tests/examples/gbd/gbd.py +++ b/mpisppy/tests/examples/gbd/gbd.py @@ -288,8 +288,8 @@ def xhat_generator_gbd(scenario_names, solver_name="gurobi", solver_options=None #Correcting the building by putting the right scenarios. ama.scenario_names = scenario_names ama.run() - print(f"inner bound=", ama.best_inner_bound) - print(f"outer bound=", ama.best_outer_bound) + print("inner bound=", ama.best_inner_bound) + print("outer bound=", ama.best_outer_bound) xhat = sputils.nonant_cache_from_ef(ama.ef) print("xhat=",xhat['ROOT']) diff --git a/mpisppy/tests/examples/sizes/sizes.py b/mpisppy/tests/examples/sizes/sizes.py index 392fe2e07..817043c19 100644 --- a/mpisppy/tests/examples/sizes/sizes.py +++ b/mpisppy/tests/examples/sizes/sizes.py @@ -24,7 +24,7 @@ def scenario_creator(scenario_name, scenario_count=None): datadir = os.sep.join((sizes_dir, f"SIZES{scenario_count}")) try: fname = datadir + os.sep + scenario_name + ".dat" - except: + except Exception: print("FAIL: datadir=", datadir, " scenario_name=", scenario_name) model = ref.model.create_instance(fname) diff --git a/mpisppy/tests/examples/stoch_distr/stoch_distr.py b/mpisppy/tests/examples/stoch_distr/stoch_distr.py index 6aaca0055..01cbe47f0 100644 --- a/mpisppy/tests/examples/stoch_distr/stoch_distr.py +++ b/mpisppy/tests/examples/stoch_distr/stoch_distr.py @@ -247,7 +247,7 @@ def region_dict_creator(admm_subproblem_name): #in this precise example region_d def _scenario_number(stoch_scenario_name, demand=None): - if demand == None: + if demand is None: scennum = sputils.extract_num(stoch_scenario_name) else: # 3-stage production_num = int(re.search(r'\d+', stoch_scenario_name).group()) @@ -417,7 +417,7 @@ def branching_factors_creator(num_stoch_scens, num_stage): # BFs is only used with multiple stages if num_stage == 3: # There should always be a high demand and a low demand version - assert num_stoch_scens % 2 == 0, f"there should be an even number of stochastic scenarios for this 3 stage problem, but it is odd" + assert num_stoch_scens % 2 == 0, "there should be an even number of stochastic scenarios for this 3 stage problem, but it is odd" BFs = [num_stoch_scens//2, 2] elif num_stage == 2: BFs = None # No need to use branching factors (or even to define them with two stage problems) @@ -496,12 +496,12 @@ def consensus_vars_creator(admm_subproblem_names, stoch_scenario_name, kwargs, n vstr = f"y[{dummy_node}]" #variable name as string, y is the slack #adds dummy_node in the source region - if not region_source in consensus_vars: #initiates consensus_vars[region_source] + if region_source not in consensus_vars: #initiates consensus_vars[region_source] consensus_vars[region_source] = list() consensus_vars[region_source].append((vstr,num_stage)) #adds dummy_node in the target region - if not region_target in consensus_vars: #initiates consensus_vars[region_target] + if region_target not in consensus_vars: #initiates consensus_vars[region_target] consensus_vars[region_target] = list() consensus_vars[region_target].append((vstr,num_stage)) # now add the parents. It doesn't depend on the stochastic scenario so we chose one and @@ -514,7 +514,7 @@ def consensus_vars_creator(admm_subproblem_names, stoch_scenario_name, kwargs, n for var in node.nonant_list: #print(f"{admm_subproblem_name=}") #print(f"{var.name=}") - if not var.name in consensus_vars[admm_subproblem_name]: + if var.name not in consensus_vars[admm_subproblem_name]: consensus_vars[admm_subproblem_name].append((var.name, node.stage)) return consensus_vars diff --git a/mpisppy/tests/examples/stoch_distr/stoch_distr_admm_cylinders.py b/mpisppy/tests/examples/stoch_distr/stoch_distr_admm_cylinders.py index 17d99891f..207ec360f 100644 --- a/mpisppy/tests/examples/stoch_distr/stoch_distr_admm_cylinders.py +++ b/mpisppy/tests/examples/stoch_distr/stoch_distr_admm_cylinders.py @@ -18,7 +18,6 @@ import mpisppy.utils.stoch_admmWrapper as stoch_admmWrapper # import stoch_distr ## It is necessary for the test to have the full direction import mpisppy.tests.examples.stoch_distr.stoch_distr as stoch_distr -import mpisppy.cylinders from mpisppy.spin_the_wheel import WheelSpinner import mpisppy.utils.sputils as sputils diff --git a/mpisppy/tests/examples/stoch_distr/stoch_distr_ef.py b/mpisppy/tests/examples/stoch_distr/stoch_distr_ef.py index 4839b2786..19af1eafe 100644 --- a/mpisppy/tests/examples/stoch_distr/stoch_distr_ef.py +++ b/mpisppy/tests/examples/stoch_distr/stoch_distr_ef.py @@ -15,8 +15,6 @@ # Solves the stochastic distribution problem import stoch_distr import stoch_distr_admm_cylinders -import examples.distr.distr_data as distr_data -import mpisppy.cylinders import pyomo.environ as pyo import mpisppy.utils.sputils as sputils diff --git a/mpisppy/tests/examples/uc/uc_funcs.py b/mpisppy/tests/examples/uc/uc_funcs.py index d34644728..3d419d11a 100644 --- a/mpisppy/tests/examples/uc/uc_funcs.py +++ b/mpisppy/tests/examples/uc/uc_funcs.py @@ -14,7 +14,6 @@ from pyomo.dataportal import DataPortal -import mpisppy.scenario_tree as scenario_tree import pyomo.environ as pyo import mpisppy.utils.sputils as sputils @@ -103,7 +102,6 @@ def scenario_rhos(scenario_instance, rho_scale_factor=0.1): computed_rhos = [] for t in scenario_instance.TimePeriods: for g in scenario_instance.ThermalGenerators: - max_capacity = pyo.value(scenario_instance.MaximumPowerOutput[g,t]) min_power = pyo.value(scenario_instance.MinimumPowerOutput[g,t]) max_power = pyo.value(scenario_instance.MaximumPowerOutput[g,t]) avg_power = min_power + ((max_power - min_power) / 2.0) @@ -136,7 +134,7 @@ def scenario_rhos_trial_from_file(scenario_instance, rho_scale_factor=0.01, rho_scale_factor=rho_scale_factor) try: trial_rhos = _get_saved_rhos(fname) - except: + except Exception: raise RuntimeError('Formatting issue in specified rho file ' + fname + '. Format should be (variable_name,rho_value) for ' 'each row, with no blank lines, and no ' @@ -147,7 +145,6 @@ def scenario_rhos_trial_from_file(scenario_instance, rho_scale_factor=0.01, for t in sorted(scenario_instance.TimePeriods): for g in sorted(scenario_instance.ThermalGeneratorsAtBus[b]): var = scenario_instance.UnitOn[g,t] - computed_rho = computed_rhos[index] try: trial_rho = trial_rhos[var.name] except KeyError: diff --git a/mpisppy/tests/examples/w_test_data/farmer_get.py b/mpisppy/tests/examples/w_test_data/farmer_get.py index 70e77b34a..4099e7eda 100644 --- a/mpisppy/tests/examples/w_test_data/farmer_get.py +++ b/mpisppy/tests/examples/w_test_data/farmer_get.py @@ -9,7 +9,6 @@ # general example driver for farmer with cylinders import farmer -import mpisppy.cylinders # Make it all go from mpisppy.spin_the_wheel import WheelSpinner @@ -89,7 +88,6 @@ def main(): 'use_integer': False, "crops_multiplier": crops_multiplier, } - scenario_names = [f"Scenario{i+1}" for i in range(num_scen)] # Things needed for vanilla cylinders beans = (cfg, scenario_creator, scenario_denouement, all_scenario_names) diff --git a/mpisppy/tests/examples/w_test_data/farmer_set.py b/mpisppy/tests/examples/w_test_data/farmer_set.py index e97d84b89..f28373dac 100644 --- a/mpisppy/tests/examples/w_test_data/farmer_set.py +++ b/mpisppy/tests/examples/w_test_data/farmer_set.py @@ -9,7 +9,6 @@ # general example driver for farmer with cylinders import farmer -import mpisppy.cylinders # Make it all go from mpisppy.spin_the_wheel import WheelSpinner @@ -91,8 +90,6 @@ def main(): 'use_integer': False, "crops_multiplier": crops_multiplier, } - scenario_names = [f"Scenario{i+1}" for i in range(num_scen)] - multi_ext = {"ext_classes" : [WXBarWriter, WXBarReader]} diff --git a/mpisppy/tests/helper_extension.py b/mpisppy/tests/helper_extension.py index f945c081b..958840ad8 100644 --- a/mpisppy/tests/helper_extension.py +++ b/mpisppy/tests/helper_extension.py @@ -9,9 +9,7 @@ # This is an extension to be used for testing. from collections import defaultdict -import mpisppy.utils.sputils as sputils import mpisppy.extensions.xhatbase -import mpisppy.phbase as phbase class TestHelperExtension(mpisppy.extensions.extension.Extension): """ diff --git a/mpisppy/tests/straight_tests.py b/mpisppy/tests/straight_tests.py index d4d015fbf..5f525b6ef 100644 --- a/mpisppy/tests/straight_tests.py +++ b/mpisppy/tests/straight_tests.py @@ -9,10 +9,8 @@ # straight smoke tests (with no unittest, which is a bummer but we need mpiexec) import os -import sys -import tempfile -from mpisppy.tests.utils import get_solver, round_pos_sig +from mpisppy.tests.utils import get_solver solver_available, solver_name, persistent_available, persistent_solver_name= get_solver() badguys = list() diff --git a/mpisppy/tests/test_admmWrapper.py b/mpisppy/tests/test_admmWrapper.py index 42e5300c4..1371f2653 100644 --- a/mpisppy/tests/test_admmWrapper.py +++ b/mpisppy/tests/test_admmWrapper.py @@ -142,7 +142,7 @@ def test_values(self): objectives["EF objective"] = float(decomposed_line[1]) try: correct_order = objectives["outer bound"] <= objectives["EF objective"] <= objectives["inner bound"] - except: + except Exception: raise RuntimeError("The output could not be read to capture the values") assert correct_order, f' We obtained {objectives["outer bound"]=}, {objectives["EF objective"]=}, {objectives["inner bound"]=}' os.chdir(original_dir) diff --git a/mpisppy/tests/test_aph.py b/mpisppy/tests/test_aph.py index 4e3743308..8d43711d7 100644 --- a/mpisppy/tests/test_aph.py +++ b/mpisppy/tests/test_aph.py @@ -17,19 +17,17 @@ import unittest from math import log10, floor -import pyomo.environ as pyo import mpisppy.opt.aph import mpisppy.phbase from mpisppy.tests.examples.sizes.sizes import scenario_creator, \ - scenario_denouement, \ - _rho_setter + scenario_denouement import mpisppy.tests.examples.farmer as farmer -from mpisppy.tests.utils import get_solver, round_pos_sig +from mpisppy.tests.utils import get_solver +import mpisppy.MPI as mpi __version__ = 0.6 solver_available, solver_name, persistent_available, persistent_solver_name= get_solver() -import mpisppy.MPI as mpi fullcomm = mpi.COMM_WORLD global_rank = fullcomm.Get_rank() @@ -80,6 +78,7 @@ def test_make_aph(self): scenario_denouement, scenario_creator_kwargs={"scenario_count": 3}, ) + assert aph is not None @unittest.skipIf(not solver_available, "%s solver is not available" % (solver_name,)) @@ -147,7 +146,6 @@ def test_use_lag(self): options["PHIterLimit"] = 2 options["async_frac_needed"] = 0.5 options["async_sleep_secs"] = 0.5 - a = 2 options["APHuse_lag"] = True aph = mpisppy.opt.aph.APH( options, diff --git a/mpisppy/tests/test_conf_int_aircond.py b/mpisppy/tests/test_conf_int_aircond.py index 497710b52..6e5c741e0 100644 --- a/mpisppy/tests/test_conf_int_aircond.py +++ b/mpisppy/tests/test_conf_int_aircond.py @@ -15,17 +15,13 @@ import tempfile import numpy as np import unittest -import subprocess -import importlib -import mpisppy.MPI as mpi from mpisppy.tests.utils import get_solver, round_pos_sig import mpisppy.utils.sputils as sputils import mpisppy.tests.examples.aircond as aircond import mpisppy.confidence_intervals.mmw_ci as MMWci -import mpisppy.confidence_intervals.zhat4xhat as zhat4xhat import mpisppy.utils.amalgamator as ama from mpisppy.utils.xhat_eval import Xhat_Eval import mpisppy.confidence_intervals.seqsampling as seqsampling @@ -135,6 +131,7 @@ def test_ama_creator(self): ama_object = ama.from_module(self.refmodelname, cfg=options, use_command_line=False) + assert ama_object is not None def test_MMW_constructor(self): options, scenario_creator_kwargs = self._get_base_options() @@ -144,10 +141,9 @@ def test_MMW_constructor(self): options, xhat, options['num_batches'], batch_size = options["batch_size"], start = options['num_scens']) + assert MMW is not None def test_seqsampling_creator(self): - BFs = [4, 3, 2] - xhat_gen_options = self._get_xhat_gen_options(BFs) optionsBM = config.Config() confidence_config.confidence_config(optionsBM) confidence_config.sequential_config(optionsBM) @@ -173,8 +169,6 @@ def test_seqsampling_creator(self): def test_indepscens_seqsampling_creator(self): options, scenario_creator_kwargs = self._get_base_options() - branching_factors= global_BFs - xhat_gen_options = self._get_xhat_gen_options(branching_factors) # We want a very small instance for testing on GitHub. optionsBM = config.Config() @@ -215,6 +209,7 @@ def test_ama_running(self): "no solver is available") def test_xhat_eval_creator(self): ev = self._eval_creator() + assert ev is not None @unittest.skipIf(not solver_available, diff --git a/mpisppy/tests/test_conf_int_farmer.py b/mpisppy/tests/test_conf_int_farmer.py index 118033326..e130b9277 100644 --- a/mpisppy/tests/test_conf_int_farmer.py +++ b/mpisppy/tests/test_conf_int_farmer.py @@ -15,8 +15,6 @@ import tempfile import numpy as np import unittest -import subprocess -import importlib import pyomo.environ as pyo import mpisppy.MPI as mpi @@ -25,7 +23,6 @@ import mpisppy.tests.examples.farmer as farmer import mpisppy.confidence_intervals.mmw_ci as MMWci -import mpisppy.confidence_intervals.zhat4xhat as zhat4xhat import mpisppy.utils.amalgamator as ama from mpisppy.utils.xhat_eval import Xhat_Eval import mpisppy.confidence_intervals.seqsampling as seqsampling @@ -91,6 +88,7 @@ def test_MMW_constructor(self): cfg, xhat, cfg['num_batches'], batch_size = cfg["batch_size"], start = cfg['num_scens']) + assert MMW is not None def test_xhat_read_write(self): path = tempfile.mkstemp(prefix="xhat",suffix=".npy")[1] @@ -111,6 +109,7 @@ def test_ama_creator(self): ama_object = ama.from_module(self.refmodelname, cfg=ama_options, use_command_line=False) + assert ama_object is not None def test_seqsampling_creator(self): optionsBM = config.Config() @@ -168,6 +167,7 @@ def test_xhat_eval_creator(self): scenario_denouement=None, scenario_creator_kwargs=scenario_creator_kwargs ) + assert ev is not None @unittest.skipIf(not solver_available, "no solver is available") diff --git a/mpisppy/tests/test_ef_ph.py b/mpisppy/tests/test_ef_ph.py index bc945884e..8a1154688 100644 --- a/mpisppy/tests/test_ef_ph.py +++ b/mpisppy/tests/test_ef_ph.py @@ -92,7 +92,7 @@ def test_disable_tictoc(self): options = self._copy_of_base_options() options["PHIterLimit"] = 0 - ph = mpisppy.opt.ph.PH( + mpisppy.opt.ph.PH( options, self.all3_scenario_names, scenario_creator, @@ -114,6 +114,7 @@ def test_ph_constructor(self): scenario_denouement, scenario_creator_kwargs={"scenario_count": 3}, ) + assert ph is not None def test_ef_constructor(self): ScenCount = 3 @@ -123,6 +124,7 @@ def test_ef_constructor(self): scenario_creator_kwargs={"scenario_count": ScenCount}, suppress_warnings=True ) + assert ef is not None @unittest.skipIf(not solver_available, "no solver is available") @@ -139,6 +141,7 @@ def test_ef_solve(self): if '_persistent' in options["solver_name"]: solver.set_instance(ef) results = solver.solve(ef, tee=False) + pyo.assert_optimal_termination(results) sig2eobj = round_pos_sig(pyo.value(ef.EF_Obj),2) self.assertEqual(220000.0, sig2eobj) @@ -156,7 +159,7 @@ def test_fix_ef_solve(self): if '_persistent' in options["solver_name"]: solver.set_instance(ef) results = solver.solve(ef, tee=False) - sig2eobj = round_pos_sig(pyo.value(ef.EF_Obj),2) + pyo.assert_optimal_termination(results) # the fix creator fixed num prod first stage for size 5 to 1134 self.assertEqual(pyo.value(ef.Scenario1.NumProducedFirstStage[5]), 1134) @@ -176,9 +179,6 @@ def test_ph_iter0(self): conv, obj, tbound = ph.ph_main() - sig2obj = round_pos_sig(obj,2) - #self.assertEqual(1400000000, sig2obj) - @unittest.skipIf(not solver_available, "no solver is available") def test_fix_ph_iter0(self): @@ -492,12 +492,12 @@ def smoke_for_extensions(self): options = self._copy_of_base_options() options["PHIterLimit"] = 2 + multi_ext = {"ext_classes": [Fixer, Gapper, XhatLooper, XhatClosest]} ph = mpisppy.opt.ph.PH(options, self.all3_scenario_names, scenario_creator, scenario_denouement, extensions=MultiExtension, extension_kwargs=multi_ext, ) - multi_ext = {"ext_classes": [Fixer, Gapper, XhatLooper, XhatClosest]} conv, basic_obj, tbound = ph.ph_main() @@ -513,12 +513,12 @@ def fix_for_extensions(self): from mpisppy.extensions.xhatclosest import XhatClosest options = self._copy_of_base_options() options["PHIterLimit"] = 2 + multi_ext = {"ext_classes": [Fixer, Gapper, XhatLooper, XhatClosest]} ph = mpisppy.opt.ph.PH(options, self.all3_scenario_names, self._fix_creator, scenario_denouement, extensions=MultiExtension, extension_kwargs=multi_ext, ) - multi_ext = {"ext_classes": [Fixer, Gapper, XhatLooper, XhatClosest]} conv, basic_obj, tbound = ph.ph_main( ) for k,s in ph.local_scenarios.items(): self.assertTrue(s.NumProducedFirstStage[5].is_fixed()) @@ -579,6 +579,7 @@ def test_ph_constructor(self): all_nodenames=self.all_nodenames, scenario_creator_kwargs={"branching_factors": self.branching_factors}, ) + assert ph is not None def test_ef_constructor(self): ef = mpisppy.utils.sputils.create_EF( @@ -586,6 +587,7 @@ def test_ef_constructor(self): hydro.scenario_creator, scenario_creator_kwargs={"branching_factors": self.branching_factors}, ) + assert ef is not None @unittest.skipIf(not solver_available, "no solver is available") @@ -600,6 +602,7 @@ def test_ef_solve(self): if '_persistent' in options["solver_name"]: solver.set_instance(ef) results = solver.solve(ef, tee=False) + pyo.assert_optimal_termination(results) mpisppy.utils.sputils.ef_nonants_csv(ef, "delme.csv") df = pd.read_csv("delme.csv", index_col=1) @@ -621,6 +624,7 @@ def test_ef_csv(self): if '_persistent' in options["solver_name"]: solver.set_instance(ef) results = solver.solve(ef, tee=False) + pyo.assert_optimal_termination(results) @unittest.skipIf(not solver_available, diff --git a/mpisppy/tests/test_gradient_rho.py b/mpisppy/tests/test_gradient_rho.py index 7c019a974..19af19d16 100644 --- a/mpisppy/tests/test_gradient_rho.py +++ b/mpisppy/tests/test_gradient_rho.py @@ -14,27 +14,17 @@ """ import os -import glob import unittest -import pandas as pd import csv -import pyomo.environ as pyo -import mpisppy.opt.ph -import mpisppy.phbase from mpisppy.utils import config import mpisppy.utils.cfg_vanilla as vanilla -import mpisppy.utils.sputils as sputils -import mpisppy.utils.rho_utils as rho_utils -import mpisppy.confidence_intervals.ciutils as ciutils import mpisppy.tests.examples.farmer as farmer from mpisppy.spin_the_wheel import WheelSpinner -from mpisppy.tests.utils import get_solver,round_pos_sig +from mpisppy.tests.utils import get_solver import mpisppy.utils.gradient as grad import mpisppy.utils.find_rho as find_rho -from mpisppy.extensions.norm_rho_updater import NormRhoUpdater -from mpisppy.convergers.norm_rho_converger import NormRhoConverger from mpisppy.extensions.gradient_extension import Gradient_extension from mpisppy.extensions.extension import MultiExtension @@ -103,7 +93,7 @@ def test_write_grad_cost(self): self.grad_object.write_grad_cost() try: os.remove(self.cfg.grad_cost_file_out) - except: + except Exception: raise RuntimeError('gradient.write_grad_cost() did not write a csv file') def test_find_grad_rho(self): @@ -118,7 +108,7 @@ def test_compute_and_write_grad_rho(self): self.grad_object.write_grad_rho() try: os.remove(self.cfg.grad_rho_file_out) - except: + except Exception: raise RuntimeError('gradient.compute_and_write_grad_rho() did not write a csv file') def test_grad_cost_and_rho(self): diff --git a/mpisppy/tests/test_headers.py b/mpisppy/tests/test_headers.py index 5846d1442..36c1302a5 100644 --- a/mpisppy/tests/test_headers.py +++ b/mpisppy/tests/test_headers.py @@ -11,12 +11,12 @@ import pytest -yaml = pytest.importorskip("yaml") -addheader = pytest.importorskip("addheader") - from addheader.add import FileFinder, detect_files import mpisppy +yaml = pytest.importorskip("yaml") +addheader = pytest.importorskip("addheader") + def test_headers(): root = Path(mpisppy.__file__).parent.parent diff --git a/mpisppy/tests/test_pickle_bundle.py b/mpisppy/tests/test_pickle_bundle.py index 3aab96251..4682b048b 100644 --- a/mpisppy/tests/test_pickle_bundle.py +++ b/mpisppy/tests/test_pickle_bundle.py @@ -13,24 +13,12 @@ import os import tempfile -import numpy as np import unittest -import subprocess -import importlib import mpisppy.MPI as mpi -from mpisppy.tests.utils import get_solver, round_pos_sig -import mpisppy.utils.sputils as sputils -import mpisppy.tests.examples.aircond as aircond - -import mpisppy.confidence_intervals.mmw_ci as MMWci -import mpisppy.confidence_intervals.zhat4xhat as zhat4xhat -import mpisppy.utils.amalgamator as ama -from mpisppy.utils.xhat_eval import Xhat_Eval -import mpisppy.confidence_intervals.seqsampling as seqsampling -import mpisppy.confidence_intervals.multi_seqsampling as multi_seqsampling -import mpisppy.confidence_intervals.ciutils as ciutils +from mpisppy.tests.utils import get_solver + fullcomm = mpi.COMM_WORLD global_rank = fullcomm.Get_rank() diff --git a/mpisppy/tests/test_pysp_model.py b/mpisppy/tests/test_pysp_model.py index fd5a388e2..817bb479e 100644 --- a/mpisppy/tests/test_pysp_model.py +++ b/mpisppy/tests/test_pysp_model.py @@ -1,4 +1,4 @@ -############################################################################### +############################################################################## # mpi-sppy: MPI-based Stochastic Programming in PYthon # # Copyright (c) 2024, Lawrence Livermore National Security, LLC, Alliance for @@ -43,6 +43,7 @@ def test_ph_constructor(self): pysp_sizes.scenario_creator, lambda *args : None, ) + assert ph is not None def test_ef_constructor(self): pysp_sizes = self.pysp_sizes3 @@ -52,6 +53,7 @@ def test_ef_constructor(self): pysp_sizes.all_scenario_names, pysp_sizes.scenario_creator, ) + assert ef is not None @unittest.skipIf(not solver_available, @@ -66,6 +68,7 @@ def test_ef_solve(self): pysp_sizes.scenario_creator, ) results = ef.solve_extensive_form(tee=False) + pyo.assert_optimal_termination(results) sig2eobj = round_pos_sig(pyo.value(ef.ef.EF_Obj),2) self.assertEqual(220000.0, sig2eobj) diff --git a/mpisppy/tests/test_stoch_admmWrapper.py b/mpisppy/tests/test_stoch_admmWrapper.py index 38e49e932..7f9e76180 100644 --- a/mpisppy/tests/test_stoch_admmWrapper.py +++ b/mpisppy/tests/test_stoch_admmWrapper.py @@ -12,7 +12,6 @@ import examples.stoch_distr.stoch_distr as stoch_distr from mpisppy.utils import config from mpisppy.tests.utils import get_solver -from mpisppy.utils import config import os solver_available, solver_name, persistent_available, persistent_solver_name= get_solver() @@ -150,7 +149,7 @@ def test_values(self): objectives["EF objective"] = float(decomposed_line[1])#math.ceil(float(decomposed_line[1])) try: correct_order = objectives["outer bound"] <= objectives["EF objective"] <= objectives["inner bound"] - except: + except Exception: raise RuntimeError("The output could not be read to capture the values") assert correct_order, f' We obtained {objectives["outer bound"]=}, {objectives["EF objective"]=}, {objectives["inner bound"]=}' os.chdir(original_dir) @@ -158,4 +157,4 @@ def test_values(self): if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() diff --git a/mpisppy/tests/test_w_writer.py b/mpisppy/tests/test_w_writer.py index 6946919e7..ea09b9c61 100644 --- a/mpisppy/tests/test_w_writer.py +++ b/mpisppy/tests/test_w_writer.py @@ -14,24 +14,14 @@ """ import os -import glob import unittest -import pandas as pd import csv -import pyomo.environ as pyo -import mpisppy.opt.ph -import mpisppy.phbase from mpisppy.utils import config import mpisppy.utils.cfg_vanilla as vanilla -import mpisppy.utils.sputils as sputils -import mpisppy.utils.rho_utils as rho_utils -import mpisppy.confidence_intervals.ciutils as ciutils import mpisppy.tests.examples.farmer as farmer from mpisppy.spin_the_wheel import WheelSpinner -from mpisppy.tests.utils import get_solver,round_pos_sig -import mpisppy.utils.gradient as grad -import mpisppy.utils.find_rho as find_rho +from mpisppy.tests.utils import get_solver from mpisppy.utils.wxbarwriter import WXBarWriter from mpisppy.utils.wxbarreader import WXBarReader diff --git a/mpisppy/tests/test_with_cylinders.py b/mpisppy/tests/test_with_cylinders.py index 8de3fb5b1..4b035b62b 100644 --- a/mpisppy/tests/test_with_cylinders.py +++ b/mpisppy/tests/test_with_cylinders.py @@ -12,15 +12,13 @@ """ -import os import unittest from mpisppy.utils import config import mpisppy.utils.cfg_vanilla as vanilla -import mpisppy.utils.sputils as sputils import mpisppy.tests.examples.farmer as farmer from mpisppy.spin_the_wheel import WheelSpinner -from mpisppy.tests.utils import get_solver,round_pos_sig +from mpisppy.tests.utils import get_solver __version__ = 0.1 diff --git a/mpisppy/tests/utils.py b/mpisppy/tests/utils.py index 4d570d4e2..f3b3f1020 100644 --- a/mpisppy/tests/utils.py +++ b/mpisppy/tests/utils.py @@ -17,7 +17,7 @@ def get_solver(): for solver_name in solvers: try: solver_available = pyo.SolverFactory(solver_name).available() - except: + except Exception: solver_available = False if solver_available: break @@ -28,7 +28,7 @@ def get_solver(): persistent_solver_name = solver_name+"_persistent" try: persistent_available = pyo.SolverFactory(persistent_solver_name).available() - except: + except Exception: persistent_available = False return solver_available, solver_name, persistent_available, persistent_solver_name diff --git a/mpisppy/utils/admmWrapper.py b/mpisppy/utils/admmWrapper.py index a58442b4a..73f71c005 100644 --- a/mpisppy/utils/admmWrapper.py +++ b/mpisppy/utils/admmWrapper.py @@ -9,8 +9,6 @@ #creating the class AdmmWrapper import mpisppy.utils.sputils as sputils import pyomo.environ as pyo -import mpisppy -from collections import OrderedDict from mpisppy import MPI global_rank = MPI.COMM_WORLD.Get_rank() @@ -28,7 +26,7 @@ def _consensus_vars_number_creator(consensus_vars): consensus_vars_number={} for subproblem in consensus_vars: for var in consensus_vars[subproblem]: - if not var in consensus_vars_number: # instanciates consensus_vars_number[var] + if var not in consensus_vars_number: # instanciates consensus_vars_number[var] consensus_vars_number[var] = 0 consensus_vars_number[var] += 1 for var in consensus_vars_number: diff --git a/mpisppy/utils/amalgamator.py b/mpisppy/utils/amalgamator.py index a25457d6a..b051bbdc5 100644 --- a/mpisppy/utils/amalgamator.py +++ b/mpisppy/utils/amalgamator.py @@ -8,6 +8,20 @@ ############################################################################### # Amalgamator.py starting point; DLW March 2021 # To test : python amalgamator.py 10 --solver-name=cplex --default-rho=1 +import importlib +import inspect +import pyomo.environ as pyo +import copy +import pyomo.common.config as pyofig +from mpisppy.utils import config +import mpisppy.utils.solver_spec as solver_spec + +from mpisppy.spin_the_wheel import WheelSpinner +import mpisppy.utils.sputils as sputils +import mpisppy.utils.cfg_vanilla as vanilla +from mpisppy import global_toc + +from mpisppy.extensions.fixer import Fixer """Takes a scenario list and a scenario creator (and options) as input and produces an outer bound on the objective function (solving the EF directly @@ -38,23 +52,6 @@ It no longer has options, just a cfg. You might want to copy your cfg before passing it in. """ -import numpy as np -import importlib -import inspect -import pyomo.environ as pyo -import argparse -import copy -import pyomo.common.config as pyofig -from mpisppy.utils import config -import mpisppy.utils.solver_spec as solver_spec - -from mpisppy.utils.sputils import get_objs, nonant_cache_from_ef -from mpisppy.spin_the_wheel import WheelSpinner -import mpisppy.utils.sputils as sputils -import mpisppy.utils.cfg_vanilla as vanilla -from mpisppy import global_toc - -from mpisppy.extensions.fixer import Fixer hubs_and_multi_compatibility = {'ph': True, 'aph': True, @@ -116,7 +113,7 @@ def find_hub(cylinders, is_multi=False): def find_spokes(cylinders, is_multi=False): spokes = [] for c in cylinders: - if not c in hubs_and_multi_compatibility: + if c not in hubs_and_multi_compatibility: if c not in spokes_and_multi_compatibility: raise RuntimeError(f"The cylinder {c} do not exist or cannot be called via amalgamator.") if is_multi and not spokes_and_multi_compatibility[c]: @@ -136,10 +133,10 @@ def check_module_ama(module): you_can_have_it_all = True for ething in everything: if not hasattr(module, ething): - print(f"Module {mname} is missing {ething}") + print(f"Module {module} is missing {ething}") you_can_have_it_all = False if not you_can_have_it_all: - raise RuntimeError(f"Module {mname} not complete for from_module") + raise RuntimeError(f"Module {module} not complete for from_module") #========== @@ -213,7 +210,7 @@ def Amalgamator_parser(cfg, inparser_adder, extraargs_fct=None, use_command_line cfg.mip_options() #Adding cylinders - if not "cylinders" in cfg: + if "cylinders" not in cfg: raise RuntimeError("A cylinder list must be specified") for cylinder in cfg['cylinders']: @@ -246,9 +243,9 @@ def Amalgamator_parser(cfg, inparser_adder, extraargs_fct=None, use_command_line #Checking if cfg has all the options we need if not (_bool_option(cfg, "EF_2stage") or _bool_option(cfg, "EF_mstage")): raise RuntimeError("For now, completly bypassing command line only works with EF." ) - if not ('EF_solver_name' in cfg): + if 'EF_solver_name' not in cfg: raise RuntimeError("EF_solver_name must be specified for the amalgamator." ) - if not ('num_scens' in cfg): + if 'num_scens' not in cfg: raise RuntimeWarning("cfg should have a number of scenarios to compute a xhat") if _bool_option(cfg, 'EF-mstage') and 'branching_factors' not in cfg: raise RuntimeError("For a multistage problem, cfg must have a 'branching_factors' attribute with branching factors") @@ -289,7 +286,7 @@ def __init__(self, cfg, if self.is_EF: sroot, self.solver_name, self.solver_options = solver_spec.solver_specification(cfg, ["EF", ""]) self.is_multi = _bool_option(cfg, "EF-mstage") or _bool_option(cfg, "mstage") - if self.is_multi and not "all_nodenames" in cfg: + if self.is_multi and "all_nodenames" not in cfg: if "branching_factors" in cfg: ndnms = sputils.create_nodenames_from_branching_factors(cfg["branching_factors"]) self.cfg.quick_assign("all_nodenames", domain=pyofig.ListOf(str), value=ndnms) @@ -418,7 +415,6 @@ def run(self): if __name__ == "__main__": # For use by developers doing ad hoc testing, our example is farmer - import mpisppy.tests.examples.farmer as farmer # EF, PH, L-shaped, APH flags, and then boolean multi-stage """ ama_options = {"2stage": True, # 2stage vs. mstage diff --git a/mpisppy/utils/callbacks/termination/__init__.py b/mpisppy/utils/callbacks/termination/__init__.py index 2b1724d56..f92d8b81d 100644 --- a/mpisppy/utils/callbacks/termination/__init__.py +++ b/mpisppy/utils/callbacks/termination/__init__.py @@ -7,6 +7,6 @@ # full copyright and license information. ############################################################################### from .termination_callbacks import ( - supports_termination_callback, - set_termination_callback, + supports_termination_callback as supports_termination_callback, + set_termination_callback as set_termination_callback, ) diff --git a/mpisppy/utils/callbacks/termination/termination_callbacks.py b/mpisppy/utils/callbacks/termination/termination_callbacks.py index 5409ad195..c736e7d57 100644 --- a/mpisppy/utils/callbacks/termination/termination_callbacks.py +++ b/mpisppy/utils/callbacks/termination/termination_callbacks.py @@ -56,7 +56,7 @@ def set_termination_callback(solver_instance, termination_callback): if not tc.check_user_termination_callback_signature(termination_callback): raise RuntimeError( - f"Provided user termination callback did not match expected signature with 3 positional arguments" + "Provided user termination callback did not match expected signature with 3 positional arguments" ) try: diff --git a/mpisppy/utils/cfg_vanilla.py b/mpisppy/utils/cfg_vanilla.py index 24e25810e..57ae43469 100644 --- a/mpisppy/utils/cfg_vanilla.py +++ b/mpisppy/utils/cfg_vanilla.py @@ -175,11 +175,11 @@ def extension_adder(hub_dict,ext_class): elif hub_dict["opt_kwargs"]["extensions"] == MultiExtension: if hub_dict["opt_kwargs"]["extension_kwargs"] is None: hub_dict["opt_kwargs"]["extension_kwargs"] = {"ext_classes": []} - if not ext_class in hub_dict["opt_kwargs"]["extension_kwargs"]["ext_classes"]: + if ext_class not in hub_dict["opt_kwargs"]["extension_kwargs"]["ext_classes"]: hub_dict["opt_kwargs"]["extension_kwargs"]["ext_classes"].append(ext_class) elif hub_dict["opt_kwargs"]["extensions"] != ext_class: #ext_class is the second extension - if not "extensions_kwargs" in hub_dict["opt_kwargs"]: + if "extensions_kwargs" not in hub_dict["opt_kwargs"]: hub_dict["opt_kwargs"]["extension_kwargs"] = {} hub_dict["opt_kwargs"]["extension_kwargs"]["ext_classes"] = \ [hub_dict["opt_kwargs"]["extensions"], ext_class] diff --git a/mpisppy/utils/find_rho.py b/mpisppy/utils/find_rho.py index b0a679e84..ec7226197 100644 --- a/mpisppy/utils/find_rho.py +++ b/mpisppy/utils/find_rho.py @@ -9,34 +9,19 @@ # Code to compute rhos from Ws. It also provides a corresponding rho setter. # To test: /examples/farmer/farmer_demo.py -import sys import os import inspect -import pyomo.environ as pyo -from pyomo.opt import SolverFactory, SolutionStatus, TerminationCondition -import logging import numpy as np -import math import importlib import csv -import inspect -import typing import copy -import time from sortedcollections import OrderedSet -import mpisppy.log from mpisppy import MPI -import mpisppy.utils.sputils as sputils -import mpisppy.spopt from mpisppy.utils import config import mpisppy.utils.cfg_vanilla as vanilla from mpisppy.utils.wxbarwriter import WXBarWriter from mpisppy.spin_the_wheel import WheelSpinner -import mpisppy.confidence_intervals.ciutils as ciutils -from pyomo.contrib.pynumero.interfaces.pyomo_nlp import PyomoNLP -import mpisppy.utils.wxbarutils as wxbarutils -import mpisppy.utils.rho_utils as rho_utils import mpisppy.phbase as phbase @@ -279,7 +264,7 @@ def rho_setter(self, scenario): rho_list (list): list of (id(variable), rho) """ - assert self.cfg != None, "you have to give the rho_setter a cfg" + assert self.cfg is not None, "you have to give the rho_setter a cfg" assert self.cfg.rho_file_in != '', "use --rho-file-in to give the path of your rhos file" rhofile = self.cfg.rho_file_in rho_list = list() @@ -294,8 +279,8 @@ def rho_setter(self, scenario): if vo is not None: rho_list.append((id(vo), float(row[1]))) else: - raise RuntimeError(f"rho values from {filename} found Var {fullname} " - f"that is not found in the scenario given (name={s._name})") + raise RuntimeError(f"rho values from {rhofile} found Var {fullname} " + f"that is not found in the scenario given (name={scenario._name})") return rho_list @@ -335,7 +320,7 @@ def get_rho_from_W(mname, original_cfg): try: model_module = importlib.import_module(mname) - except: + except Exception: raise RuntimeError(f"Could not import module: {mname}") cfg = copy.deepcopy(original_cfg) cfg.max_iterations = 0 #we only need x0 here diff --git a/mpisppy/utils/gradient.py b/mpisppy/utils/gradient.py index 01072a0a7..d86b6d6c5 100644 --- a/mpisppy/utils/gradient.py +++ b/mpisppy/utils/gradient.py @@ -9,36 +9,19 @@ # Code to compute gradient cost and rhos from the gradient. It also provides a corresponding rho setter. # To test: /examples/farmer/farmer_rho_demo.py -import sys -import os import inspect import pyomo.environ as pyo -from pyomo.opt import SolverFactory, SolutionStatus, TerminationCondition -import logging -import numpy as np -import math import importlib import csv -import inspect -import typing import copy -import time -import mpisppy.log -from mpisppy import global_toc -from mpisppy import MPI -import mpisppy.utils.sputils as sputils -import mpisppy.spopt from mpisppy.utils import config import mpisppy.utils.cfg_vanilla as vanilla from mpisppy.utils.wxbarwriter import WXBarWriter from mpisppy.spin_the_wheel import WheelSpinner import mpisppy.confidence_intervals.ciutils as ciutils from pyomo.contrib.pynumero.interfaces.pyomo_nlp import PyomoNLP -import mpisppy.utils.wxbarutils as wxbarutils -import mpisppy.utils.rho_utils as rho_utils import mpisppy.utils.find_rho as find_rho -import mpisppy.phbase as phbase # Could also pass, e.g., sys.stdout instead of a filename @@ -95,10 +78,9 @@ def compute_grad(self, sname, scenario): relax_int.apply_to(scenario) nlp = PyomoNLP(scenario) - nlp_vars = nlp.get_pyomo_variables() try: grad = nlp.evaluate_grad_objective() - except: + except Exception: raise RuntimeError("Cannot compute the gradient") grad = nlp.evaluate_grad_objective() grad_dict = {ndn_i: -grad[ndn_i[1]] @@ -122,7 +104,6 @@ def find_grad_cost(self): self.ph_object.disable_W_and_prox() xhatfile = self.cfg.xhatpath xhat = ciutils.read_xhat(xhatfile) - xhat_one = xhat["ROOT"] self.ph_object._save_nonants() self.ph_object._fix_nonants(xhat) self.ph_object.solve_loop() @@ -139,7 +120,6 @@ def find_grad_cost(self): for (ix, var) in enumerate(node.nonant_vardata_list)} comm = self.ph_object.comms['ROOT'] costs = comm.gather(local_costs, root=0) - rank = self.ph_object.cylinder_rank if (self.ph_object.cylinder_rank == 0): self.c = {key: val for cost in costs @@ -241,11 +221,12 @@ def grad_cost_and_rho(mname, original_cfg): original_cfg (Config object): config object """ - if (original_cfg.grad_rho_file_out == '') and (original_cfg.grad_cost_file_out == ''): raise RuntimeError ("TBD: work not finished") + if (original_cfg.grad_rho_file_out == '') and (original_cfg.grad_cost_file_out == ''): + raise RuntimeError ("Presently, grad-rho-file-out and grad-cost-file cannot both be empty") try: model_module = importlib.import_module(mname) - except: + except Exception: raise RuntimeError(f"Could not import module: {mname}") cfg = copy.deepcopy(original_cfg) cfg.max_iterations = 0 #we only need x0 here diff --git a/mpisppy/utils/listener_util/demo_listener_util.py b/mpisppy/utils/listener_util/demo_listener_util.py index 3c4e5c391..c44ccd18f 100644 --- a/mpisppy/utils/listener_util/demo_listener_util.py +++ b/mpisppy/utils/listener_util/demo_listener_util.py @@ -16,9 +16,7 @@ import collections import numpy as np import mpisppy.MPI as mpi -import time import datetime as dt -import threading import logging import mpisppy.utils.listener_util.listener_util as listener_util @@ -194,7 +192,6 @@ def side_gig(synchro, msg = None): # Normally, the concats would be created once in an __init__, btw. local_concat = {"SecondReduce": {"ROOT": np.zeros(1, dtype='d')}} - global_concat = {"SecondReduce": {"ROOT": np.zeros(1, dtype='d')}} local_concat["SecondReduce"]["ROOT"][0] = rank # We can (and should) do a dangerous put in the side_gig because # the listener will have the lock. If the worker gets to its compute_global @@ -217,15 +214,15 @@ def side_gig(synchro, msg = None): raise RuntimeError(usemsg) try: iters = int(sys.argv[1]) -except: +except Exception: raise RuntimeError(sys.argv[1]+" is not a valid iters\n"+usemsg) try: sleep = float(sys.argv[2]) -except: +except Exception: raise RuntimeError(sys.argv[2]+" is not a valid sleep\n"+usemsg) try: seed = int(sys.argv[3]) -except: +except Exception: raise RuntimeError(sys.argv[3]+" is not a valid seed\n"+usemsg) sting = 1 # standard devation @@ -234,7 +231,7 @@ def side_gig(synchro, msg = None): # Note: at this point the first reduce is the only reduce Lens = collections.OrderedDict({"FirstReduce": {"ROOT": 2+n_proc}}) if rank == 0: - logging.debug("iters %d, sleep %f, seed %d".format((iters, sleep, seed))) + logging.debug("iters %d, sleep %f, seed %d" % (iters, sleep, seed)) # "ROOT" is required to be the name of the global comm synchronizer = listener_util.Synchronizer(comms = {"ROOT": fullcomm}, Lens = Lens, diff --git a/mpisppy/utils/listener_util/doc/conf.py b/mpisppy/utils/listener_util/doc/conf.py index 59f0db4a2..2da411b51 100644 --- a/mpisppy/utils/listener_util/doc/conf.py +++ b/mpisppy/utils/listener_util/doc/conf.py @@ -197,7 +197,7 @@ def setup(app): (root_doc, 'listener_util', 'listener_util Documentation', author, 'listener_util', 'One line description of project.', 'Miscellaneous'), - +] #autodoc_member_order = 'bysource' #autodoc_member_order = 'groupwise' diff --git a/mpisppy/utils/listener_util/listener_util.py b/mpisppy/utils/listener_util/listener_util.py index 0ab5fa050..366c60aaf 100644 --- a/mpisppy/utils/listener_util/listener_util.py +++ b/mpisppy/utils/listener_util/listener_util.py @@ -20,7 +20,6 @@ import collections import mpisppy.MPI as mpi import time -import cProfile import threading import logging @@ -96,15 +95,15 @@ def run(self, args, kwargs): #ph.setDaemon(True) listenargs = [self._rank, self] - l = threading.Thread(name='listener', + listener = threading.Thread(name='listener', target=Synchronizer.listener_daemon, args=listenargs) - #l.setDaemon(True) + #listener.setDaemon(True) - l.start() + listener.start() wthread.start() - l.join() + listener.join() else: self.work_fct(*args, **kwargs) diff --git a/mpisppy/utils/lshaped_cuts.py b/mpisppy/utils/lshaped_cuts.py index 910dc4048..6a6d3e037 100644 --- a/mpisppy/utils/lshaped_cuts.py +++ b/mpisppy/utils/lshaped_cuts.py @@ -6,25 +6,13 @@ # All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md for # full copyright and license information. ############################################################################### -from pyomo.core.base.block import _BlockData, declare_custom_block +from pyomo.core.base.block import declare_custom_block import pyomo.environ as pe from pyomo.solvers.plugins.solvers.persistent_solver import PersistentSolver import pyomo.contrib.benders.benders_cuts as bc from mpisppy.spopt import set_instance_retry -try: - from mpisppy import MPI - - mpi4py_available = True -except: - mpi4py_available = False -try: - import numpy as np - - numpy_available = True -except: - numpy_available = False import logging logger = logging.getLogger(__name__) diff --git a/mpisppy/utils/pickle_bundle.py b/mpisppy/utils/pickle_bundle.py index 587b2869e..06bac6d39 100644 --- a/mpisppy/utils/pickle_bundle.py +++ b/mpisppy/utils/pickle_bundle.py @@ -36,7 +36,7 @@ def dill_unpickle(fname): return m -def pickle_bundle_parser(cfg): +def pickle_bundle_config(cfg): """ Add command line options for creation and use of "proper" bundles args: cfg (Config): the Config object to which we add""" diff --git a/mpisppy/utils/prox_approx.py b/mpisppy/utils/prox_approx.py index a089fced2..c11edb5bd 100644 --- a/mpisppy/utils/prox_approx.py +++ b/mpisppy/utils/prox_approx.py @@ -8,7 +8,6 @@ ############################################################################### from math import isclose -from pyomo.environ import value from pyomo.core.expr.numeric_expr import LinearExpression # helpers for distance from y = x**2 diff --git a/mpisppy/utils/pysp_model/__init__.py b/mpisppy/utils/pysp_model/__init__.py index 83e2b831a..d32982fb4 100644 --- a/mpisppy/utils/pysp_model/__init__.py +++ b/mpisppy/utils/pysp_model/__init__.py @@ -6,4 +6,4 @@ # All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md for # full copyright and license information. ############################################################################### -from .pysp_model import PySPModel +from .pysp_model import PySPModel as PySPModel diff --git a/mpisppy/utils/pysp_model/archivereader.py b/mpisppy/utils/pysp_model/archivereader.py index 8d19880e3..3e13275fc 100644 --- a/mpisppy/utils/pysp_model/archivereader.py +++ b/mpisppy/utils/pysp_model/archivereader.py @@ -26,34 +26,14 @@ import tempfile import shutil import posixpath +from pyomo.common.dependencies import attempt_import +zipfile, zipfile_available = attempt_import("zipfile") +tarfile, tarfile_available = attempt_import("tarfile") +gzip, gzip_available = attempt_import("gzip") +bz2, bz2_available = attempt_import("bz2") _sep = '/' -zipfile_available = False -tarfile_available = False -gzip_available = False -bz2_available = False -try: - import zipfile - zipfile_available = True -except: - pass -try: - import tarfile - tarfile_available = True -except: - pass -try: - import gzip - gzip_available = True -except: - pass -try: - import bz2 - bz2_available = True -except: - pass - _WindowsError = None try: _WindowsError = WindowsError @@ -111,7 +91,7 @@ def isZip(name): raise ImportError("zipfile support is disabled") try: return zipfile.is_zipfile(ArchiveReader.normalize_name(name)) - except: + except Exception: return False @staticmethod diff --git a/mpisppy/utils/pysp_model/instance_factory.py b/mpisppy/utils/pysp_model/instance_factory.py index 2fe974b61..8f7b229d4 100644 --- a/mpisppy/utils/pysp_model/instance_factory.py +++ b/mpisppy/utils/pysp_model/instance_factory.py @@ -37,7 +37,6 @@ from pyomo.core.base.block import _BlockData from pyomo.common.dependencies import yaml, yaml_available, yaml_load_args from pyomo.common.gc_manager import PauseGC -from pyomo.common.plugin import ExtensionPoint from pyomo.common.fileutils import import_file from .tree_structure_model import \ (CreateAbstractScenarioTreeModel, @@ -744,7 +743,7 @@ def construct_instances_for_scenario_tree( # scenarios, we could manually collect every time X # instances have been created. scenario_instance = None - with PauseGC() as pgc: + with PauseGC(): scenario_instance = \ self.construct_scenario_instance( scenario._name, diff --git a/mpisppy/utils/pysp_model/phutils.py b/mpisppy/utils/pysp_model/phutils.py index 4e1ad1c58..4b6c01f75 100644 --- a/mpisppy/utils/pysp_model/phutils.py +++ b/mpisppy/utils/pysp_model/phutils.py @@ -19,7 +19,6 @@ # This file was originally part of PySP and Pyomo, available: https://github.com/Pyomo/pysp # Copied with modification from pysp/phutils.py -from pyomo.core import Objective class BasicSymbolMap: @@ -40,7 +39,7 @@ def updateSymbols(self, data_stream): # if so, we need to copy since we use it twice if hasattr(data_stream, '__iter__') and \ not hasattr(data_stream, '__len__'): - obj_symbol_tuples = list(obj_symbol_tuples) + data_stream = list(data_stream) self.byObject.update((id(obj), label) for obj,label in data_stream) self.bySymbol.update((label,obj) for obj,label in data_stream) @@ -193,7 +192,7 @@ def extractComponentIndices(component, index_template): # if the input index template is not a tuple, make it one. # one-dimensional indices in pyomo are not tuples, but # everything else is. - if type(index_template) != tuple: + if type(index_template) is not tuple: index_template = (index_template,) if component_index_dimension != len(index_template): diff --git a/mpisppy/utils/pysp_model/tests/test_archivereader.py b/mpisppy/utils/pysp_model/tests/test_archivereader.py index c5e7ab7a6..c4dafc03e 100644 --- a/mpisppy/utils/pysp_model/tests/test_archivereader.py +++ b/mpisppy/utils/pysp_model/tests/test_archivereader.py @@ -79,7 +79,7 @@ def test_ArchiveReaderFactory_bzip2(self): def test_ArchiveReaderFactory_nonexist(self): try: - archive = ArchiveReaderFactory( + ArchiveReaderFactory( os.path.join(testdatadir, '_does_not_exist_')) except IOError: pass diff --git a/mpisppy/utils/pysp_model/tests/test_instancefactory.py b/mpisppy/utils/pysp_model/tests/test_instancefactory.py index 92680efc5..d678662e5 100644 --- a/mpisppy/utils/pysp_model/tests/test_instancefactory.py +++ b/mpisppy/utils/pysp_model/tests/test_instancefactory.py @@ -25,6 +25,7 @@ from os.path import join, dirname, abspath, exists import pyomo.common.unittest as unittest +from pyomo.common.dependencies import networkx_available as has_networkx from pyomo.common.dependencies import yaml_available from mpisppy.utils.pysp_model.instance_factory import \ @@ -35,11 +36,6 @@ ScenarioTree from pyomo.common.fileutils import import_file -try: - import networkx - has_networkx = True -except: - has_networkx = False thisfile = abspath(__file__) thisdir = dirname(thisfile) @@ -56,7 +52,7 @@ class Test(unittest.TestCase): @classmethod def setUpClass(cls): - import pyomo.environ + pass def setUp(self): if "ReferenceModel" in sys.modules: @@ -314,27 +310,27 @@ def test_init6(self): with self.assertRaises(TypeError): with ScenarioTreeInstanceFactory( model=join(testdatadir, "reference_test_model.py"), - scenario_tree=int) as f: + scenario_tree=int): pass with self.assertRaises(ValueError): with ScenarioTreeInstanceFactory( model=join(testdatadir, "reference_test_model.py"), - scenario_tree=None) as f: + scenario_tree=None): pass with self.assertRaises(TypeError): with ScenarioTreeInstanceFactory( model=None, - scenario_tree=scenario_tree_model) as f: + scenario_tree=scenario_tree_model): pass with self.assertRaises(IOError): with ScenarioTreeInstanceFactory( model=join(testdatadir, "reference_test_model_does_not_exist.py"), - scenario_tree=scenario_tree_model) as f: + scenario_tree=scenario_tree_model): pass with self.assertRaises(ValueError): with ScenarioTreeInstanceFactory( model=join(testdatadir, "reference_test_model.py"), - scenario_tree=CreateAbstractScenarioTreeModel()) as f: + scenario_tree=CreateAbstractScenarioTreeModel()): pass self.assertEqual(len(factory._archives), 0) self.assertTrue("reference_test_model" in sys.modules) diff --git a/mpisppy/utils/pysp_model/tree_structure.py b/mpisppy/utils/pysp_model/tree_structure.py index c1e94bca5..08fe48a61 100644 --- a/mpisppy/utils/pysp_model/tree_structure.py +++ b/mpisppy/utils/pysp_model/tree_structure.py @@ -28,7 +28,6 @@ import sys import random import copy -import math import logging try: @@ -37,17 +36,10 @@ from ordereddict import OrderedDict from pyomo.common.collections import ComponentMap -from pyomo.core import (value, minimize, maximize, - Var, Expression, Block, - Objective, SOSConstraint, - ComponentUID) -from pyomo.core.base.sos import _SOSConstraintData -from pyomo.repn import generate_standard_repn -from .phutils import (BasicSymbolMap, - indexToString, +from pyomo.core import (value, ComponentUID) +from .phutils import (indexToString, isVariableNameIndexed, extractVariableNameAndIndex, - extractComponentIndices, ) logger = logging.getLogger("mpisppy.utils.pysp_model") @@ -1279,8 +1271,6 @@ def create_random_bundles(self, sequence = list(range(num_scenarios)) random.shuffle(sequence) - next_scenario_index = 0 - # this is a hack-ish way to re-initialize the Bundles set of a # scenario tree instance, which should already be there # (because it is defined in the abstract model). however, we diff --git a/mpisppy/utils/solver_spec.py b/mpisppy/utils/solver_spec.py index 7823fdd56..1cb1fca72 100644 --- a/mpisppy/utils/solver_spec.py +++ b/mpisppy/utils/solver_spec.py @@ -72,5 +72,5 @@ def solver_specification(cfg, prefix="", name_required=True): if name_required: # Leaving in underscores even though it might confuse command line users print(f"\nsolver name arguments checked in Config object = {idx_list}\n") - raise RuntimeError(f"The Config object did not specify a solver") + raise RuntimeError("The Config object did not specify a solver") return sroot, solver_name, solver_options diff --git a/mpisppy/utils/sputils.py b/mpisppy/utils/sputils.py index 8e9984e36..b33639cf2 100644 --- a/mpisppy/utils/sputils.py +++ b/mpisppy/utils/sputils.py @@ -13,17 +13,17 @@ import sys import os import re -import time import numpy as np import mpisppy.scenario_tree as scenario_tree from pyomo.core import Objective from mpisppy import MPI, haveMPI -global_rank = MPI.COMM_WORLD.Get_rank() from pyomo.core.expr.numeric_expr import LinearExpression from pyomo.opt import SolutionStatus, TerminationCondition -from mpisppy import tt_timer, global_toc +from mpisppy import tt_timer + +global_rank = MPI.COMM_WORLD.Get_rank() def not_good_enough_results(results): return (results is None) or (len(results.solution) == 0) or \ @@ -597,7 +597,7 @@ def convert_value_string_to_number(s): solver_options[option_key] = None else: raise RuntimeError("Illegally formed subsolve directive"\ - + " option=%s detected" % this_option) + + " option=%s detected" % this_option_string) return solver_options @@ -707,7 +707,7 @@ def __init__(self, Parent, scenfirst, scenlast, desc_leaf_dict, name): if len(desc_leaf_dict)==1 and list(desc_leaf_dict.keys()) == ['ROOT']: #2-stage problem, we don't create leaf nodes self.kids = [] - elif not name+"_0" in desc_leaf_dict: + elif name+"_0" not in desc_leaf_dict: self.is_leaf = True self.kids = [] else: @@ -720,7 +720,7 @@ def __init__(self, Parent, scenfirst, scenlast, desc_leaf_dict, name): child_list = [x for x in desc_leaf_dict if child_regex.match(x) ] for i in range(len(desc_leaf_dict)): childname = name+f"_{i}" - if not childname in desc_leaf_dict: + if childname not in desc_leaf_dict: if len(child_list) != i: raise RuntimeError("The all_nodenames argument is giving an inconsistent tree." f"The node {name} has {len(child_list)} children, but {childname} is not one of them.") @@ -746,13 +746,13 @@ def stage_max(self): if self.is_leaf: return 1 else: - l = [child.stage_max() for child in self.kids] - if l.count(l[0]) != len(l): - maxstage = max(l)+ self.stage - minstage = min(l)+ self.stage + leaves = [child.stage_max() for child in self.kids] + if leaves.count(leaves[0]) != len(leaves): + maxstage = max(leaves)+ self.stage + minstage = min(leaves)+ self.stage raise RuntimeError("The all_nodenames argument is giving an inconsistent tree. " f"The node {self.name} has descendant leaves with stages going from {minstage} to {maxstage}") - return 1+l[0] + return 1+leaves[0] @@ -921,7 +921,7 @@ def check4losses(numscens, branching_factors, for s in scenlist: snum = int(s[8:]) stagepresents[stagenum][snum] = True - missingone = False + missingsome = False for stage in stagepresents: for scen, there in enumerate(stagepresents[stage]): if not there: diff --git a/mpisppy/utils/stoch_admmWrapper.py b/mpisppy/utils/stoch_admmWrapper.py index 6a6caa8d7..e7183065a 100644 --- a/mpisppy/utils/stoch_admmWrapper.py +++ b/mpisppy/utils/stoch_admmWrapper.py @@ -9,7 +9,6 @@ #creating the class stoch_admmWrapper import mpisppy.utils.sputils as sputils import pyomo.environ as pyo -from collections import OrderedDict import mpisppy.scenario_tree as scenario_tree import numpy as np @@ -28,7 +27,7 @@ def _consensus_vars_number_creator(consensus_vars): for subproblem in consensus_vars: for var_stage_tuple in consensus_vars[subproblem]: var = var_stage_tuple[0] - if not var in consensus_vars_number: # instanciates consensus_vars_number[var] + if var not in consensus_vars_number: # instanciates consensus_vars_number[var] consensus_vars_number[var] = 0 consensus_vars_number[var] += 1 return consensus_vars_number diff --git a/mpisppy/utils/wtracker.py b/mpisppy/utils/wtracker.py index 124a2ca3f..04898ebb9 100644 --- a/mpisppy/utils/wtracker.py +++ b/mpisppy/utils/wtracker.py @@ -181,7 +181,6 @@ def check_cross_zero(self, wlen, offsetback=0): f" offsetback {offsetback}\n") else: print(f"{np.shape(self.local_Ws)}") - wlist = dict() for i in range(fi+1, li+1): for sname, _ in self.PHB.local_scenarios.items(): sgn_curr_iter = np.sign(np.array(self.local_Ws[fi][sname])) diff --git a/mpisppy/utils/wxbartester.py b/mpisppy/utils/wxbartester.py index 5444fc026..15cc421c7 100644 --- a/mpisppy/utils/wxbartester.py +++ b/mpisppy/utils/wxbartester.py @@ -12,9 +12,7 @@ import mpisppy.tests.examples.uc.uc_funcs as uc_funcs # this version is locked to three scenarios -from mpisppy.utils.wxbarwriter import WXBarWriter from mpisppy.utils.wxbarreader import WXBarReader -import os from mpisppy.opt.ph import PH diff --git a/mpisppy/utils/wxbarutils.py b/mpisppy/utils/wxbarutils.py index 0ded848f0..f8eca3531 100644 --- a/mpisppy/utils/wxbarutils.py +++ b/mpisppy/utils/wxbarutils.py @@ -41,7 +41,6 @@ import os import numpy as np import pyomo.environ as pyo -import mpisppy.utils.sputils as sputils ''' W utilities ''' diff --git a/mpisppy/utils/wxbarwriter.py b/mpisppy/utils/wxbarwriter.py index 566b29974..46bfeb56a 100644 --- a/mpisppy/utils/wxbarwriter.py +++ b/mpisppy/utils/wxbarwriter.py @@ -30,7 +30,6 @@ ''' import os -import pyomo.environ as pyo import mpisppy.utils.wxbarutils import mpisppy.extensions.extension @@ -100,9 +99,11 @@ def post_everything(self): mpisppy.utils.wxbarutils.write_W_to_file(self.PHB, fname, sep_files=self.sep_files) if (self.w_grad_fname): - grad_fname = f'grad_fname.csv' + # TODO: finish implementing? + #grad_fname = 'grad_fname.csv' #mpisppy.utils.wxbarutils.write_W_grad_to_file(self.PHB, grad_fname, #sep_files=self.sep_files) + pass if (self.x_fname): mpisppy.utils.wxbarutils.write_xbar_to_file(self.PHB, self.x_fname) diff --git a/mpisppy/utils/xhat_eval.py b/mpisppy/utils/xhat_eval.py index afb7e643a..ac826fe31 100644 --- a/mpisppy/utils/xhat_eval.py +++ b/mpisppy/utils/xhat_eval.py @@ -11,10 +11,8 @@ import inspect import pyomo.environ as pyo -from pyomo.opt import SolverFactory, SolutionStatus, TerminationCondition import logging import numpy as np -import math import mpisppy.log from mpisppy import MPI @@ -208,7 +206,7 @@ def Eobjective(self, verbose=False, fct=None): local_Eobjs = [] for k,s in self.local_scenarios.items(): - if not k in self.objs_dict: + if k not in self.objs_dict: raise RuntimeError(f"No value has been calculated for the scenario {k}") local_Eobjs.append(s._mpisppy_probability * fct(self.objs_dict[k])) local_Eobjs = np.array(local_Eobjs) @@ -241,7 +239,7 @@ def evaluate_one(self, nonant_cache,scenario_name,s): solver_options = self.options["solver_options"] if "solver_options" in self.options else None k = scenario_name - pyomo_solve_time = self.solve_one(solver_options,k, s, + self.solve_one(solver_options,k, s, dtiming=False, verbose=self.verbose, tee=False, diff --git a/paperruns/larger_uc/uc_cylinders.py b/paperruns/larger_uc/uc_cylinders.py index d230adb58..ef8cc7e31 100644 --- a/paperruns/larger_uc/uc_cylinders.py +++ b/paperruns/larger_uc/uc_cylinders.py @@ -13,7 +13,6 @@ # There is manipulation of the mip gap, # so we need modifications of the vanilla dicts. # Notice also that this uses MutliExtensions -import sys import json import uc_funcs as uc diff --git a/paperruns/larger_uc/uc_funcs.py b/paperruns/larger_uc/uc_funcs.py index aa728f315..a81c16352 100644 --- a/paperruns/larger_uc/uc_funcs.py +++ b/paperruns/larger_uc/uc_funcs.py @@ -11,7 +11,6 @@ from pyomo.dataportal import DataPortal -import mpisppy.scenario_tree as scenario_tree import pyomo.environ as pyo import mpisppy.utils.sputils as sputils @@ -106,7 +105,6 @@ def scenario_rhos(scenario_instance, rho_scale_factor=0.1): computed_rhos = [] for t in scenario_instance.TimePeriods: for g in scenario_instance.ThermalGenerators: - max_capacity = pyo.value(scenario_instance.MaximumPowerOutput[g,t]) min_power = pyo.value(scenario_instance.MinimumPowerOutput[g,t]) max_power = pyo.value(scenario_instance.MaximumPowerOutput[g,t]) avg_power = min_power + ((max_power - min_power) / 2.0) @@ -139,7 +137,7 @@ def scenario_rhos_trial_from_file(scenario_instance, rho_scale_factor=0.01, rho_scale_factor=rho_scale_factor) try: trial_rhos = _get_saved_rhos(fname) - except: + except Exception: raise RuntimeError('Formatting issue in specified rho file ' + fname + '. Format should be (variable_name,rho_value) for ' 'each row, with no blank lines, and no ' @@ -150,7 +148,6 @@ def scenario_rhos_trial_from_file(scenario_instance, rho_scale_factor=0.01, for t in sorted(scenario_instance.TimePeriods): for g in sorted(scenario_instance.ThermalGeneratorsAtBus[b]): var = scenario_instance.UnitOn[g,t] - computed_rho = computed_rhos[index] try: trial_rho = trial_rhos[var.name] except KeyError: diff --git a/setup.py b/setup.py index 4e667b093..4f6a0ef88 100644 --- a/setup.py +++ b/setup.py @@ -7,9 +7,7 @@ # All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md for # full copyright and license information. ############################################################################### -import glob import sys -import os # We raise an error if trying to install with python2 if sys.version[0] == '2':