From fdec6cba77f8a662870b169164b5536d933929dd Mon Sep 17 00:00:00 2001 From: "David L. Woodruff" Date: Fri, 15 Nov 2024 10:12:01 -0800 Subject: [PATCH 01/13] improve some rho setter options and help text --- examples/farmer/farmer_rho_demo.py | 6 +++--- examples/uc/gradient_uc_cylinders.py | 4 ++-- mpisppy/extensions/gradient_extension.py | 3 +-- mpisppy/generic_cylinders.py | 2 +- mpisppy/tests/test_gradient_rho.py | 2 +- mpisppy/utils/config.py | 12 ++++++------ 6 files changed, 14 insertions(+), 15 deletions(-) diff --git a/examples/farmer/farmer_rho_demo.py b/examples/farmer/farmer_rho_demo.py index 99c21322..b9ae42a4 100644 --- a/examples/farmer/farmer_rho_demo.py +++ b/examples/farmer/farmer_rho_demo.py @@ -84,7 +84,7 @@ def main(): if cfg.use_norm_rho_converger: if not cfg.use_norm_rho_updater: raise RuntimeError("--use-norm-rho-converger requires --use-norm-rho-updater") - elif cfg.grad_rho_setter: + elif cfg.grad_rho: raise RuntimeError("You cannot have--use-norm-rho-converger and --grad-rho-setter") else: ph_converger = NormRhoConverger @@ -103,7 +103,7 @@ def main(): beans = (cfg, scenario_creator, scenario_denouement, all_scenario_names) ext_classes = [] - if cfg.grad_rho_setter: + if cfg.grad_rho: ext_classes.append(Gradient_extension) if cfg.run_async: @@ -119,7 +119,7 @@ def main(): hub_dict['opt_kwargs']['extensions'] = MultiExtension # DLW: ???? (seems to not matter) #gradient extension kwargs - if cfg.grad_rho_setter: + if cfg.grad_rho: ext_classes.append(Gradient_extension) hub_dict['opt_kwargs']['options']['gradient_extension_options'] = {'cfg': cfg} diff --git a/examples/uc/gradient_uc_cylinders.py b/examples/uc/gradient_uc_cylinders.py index 03898d52..a2be8a6e 100644 --- a/examples/uc/gradient_uc_cylinders.py +++ b/examples/uc/gradient_uc_cylinders.py @@ -123,7 +123,7 @@ def main(): if cfg.xhat_closest_tree: ext_classes.append(XhatClosest) - if cfg.grad_rho_setter: + if cfg.grad_rho: ext_classes.append(Gradient_extension) hub_dict["opt_kwargs"]["extension_kwargs"] = {"ext_classes" : ext_classes} @@ -143,7 +143,7 @@ def main(): "keep_solution" : True } - if cfg.grad_rho_setter: + if cfg.grad_rho: hub_dict['opt_kwargs']['options']['gradient_extension_options'] = {'cfg': cfg} if cfg.ph_mipgaps_json is not None: diff --git a/mpisppy/extensions/gradient_extension.py b/mpisppy/extensions/gradient_extension.py index ac3f8b57..d1009dbf 100644 --- a/mpisppy/extensions/gradient_extension.py +++ b/mpisppy/extensions/gradient_extension.py @@ -36,8 +36,7 @@ def __init__(self, opt, comm=None): # TBD: stop using files # TBD: restore the rho_setter? self.cfg_args_cache = {'rho_file_in': self.cfg.rho_file_in, - 'grad_rho_file_out': self.cfg.grad_rho_file_out, - 'rho_setter': self.cfg.grad_rho_setter} + 'grad_rho_file_out': self.cfg.grad_rho_file_out} if self.cfg.get('grad_cost_file_out', ifmissing="") == "": self.cfg.grad_cost_file_out = './_temp_grad_cost_file.csv' # else: diff --git a/mpisppy/generic_cylinders.py b/mpisppy/generic_cylinders.py index 37be1c5e..fc07be4c 100644 --- a/mpisppy/generic_cylinders.py +++ b/mpisppy/generic_cylinders.py @@ -178,7 +178,7 @@ def _do_decomp(module, cfg, scenario_creator, scenario_creator_kwargs, scenario_ if cfg.rc_fixer: vanilla.add_reduced_costs_fixer(hub_dict, cfg) - if cfg.grad_rho_setter: + if cfg.grad_rho: ext_classes.append(Gradient_extension) hub_dict['opt_kwargs']['options']['gradient_extension_options'] = {'cfg': cfg} diff --git a/mpisppy/tests/test_gradient_rho.py b/mpisppy/tests/test_gradient_rho.py index e1cddb28..058c7834 100644 --- a/mpisppy/tests/test_gradient_rho.py +++ b/mpisppy/tests/test_gradient_rho.py @@ -202,7 +202,7 @@ def test_compute_and_write_grad_rho(self): """ def test_rho_setter(self): - self.cfg.grad_rho_setter = True + self.cfg.grad_rho = True self.cfg.rho_file_in = './examples/rho_test_data/rho.csv' self.rho_object = find_rho.Find_Rho(self.ph_object, self.cfg) self.set_rho = find_rho.Set_Rho(self.cfg) diff --git a/mpisppy/utils/config.py b/mpisppy/utils/config.py index da5fa666..c9573926 100644 --- a/mpisppy/utils/config.py +++ b/mpisppy/utils/config.py @@ -147,9 +147,9 @@ def _bad_rho_setters(msg): raise ValueError("Rho setter options do not make sense together:\n" f"{msg}") - if self.grad_rho_setter and self.sensi_rho: + if self.grad_rho and self.sensi_rho: _bad_rho_setters("Only one rho setter can be active.") - if not (self.grad_rho_setter or self.sensi_rho or self.sep_rho or self.reduced_costs_rho): + if not (self.grad_rho or self.sensi_rho or self.sep_rho or self.reduced_costs_rho): if self.dynamic_rho_primal_crit or self.dynamic_rho_dual_crit: _bad_rho_setters("dynamic rho only works with grad-, sensi-, and sep-rho") @@ -434,7 +434,7 @@ def reduced_costs_rho_args(self): def sep_rho_args(self): self.add_to_config("sep_rho", - description="have a SepRho extension", + description="have an extension that computes rho using the seprho method from the Watson/Woodruff CMS paper", domain=bool, default=False) self.add_to_config("sep_rho_multiplier", @@ -445,7 +445,7 @@ def sep_rho_args(self): def sensi_rho_args(self): self.add_to_config("sensi_rho", - description="have a SensiRho extension", + description="have an extension that sets rho values based on objective function sensitivity", domain=bool, default=False) self.add_to_config("sensi_rho_multiplier", @@ -833,8 +833,8 @@ def gradient_args(self): # domain=float, # default=0.1) - self.add_to_config('grad_rho_setter', - description="use rho setter from a rho file", + self.add_to_config('grad_rho', + description="use a gradient-based rho setter (if yourproblem is linear, use coeff-rho instead)", domain=bool, default=False) """ From d38829e8f03c74422a4b1d3e388e45c811f80638 Mon Sep 17 00:00:00 2001 From: "David L. Woodruff" Date: Fri, 15 Nov 2024 10:29:06 -0800 Subject: [PATCH 02/13] add a space --- mpisppy/utils/config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mpisppy/utils/config.py b/mpisppy/utils/config.py index c9573926..4c1538c3 100644 --- a/mpisppy/utils/config.py +++ b/mpisppy/utils/config.py @@ -834,7 +834,8 @@ def gradient_args(self): # default=0.1) self.add_to_config('grad_rho', - description="use a gradient-based rho setter (if yourproblem is linear, use coeff-rho instead)", + description="use a gradient-based rho setter (if your +problem is linear, use coeff-rho instead)", domain=bool, default=False) """ From c9be8c6f8f504984fdb4ccd544e3f1ae288d1b45 Mon Sep 17 00:00:00 2001 From: "David L. Woodruff" Date: Fri, 15 Nov 2024 10:36:29 -0800 Subject: [PATCH 03/13] really add space --- mpisppy/utils/config.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mpisppy/utils/config.py b/mpisppy/utils/config.py index 4c1538c3..629f63bc 100644 --- a/mpisppy/utils/config.py +++ b/mpisppy/utils/config.py @@ -834,8 +834,7 @@ def gradient_args(self): # default=0.1) self.add_to_config('grad_rho', - description="use a gradient-based rho setter (if your -problem is linear, use coeff-rho instead)", + description="use a gradient-based rho setter (if your problem is linear, use coeff-rho instead)", domain=bool, default=False) """ From a52263c7454f5e8ac6a8f7740938d280e46d6bfc Mon Sep 17 00:00:00 2001 From: David L Woodruff Date: Fri, 15 Nov 2024 12:40:18 -0800 Subject: [PATCH 04/13] improve some rho setter options and help text (#450) * improve some rho setter options and help text * add a space * really add space --- examples/farmer/farmer_rho_demo.py | 6 +++--- examples/uc/gradient_uc_cylinders.py | 4 ++-- mpisppy/extensions/gradient_extension.py | 3 +-- mpisppy/generic_cylinders.py | 2 +- mpisppy/tests/test_gradient_rho.py | 2 +- mpisppy/utils/config.py | 12 ++++++------ 6 files changed, 14 insertions(+), 15 deletions(-) diff --git a/examples/farmer/farmer_rho_demo.py b/examples/farmer/farmer_rho_demo.py index 99c21322..b9ae42a4 100644 --- a/examples/farmer/farmer_rho_demo.py +++ b/examples/farmer/farmer_rho_demo.py @@ -84,7 +84,7 @@ def main(): if cfg.use_norm_rho_converger: if not cfg.use_norm_rho_updater: raise RuntimeError("--use-norm-rho-converger requires --use-norm-rho-updater") - elif cfg.grad_rho_setter: + elif cfg.grad_rho: raise RuntimeError("You cannot have--use-norm-rho-converger and --grad-rho-setter") else: ph_converger = NormRhoConverger @@ -103,7 +103,7 @@ def main(): beans = (cfg, scenario_creator, scenario_denouement, all_scenario_names) ext_classes = [] - if cfg.grad_rho_setter: + if cfg.grad_rho: ext_classes.append(Gradient_extension) if cfg.run_async: @@ -119,7 +119,7 @@ def main(): hub_dict['opt_kwargs']['extensions'] = MultiExtension # DLW: ???? (seems to not matter) #gradient extension kwargs - if cfg.grad_rho_setter: + if cfg.grad_rho: ext_classes.append(Gradient_extension) hub_dict['opt_kwargs']['options']['gradient_extension_options'] = {'cfg': cfg} diff --git a/examples/uc/gradient_uc_cylinders.py b/examples/uc/gradient_uc_cylinders.py index 03898d52..a2be8a6e 100644 --- a/examples/uc/gradient_uc_cylinders.py +++ b/examples/uc/gradient_uc_cylinders.py @@ -123,7 +123,7 @@ def main(): if cfg.xhat_closest_tree: ext_classes.append(XhatClosest) - if cfg.grad_rho_setter: + if cfg.grad_rho: ext_classes.append(Gradient_extension) hub_dict["opt_kwargs"]["extension_kwargs"] = {"ext_classes" : ext_classes} @@ -143,7 +143,7 @@ def main(): "keep_solution" : True } - if cfg.grad_rho_setter: + if cfg.grad_rho: hub_dict['opt_kwargs']['options']['gradient_extension_options'] = {'cfg': cfg} if cfg.ph_mipgaps_json is not None: diff --git a/mpisppy/extensions/gradient_extension.py b/mpisppy/extensions/gradient_extension.py index ac3f8b57..d1009dbf 100644 --- a/mpisppy/extensions/gradient_extension.py +++ b/mpisppy/extensions/gradient_extension.py @@ -36,8 +36,7 @@ def __init__(self, opt, comm=None): # TBD: stop using files # TBD: restore the rho_setter? self.cfg_args_cache = {'rho_file_in': self.cfg.rho_file_in, - 'grad_rho_file_out': self.cfg.grad_rho_file_out, - 'rho_setter': self.cfg.grad_rho_setter} + 'grad_rho_file_out': self.cfg.grad_rho_file_out} if self.cfg.get('grad_cost_file_out', ifmissing="") == "": self.cfg.grad_cost_file_out = './_temp_grad_cost_file.csv' # else: diff --git a/mpisppy/generic_cylinders.py b/mpisppy/generic_cylinders.py index 37be1c5e..fc07be4c 100644 --- a/mpisppy/generic_cylinders.py +++ b/mpisppy/generic_cylinders.py @@ -178,7 +178,7 @@ def _do_decomp(module, cfg, scenario_creator, scenario_creator_kwargs, scenario_ if cfg.rc_fixer: vanilla.add_reduced_costs_fixer(hub_dict, cfg) - if cfg.grad_rho_setter: + if cfg.grad_rho: ext_classes.append(Gradient_extension) hub_dict['opt_kwargs']['options']['gradient_extension_options'] = {'cfg': cfg} diff --git a/mpisppy/tests/test_gradient_rho.py b/mpisppy/tests/test_gradient_rho.py index e1cddb28..058c7834 100644 --- a/mpisppy/tests/test_gradient_rho.py +++ b/mpisppy/tests/test_gradient_rho.py @@ -202,7 +202,7 @@ def test_compute_and_write_grad_rho(self): """ def test_rho_setter(self): - self.cfg.grad_rho_setter = True + self.cfg.grad_rho = True self.cfg.rho_file_in = './examples/rho_test_data/rho.csv' self.rho_object = find_rho.Find_Rho(self.ph_object, self.cfg) self.set_rho = find_rho.Set_Rho(self.cfg) diff --git a/mpisppy/utils/config.py b/mpisppy/utils/config.py index da5fa666..629f63bc 100644 --- a/mpisppy/utils/config.py +++ b/mpisppy/utils/config.py @@ -147,9 +147,9 @@ def _bad_rho_setters(msg): raise ValueError("Rho setter options do not make sense together:\n" f"{msg}") - if self.grad_rho_setter and self.sensi_rho: + if self.grad_rho and self.sensi_rho: _bad_rho_setters("Only one rho setter can be active.") - if not (self.grad_rho_setter or self.sensi_rho or self.sep_rho or self.reduced_costs_rho): + if not (self.grad_rho or self.sensi_rho or self.sep_rho or self.reduced_costs_rho): if self.dynamic_rho_primal_crit or self.dynamic_rho_dual_crit: _bad_rho_setters("dynamic rho only works with grad-, sensi-, and sep-rho") @@ -434,7 +434,7 @@ def reduced_costs_rho_args(self): def sep_rho_args(self): self.add_to_config("sep_rho", - description="have a SepRho extension", + description="have an extension that computes rho using the seprho method from the Watson/Woodruff CMS paper", domain=bool, default=False) self.add_to_config("sep_rho_multiplier", @@ -445,7 +445,7 @@ def sep_rho_args(self): def sensi_rho_args(self): self.add_to_config("sensi_rho", - description="have a SensiRho extension", + description="have an extension that sets rho values based on objective function sensitivity", domain=bool, default=False) self.add_to_config("sensi_rho_multiplier", @@ -833,8 +833,8 @@ def gradient_args(self): # domain=float, # default=0.1) - self.add_to_config('grad_rho_setter', - description="use rho setter from a rho file", + self.add_to_config('grad_rho', + description="use a gradient-based rho setter (if your problem is linear, use coeff-rho instead)", domain=bool, default=False) """ From 7cab64761004a7ceafce5d20c7a9bbc43970eb13 Mon Sep 17 00:00:00 2001 From: Bernard Knueven Date: Fri, 15 Nov 2024 16:25:05 -0700 Subject: [PATCH 05/13] deal with nan bounds in presolve --- mpisppy/opt/presolve.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mpisppy/opt/presolve.py b/mpisppy/opt/presolve.py index 87edece5..4418c9e8 100644 --- a/mpisppy/opt/presolve.py +++ b/mpisppy/opt/presolve.py @@ -143,6 +143,10 @@ def presolve(self): print( f"Tightening bounds on nonant {var.name} in scenario {k} from {var.bounds} to {(lb, ub)} based on global bound information." ) + if np.isnan(lb): + lb = None + if np.isnan(ub): + ub = None var.bounds = (lb, ub) # Now do FBBT From db7ea1fcf64ae61a76bddb3be0b5b794937964f9 Mon Sep 17 00:00:00 2001 From: "David L. Woodruff" Date: Fri, 15 Nov 2024 15:43:37 -0800 Subject: [PATCH 06/13] move the APH boolean to the cfg 'block' for aph commands --- mpisppy/generic_cylinders.py | 9 +-------- mpisppy/utils/config.py | 6 +++++- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/mpisppy/generic_cylinders.py b/mpisppy/generic_cylinders.py index fc07be4c..90bcf725 100644 --- a/mpisppy/generic_cylinders.py +++ b/mpisppy/generic_cylinders.py @@ -29,7 +29,6 @@ from mpisppy import MPI - def _parse_args(m): # m is the model file module cfg = config.Config() @@ -46,12 +45,6 @@ def _parse_args(m): description="The string used for a directory of ouput along with a csv and an npv file (default None, which means no soltion output)", domain=str, default=None) - cfg.add_to_config(name="run_async", - description="Use APH instead of PH (default False)", - domain=bool, - default=False) - - m.inparser_adder(cfg) # many models, e.g., farmer, need num_scens_required # in which case, it should go in the inparser_adder function @@ -136,7 +129,7 @@ def _do_decomp(module, cfg, scenario_creator, scenario_creator_kwargs, scenario_ # Things needed for vanilla cylinders beans = (cfg, scenario_creator, scenario_denouement, all_scenario_names) - if cfg.run_async: + if cfg.APH: # Vanilla APH hub hub_dict = vanilla.aph_hub(*beans, scenario_creator_kwargs=scenario_creator_kwargs, diff --git a/mpisppy/utils/config.py b/mpisppy/utils/config.py index 629f63bc..453e0b22 100644 --- a/mpisppy/utils/config.py +++ b/mpisppy/utils/config.py @@ -387,7 +387,11 @@ def mip_options(self): def aph_args(self): - + + solf.add_to_config(name="APH", + description="Use APH instead of PH (default False)", + domain=bool, + default=False) self.add_to_config('aph_gamma', description='Gamma parameter associated with asychronous projective hedging (default 1.0)', domain=float, From 535dc24cc6f3eb0dd50f555fa8d32976ad3669b1 Mon Sep 17 00:00:00 2001 From: "David L. Woodruff" Date: Fri, 15 Nov 2024 15:55:15 -0800 Subject: [PATCH 07/13] fix a typo in config.py --- mpisppy/utils/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpisppy/utils/config.py b/mpisppy/utils/config.py index 453e0b22..408a0e7b 100644 --- a/mpisppy/utils/config.py +++ b/mpisppy/utils/config.py @@ -388,7 +388,7 @@ def mip_options(self): def aph_args(self): - solf.add_to_config(name="APH", + self.add_to_config(name="APH", description="Use APH instead of PH (default False)", domain=bool, default=False) From 0ddfb04d8e01c7137cb1327957b880d51922ed39 Mon Sep 17 00:00:00 2001 From: "David L. Woodruff" Date: Fri, 15 Nov 2024 16:16:20 -0800 Subject: [PATCH 08/13] rc_fixer require reduced_costs --- mpisppy/utils/config.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mpisppy/utils/config.py b/mpisppy/utils/config.py index 629f63bc..76aaaa26 100644 --- a/mpisppy/utils/config.py +++ b/mpisppy/utils/config.py @@ -147,11 +147,14 @@ def _bad_rho_setters(msg): raise ValueError("Rho setter options do not make sense together:\n" f"{msg}") - if self.grad_rho and self.sensi_rho: + if self.get(grad_rho) and if self.get(sensi_rho): _bad_rho_setters("Only one rho setter can be active.") - if not (self.grad_rho or self.sensi_rho or self.sep_rho or self.reduced_costs_rho): - if self.dynamic_rho_primal_crit or self.dynamic_rho_dual_crit: + if not (self.get("grad_rho") or self.get("sensi_rho") or self.get("sep_rho") or self.get("reduced_costs_rho"): + if self.get("dynamic_rho_primal_crit") or self.get("dynamic_rho_dual_crit"): _bad_rho_setters("dynamic rho only works with grad-, sensi-, and sep-rho") + if self.get("rc_fixer") and not self.get("reduced_costs"): + _bad_rho_setters("--rc-fixer requires --reduced-costs") + def add_solver_specs(self, prefix=""): sstr = f"{prefix}_solver" if prefix != "" else "solver" From 2ec9f5c5e37cb7869f40580b7092927f82956044 Mon Sep 17 00:00:00 2001 From: David L Woodruff Date: Tue, 19 Nov 2024 15:09:28 -0800 Subject: [PATCH 09/13] Update config.py typo --- mpisppy/utils/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpisppy/utils/config.py b/mpisppy/utils/config.py index 76aaaa26..6970e0be 100644 --- a/mpisppy/utils/config.py +++ b/mpisppy/utils/config.py @@ -147,7 +147,7 @@ def _bad_rho_setters(msg): raise ValueError("Rho setter options do not make sense together:\n" f"{msg}") - if self.get(grad_rho) and if self.get(sensi_rho): + if self.get(grad_rho) and self.get(sensi_rho): _bad_rho_setters("Only one rho setter can be active.") if not (self.get("grad_rho") or self.get("sensi_rho") or self.get("sep_rho") or self.get("reduced_costs_rho"): if self.get("dynamic_rho_primal_crit") or self.get("dynamic_rho_dual_crit"): From 6835bb25d78628e287bbf9c49aef4478b8e65a01 Mon Sep 17 00:00:00 2001 From: David L Woodruff Date: Tue, 19 Nov 2024 15:11:59 -0800 Subject: [PATCH 10/13] Update config.py another typo --- mpisppy/utils/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpisppy/utils/config.py b/mpisppy/utils/config.py index 6970e0be..828cc6bb 100644 --- a/mpisppy/utils/config.py +++ b/mpisppy/utils/config.py @@ -149,7 +149,7 @@ def _bad_rho_setters(msg): if self.get(grad_rho) and self.get(sensi_rho): _bad_rho_setters("Only one rho setter can be active.") - if not (self.get("grad_rho") or self.get("sensi_rho") or self.get("sep_rho") or self.get("reduced_costs_rho"): + if not self.get("grad_rho") or self.get("sensi_rho") or self.get("sep_rho") or self.get("reduced_costs_rho"): if self.get("dynamic_rho_primal_crit") or self.get("dynamic_rho_dual_crit"): _bad_rho_setters("dynamic rho only works with grad-, sensi-, and sep-rho") if self.get("rc_fixer") and not self.get("reduced_costs"): From 228de08cae9f66418f45412e1175a0677a96a148 Mon Sep 17 00:00:00 2001 From: David L Woodruff Date: Tue, 19 Nov 2024 15:13:49 -0800 Subject: [PATCH 11/13] Update config.py more last-thing-friday typos --- mpisppy/utils/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpisppy/utils/config.py b/mpisppy/utils/config.py index 828cc6bb..566052c7 100644 --- a/mpisppy/utils/config.py +++ b/mpisppy/utils/config.py @@ -147,7 +147,7 @@ def _bad_rho_setters(msg): raise ValueError("Rho setter options do not make sense together:\n" f"{msg}") - if self.get(grad_rho) and self.get(sensi_rho): + if self.get("grad_rho") and self.get("sensi_rho"): _bad_rho_setters("Only one rho setter can be active.") if not self.get("grad_rho") or self.get("sensi_rho") or self.get("sep_rho") or self.get("reduced_costs_rho"): if self.get("dynamic_rho_primal_crit") or self.get("dynamic_rho_dual_crit"): From c6d5cae6001a4486e9fb8428af660a619747b643 Mon Sep 17 00:00:00 2001 From: David L Woodruff Date: Tue, 19 Nov 2024 15:25:55 -0800 Subject: [PATCH 12/13] Update config.py to trigger re-running tests --- mpisppy/utils/config.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mpisppy/utils/config.py b/mpisppy/utils/config.py index 408a0e7b..1a6695b9 100644 --- a/mpisppy/utils/config.py +++ b/mpisppy/utils/config.py @@ -385,7 +385,6 @@ def mip_options(self): domain=float, default=None) - def aph_args(self): self.add_to_config(name="APH", From c6e9d9d5b8bc59dcf7e57d9a5cf2de2ddf8873f8 Mon Sep 17 00:00:00 2001 From: David L Woodruff Date: Tue, 19 Nov 2024 18:18:01 -0800 Subject: [PATCH 13/13] Conv detail bug (#451) * improve some rho setter options and help text * add a space * really add space * bug fix for convergence detail (deal with all vars fixed) * deal with a rare NaN for the serial number in the buffer * Update spoke.py Force the tests to run again on github by removing a blank line --- mpisppy/cylinders/spoke.py | 4 ++-- mpisppy/spbase.py | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/mpisppy/cylinders/spoke.py b/mpisppy/cylinders/spoke.py index 1d59e58c..7be2d5a6 100644 --- a/mpisppy/cylinders/spoke.py +++ b/mpisppy/cylinders/spoke.py @@ -13,7 +13,6 @@ import os import math - from pyomo.environ import ComponentMap, Var from mpisppy import MPI from mpisppy.cylinders.spcommunicator import SPCommunicator, communicator_array @@ -100,7 +99,8 @@ def spoke_from_hub(self, values): window.Get((values, len(values), MPI.DOUBLE), 0) window.Unlock(0) - new_id = int(values[-1]) + # On rare occasions a NaN is seen... + new_id = int(values[-1]) if not math.isnan(values[-1]) else 0 local_val = np.array((new_id,-new_id), 'i') max_min_ids = np.zeros(2, 'i') self.cylinder_comm.Allreduce((local_val, MPI.INT), diff --git a/mpisppy/spbase.py b/mpisppy/spbase.py index 055a8c30..3516e83e 100644 --- a/mpisppy/spbase.py +++ b/mpisppy/spbase.py @@ -607,7 +607,9 @@ def report_var_values_at_rank0(self, header="", print_zero_prob_values=False, fi if len(header) != 0: print(header) - + if len(var_values) == 0: + print("No variables to report (perhaps all are fixed?)") + return scenario_names = sorted(set(x for (x,y) in var_values)) max_scenario_name_len = max(len(s) for s in scenario_names) variable_names = sorted(set(y for (x,y) in var_values))