Skip to content

Commit

Permalink
Merge branch 'main' into __init__-test
Browse files Browse the repository at this point in the history
  • Loading branch information
jsiirola committed Aug 19, 2021
2 parents 5567cf7 + 8efb0aa commit 29fd4fd
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 61 deletions.
112 changes: 86 additions & 26 deletions pyomo/contrib/appsi/build.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,96 @@
# ___________________________________________________________________________
#
# Pyomo: Python Optimization Modeling Objects
# Copyright 2017 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 shutil
import glob
import os
import sys
import tempfile

def build_appsi():
from pyomo.common.envvar import PYOMO_CONFIG_DIR
from pyomo.common.fileutils import this_file_dir


def handleReadonly(function, path, excinfo):
excvalue = excinfo[1]
if excvalue.errno == errno.EACCES:
os.chmod(path, stat.S_IRWXU| stat.S_IRWXG| stat.S_IRWXO) # 0777
function(path)
else:
raise


def build_appsi(args=[]):
print('\n\n**** Building APPSI ****')
import setuptools
from distutils.dist import Distribution
import shutil
import glob
import os
from pybind11.setup_helpers import Pybind11Extension, build_ext
import pybind11.setup_helpers

original_pybind11_setup_helpers_macos = pybind11.setup_helpers.MACOS
pybind11.setup_helpers.MACOS = False

ext_modules = [Pybind11Extension("cmodel.cmodel",
['cmodel/src/expression.cpp',
'cmodel/src/common.cpp',
'cmodel/src/nl_writer.cpp',
'cmodel/src/lp_writer.cpp',
'cmodel/src/cmodel_bindings.cpp'])]

package_config = {'name': 'appsi',
'packages': list(),
'ext_modules': ext_modules,
'cmdclass': {"build_ext": build_ext}}
dist = Distribution(package_config)
appsi_root = this_file_dir()
sources = [
os.path.join(appsi_root, 'cmodel', 'src', file_)
for file_ in (
'expression.cpp',
'common.cpp',
'nl_writer.cpp',
'lp_writer.cpp',
'cmodel_bindings.cpp',
)
]

class appsi_build_ext(build_ext):
def run(self):
basedir = os.path.abspath(os.path.curdir)
if self.inplace:
tmpdir = os.path.join(this_file_dir(), 'cmodel')
else:
tmpdir = os.path.abspath(tempfile.mkdtemp())
print("Building in '%s'" % tmpdir)
os.chdir(tmpdir)
try:
super(appsi_build_ext, self).run()
if not self.inplace:
library = glob.glob("build/*/appsi_cmodel.*")[0]
target = os.path.join(
PYOMO_CONFIG_DIR, 'lib',
'python%s.%s' % sys.version_info[:2],
'site-packages', '.')
if not os.path.exists(target):
os.makedirs(target)
shutil.copy(library, target)
finally:
os.chdir(basedir)
if not self.inplace:
shutil.rmtree(tmpdir, onerror=handleReadonly)

try:
basedir = os.path.abspath(os.path.curdir)
current_dir = os.path.dirname(os.path.abspath(__file__))
os.chdir(current_dir)
original_pybind11_setup_helpers_macos = pybind11.setup_helpers.MACOS
pybind11.setup_helpers.MACOS = False

package_config = {
'name': 'appsi_cmodel',
'packages': [],
'ext_modules': [
Pybind11Extension("appsi_cmodel", sources)
],
'cmdclass': {
"build_ext": appsi_build_ext,
},
}

dist = Distribution(package_config)
dist.script_args = ['build_ext'] + args
dist.parse_command_line()
dist.run_command('build_ext')
library = glob.glob("build/*/cmodel/cmodel.*")[0]
shutil.copy(library, 'cmodel/')
finally:
os.chdir(basedir)
pybind11.setup_helpers.MACOS = original_pybind11_setup_helpers_macos


Expand All @@ -43,4 +100,7 @@ def __call__(self, parallel):


if __name__ == '__main__':
build_appsi()
# Note: this recognizes the "--inplace" command line argument: build
# directory will be put in the source tree (and preserved), and the
# SO will be left in appsi/cmodel.
build_appsi(sys.argv[1:])
36 changes: 36 additions & 0 deletions pyomo/contrib/appsi/cmodel/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# ___________________________________________________________________________
#
# Pyomo: Python Optimization Modeling Objects
# Copyright 2017 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.
# ___________________________________________________________________________

from pyomo.common.dependencies import attempt_import as _attempt_import

def _importer():
import os
import sys
from pyomo.common.envvar import PYOMO_CONFIG_DIR
try:
pyomo_config_dir = os.path.join(
PYOMO_CONFIG_DIR, 'lib', 'python%s.%s' % sys.version_info[:2],
'site-packages')
sys.path.insert(0, pyomo_config_dir)
import appsi_cmodel
except ImportError:
from . import appsi_cmodel
finally:
assert sys.path[0] == pyomo_config_dir
sys.path.pop(0)

return appsi_cmodel

cmodel, cmodel_available = _attempt_import(
'appsi_cmodel',
error_message=('Appsi requires building a small c++ extension. '
'Please use thye "pyomo build-extensions" command'),
importer=_importer,
)
13 changes: 12 additions & 1 deletion pyomo/contrib/appsi/cmodel/src/cmodel_bindings.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
/**___________________________________________________________________________
*
* Pyomo: Python Optimization Modeling Objects
* Copyright 2017 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.
* ___________________________________________________________________________
**/

#include "lp_writer.hpp"


PYBIND11_MODULE(cmodel, m)
PYBIND11_MODULE(appsi_cmodel, m)
{
m.attr("inf") = inf;
m.def("process_lp_constraints", &process_lp_constraints);
Expand Down
7 changes: 2 additions & 5 deletions pyomo/contrib/appsi/examples/tests/test_examples.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
from pyomo.contrib.appsi.examples import getting_started
import pyomo.common.unittest as unittest
import pyomo.environ as pe
try:
from pyomo.contrib.appsi.cmodel import cmodel
except ImportError:
raise unittest.SkipTest('appsi extensions are not available')
from pyomo.contrib.appsi.cmodel import cmodel_available
from pyomo.contrib import appsi


@unittest.skipUnless(cmodel_available, 'appsi extensions are not available')
class TestExamples(unittest.TestCase):
def test_getting_started(self):
try:
Expand Down
8 changes: 3 additions & 5 deletions pyomo/contrib/appsi/solvers/tests/test_persistent_solvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@
if not param_available:
raise unittest.SkipTest('Parameterized is not available.')
parameterized = parameterized.parameterized
try:
from pyomo.contrib.appsi.cmodel import cmodel
except ImportError:
raise unittest.SkipTest('appsi extensions are not available')
from pyomo.contrib.appsi.base import TerminationCondition, Results, PersistentSolver
from pyomo.contrib.appsi.cmodel import cmodel_available
from pyomo.contrib.appsi.solvers import Gurobi, Ipopt, Cplex, Cbc
from typing import Type
from pyomo.core.expr.numeric_expr import LinearExpression
Expand Down Expand Up @@ -56,7 +53,7 @@
fixed variables
"""


@unittest.skipUnless(cmodel_available, 'appsi extensions are not available')
class TestSolvers(unittest.TestCase):
@parameterized.expand(input=all_solvers)
def test_range_constraint(self, name: str, opt_class: Type[PersistentSolver]):
Expand Down Expand Up @@ -561,6 +558,7 @@ def test_log(self, name: str, opt_class: Type[PersistentSolver]):
self.assertAlmostEqual(m.y.value, -0.42630274815985264)


@unittest.skipUnless(cmodel_available, 'appsi extensions are not available')
class TestLegacySolverInterface(unittest.TestCase):
@parameterized.expand(input=all_solvers)
def test_param_updates(self, name: str, opt_class: Type[PersistentSolver]):
Expand Down
6 changes: 1 addition & 5 deletions pyomo/contrib/appsi/writers/cmodel_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
from pyomo.core.expr.numvalue import value, is_constant
from pyomo.core.expr import current as _expr
from pyomo.common.dependencies import attempt_import


cmodel, cmodel_available = attempt_import('pyomo.contrib.appsi.cmodel.cmodel',
'Appsi requires building a small c++ extension. '
'Please use thye "pyomo build-extensions" command')
from ..cmodel import cmodel, cmodel_available


class PyomoToCModelWalker(ExpressionValueVisitor):
Expand Down
10 changes: 2 additions & 8 deletions pyomo/contrib/appsi/writers/lp_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,10 @@
from pyomo.contrib.appsi.base import PersistentBase
from pyomo.core.base import SymbolMap, NumericLabeler, TextLabeler
from pyomo.common.timing import HierarchicalTimer
from pyomo.core.kernel.objective import minimize, maximize
from .config import WriterConfig
from .cmodel_converter import PyomoToCModelWalker
from pyomo.common.dependencies import attempt_import
from pyomo.core.kernel.objective import minimize, maximize


cmodel, cmodel_available = attempt_import('pyomo.contrib.appsi.cmodel.cmodel',
'Appsi requires building a small c++ extension. '
'Please use thye "pyomo build-extensions" command')

from ..cmodel import cmodel, cmodel_available

id = id

Expand Down
9 changes: 2 additions & 7 deletions pyomo/contrib/appsi/writers/nl_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,10 @@
from pyomo.contrib.appsi.base import PersistentBase
from pyomo.core.base import SymbolMap, NumericLabeler, TextLabeler
from pyomo.common.timing import HierarchicalTimer
from pyomo.core.kernel.objective import minimize
from .config import WriterConfig
from .cmodel_converter import PyomoToCModelWalker
from pyomo.common.dependencies import attempt_import
from pyomo.core.kernel.objective import minimize


cmodel, cmodel_available = attempt_import('pyomo.contrib.appsi.cmodel.cmodel',
'Appsi requires building a small c++ extension. '
'Please use thye "pyomo build-extensions" command')
from ..cmodel import cmodel, cmodel_available


class NLWriter(PersistentBase):
Expand Down
6 changes: 2 additions & 4 deletions pyomo/contrib/appsi/writers/tests/test_nl_writer.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import pyomo.common.unittest as unittest
from pyomo.common.tempfiles import TempfileManager
import pyomo.environ as pe
try:
from pyomo.contrib.appsi.cmodel import cmodel
except ImportError:
raise unittest.SkipTest('appsi extensions are not available')
from pyomo.contrib import appsi
from pyomo.contrib.appsi.cmodel import cmodel_available
import os


@unittest.skipUnless(cmodel_available, 'appsi extensions are not available')
class TestNLWriter(unittest.TestCase):
def _write_and_check_header(self, m, correct_lines):
writer = appsi.writers.NLWriter()
Expand Down

0 comments on commit 29fd4fd

Please sign in to comment.