Skip to content

Commit

Permalink
Merge pull request Pyomo#2913 from jsiirola/gams-pickle
Browse files Browse the repository at this point in the history
GAMS: fix pickling models, update tests
  • Loading branch information
mrmundt authored Jul 19, 2023
2 parents be93e57 + 777d242 commit 4f2d5fc
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 95 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/test_branches.yml
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,8 @@ jobs:
echo "DYLD_LIBRARY_PATH=${env:DYLD_LIBRARY_PATH}:$GAMS_DIR" `
Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
$INSTALLER = "${env:DOWNLOAD_DIR}/gams_install.exe"
# We are pinning to 29.1.0 because a license is required for
# versions after this in order to run in demo mode.
$URL = "https://d37drm4t2jghv5.cloudfront.net/distributions/29.1.0"
if ( "${{matrix.TARGET}}" -eq "win" ) {
$URL = "$URL/windows/windows_x64_64.exe"
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/test_pr_and_main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,8 @@ jobs:
echo "DYLD_LIBRARY_PATH=${env:DYLD_LIBRARY_PATH}:$GAMS_DIR" `
Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
$INSTALLER = "${env:DOWNLOAD_DIR}/gams_install.exe"
# We are pinning to 29.1.0 because a license is required for
# versions after this in order to run in demo mode.
$URL = "https://d37drm4t2jghv5.cloudfront.net/distributions/29.1.0"
if ( "${{matrix.TARGET}}" -eq "win" ) {
$URL = "$URL/windows/windows_x64_64.exe"
Expand Down
39 changes: 23 additions & 16 deletions pyomo/repn/plugins/gams_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,27 @@ def split_long_line(line):
return new_lines


class GAMSSymbolMap(SymbolMap):
def __init__(self, var_labeler, var_list):
super().__init__(self.var_label)
self.var_labeler = var_labeler
self.var_list = var_list

def var_label(self, obj):
# if obj.is_fixed():
# return str(value(obj))
return self.getSymbol(obj, self.var_recorder)

def var_recorder(self, obj):
ans = self.var_labeler(obj)
try:
if obj.is_variable_type():
self.var_list.append(ans)
except:
pass
return ans


@WriterFactory.register('gams', 'Generate the corresponding GAMS file')
class ProblemWriter_gams(AbstractProblemWriter):
def __init__(self):
Expand Down Expand Up @@ -492,21 +513,7 @@ def __call__(self, model, output_filename, solver_capability, io_options):

var_list = []

def var_recorder(obj):
ans = var_labeler(obj)
try:
if obj.is_variable_type():
var_list.append(ans)
except:
pass
return ans

def var_label(obj):
# if obj.is_fixed():
# return str(value(obj))
return symbolMap.getSymbol(obj, var_recorder)

symbolMap = SymbolMap(var_label)
symbolMap = GAMSSymbolMap(var_labeler, var_list)

# when sorting, there are a non-trivial number of
# temporary objects created. these all yield
Expand All @@ -527,7 +534,7 @@ def var_label(obj):
output_file=output_file,
solver_capability=solver_capability,
var_list=var_list,
var_label=var_label,
var_label=symbolMap.var_label,
symbolMap=symbolMap,
con_labeler=con_labeler,
sort=sort,
Expand Down
10 changes: 9 additions & 1 deletion pyomo/solvers/tests/checks/test_pickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,15 @@ def return_test(self):
for key, value in generate_scenarios(lambda c: c.test_pickling):
model, solver, io = key
cls = driver[model]

# July 19, 2023: There is an issue with certain GAMS cases that is
# causing failures. This is not universal, however, so we cannot add
# the cases directly to testcases.py.
if (
(solver == 'gams')
and (io in ['gms', 'python'])
and ('.LP_simple_kernel' in str(value.model))
):
value.status = 'expected failure'
# Symbolic labels
test_name = "test_" + solver + "_" + io + "_symbolic_labels"
test_method = create_method(model, solver, io, value, True)
Expand Down
2 changes: 1 addition & 1 deletion pyomo/solvers/tests/solvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# This software is distributed under the 3-clause BSD License.
# ___________________________________________________________________________

__all__ = ['test_solver_cases', 'available_solvers']
__all__ = ['test_solver_cases']

import logging

Expand Down
97 changes: 20 additions & 77 deletions pyomo/solvers/tests/testcases.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,26 @@
# NO EXPECTED FAILURES
#

#
# GAMS
#

ExpectedFailures['gams', 'gms', 'MILP_unbounded'] = (
lambda v: v <= _trunk_version,
"GAMS requires finite bounds for integer variables. 1.0E100 is as extreme"
"as GAMS will define, and should be enough to appear unbounded. If the"
"solver cannot handle this bound, explicitly set a smaller bound on"
"the pyomo model, or try a different GAMS solver.",
)

ExpectedFailures['gams', 'python', 'MILP_unbounded'] = (
lambda v: v <= _trunk_version,
"GAMS requires finite bounds for integer variables. 1.0E100 is as extreme"
"as GAMS will define, and should be enough to appear unbounded. If the"
"solver cannot handle this bound, explicitly set a smaller bound on"
"the pyomo model, or try a different GAMS solver.",
)

#
# GLPK
#
Expand Down Expand Up @@ -261,83 +281,6 @@
'BARON 22.1.19 reports model as optimal',
)

#
# The following were necessary before we started adding the 'WantDual'
# option when a user explicitly defines a 'dual' or 'rc' suffix to
# "force" Baron to run a local solve (if necessary) and always return
# dual nformation.
#

# # Known to fail through 18.11.15, but was resolved by 19.12.7
# ExpectedFailures['baron', 'bar', 'MILP_unbounded'] = (
# lambda v: v <= (18,11,15),
# ['dual'],
# "Baron fails to report a MILP model as unbounded")

# # Known to work through 18.11.15, and fail in 19.12.7
# MissingSuffixFailures['baron', 'bar', 'LP_piecewise'] = (
# lambda v: v <= (15,0,0,0) or v > (18,11,15),
# ['dual'],
# "Baron will not return dual solution when a solution is "
# "found during preprocessing.")

# # Marking this test suffixes as fragile: Baron 20.4.14 will
# # intermittently return suffixes.
# MissingSuffixFailures['baron', 'bar', 'QP_simple'] = (
# lambda v: v <= (15,2,0,0) or v > (18,11,15),
# {'dual': (False, {}), 'rc': (False, {})},
# "Baron will intermittently return dual solution when "
# "a solution is found during preprocessing.")

# # Known to fail through 17.4.1, but was resolved by 18.5.9
# MissingSuffixFailures['baron', 'bar', 'QCP_simple'] = (
# lambda v: v <= (17,4,1) or v > (18,11,15),
# ['dual','rc'],
# "Baron will not return dual solution when a solution is "
# "found during preprocessing.")

# # Known to work through 18.11.15, and fail in 19.12.7
# MissingSuffixFailures['baron', 'bar', 'LP_block'] = (
# lambda v: v > (18,11,15),
# ['dual'],
# "Baron will not return dual solution when a solution is "
# "found during preprocessing.")

# # Known to work through 18.11.15, and fail in 19.12.7
# MissingSuffixFailures['baron', 'bar', 'LP_inactive_index'] = (
# lambda v: v > (18,11,15),
# ['dual'],
# "Baron will not return dual solution when a solution is "
# "found during preprocessing.")

# # Known to work through 18.11.15, and fail in 19.12.7
# MissingSuffixFailures['baron', 'bar', 'LP_simple'] = (
# lambda v: v > (18,11,15),
# ['dual'],
# "Baron will not return dual solution when a solution is "
# "found during preprocessing.")

# # Known to work through 18.11.15, and fail in 19.12.7
# MissingSuffixFailures['baron', 'bar', 'LP_trivial_constraints'] = (
# lambda v: v > (18,11,15),
# ['dual'],
# "Baron will not return dual solution when a solution is "
# "found during preprocessing.")

# # Known to work through 19.12.7, and fail in 20.4.14
# MissingSuffixFailures['baron', 'bar', 'LP_duals_minimize'] = (
# lambda v: v > (19,12,7),
# ['dual','rc'],
# "Baron will not return dual solution when a solution is "
# "found during preprocessing.")

# # Known to work through 19.12.7, and fail in 20.4.14
# MissingSuffixFailures['baron', 'bar', 'LP_duals_maximize'] = (
# lambda v: v > (19,12,7),
# ['dual','rc'],
# "Baron will not return dual solution when a solution is "
# "found during preprocessing.")


#
# KNITROAMPL
Expand Down

0 comments on commit 4f2d5fc

Please sign in to comment.