https://github.com/d-krupke/cpsat-logutils

Utils for parsing the logs of OR-Tools' CP-SAT solver.

https://github.com/d-krupke/cpsat-logutils

Science Score: 26.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Academic email domains
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (9.5%) to scientific vocabulary
Last synced: 9 months ago · JSON representation

Repository

Utils for parsing the logs of OR-Tools' CP-SAT solver.

Basic Info
  • Host: GitHub
  • Owner: d-krupke
  • License: mit
  • Language: Python
  • Default Branch: main
  • Size: 138 KB
Statistics
  • Stars: 2
  • Watchers: 1
  • Forks: 1
  • Open Issues: 0
  • Releases: 2
Created about 1 year ago · Last pushed 10 months ago
Metadata Files
Readme License

README.md

cpsat-logutils

Utilities to parse and work with the logs of OR‑Tools CP‑SAT.

This library extracts key information from CP‑SAT logs (solutions, bounds, presolve stats, subsolver activity, search progress, conflicts, etc.) and exposes them in structured Python objects you can analyze or visualize.

Installation

bash pip install cpsat-logutils

Quickstart

1) Enable CP‑SAT logging in your solver

Enable detailed CP‑SAT log output and capture it programmatically.

```python from ortools.sat.python import cp_model

model = cp_model.CpModel()

... build your model ...

solver = cpmodel.CpSolver() solver.parameters.logsearch_progress = True # Show detailed search log

loglines: list[str] = [] solver.logcallback = log_lines.append # Capture logs in a list

status = solver.Solve(model) rawlog = "\n".join(loglines) ```

2) Parse the log with cpsat-logutils

Below is a step-by-step parsing workflow. For each block, explore its block-specific methods in the blocks/ directory, and adapt the calls shown here to your needs.

a) Instantiate the parser

Create the parser instance from the raw log string.

```python from cpsat_logutils import LogParser

parser = LogParser(raw_log) ```

b) Retrieve solver-level info

Get high-level solver metadata such as version, number of workers, and parameters.

```python from cpsat_logutils.blocks import SolverBlock

if solverblock := parser.getblockoftypeornone(SolverBlock): print("CP-SAT version:", solverblock.getversion()) print("Workers:", solverblock.getnumberofworkers()) print("Parameters:", solverblock.getparameters()) ```

c) Inspect model statistics

Display the number of variables and constraints before and after presolve.

```python from cpsat_logutils.blocks import InitialModelBlock, PresolvedModelBlock

if initial := parser.getblockoftypeornone(InitialModelBlock): print( "Initial model:", initial.getnumvariables(), "vars,", initial.getnum_constraints(), "constraints", )

if presolved := parser.getblockoftypeornone(PresolvedModelBlock): print( "Presolved model:", presolved.getnumvariables(), "vars,", presolved.getnum_constraints(), "constraints", ) ```

d) Check presolve outcome

Determine whether the problem was solved during presolve.

```python from cpsat_logutils.blocks import PresolveSummaryBlock

solvedbypresolve = False if ps := parser.getblockoftypeornone(PresolveSummaryBlock): solvedbypresolve = ps.issolvedbypresolve() print("Solved by presolve:", solvedbypresolve) ```

e) Explore search progress and stats

If presolve did not solve the problem, inspect search progress events, task timing, search statistics, and objective bounds.

```python from cpsat_logutils.blocks import ( SearchProgressBlock, SearchStatsBlock, TaskTimingBlock, ObjectiveBoundsBlock, )

if not solvedbypresolve: if sp := parser.getblockoftypeornone(SearchProgressBlock): print("Presolve time (s):", sp.getpresolvetime()) print(sp.getevents()) # list of events, see BoundEvent, ObjEvent, ModelEvent

if tt := parser.get_block_of_type_or_none(TaskTimingBlock):
    print(tt.to_pandas().head())

if ss := parser.get_block_of_type_or_none(SearchStatsBlock):
    print(ss.to_pandas().head())

if ob := parser.get_block_of_type_or_none(ObjectiveBoundsBlock):
    print(ob.to_pandas().head())

```

f) Get final solver response

Access the solver’s final response, including status and objective value.

```python from cpsat_logutils.blocks import ResponseBlock

if resp := parser.getblockoftypeornone(ResponseBlock): print(resp.todict()) ```

3) Save or visualize

cpsat-logutils focuses on parsing and structuring; you can:

  • export DataFrames to CSV/JSON for dashboards,
  • plot progress/bounds over time with matplotlib/plotly,
  • feed the output into your own analyzers.

If you prefer a ready‑made GUI, see the CP‑SAT Log Analyzer below.

Examples

  • Minimal example logs live in example_logs/ of this repo.
  • See the test suite in tests/ for end‑to‑end parsing and assertions.

FAQ

Which CP‑SAT versions are supported? The parser targets the log format used by recent OR‑Tools releases (9.8+). If a newer CP‑SAT version changes the log format and something breaks, please open an issue with a sample CP‑SAT output log.

Can I parse logs from other languages (C++/Java/C#)? Yes. As long as you enable log_search_progress and collect the textual CP‑SAT log, the content is the same. Save it to a text file or feed the string to the parser.

Do I need to redirect stdout? No. In Python you can capture logs via solver.log_callback = my_fn to avoid duplicates.

Related resources

Contributing

Issues and PRs are welcome! If you hit a parsing edge case, please attach a sample CP‑SAT output log that reproduces it.

When submitting a merge request, please ensure:

  • All tests pass locally: pytest
  • Code style and linting pass: use pre-commit with the provided configuration (.pre-commit-config.yaml). Run pre-commit run --all-files before submitting.

Refer to the CI workflow for the full test and lint configuration.

Version History

  • v0.0.3: Extended __all__ import

Owner

  • Name: Dominik Krupke
  • Login: d-krupke
  • Kind: user
  • Location: Germany
  • Company: TU Braunschweig

Postdoc at TU Braunschweig, IBR, Algorithms Group.

GitHub Events

Total
  • Create event: 1
  • Issues event: 3
  • Release event: 1
  • Watch event: 2
  • Issue comment event: 7
  • Push event: 6
  • Pull request event: 1
Last Year
  • Create event: 1
  • Issues event: 3
  • Release event: 1
  • Watch event: 2
  • Issue comment event: 7
  • Push event: 6
  • Pull request event: 1

Issues and Pull Requests

Last synced: 10 months ago

All Time
  • Total issues: 1
  • Total pull requests: 0
  • Average time to close issues: 9 minutes
  • Average time to close pull requests: N/A
  • Total issue authors: 1
  • Total pull request authors: 0
  • Average comments per issue: 2.0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 1
  • Pull requests: 0
  • Average time to close issues: 9 minutes
  • Average time to close pull requests: N/A
  • Issue authors: 1
  • Pull request authors: 0
  • Average comments per issue: 2.0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • rungeard (2)
  • pchtsp (1)
Pull Request Authors
  • rungeard (1)
Top Labels
Issue Labels
Pull Request Labels

Packages

  • Total packages: 1
  • Total downloads:
    • pypi 3,088 last-month
  • Total dependent packages: 0
  • Total dependent repositories: 0
  • Total versions: 3
  • Total maintainers: 1
pypi.org: cpsat-logutils

Utils for parsing the logs of OR-Tools' CP-SAT solver.

  • Versions: 3
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Downloads: 3,088 Last month
Rankings
Dependent packages count: 9.5%
Average: 31.4%
Dependent repos count: 53.3%
Maintainers (1)
Last synced: 9 months ago

Dependencies

.github/workflows/pytest.yml actions
  • actions/checkout v3 composite
  • actions/setup-python v4 composite
.github/workflows/release.yml actions
  • actions/checkout master composite
  • actions/setup-python v4 composite
  • pypa/gh-action-pypi-publish release/v1 composite
pyproject.toml pypi