# ____________________________________________________________________________________
#
# Pyomo: Python Optimization Modeling Objects
# Copyright (c) 2008-2026 National Technology and Engineering Solutions of Sandia, LLC
# Under the terms of Contract DE-NA0003525 with National Technology and Engineering
# Solutions of Sandia, LLC, the U.S. Government retains certain rights in this
# software. This software is distributed under the 3-clause BSD License.
# ____________________________________________________________________________________
import os
from pyomo.common.tempfiles import TempfileManager
from pyomo.opt.base import ProblemFormat
from pyomo.opt.base.convert import ProblemConverterFactory
from pyomo.solvers.plugins.converter.pico import PicoMIPConverter
from pyomo.core.kernel.block import IBlock
[docs]
@ProblemConverterFactory.register('pyomo')
class PyomoMIPConverter:
pico_converter = PicoMIPConverter()
[docs]
def can_convert(self, from_type, to_type):
"""Returns true if this object supports the specified conversion"""
if from_type != ProblemFormat.pyomo:
return False
#
# Return True for specific from/to pairs
#
if to_type in (
ProblemFormat.nl,
ProblemFormat.cpxlp,
ProblemFormat.osil,
ProblemFormat.bar,
ProblemFormat.mps,
):
return True
return False
[docs]
def apply(self, *args, **kwds):
"""
Generate a NL or LP file from Pyomo, and then do subsequent
conversions.
"""
import pyomo.scripting.convert
capabilities = kwds.pop("capabilities", None)
# all non-consumed keywords are assumed to be options
# that should be passed to the writer.
io_options = {}
for kwd, value in kwds.items():
io_options[kwd] = value
kwds.clear()
if isinstance(args[2], str):
instance = None
else:
instance = args[2]
if args[1] == ProblemFormat.cpxlp:
problem_filename = TempfileManager.create_tempfile(suffix='.pyomo.lp')
if instance is not None:
if isinstance(instance, IBlock):
symbol_map_id = instance.write(
problem_filename,
format=ProblemFormat.cpxlp,
_solver_capability=capabilities,
_called_by_solver=True,
**io_options,
)
else:
problem_filename, symbol_map_id = instance.write(
filename=problem_filename,
format=ProblemFormat.cpxlp,
solver_capability=capabilities,
io_options=io_options,
)
return (problem_filename,), symbol_map_id
else:
#
# I'm simply exposing a fatal issue with
# this code path. How would we convert the
# collected keywords into command-line
# arguments that can be sent to the writer?
#
if len(io_options):
raise ValueError(
"The following io_options will be ignored "
"(please create a bug report):\n\t"
+ "\n\t".join("%s = %s" % (k, v) for k, v in io_options.items())
)
ans = pyomo.scripting.convert.pyomo2lp(
['--output', problem_filename, args[2]]
)
if ans.errorcode:
raise RuntimeError(
"pyomo2lp conversion "
"returned nonzero error code "
"(%s)" % ans.errorcode
)
model = ans.retval
problem_filename = model.filename
symbol_map = model.symbol_map
return (problem_filename,), symbol_map
elif args[1] == ProblemFormat.bar:
problem_filename = TempfileManager.create_tempfile(suffix='.pyomo.bar')
if instance is not None:
if isinstance(instance, IBlock):
symbol_map_id = instance.write(
problem_filename,
format=ProblemFormat.bar,
_solver_capability=capabilities,
_called_by_solver=True,
**io_options,
)
else:
problem_filename, symbol_map_id = instance.write(
filename=problem_filename,
format=ProblemFormat.bar,
solver_capability=capabilities,
io_options=io_options,
)
return (problem_filename,), symbol_map_id
else:
#
# I'm simply exposing a fatal issue with
# this code path. How would we convert the
# collected keywords into command-line
# arguments that can be sent to the writer?
#
if len(io_options):
raise ValueError(
"The following io_options will be ignored "
"(please create a bug report):\n\t"
+ "\n\t".join("%s = %s" % (k, v) for k, v in io_options.items())
)
ans = pyomo.scripting.convert.pyomo2bar(
['--output', problem_filename, args[2]]
)
if ans.errorcode:
raise RuntimeError(
"pyomo2bar conversion "
"returned nonzero error code "
"(%s)" % ans.errorcode
)
model = ans.retval
problem_filename = model.filename
symbol_map = model.symbol_map
return (problem_filename,), symbol_map
elif args[1] in [ProblemFormat.mps, ProblemFormat.nl]:
if args[1] == ProblemFormat.nl:
problem_filename = TempfileManager.create_tempfile(suffix='.pyomo.nl')
if io_options.get("symbolic_solver_labels", False):
TempfileManager.add_tempfile(
problem_filename[:-3] + ".row", exists=False
)
TempfileManager.add_tempfile(
problem_filename[:-3] + ".col", exists=False
)
else:
assert args[1] == ProblemFormat.mps
problem_filename = TempfileManager.create_tempfile(suffix='.pyomo.mps')
if instance is not None:
if isinstance(instance, IBlock):
symbol_map_id = instance.write(
problem_filename,
format=args[1],
_solver_capability=capabilities,
_called_by_solver=True,
**io_options,
)
else:
problem_filename, symbol_map_id = instance.write(
filename=problem_filename,
format=args[1],
solver_capability=capabilities,
io_options=io_options,
)
return (problem_filename,), symbol_map_id
else:
#
# I'm simply exposing a fatal issue with
# this code path. How would we convert the
# collected keywords into command-line
# arguments that can be sent to the writer?
#
if len(io_options):
raise ValueError(
"The following io_options will be ignored "
"(please create a bug report):\n\t"
+ "\n\t".join("%s = %s" % (k, v) for k, v in io_options.items())
)
ans = pyomo.scripting.convert.pyomo2nl(
['--output', problem_filename, args[2]]
)
if ans.errorcode:
raise RuntimeError(
"pyomo2nl conversion "
"returned nonzero error "
"code (%s)" % ans.errorcode
)
model = ans.retval
problem_filename = model.filename
symbol_map = model.symbol_map
if args[1] == ProblemFormat.nl:
return (problem_filename,), symbol_map
#
# Convert from NL to MPS
#
# TBD: We don't support a variable map file when going
# from NL to MPS within the PICO converter.
# NOTE: this is a problem with the MPS writer that is
# provided by COIN-OR
# NOTE: we should generalize this so it doesn't strictly
# depend on the PICO converter utility.
#
ans = self.pico_converter.apply(
ProblemFormat.nl, ProblemFormat.mps, problem_filename
)
os.remove(problem_filename)
return ans
elif args[1] == ProblemFormat.osil:
if False:
problem_filename = TempfileManager.create_tempfile(suffix='pyomo.osil')
if instance:
if isinstance(instance, IBlock):
symbol_map_id = instance.write(
problem_filename,
format=ProblemFormat.osil,
_solver_capability=capabilities,
_called_by_solver=True,
**io_options,
)
else:
problem_filename, symbol_map_id = instance.write(
filename=problem_filename,
format=ProblemFormat.osil,
solver_capability=capabilities,
io_options=io_options,
)
return (problem_filename,), None
else:
raise NotImplementedError(
"There is currently no "
"script conversion available from "
"Pyomo to OSiL format."
)