Updates to support clingo-cffi (#20657)
* Support clingo when used with cffi Clingo recently merged in a new Python module option based on cffi. Compatibility with this module requires a few changes to spack - it does not automatically convert strings/ints/etc to Symbol and clingo.Symbol.string throws on failure. manually convert str/int to clingo.Symbol types catch stringify exceptions add job for clingo-cffi to Spack CI switch to potassco-vendored wheel for clingo-cffi CI on_unsat argument when cffi
This commit is contained in:
parent
6622856076
commit
93ed1a410c
2 changed files with 70 additions and 9 deletions
51
.github/workflows/linux_unit_tests.yaml
vendored
51
.github/workflows/linux_unit_tests.yaml
vendored
|
@ -165,3 +165,54 @@ jobs:
|
|||
- uses: codecov/codecov-action@v1
|
||||
with:
|
||||
flags: unittests,linux,clingo
|
||||
clingo-cffi:
|
||||
# Test for the clingo based solver using the CFFI package
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.8
|
||||
- name: Install System packages
|
||||
run: |
|
||||
sudo apt-get -y update
|
||||
# Needed for unit tests
|
||||
sudo apt-get install -y coreutils gfortran graphviz gnupg2 mercurial
|
||||
sudo apt-get install -y ninja-build patchelf
|
||||
# Needed for kcov
|
||||
sudo apt-get -y install cmake binutils-dev libcurl4-openssl-dev
|
||||
sudo apt-get -y install zlib1g-dev libdw-dev libiberty-dev
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
pip install --upgrade pip six setuptools codecov coverage cffi
|
||||
pip install -i https://test.pypi.org/simple/ clingo-cffi
|
||||
- name: Setup git configuration
|
||||
run: |
|
||||
# Need this for the git tests to succeed.
|
||||
git --version
|
||||
. .github/workflows/setup_git.sh
|
||||
- name: Install kcov for bash script coverage
|
||||
env:
|
||||
KCOV_VERSION: 34
|
||||
run: |
|
||||
KCOV_ROOT=$(mktemp -d)
|
||||
wget --output-document=${KCOV_ROOT}/${KCOV_VERSION}.tar.gz https://github.com/SimonKagstrom/kcov/archive/v${KCOV_VERSION}.tar.gz
|
||||
tar -C ${KCOV_ROOT} -xzvf ${KCOV_ROOT}/${KCOV_VERSION}.tar.gz
|
||||
mkdir -p ${KCOV_ROOT}/build
|
||||
cd ${KCOV_ROOT}/build && cmake -Wno-dev ${KCOV_ROOT}/kcov-${KCOV_VERSION} && cd -
|
||||
make -C ${KCOV_ROOT}/build && sudo make -C ${KCOV_ROOT}/build install
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
whoami && echo PWD=$PWD && echo HOME=$HOME && echo SPACK_TEST_SOLVER=$SPACK_TEST_SOLVER
|
||||
python -c "import clingo; print(hasattr(clingo.Symbol, '_rep'), clingo.__version__)"
|
||||
. share/spack/setup-env.sh
|
||||
spack compiler find
|
||||
spack solve mpileaks%gcc
|
||||
coverage run $(which spack) unit-test -v
|
||||
coverage combine
|
||||
coverage xml
|
||||
- uses: codecov/codecov-action@v1
|
||||
with:
|
||||
flags: unittests,linux,clingo
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
try:
|
||||
import clingo
|
||||
# There may be a better way to detect this
|
||||
clingo_cffi = hasattr(clingo.Symbol, '_rep')
|
||||
except ImportError:
|
||||
clingo = None # type: ignore
|
||||
|
||||
|
@ -119,11 +121,11 @@ def __call__(self, *args):
|
|||
def symbol(self, positive=True):
|
||||
def argify(arg):
|
||||
if isinstance(arg, bool):
|
||||
return str(arg)
|
||||
return clingo.String(str(arg))
|
||||
elif isinstance(arg, int):
|
||||
return arg
|
||||
return clingo.Number(arg)
|
||||
else:
|
||||
return str(arg)
|
||||
return clingo.String(str(arg))
|
||||
return clingo.Function(
|
||||
self.name, [argify(arg) for arg in self.args], positive=positive)
|
||||
|
||||
|
@ -318,17 +320,25 @@ def solve(
|
|||
def on_model(model):
|
||||
models.append((model.cost, model.symbols(shown=True, terms=True)))
|
||||
|
||||
solve_result = self.control.solve(
|
||||
assumptions=self.assumptions,
|
||||
on_model=on_model,
|
||||
on_core=cores.append
|
||||
)
|
||||
solve_kwargs = {"assumptions": self.assumptions,
|
||||
"on_model": on_model,
|
||||
"on_core": cores.append}
|
||||
if clingo_cffi:
|
||||
solve_kwargs["on_unsat"] = cores.append
|
||||
solve_result = self.control.solve(**solve_kwargs)
|
||||
timer.phase("solve")
|
||||
|
||||
# once done, construct the solve result
|
||||
result.satisfiable = solve_result.satisfiable
|
||||
|
||||
def stringify(x):
|
||||
if clingo_cffi:
|
||||
# Clingo w/ CFFI will throw an exception on failure
|
||||
try:
|
||||
return x.string
|
||||
except RuntimeError:
|
||||
return str(x)
|
||||
else:
|
||||
return x.string or str(x)
|
||||
|
||||
if result.satisfiable:
|
||||
|
|
Loading…
Reference in a new issue