Skip to content

Commit b4f01e7

Browse files
committed
factored from problem-specific scenario creator, but transport example needs to be updated.
1 parent 634e356 commit b4f01e7

File tree

5 files changed

+53
-48
lines changed

5 files changed

+53
-48
lines changed

Diff for: mpisppy/agnostic/agnostic_cylinders.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def _parse_args(m):
104104
print("Global rank 0 has created the new .gms model file")
105105
fullcomm.Barrier()
106106

107-
guest = gams_guest.GAMS_guest(model_fname, new_file_path, nonants_name_pairs)
107+
guest = gams_guest.GAMS_guest(model_fname, new_file_path, nonants_name_pairs, cfg)
108108
Ag = agnostic.Agnostic(guest, cfg)
109109

110110
scenario_creator = Ag.scenario_creator

Diff for: mpisppy/agnostic/examples/ag_farmer_gams.bash

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
SOLVERNAME=gurobi
44

5-
#python -u ../agnostic_cylinders.py --module-name mpisppy.agnostic.examples.farmer_gams_model --num-scens 3 --default-rho 1 --solver-name $SOLVERNAME --max-iterations=5 --rel-gap 0.01 --display-progress --guest-language GAMS --gams-model-file farmer_average.gms
5+
python -u ../agnostic_cylinders.py --module-name mpisppy.agnostic.examples.farmer_gams_model --num-scens 3 --default-rho 1 --solver-name $SOLVERNAME --max-iterations=5 --rel-gap 0.01 --display-progress --guest-language GAMS --gams-model-file farmer_average.gms
66

7-
mpiexec -np 3 python -m mpi4py ../agnostic_cylinders.py --module-name mpisppy.agnostic.examples.farmer_gams_model --num-scens 3 --default-rho 0.5 --solver-name $SOLVERNAME --max-iterations=30 --xhatshuffle --lagrangian --rel-gap 0.01 --guest-language GAMS --gams-model-file farmer_average.gms
7+
# lagrangian only
8+
#mpiexec -np 2 python -m mpi4py ../agnostic_cylinders.py --module-name mpisppy.agnostic.examples.farmer_gams_model --num-scens 3 --default-rho 0.5 --solver-name $SOLVERNAME --max-iterations=30 --lagrangian --rel-gap 0.01 --guest-language GAMS --gams-model-file farmer_average.gms
9+
10+
#mpiexec -np 3 python -m mpi4py ../agnostic_cylinders.py --module-name mpisppy.agnostic.examples.farmer_gams_model --num-scens 3 --default-rho 0.5 --solver-name $SOLVERNAME --max-iterations=30 --xhatshuffle --lagrangian --rel-gap 0.01 --guest-language GAMS --gams-model-file farmer_average.gms

Diff for: mpisppy/agnostic/examples/farmer_gams_model.py

+5-27
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def nonants_name_pairs_creator():
2222
"""Mustn't take any argument. Is called in agnostic cylinders
2323
2424
Returns:
25-
list of pairs (str, str): for each non-anticipative variable, the name of the support set must be given with the name of the parameter.
25+
list of pairs (str, str): for each non-anticipative variable, the name of the support set must be given with the name of the variable.
2626
If the set is a cartesian set, there should be no paranthesis when given
2727
"""
2828
return [("crop", "x")]
@@ -31,43 +31,21 @@ def nonants_name_pairs_creator():
3131
def stoch_param_name_pairs_creator():
3232
"""
3333
Returns:
34-
list of pairs (str, str): for each stochastic parameter, the name of the support set must be given with the name of the variable.
34+
list of pairs (str, str): for each stochastic parameter, the name of the support set must be given with the name of the parameter.
3535
If the set is a cartesian set, there should be no paranthesis when given
3636
"""
3737
return [("crop", "yield")]
3838

3939

40-
def scenario_creator(scenario_name, new_file_name, nonants_name_pairs, cfg=None):
40+
def scenario_creator(scenario_name, mi, cfg=None):
4141
""" Create a scenario for the (scalable) farmer example.
4242
4343
Args:
4444
scenario_name (str):
4545
Name of the scenario to construct.
46-
new_file_name (str):
47-
the gms file in which is created the gams model with the ph_objective
48-
nonants_name_pairs (list of (str,str)): list of (non_ant_support_set_name, non_ant_variable_name)
46+
mi (gams model instance): the base model
4947
cfg: pyomo config
5048
"""
51-
assert new_file_name is not None
52-
stoch_param_name_pairs = stoch_param_name_pairs_creator()
53-
54-
ws = gams.GamsWorkspace(working_directory=this_dir, system_directory=gamspy_base_dir)
55-
56-
### Calling this function is required regardless of the model
57-
# This function creates a model instance not instantiated yet, and gathers in glist all the parameters and variables that need to be modifiable
58-
mi, job, glist, all_ph_parameters_dicts, xlo_dict, xup_dict, x_out_dict = gams_guest.pre_instantiation_for_PH(ws, new_file_name, nonants_name_pairs, stoch_param_name_pairs)
59-
60-
opt = ws.add_options()
61-
opt.all_model_types = cfg.solver_name
62-
if LINEARIZED:
63-
mi.instantiate("simple using lp minimizing objective_ph", glist, opt)
64-
else:
65-
mi.instantiate("simple using qcp minimizing objective_ph", glist, opt)
66-
67-
### Calling this function is required regardless of the model
68-
# This functions initializes, by adding records (and values), all the parameters that appear due to PH
69-
nonant_set_sync_dict = gams_guest.adding_record_for_PH(nonants_name_pairs, cfg, all_ph_parameters_dicts, xlo_dict, xup_dict, x_out_dict, job)
70-
7149
### This part is model specific, we define the values of the stochastic parameters depending on scenario_name
7250
scennum = sputils.extract_num(scenario_name)
7351
assert scennum < 3, "three scenarios hardwired for now"
@@ -86,7 +64,7 @@ def scenario_creator(scenario_name, new_file_name, nonants_name_pairs, cfg=None)
8664
y.add_record("corn").value = 3.6
8765
y.add_record("sugarbeets").value = 24.0
8866

89-
return mi, nonants_name_pairs, nonant_set_sync_dict
67+
return mi
9068

9169

9270
#=========

Diff for: mpisppy/agnostic/examples/transport_gams_model.py

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ def stoch_param_name_pairs_creator():
3838

3939

4040
def scenario_creator(scenario_name, new_file_name, nonants_name_pairs, cfg=None):
41+
xxxx match factoring from farmer; drop new_file_name a non-specific lines at the beginning of the function xxxx also look at args and returns that are gone
4142
""" Create a scenario for the (scalable) farmer example.
4243
4344
Args:

Diff for: mpisppy/agnostic/gams_guest.py

+41-18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# <special for agnostic debugging DLW Aug 2023>
21
# In this example, GAMS is the guest language.
32
# NOTE: unlike everywhere else, we are using xbar instead of xbars (no biggy)
43

@@ -29,18 +28,20 @@
2928

3029
class GAMS_guest():
3130
"""
32-
Provide an interface to a model file for an AMPL guest.
31+
Provide an interface to a model file for a GAMS guest.
3332
3433
Args:
3534
model_file_name (str): name of Python file that has functions like scenario_creator
36-
ampl_file_name (str): name of AMPL file that is passed to the model file
35+
gams_file_name (str): name of GAMS file that is passed to the model file
3736
nonants_name_pairs (list of (str,str)): list of (non_ant_support_set_name, non_ant_variable_name)
37+
cfg (pyomo config object)
3838
"""
39-
def __init__(self, model_file_name, new_file_name, nonants_name_pairs):
39+
def __init__(self, model_file_name, new_file_name, nonants_name_pairs, cfg):
4040
self.model_file_name = model_file_name
4141
self.model_module = sputils.module_name_to_module(model_file_name)
4242
self.new_file_name = new_file_name
4343
self.nonants_name_pairs = nonants_name_pairs
44+
self.cfg = cfg
4445

4546
def scenario_creator(self, scenario_name, **kwargs):
4647
""" Wrap the guest (GAMS in this case) scenario creator
@@ -50,12 +51,31 @@ def scenario_creator(self, scenario_name, **kwargs):
5051
Name of the scenario to construct.
5152
5253
"""
53-
mi, nonants_name_pairs, nonant_set_sync_dict = self.model_module.scenario_creator(scenario_name,
54-
self.new_file_name,
55-
self.nonants_name_pairs,
56-
**kwargs)
54+
new_file_name = self.new_file_name
55+
assert new_file_name is not None
56+
stoch_param_name_pairs = self.model_module.stoch_param_name_pairs_creator()
57+
58+
ws = gams.GamsWorkspace(working_directory=this_dir, system_directory=gamspy_base_dir)
59+
60+
### Calling this function is required regardless of the model
61+
# This function creates a model instance not instantiated yet, and gathers in glist all the parameters and variables that need to be modifiable
62+
mi, job, glist, all_ph_parameters_dicts, xlo_dict, xup_dict, x_out_dict = pre_instantiation_for_PH(ws, new_file_name, self.nonants_name_pairs, stoch_param_name_pairs)
63+
64+
opt = ws.add_options()
65+
opt.all_model_types = self.cfg.solver_name
66+
if LINEARIZED:
67+
mi.instantiate("simple using lp minimizing objective_ph", glist, opt)
68+
else:
69+
mi.instantiate("simple using qcp minimizing objective_ph", glist, opt)
70+
71+
### Calling this function is required regardless of the model
72+
# This functions initializes, by adding records (and values), all the parameters that appear due to PH
73+
nonant_set_sync_dict = adding_record_for_PH(self.nonants_name_pairs, self.cfg, all_ph_parameters_dicts, xlo_dict, xup_dict, x_out_dict, job)
74+
75+
# delete this line (end of factor)
76+
mi = self.model_module.scenario_creator(scenario_name, mi, **kwargs)
5777
mi.solve()
58-
nonant_variable_list = [nonant_var for (_, nonant_variables_name) in nonants_name_pairs for nonant_var in mi.sync_db.get_variable(nonant_variables_name)]
78+
nonant_variable_list = [nonant_var for (_, nonant_variables_name) in self.nonants_name_pairs for nonant_var in mi.sync_db.get_variable(nonant_variables_name)]
5979

6080
gd = {
6181
"scenario": mi,
@@ -65,7 +85,7 @@ def scenario_creator(self, scenario_name, **kwargs):
6585
"probability": "uniform",
6686
"sense": pyo.minimize,
6787
"BFs": None,
68-
"nonants_name_pairs": nonants_name_pairs,
88+
"nonants_name_pairs": self.nonants_name_pairs,
6989
"nonant_set_sync_dict": nonant_set_sync_dict
7090
}
7191
return gd
@@ -474,8 +494,9 @@ def file_name_creator(original_file_path):
474494
Args:
475495
original_file_path (str): the path (including the name) of the original gms path
476496
"""
477-
# Get the directory and filename
478-
directory, filename = os.path.split(original_file_path)
497+
# Get the directory and filename
498+
499+
directory, filename = os.path.split(os.path.abspath(original_file_path))
479500
name, ext = os.path.splitext(filename)
480501

481502
assert ext == ".gms", "the original data file should be a gms file"
@@ -492,7 +513,7 @@ def file_name_creator(original_file_path):
492513

493514
### Generic functions called inside the specific scenario creator
494515
def _add_or_get_set(mi, out_set):
495-
# Captures the set, thanks to the data of the out_database. If it hasn't been added yet to the model insatnce it adds it as well
516+
# Captures the set using data from the out_database. If it hasn't been added yet to the model insatnce it adds it as well
496517
try:
497518
return mi.sync_db.add_set(out_set.name, out_set._dim, out_set.text)
498519
except gams.GamsException:
@@ -505,22 +526,24 @@ def pre_instantiation_for_PH(ws, new_file_name, nonants_name_pairs, stoch_param_
505526
Args:
506527
ws (GamsWorkspace): the workspace to create the model instance
507528
new_file_name (str): the gms file in which is created the gams model with the ph_objective
508-
nonants_name_pairs (list of pairs (str, str)): for each non-anticipative variable, the name of the support set must be given with the name of the parameter
529+
nonants_name_pairs (list of pairs (str, str)): for each non-anticipative variable, the name of the support set must be given with the name of the paramete
509530
stoch_param_name_pairs (_type_): for each stochastic parameter, the name of the support set must be given with the name of the variable
510531
511532
Returns:
512533
tuple: include everything needed for creating the model instance
513-
nonant_set_sync_dict gives the name of all t
534+
nonant_set_sync_dict gives the name of all the elements of the sets presented as tuples. It is useful if the set is a cartesian set: i,j then the elements
535+
will be of the shape (element_in_i,element_in_j). Some functions iterate over this set.
536+
514537
"""
515538
### First create the model instance
516-
job = ws.add_job_from_file(new_file_name)
539+
job = ws.add_job_from_file(new_file_name.replace(".gms",""))
517540
cp = ws.add_checkpoint()
518541
mi = cp.add_modelinstance()
519542

520-
job.run(checkpoint=cp) # at this point the model with bad values is solved, it creates the file _gams_py_gjo0.lst
543+
job.run(checkpoint=cp) # at this point the model (with what data?) is solved, it creates the file _gams_py_gjo0.lst
521544

522545
### Add to the elements that should be modified the stochastic parameters
523-
# The parameters don't exist yet in the model instance, so they need to be redefined thanks to the job
546+
# The parameters don't exist yet in the model instance, so they need to be redefined using the job
524547
stoch_sets_out_dict = {param_name: [job.out_db.get_set(elementary_set) for elementary_set in set_name.split(",")] for set_name, param_name in stoch_param_name_pairs}
525548
stoch_sets_sync_dict = {param_name: [_add_or_get_set(mi, out_elementary_set) for out_elementary_set in out_elementary_sets] for param_name, out_elementary_sets in stoch_sets_out_dict.items()}
526549
glist = [gams.GamsModifier(mi.sync_db.add_parameter_dc(param_name, [sync_elementary_set for sync_elementary_set in sync_elementary_sets])) for param_name, sync_elementary_sets in stoch_sets_sync_dict.items()]

0 commit comments

Comments
 (0)