Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
1177492
Added new GAMS solver interface, writer, and solution loader. WIP: un…
Aug 7, 2025
2385654
Ran black -S -C on commited files
Aug 7, 2025
b36086f
Typo!
mrmundt Aug 7, 2025
e91e480
Added ignore checking for constant in the objective function during w…
Aug 7, 2025
b060096
Added support for add_options for multiple solver_options
Aug 8, 2025
96ba646
typo
Aug 8, 2025
b0f16a3
ran black formatter
Aug 8, 2025
dde656c
added add_options in the solver_interface
Aug 8, 2025
3476f72
Fixed bug with unable to create tmpdir. Updated test_gams_v2.py
Aug 8, 2025
ddfd98c
Merge branch 'main' into GAMS_new_solver_interface
AnhTran01 Aug 8, 2025
eb0a3db
Added handling single bounded variable case (None,#) or (#, None)
Aug 10, 2025
c6d2d01
Match solver interface and writer configs to prevent implicit definit…
Aug 11, 2025
2a6dcb7
Added new gams solver interface for test_all_solvers_list()
Aug 12, 2025
b6ead27
Fixed bug of handling valid ub when writing pyomo expression
Aug 12, 2025
89f80e0
Fixed bug when using ComponentMap to extract duals in gms_sol_reader.py
Aug 13, 2025
b0c3450
Corrected handling of solution_loader. Implemented bounded constraint…
Aug 14, 2025
a9df1d7
Added offdigit based on error log message suggestion
Aug 14, 2025
e04c89f
Merge branch 'main' into GAMS_new_solver_interface
mrmundt Aug 15, 2025
518758e
Fixed bug of extracting constraint dual when alias exits (for bounded…
Aug 18, 2025
a2ef9cc
Added aliases as part of parse_dat_results to be consistent with pars…
Aug 18, 2025
c33095d
Removed code duplication between the solver interface and writer by p…
Aug 18, 2025
f609ca2
Revised code based on John's review. WIP: Handling rehash within avai…
Aug 19, 2025
ec5aa6a
Re-added config into available and version, and deprecated test that …
Aug 19, 2025
e760a1c
Merge branch 'main' into GAMS_new_solver_interface
mrmundt Aug 19, 2025
7bb817b
Sanity check config.writer_config.put_results_format without setdefault
Aug 20, 2025
72beeaf
Allow user to modify writer config via solver_options. Fixed bug of s…
Aug 20, 2025
3dc83ca
Merge branch 'Pyomo:main' into GAMS_new_solver_interface
AnhTran01 Aug 20, 2025
5c87b75
Corrected exeception type raised when solver return infeasible. Added…
Aug 20, 2025
d6aa9ff
Corrected test_gams_v2.py to match error raised. Corrected error mess…
Aug 20, 2025
aba0eed
Merge branch 'Pyomo:main' into GAMS_new_solver_interface
AnhTran01 Aug 20, 2025
f85d217
Prevent rewrite of termination condition in modelstat if the value is…
Aug 20, 2025
0e94742
Added an gams_solver_options (handled via solver_option in solve). Ad…
Aug 20, 2025
9d5758e
Divided solver and model termination condition into separate config.
Aug 21, 2025
d1285e3
Merge branch 'Pyomo:main' into GAMS_new_solver_interface
AnhTran01 Aug 21, 2025
2973d9c
Added unittest skipif for linux_3.9_slim and linux_3.12_numpy failed …
Aug 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Re-added config into available and version, and deprecated test that …
…are no longer valid.
  • Loading branch information
Norman_Tran committed Aug 19, 2025
commit ec5aa6ae9e173c7f9b34ae83844852dbdc9b7379
20 changes: 16 additions & 4 deletions pyomo/contrib/solver/solvers/gams.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,14 @@ def __init__(self, **kwds):
self._available_cache = NOTSET
self._version_cache = NOTSET

def available(self, rehash: bool = False) -> Availability:
pth = self.config.executable.path()
def available(
self, config: Optional[GAMSConfig] = None, rehash: bool = False
) -> Availability:
if config is None:
config = self.config

pth = config.executable.path()

if pth is None:
self._available_cache = (None, Availability.NotFound)
else:
Expand Down Expand Up @@ -208,8 +214,14 @@ def _simple_model(self, n):
n,
)

def version(self, rehash: bool = False) -> Optional[Tuple[int, int, int]]:
pth = self.config.executable.path()
def version(
self, config: Optional[GAMSConfig] = None, rehash: bool = False
) -> Optional[Tuple[int, int, int]]:

if config is None:
config = self.config
pth = config.executable.path()

if pth is None:
self._version_cache = (None, None)
else:
Expand Down
41 changes: 36 additions & 5 deletions pyomo/contrib/solver/tests/solvers/test_gams_v2.py
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File should just be named test_gams.py - it's already implied that it's v2 by nature of being in contrib.solver.

Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def test_class_member_list(self):
'name',
'solve',
'version',
'license_is_valid',
# 'license_is_valid', # DEPRECATED
]
method_list = [method for method in dir(opt) if method.startswith('_') is False]
self.assertEqual(sorted(expected_list), sorted(method_list))
Expand All @@ -128,6 +128,9 @@ def test_context_manager(self):
self.assertEqual(opt.CONFIG, opt.config)
self.assertTrue(opt.available())

@unittest.skip(
"deprecated: available() is deprecated. available_cache is intended to replace this"
)
Comment on lines +138 to +140
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fairly certain this is not true. We are splitting available and license_is_valid plus plan to implement an availability cache, but we aren't getting rid of available.

def test_available(self):
opt = gams.GAMS()
self.assertTrue(opt.available())
Expand All @@ -140,6 +143,9 @@ def test_available(self):
# _run_simple_model will return False because of the invalid path
self.assertFalse(opt._run_simple_model(config, 1))

@unittest.skip(
"deprecated: test_version() is deprecated. test_version_cache is intended to replace this"
)
def test_version(self):
opt = gams.GAMS()
self.assertIsNotNone(opt.version())
Expand Down Expand Up @@ -170,6 +176,30 @@ def test_write_gms_file(self):
self.assertTrue(result.returncode == 0)
self.assertTrue(os.path.isfile(filename))

def test_available_cache(self):
opt = gams.GAMS()
opt.available()
self.assertTrue(opt._available_cache[1])
self.assertIsNotNone(opt._available_cache[0])
# Now we will try with a custom config that has a fake path
config = gams.GAMSConfig()
config.executable = Executable('/a/bogus/path')
opt.available(config=config)
self.assertFalse(opt._available_cache[1])
self.assertIsNone(opt._available_cache[0])

def test_version_cache(self):
opt = gams.GAMS()
opt.version()
self.assertIsNotNone(opt._version_cache[0])
self.assertIsNotNone(opt._version_cache[1])
# Now we will try with a custom config that has a fake path
config = gams.GAMSConfig()
config.executable = Executable('/a/bogus/path')
opt.version(config=config)
self.assertIsNone(opt._version_cache[0])
self.assertIsNone(opt._version_cache[1])


class TestGAMS(unittest.TestCase):
def create_model(self):
Expand All @@ -193,9 +223,10 @@ def test_gams_config(self):
# Test custom initialization
solver = SolverFactory('gams_v2', executable='/path/to/exe')
self.assertFalse(solver.config.tee)
self.assertTrue(solver.config.executable.startswith('/path'))
self.assertIsNone(solver.config.executable.path())
self.assertTrue(solver.config.executable._registered_name.startswith('/path'))

# Change value on a solve call
solver = SolverFactory('gams_v2')
def test_gams_solve(self):
# Gut check - does it solve?
model = self.create_model()
solver.solve(model, tee=False, load_solutions=False)
gams.GAMS().solve(model)
Loading