From 5048a11c6d7e32cc13f3ddfb9c84ace6bed18ba8 Mon Sep 17 00:00:00 2001 From: spefk Date: Mon, 19 Jan 2026 22:02:51 +0300 Subject: [PATCH 1/7] feat ci: add windows to tests configuration --- .github/workflows/python-checks.yaml | 38 ++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/.github/workflows/python-checks.yaml b/.github/workflows/python-checks.yaml index 16c008d..d389c62 100644 --- a/.github/workflows/python-checks.yaml +++ b/.github/workflows/python-checks.yaml @@ -37,48 +37,70 @@ jobs: # FIXME: try replace docformatter dependency to unblock version. python-version: [ "3.9", "3.13" ] poetry-version: ["2.1.1"] - os: [ubuntu-latest, macos-14, macos-15-intel] + os: [ubuntu-latest, macos-14, macos-15-intel, windows-latest] + runs-on: ${{ matrix.os }} + + # To use bash commands syntax on Windows. + defaults: + run: + shell: bash + # checks should not take more than 20 minutes (including build and setup step). # If it is the case probably something heavy trespassed to unit tests. timeout-minutes: 20 + + env: + DISABLE_ABC_CEXT: "1" + CMAKE_BUILD_PARALLEL_LEVEL: "8" + steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: submodules: 'true' + - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + - name: Update CMake uses: jwlawson/actions-setup-cmake@v2.0 + - name: Install poetry uses: snok/install-poetry@v1 with: version: ${{ matrix.poetry-version }} virtualenvs-create: true virtualenvs-in-project: true - - run: (export DISABLE_ABC_CEXT=1 && poetry build --no-interaction) - env: - DISABLE_ABC_CEXT: 1 - CMAKE_BUILD_PARALLEL_LEVEL: 8 - - run: (export DISABLE_ABC_CEXT=1 && poetry install --no-interaction) + + - name: Build + run: poetry build --no-interaction + + - name: Install deps + run: poetry install --no-interaction + - name: mypy if: always() run: poetry run mypy -p cirbo + - name: flake8 if: always() run: poetry run flake8 cirbo tests tools + - name: pytest if: always() run: poetry run pytest tests -v -m 'not (manual or slow or ABC)' + - name: usort if: always() run: poetry run usort check cirbo tests tools + - name: docformatter if: always() run: poetry run docformatter --check --diff cirbo/ tests/ tools/ + - name: black if: always() run: poetry run black --check --diff cirbo/ tests/ tools/ From 8daafb83e0641904d90854f9aebe0486d752cf6e Mon Sep 17 00:00:00 2001 From: spefk Date: Mon, 19 Jan 2026 22:13:06 +0300 Subject: [PATCH 2/7] bump poetry-core and setuptools versions --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2aeef9e..deed3ea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,8 +51,8 @@ Repository = "https://github.com/SPbSAT/cirbo" [build-system] requires = [ - "poetry-core>=1.0.0", - "setuptools>=45", + "poetry-core>=2.0.0,<3.0.0", + "setuptools>=65", "wheel", ] build-backend = "poetry.core.masonry.api" From 4123b0de11f32a3c95448f64ec4edc303167b339 Mon Sep 17 00:00:00 2001 From: spefk Date: Mon, 19 Jan 2026 22:26:07 +0300 Subject: [PATCH 3/7] downgrade max python version --- .github/workflows/python-checks.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-checks.yaml b/.github/workflows/python-checks.yaml index d389c62..39033c1 100644 --- a/.github/workflows/python-checks.yaml +++ b/.github/workflows/python-checks.yaml @@ -35,7 +35,7 @@ jobs: matrix: # >=3.14 is blocked by dependencies (`docformatter` seems blocked by `untokenize`). # FIXME: try replace docformatter dependency to unblock version. - python-version: [ "3.9", "3.13" ] + python-version: ["3.9", "3.13"] poetry-version: ["2.1.1"] os: [ubuntu-latest, macos-14, macos-15-intel, windows-latest] From a508cf5aeab31be51aca6904876e6e73f9883b96 Mon Sep 17 00:00:00 2001 From: spefk Date: Mon, 19 Jan 2026 22:36:18 +0300 Subject: [PATCH 4/7] try fix --- CMakeLists.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 187dc17..4721440 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,11 +19,16 @@ add_subdirectory(third_party/pybind11) add_subdirectory(third_party/mockturtle) pybind11_add_module(mockturtle_wrapper extensions/mockturtle_wrapper/src/module.cpp) - target_link_libraries(mockturtle_wrapper PRIVATE mockturtle) - target_include_directories(mockturtle_wrapper PRIVATE third_party) +# Fixes windows builds. +if (WIN32) + target_compile_definitions(mockturtle_wrapper PRIVATE + WIN32_LEAN_AND_MEAN NOMINMAX + _WIN32_WINNT=0x0601 WINVER=0x0601 + ) +endif() # ABC related libs can be disabled using environment variable. IF(NOT DISABLE_ABC_CEXT) @@ -32,7 +37,6 @@ IF(NOT DISABLE_ABC_CEXT) target_compile_options(libabc PRIVATE -fPIC) pybind11_add_module(abc_wrapper extensions/abc_wrapper/src/module.cpp) - target_link_libraries(abc_wrapper PRIVATE libabc) target_include_directories(abc_wrapper PRIVATE third_party) ENDIF(NOT DISABLE_ABC_CEXT) From a9a68acdad5984ede706e7f7f9b3f877f17c4647 Mon Sep 17 00:00:00 2001 From: spefk Date: Mon, 19 Jan 2026 22:39:44 +0300 Subject: [PATCH 5/7] try fix --- CMakeLists.txt | 8 -------- extensions/mockturtle_wrapper/src/module.cpp | 10 ++++++++++ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4721440..649df9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,14 +22,6 @@ pybind11_add_module(mockturtle_wrapper extensions/mockturtle_wrapper/src/module. target_link_libraries(mockturtle_wrapper PRIVATE mockturtle) target_include_directories(mockturtle_wrapper PRIVATE third_party) -# Fixes windows builds. -if (WIN32) - target_compile_definitions(mockturtle_wrapper PRIVATE - WIN32_LEAN_AND_MEAN NOMINMAX - _WIN32_WINNT=0x0601 WINVER=0x0601 - ) -endif() - # ABC related libs can be disabled using environment variable. IF(NOT DISABLE_ABC_CEXT) add_subdirectory(third_party/abc) diff --git a/extensions/mockturtle_wrapper/src/module.cpp b/extensions/mockturtle_wrapper/src/module.cpp index ba756ab..56e324c 100644 --- a/extensions/mockturtle_wrapper/src/module.cpp +++ b/extensions/mockturtle_wrapper/src/module.cpp @@ -1,3 +1,13 @@ +#ifdef _WIN32 + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + #ifndef NOMINMAX + #define NOMINMAX + #endif + #include +#endif + #include #include #include "cut_enumerates.hpp" From 68debfcae291ae77f39f7f82b6272572b45952db Mon Sep 17 00:00:00 2001 From: spefk Date: Tue, 20 Jan 2026 01:21:15 +0300 Subject: [PATCH 6/7] fix --- extensions/abc_wrapper/src/module.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/extensions/abc_wrapper/src/module.cpp b/extensions/abc_wrapper/src/module.cpp index 4f05e92..40ff699 100644 --- a/extensions/abc_wrapper/src/module.cpp +++ b/extensions/abc_wrapper/src/module.cpp @@ -1,3 +1,13 @@ +#ifdef _WIN32 + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + #ifndef NOMINMAX + #define NOMINMAX + #endif + #include +#endif + #include #include #include "run_abc.h" From 1857614bf5cb9665647a9c77487df93b6a5a8fb3 Mon Sep 17 00:00:00 2001 From: spefk Date: Tue, 20 Jan 2026 18:35:45 +0300 Subject: [PATCH 7/7] fix --- cirbo/synthesis/circuit_search.py | 48 +++++++++++++++++-------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/cirbo/synthesis/circuit_search.py b/cirbo/synthesis/circuit_search.py index ce6abab..9fe8fd8 100644 --- a/cirbo/synthesis/circuit_search.py +++ b/cirbo/synthesis/circuit_search.py @@ -3,12 +3,12 @@ import itertools import logging import multiprocessing as mp +import os import typing as tp from concurrent.futures import TimeoutError -from pebble import concurrent - +import pebble from pysat.formula import CNF, IDPool from pysat.solvers import Solver @@ -162,6 +162,20 @@ def _get_GateType_by_tt(gate_tt: tp.List[bool]) -> GateType: return _tt_to_gate_type[tuple(gate_tt)] +def _mp_ctx(): + # 'spawn' will be used on windows instead of a 'fork'. + return mp.get_context("spawn" if os.name == "nt" else "fork") + + +def _solve_cnf(solver_name: str, clauses: list[list[int]]) -> tp.Optional[tp.List[int]]: + s = Solver(name=solver_name, bootstrap_with=clauses) + try: + sat = s.solve() + return s.get_model() if sat else None + finally: + s.delete() + + class CircuitFinderSat: """ A class for finding Boolean circuits using SAT-solvers. @@ -288,27 +302,19 @@ def find_circuit( raise NoSolutionError() logger.debug(f"Running {solver_name.value}") - s = Solver(name=solver_name.value, bootstrap_with=self._cnf.clauses) if time_limit: - - # `pebble` has strange typing and argument actually is called - # `context` and not `mp_contest` as stated in typed signature. - @concurrent.process(timeout=time_limit, context=mp.get_context('fork')) # type: ignore - def cnf_from_bench_wrapper(): - s.solve() - return s.get_model() - - try: - future = cnf_from_bench_wrapper() - model = future.result() - except TimeoutError as te: - logger.debug("Solver timed out and is being stopped.") - s.delete() - raise SolverTimeOutError() from te + with pebble.ProcessPool(max_workers=1, context=_mp_ctx()) as pool: + future = pool.schedule( + _solve_cnf, + args=[solver_name.value, self._cnf.clauses], + timeout=time_limit, + ) + try: + model = future.result() + except TimeoutError as te: + raise SolverTimeOutError() from te else: - s.solve() - model = s.get_model() - s.delete() + model = _solve_cnf(solver_name.value, self._cnf.clauses) if model is None: raise NoSolutionError()