Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MathOpt: python_math_opt_solver_test failed on macOS #4460

Open
Mizux opened this issue Dec 2, 2024 · 2 comments
Open

MathOpt: python_math_opt_solver_test failed on macOS #4460

Mizux opened this issue Dec 2, 2024 · 2 comments
Assignees
Labels
Bug Lang: Python Python wrapper issue OS: Mac MacOS Solver: MathOpt MathOpt related issue
Milestone

Comments

@Mizux
Copy link
Collaborator

Mizux commented Dec 2, 2024

What version of OR-Tools and what language are you using?
Version: main and v99bugfix
OS: MacOS
Language: Python

Which solver are you using (e.g. CP-SAT, Routing Solver, GLOP, BOP, Gurobi)
MathOpt

What did you do?
Build and running python on macOS...

cmake -S. -Bbuild -DBUILD_PYTHON=ON -DBUILD_EXAMPLES=OFF -DBUILD_SAMPLES=OFF
cmake --build build -j 8
(cd build && ctest -C Release --output-on-failure -R "python_math_opt_solver_test")

What did you expect to see
all test passed

What did you see instead?
runner trace:

139/456 Test #139: python_math_opt_solver_test ................................................***Failed    0.63 sec
============================= test session starts ==============================
platform darwin -- Python 3.12.7, pytest-8.3.4, pluggy-1.5.0
rootdir: /Users/runner/work/or-tools/or-tools
collected 15 items

../../../ortools/math_opt/core/python/solver_test.py ..FF...........     [100%]

=================================== FAILURES ===================================
_________ PybindSolverTest.test_invalid_input_throws_error_with_solver _________

self = <solver_test.PybindSolverTest testMethod=test_invalid_input_throws_error_with_solver>
use_solver_class = True

    @parameterized.named_parameters(
        dict(testcase_name="without_solver", use_solver_class=False),
        dict(testcase_name="with_solver", use_solver_class=True),
    )
    def test_invalid_input_throws_error(self, use_solver_class: bool) -> None:
        model = _build_simple_model()
        # Add invalid variable id to cause MathOpt model validation error.
        model.objective.linear_coefficients.ids.append(7)
        model.objective.linear_coefficients.values.append(2.0)
        with self.assertRaisesRegex(StatusNotOk, "id 7 not found"):
>           _solve_model(model, use_solver_class=use_solver_class)

../../../ortools/math_opt/core/python/solver_test.py:115: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def _solve_model(
        model: model_pb2.ModelProto,
        *,
        use_solver_class: bool,
        solver_type: parameters_pb2.SolverTypeProto = parameters_pb2.SOLVER_TYPE_GLOP,
        solver_initializer: parameters_pb2.SolverInitializerProto = parameters_pb2.SolverInitializerProto(),
        parameters: parameters_pb2.SolveParametersProto = parameters_pb2.SolveParametersProto(),
        model_parameters: model_parameters_pb2.ModelSolveParametersProto = model_parameters_pb2.ModelSolveParametersProto(),
        message_callback: Optional[Callable[[Sequence[str]], None]] = None,
        callback_registration: callback_pb2.CallbackRegistrationProto = callback_pb2.CallbackRegistrationProto(),
        user_cb: Optional[
            Callable[[callback_pb2.CallbackDataProto], callback_pb2.CallbackResultProto]
        ] = None,
        interrupter: Optional[solver.SolveInterrupter] = None,
    ) -> result_pb2.SolveResultProto:
        """Convenience function for both types of solve with parameter defaults."""
        if use_solver_class:
>           pybind_solver = solver.new(
                solver_type,
                model,
                solver_initializer,
            )
E           RuntimeError: INVALID_ARGUMENT: id 7 not found; Objective.linear_coefficients.ids not found in Variables.ids; ModelProto.objective is invalid

../../../ortools/math_opt/core/python/solver_test.py:59: RuntimeError
_______ PybindSolverTest.test_invalid_input_throws_error_without_solver ________

self = <solver_test.PybindSolverTest testMethod=test_invalid_input_throws_error_without_solver>
use_solver_class = False

    @parameterized.named_parameters(
        dict(testcase_name="without_solver", use_solver_class=False),
        dict(testcase_name="with_solver", use_solver_class=True),
    )
    def test_invalid_input_throws_error(self, use_solver_class: bool) -> None:
        model = _build_simple_model()
        # Add invalid variable id to cause MathOpt model validation error.
        model.objective.linear_coefficients.ids.append(7)
        model.objective.linear_coefficients.values.append(2.0)
        with self.assertRaisesRegex(StatusNotOk, "id 7 not found"):
>           _solve_model(model, use_solver_class=use_solver_class)

../../../ortools/math_opt/core/python/solver_test.py:115: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def _solve_model(
        model: model_pb2.ModelProto,
        *,
        use_solver_class: bool,
        solver_type: parameters_pb2.SolverTypeProto = parameters_pb2.SOLVER_TYPE_GLOP,
        solver_initializer: parameters_pb2.SolverInitializerProto = parameters_pb2.SolverInitializerProto(),
        parameters: parameters_pb2.SolveParametersProto = parameters_pb2.SolveParametersProto(),
        model_parameters: model_parameters_pb2.ModelSolveParametersProto = model_parameters_pb2.ModelSolveParametersProto(),
        message_callback: Optional[Callable[[Sequence[str]], None]] = None,
        callback_registration: callback_pb2.CallbackRegistrationProto = callback_pb2.CallbackRegistrationProto(),
        user_cb: Optional[
            Callable[[callback_pb2.CallbackDataProto], callback_pb2.CallbackResultProto]
        ] = None,
        interrupter: Optional[solver.SolveInterrupter] = None,
    ) -> result_pb2.SolveResultProto:
        """Convenience function for both types of solve with parameter defaults."""
        if use_solver_class:
            pybind_solver = solver.new(
                solver_type,
                model,
                solver_initializer,
            )
            return pybind_solver.solve(
                parameters,
                model_parameters,
                message_callback,
                callback_registration,
                user_cb,
                interrupter,
            )
        else:
>           return solver.solve(
                model,
                solver_type,
                solver_initializer,
                parameters,
                model_parameters,
                message_callback,
                callback_registration,
                user_cb,
                interrupter,
            )
E           RuntimeError: INVALID_ARGUMENT: id 7 not found; Objective.linear_coefficients.ids not found in Variables.ids; ModelProto.objective is invalid

../../../ortools/math_opt/core/python/solver_test.py:73: RuntimeError
=========================== short test summary info ============================
FAILED ../../../ortools/math_opt/core/python/solver_test.py::PybindSolverTest::test_invalid_input_throws_error_with_solver - RuntimeError: INVALID_ARGUMENT: id 7 not found; Objective.linear_coefficients.ids not found in Variables.ids; ModelProto.objective is invalid
FAILED ../../../ortools/math_opt/core/python/solver_test.py::PybindSolverTest::test_invalid_input_throws_error_without_solver - RuntimeError: INVALID_ARGUMENT: id 7 not found; Objective.linear_coefficients.ids not found in Variables.ids; ModelProto.objective is invalid
========================= 2 failed, 13 passed in 0.36s =========================

        Start 140: python_math_opt_compute_infeasible_subsystem_result_test

ref: https://github.com/google/or-tools/actions/runs/12116420023/job/33776757913#step:9:318

@Mizux Mizux added Bug Lang: Python Python wrapper issue OS: Mac MacOS Solver: MathOpt MathOpt related issue labels Dec 2, 2024
@Mizux Mizux added this to the v9.12 milestone Dec 2, 2024
@Mizux Mizux self-assigned this Dec 2, 2024
@lokashrinav
Copy link

lokashrinav commented Jan 12, 2025

I might be wrong, but I think this can be fixed by converting the internal error into the custom StatusNotOk Python exception that the test is looking for since its coming through as a generic RuntimeError.

I think we need to add this on line 83 of 'or-tools/ortools/math_opt/core/python/solver_test.py' in the _solve_model function:

except RuntimeError as e:
    raise StatusNotOk(str(e))

@Mizux
Copy link
Collaborator Author

Mizux commented Jan 14, 2025

Need to investigate further but the issue seems to come from pybind_abseil directly which didn't wrap the exception the same way on macOS...
I'm currently adding some CI jobs to pybind_abseil project itself and can reproduce the same behaviour so the issue lie in our dependency imho.
see: https://github.com/pybind/pybind11_abseil/actions/runs/12713073661/job/35440135007

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Lang: Python Python wrapper issue OS: Mac MacOS Solver: MathOpt MathOpt related issue
Projects
None yet
Development

No branches or pull requests

2 participants