Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions benchmarks/tooling/providers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Executable provider-feasibility spikes owned by benchmark tooling."""
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,22 @@
from pathlib import Path
from typing import Any

from tools.command_runner import (
ToolCommandRequest,
ToolCommandResult,
ToolCommandStatus,
)

from benchmarks.tooling.spike_utils import (
canonical_json,
default_runner,
owned_fixture_path,
sha256_bytes,
)
from tools.command_runner import (
ToolCommandResult,
ToolCommandStatus,
)

PIN_PATH = Path(__file__).with_name("pin.json")
PIN_PATH = owned_fixture_path(
__file__, "tests/fixtures/providers/cddlib/pin.json", "pin.json"
)
ADAPTER_SOURCE = Path(__file__)
# Worker re-exec replaces the process environment; keep the image PYTHONPATH so
# `tools.command_runner` remains importable inside --worker mode.
Expand All @@ -40,7 +45,7 @@
"RAY": 3,
"LINEALITY": 4,
}
ProcessRunner = Callable[..., ToolCommandResult]
ProcessRunner = Callable[[ToolCommandRequest], ToolCommandResult]
_WORKER_ERROR_PREFIX = b"JACOBIAN_SPIKE_ERROR "


Expand Down Expand Up @@ -105,11 +110,9 @@ def _load_pin(path: Path) -> dict[str, Any]:
and isinstance(scope.get("covers"), list)
and all(isinstance(item, str) for item in scope["covers"])
)
sources_valid = isinstance(sources, dict) and set(sources) == {
"cddlib",
"pycddlib",
}
if sources_valid:
sources_valid = False
if isinstance(sources, dict) and set(sources) == {"cddlib", "pycddlib"}:
sources_valid = True
for source in sources.values():
if (
not isinstance(source, dict)
Expand Down Expand Up @@ -350,8 +353,8 @@ def _integer_normalize(row: Sequence[Fraction], *, sign_free: bool) -> list[Frac
value.numerator * (denominator_lcm // value.denominator) for value in row
]
divisor = 0
for value in integers:
divisor = math.gcd(divisor, abs(value))
for integer in integers:
divisor = math.gcd(divisor, abs(integer))
if divisor == 0:
return [Fraction(0) for _ in row]
integers = [value // divisor for value in integers]
Expand Down Expand Up @@ -689,15 +692,20 @@ def _run_checked(
runner: ProcessRunner,
command: Sequence[str],
*,
cwd: Path,
timeout_seconds: float,
) -> bytes:
completed = runner(
command,
input_bytes=b"",
timeout_seconds=timeout_seconds,
environment=_ENVIRONMENT,
stdout_limit=128 * 1024,
stderr_limit=16 * 1024,
ToolCommandRequest(
executable=command[0],
arguments=tuple(command[1:]),
stdin_bytes=b"",
timeout_seconds=timeout_seconds,
environment=_ENVIRONMENT,
cwd=str(cwd.resolve()),
stdout_limit_bytes=128 * 1024,
stderr_limit_bytes=16 * 1024,
)
)
if completed.status is ToolCommandStatus.START_FAILED:
raise CddlibSpikeError(
Expand Down Expand Up @@ -803,6 +811,7 @@ def run_spike(
python_executable: Path,
cddlib_source_archive: Path,
pycddlib_source_archive: Path,
cwd: Path,
timeout_seconds: float = 10,
runner: ProcessRunner = default_runner,
pin_path: Path = PIN_PATH,
Expand Down Expand Up @@ -841,6 +850,7 @@ def run_spike(
str(pin_path.resolve()),
],
timeout_seconds=timeout_seconds,
cwd=cwd,
)
provider_output = _parse_provider_output(output, pin)
by_id = {case["case_id"]: case for case in cases}
Expand Down Expand Up @@ -922,9 +932,10 @@ def _worker(pin_path: Path) -> int:
pin = _load_pin(pin_path)
cases = _validate_cases(pin)
try:
import importlib
import importlib.metadata

import cdd.gmp as cdd
cdd = importlib.import_module("cdd.gmp")
except ImportError as exc:
raise CddlibSpikeError(
"UNAVAILABLE",
Expand Down Expand Up @@ -1006,11 +1017,16 @@ def _worker(pin_path: Path) -> int:
rep_type=cdd.RepType.INEQUALITY,
)
exact_probe = probe_matrix.array[0][0]
gmp_module = Path(cdd.__file__).resolve()
module_file = getattr(cdd, "__file__", None)
if not isinstance(module_file, str):
raise CddlibSpikeError(
"UNAVAILABLE", "PROVIDER_IMPORT_ERROR", "cdd.gmp has no module file."
)
gmp_module = Path(module_file).resolve()
distribution = importlib.metadata.distribution("pycddlib")
record_path = next(
(
Path(distribution.locate_file(item))
Path(str(distribution.locate_file(item)))
for item in distribution.files or ()
if item.name == "RECORD"
),
Expand Down Expand Up @@ -1052,6 +1068,7 @@ def main(argv: Sequence[str] | None = None) -> int:
parser.add_argument("--cddlib-source-archive", type=Path)
parser.add_argument("--pycddlib-source-archive", type=Path)
parser.add_argument("--pin", type=Path, default=PIN_PATH)
parser.add_argument("--cwd", type=Path)
parser.add_argument("--output", type=Path)
parser.add_argument("--worker", action="store_true")
args = parser.parse_args(argv)
Expand All @@ -1070,16 +1087,18 @@ def main(argv: Sequence[str] | None = None) -> int:
args.python_executable is None
or args.cddlib_source_archive is None
or args.pycddlib_source_archive is None
or args.cwd is None
or args.output is None
):
parser.error(
"--python-executable, --cddlib-source-archive, "
"--pycddlib-source-archive, and --output are required"
"--pycddlib-source-archive, --cwd, and --output are required"
)
report = run_spike(
python_executable=args.python_executable,
cddlib_source_archive=args.cddlib_source_archive,
pycddlib_source_archive=args.pycddlib_source_archive,
cwd=args.cwd,
pin_path=args.pin,
)
args.output.write_text(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,34 @@
from pathlib import Path
from typing import Any

from benchmarks.tooling.spike_utils import (
default_runner,
sha256_bytes,
)
from tools.command_runner import (
ToolCommandRequest,
ToolCommandResult,
ToolCommandStatus,
)

PIN_PATH = Path(__file__).with_name("cgal_delaunay_pin.json")
ADAPTER_SOURCE = Path(__file__).with_name("cgal_delaunay_spike.cpp")
from benchmarks.tooling.spike_utils import (
default_runner,
owned_fixture_path,
sha256_bytes,
)

PIN_PATH = owned_fixture_path(
__file__,
"tests/fixtures/providers/cgal/cgal_delaunay_pin.json",
"cgal_delaunay_pin.json",
)
ADAPTER_SOURCE = owned_fixture_path(
__file__,
"tests/fixtures/providers/cgal/cgal_delaunay_spike.cpp",
"cgal_delaunay_spike.cpp",
)
_SOURCE_MEMBERS = (
"CGAL-6.2/include/CGAL/version.h",
"CGAL-6.2/include/CGAL/Delaunay_triangulation_2.h",
)
_ENVIRONMENT = {"LANG": "C", "LC_ALL": "C", "TZ": "UTC"}
ProcessRunner = Callable[..., ToolCommandResult]
ProcessRunner = Callable[[ToolCommandRequest], ToolCommandResult]


class CgalSpikeError(RuntimeError):
Expand Down Expand Up @@ -183,15 +194,20 @@ def _run_checked(
runner: ProcessRunner,
command: Sequence[str],
*,
cwd: Path,
timeout_seconds: float,
) -> bytes:
completed = runner(
command,
input_bytes=b"",
timeout_seconds=timeout_seconds,
environment=_ENVIRONMENT,
stdout_limit=32_768,
stderr_limit=16_384,
ToolCommandRequest(
executable=command[0],
arguments=tuple(command[1:]),
stdin_bytes=b"",
timeout_seconds=timeout_seconds,
environment=_ENVIRONMENT,
cwd=str(cwd.resolve()),
stdout_limit_bytes=32_768,
stderr_limit_bytes=16_384,
)
)
if completed.status is ToolCommandStatus.START_FAILED:
raise CgalSpikeError(
Expand Down Expand Up @@ -254,6 +270,7 @@ def run_spike(
*,
executable: Path,
source_archive: Path,
cwd: Path,
timeout_seconds: float = 5,
runner: ProcessRunner = default_runner,
pin_path: Path = PIN_PATH,
Expand All @@ -279,6 +296,7 @@ def run_spike(
_run_checked(
runner,
[str(resolved), "--version"],
cwd=cwd,
timeout_seconds=timeout_seconds,
),
pin,
Expand All @@ -289,6 +307,7 @@ def run_spike(
output = _run_checked(
runner,
[str(resolved), *case["command"]],
cwd=cwd,
timeout_seconds=timeout_seconds,
)
try:
Expand Down Expand Up @@ -387,12 +406,14 @@ def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--executable", type=Path, required=True)
parser.add_argument("--source-archive", type=Path, required=True)
parser.add_argument("--cwd", type=Path, required=True)
parser.add_argument("--timeout-seconds", type=float, default=5)
parser.add_argument("--output", type=Path)
args = parser.parse_args(argv)
report = run_spike(
executable=args.executable,
source_archive=args.source_archive,
cwd=args.cwd,
timeout_seconds=args.timeout_seconds,
)
encoded = json.dumps(report, indent=2, sort_keys=True) + "\n"
Expand Down
Loading
Loading