Skip to content

Commit

Permalink
Merge branch 'main' into solver-refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
mrmundt committed Feb 14, 2024
2 parents 2c8a4d8 + 5903fbc commit cb085e1
Show file tree
Hide file tree
Showing 38 changed files with 1,629 additions and 472 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/release_wheel_creation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
CIBW_BUILD_VERBOSITY: 1
CIBW_BEFORE_BUILD: pip install cython pybind11
CIBW_CONFIG_SETTINGS: '--global-option="--with-cython --with-distributable-extensions"'
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: native_wheels
path: dist/*.whl
Expand Down Expand Up @@ -72,7 +72,7 @@ jobs:
CIBW_BUILD_VERBOSITY: 1
CIBW_BEFORE_BUILD: pip install cython pybind11
CIBW_CONFIG_SETTINGS: '--global-option="--with-cython --with-distributable-extensions"'
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: alt_wheels
path: dist/*.whl
Expand All @@ -91,7 +91,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand All @@ -102,7 +102,7 @@ jobs:
run: |
python setup.py --without-cython sdist --format=gztar
- name: Upload artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: generictarball
path: dist
Expand Down
26 changes: 13 additions & 13 deletions .github/workflows/test_branches.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
- name: Checkout Pyomo source
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Black Formatting Check
Expand Down Expand Up @@ -134,23 +134,23 @@ jobs:
| tr '\n' ' ' | sed 's/ \+/ /g' >> $GITHUB_ENV
#- name: Pip package cache
# uses: actions/cache@v3
# uses: actions/cache@v4
# if: matrix.PYENV == 'pip'
# id: pip-cache
# with:
# path: cache/pip
# key: pip-${{env.CACHE_VER}}.0-${{runner.os}}-${{matrix.python}}

#- name: OS package cache
# uses: actions/cache@v3
# uses: actions/cache@v4
# if: matrix.TARGET != 'osx'
# id: os-cache
# with:
# path: cache/os
# key: pkg-${{env.CACHE_VER}}.0-${{runner.os}}

- name: TPL package download cache
uses: actions/cache@v3
uses: actions/cache@v4
if: ${{ ! matrix.slim }}
id: download-cache
with:
Expand Down Expand Up @@ -202,13 +202,13 @@ jobs:
- name: Set up Python ${{ matrix.python }}
if: matrix.PYENV == 'pip'
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}

- name: Set up Miniconda Python ${{ matrix.python }}
if: matrix.PYENV == 'conda'
uses: conda-incubator/setup-miniconda@v2
uses: conda-incubator/setup-miniconda@v3
with:
auto-update-conda: false
python-version: ${{ matrix.python }}
Expand Down Expand Up @@ -648,7 +648,7 @@ jobs:
coverage xml -i
- name: Record build artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{github.job}}_${{env.GHA_JOBGROUP}}-${{env.GHA_JOBNAME}}
path: |
Expand All @@ -668,7 +668,7 @@ jobs:
uses: actions/checkout@v4

- name: Set up Python 3.8
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: 3.8

Expand Down Expand Up @@ -724,19 +724,19 @@ jobs:
# We need the source for .codecov.yml and running "coverage xml"

#- name: Pip package cache
# uses: actions/cache@v3
# uses: actions/cache@v4
# id: pip-cache
# with:
# path: cache/pip
# key: pip-${{env.CACHE_VER}}.0-${{runner.os}}-3.8

- name: Download build artifacts
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
path: artifacts

- name: Set up Python 3.8
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: 3.8

Expand Down Expand Up @@ -831,7 +831,7 @@ jobs:
- name: Upload codecov reports
if: github.repository_owner == 'Pyomo' || github.ref != 'refs/heads/main'
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
files: coverage.xml
token: ${{ secrets.PYOMO_CODECOV_TOKEN }}
Expand All @@ -843,7 +843,7 @@ jobs:
if: |
hashFiles('coverage-other.xml') != '' &&
(github.repository_owner == 'Pyomo' || github.ref != 'refs/heads/main')
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
files: coverage-other.xml
token: ${{ secrets.PYOMO_CODECOV_TOKEN }}
Expand Down
26 changes: 13 additions & 13 deletions .github/workflows/test_pr_and_main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
- name: Checkout Pyomo source
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Black Formatting Check
Expand Down Expand Up @@ -164,23 +164,23 @@ jobs:
| tr '\n' ' ' | sed 's/ \+/ /g' >> $GITHUB_ENV
#- name: Pip package cache
# uses: actions/cache@v3
# uses: actions/cache@v4
# if: matrix.PYENV == 'pip'
# id: pip-cache
# with:
# path: cache/pip
# key: pip-${{env.CACHE_VER}}.0-${{runner.os}}-${{matrix.python}}

#- name: OS package cache
# uses: actions/cache@v3
# uses: actions/cache@v4
# if: matrix.TARGET != 'osx'
# id: os-cache
# with:
# path: cache/os
# key: pkg-${{env.CACHE_VER}}.0-${{runner.os}}

- name: TPL package download cache
uses: actions/cache@v3
uses: actions/cache@v4
if: ${{ ! matrix.slim }}
id: download-cache
with:
Expand Down Expand Up @@ -232,13 +232,13 @@ jobs:
- name: Set up Python ${{ matrix.python }}
if: matrix.PYENV == 'pip'
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}

- name: Set up Miniconda Python ${{ matrix.python }}
if: matrix.PYENV == 'conda'
uses: conda-incubator/setup-miniconda@v2
uses: conda-incubator/setup-miniconda@v3
with:
auto-update-conda: false
python-version: ${{ matrix.python }}
Expand Down Expand Up @@ -678,7 +678,7 @@ jobs:
coverage xml -i
- name: Record build artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{github.job}}_${{env.GHA_JOBGROUP}}-${{env.GHA_JOBNAME}}
path: |
Expand All @@ -699,7 +699,7 @@ jobs:
uses: actions/checkout@v4

- name: Set up Python 3.8
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: 3.8

Expand Down Expand Up @@ -755,19 +755,19 @@ jobs:
# We need the source for .codecov.yml and running "coverage xml"

#- name: Pip package cache
# uses: actions/cache@v3
# uses: actions/cache@v4
# id: pip-cache
# with:
# path: cache/pip
# key: pip-${{env.CACHE_VER}}.0-${{runner.os}}-3.8

- name: Download build artifacts
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
path: artifacts

- name: Set up Python 3.8
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: 3.8

Expand Down Expand Up @@ -862,7 +862,7 @@ jobs:
- name: Upload codecov reports
if: github.repository_owner == 'Pyomo' || github.ref != 'refs/heads/main'
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
files: coverage.xml
token: ${{ secrets.PYOMO_CODECOV_TOKEN }}
Expand All @@ -874,7 +874,7 @@ jobs:
if: |
hashFiles('coverage-other.xml') != '' &&
(github.repository_owner == 'Pyomo' || github.ref != 'refs/heads/main')
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
files: coverage-other.xml
token: ${{ secrets.PYOMO_CODECOV_TOKEN }}
Expand Down
13 changes: 12 additions & 1 deletion pyomo/contrib/cp/repn/docplex_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
IndexedBooleanVar,
)
from pyomo.core.base.expression import ScalarExpression, _GeneralExpressionData
from pyomo.core.base.param import IndexedParam, ScalarParam
from pyomo.core.base.param import IndexedParam, ScalarParam, _ParamData
from pyomo.core.base.var import ScalarVar, _GeneralVarData, IndexedVar
import pyomo.core.expr as EXPR
from pyomo.core.expr.visitor import StreamBasedExpressionVisitor, identify_variables
Expand Down Expand Up @@ -805,6 +805,14 @@ def _handle_at_least_node(visitor, node, *args):
)


def _handle_all_diff_node(visitor, node, *args):
return (_GENERAL, cp.all_diff(_get_int_valued_expr(arg) for arg in args))


def _handle_count_if_node(visitor, node, *args):
return (_GENERAL, cp.count((_get_bool_valued_expr(arg) for arg in args), 1))


## CallExpression handllers


Expand Down Expand Up @@ -932,6 +940,8 @@ class LogicalToDoCplex(StreamBasedExpressionVisitor):
EXPR.ExactlyExpression: _handle_exactly_node,
EXPR.AtMostExpression: _handle_at_most_node,
EXPR.AtLeastExpression: _handle_at_least_node,
EXPR.AllDifferentExpression: _handle_all_diff_node,
EXPR.CountIfExpression: _handle_count_if_node,
EXPR.EqualityExpression: _handle_equality_node,
EXPR.NotEqualExpression: _handle_not_equal_node,
EXPR.InequalityExpression: _handle_inequality_node,
Expand Down Expand Up @@ -960,6 +970,7 @@ class LogicalToDoCplex(StreamBasedExpressionVisitor):
ScalarExpression: _before_named_expression,
IndexedParam: _before_indexed_param, # Because of indirection
ScalarParam: _before_param,
_ParamData: _before_param,
}

def __init__(self, cpx_model, symbolic_solver_labels=False):
Expand Down
41 changes: 40 additions & 1 deletion pyomo/contrib/cp/tests/test_docplex_walker.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@

from pyomo.core.base.range import NumericRange
from pyomo.core.expr.numeric_expr import MinExpression, MaxExpression
from pyomo.core.expr.logical_expr import equivalent, exactly, atleast, atmost
from pyomo.core.expr.logical_expr import (
equivalent,
exactly,
atleast,
atmost,
all_different,
count_if,
)
from pyomo.core.expr.relational_expr import NotEqualExpression

from pyomo.environ import (
Expand Down Expand Up @@ -401,6 +408,38 @@ def test_atmost_expression(self):
expr[1].equals(cp.less_or_equal(cp.count([a[i] == 4 for i in m.I], 1), 3))
)

def test_all_diff_expression(self):
m = self.get_model()
m.a.domain = Integers
m.a.bounds = (11, 20)
m.c = LogicalConstraint(expr=all_different(m.a))

visitor = self.get_visitor()
expr = visitor.walk_expression((m.c.body, m.c, 0))

a = {}
for i in m.I:
self.assertIn(id(m.a[i]), visitor.var_map)
a[i] = visitor.var_map[id(m.a[i])]

self.assertTrue(expr[1].equals(cp.all_diff(a[i] for i in m.I)))

def test_count_if_expression(self):
m = self.get_model()
m.a.domain = Integers
m.a.bounds = (11, 20)
m.c = Constraint(expr=count_if(m.a[i] == i for i in m.I) == 5)

visitor = self.get_visitor()
expr = visitor.walk_expression((m.c.expr, m.c, 0))

a = {}
for i in m.I:
self.assertIn(id(m.a[i]), visitor.var_map)
a[i] = visitor.var_map[id(m.a[i])]

self.assertTrue(expr[1].equals(cp.count((a[i] == i for i in m.I), 1) == 5))

def test_interval_var_is_present(self):
m = self.get_model()
m.a.domain = Integers
Expand Down
Loading

0 comments on commit cb085e1

Please sign in to comment.