Skip to content

Conversation

jake-arkinstall
Copy link
Contributor

This adds builder.with_build_arg(name: str, value: Any), which allows for build customisation.

Background

Selene builds are managed by the selene_core BuildPlanner. This is a graph comprising:

  • nodes: artifact kinds (e.g. "a .hugr file", "a .bc file with external calls to __foo()", "a string containing llvm")
  • edges: steps that each map from one kind to another, e.g. compilation steps, along with associated cost.

It is configured with sensible defaults, but one can add kinds and steps to the default build planner with custom extensions.

Upon providing an input to build(), the artifact kind is determined, and djikstra provides the walk of least total cost from the input kind to a selene executable.

Costs and steps can be customised in the definition of steps. If custom steps are added into the build planner, a common pattern is to enable them (by reducing their cost) upon presence of custom build arguments.

Concrete Example

The build steps undertaken during a walk of least cost can be inspected by looking at the 'steps' entry in ${build_dir}/selene.yaml, which for a vanilla run looks like:

steps:
- class: HUGRPackageToHUGREnvelopeBytesStep
  module: selene_core.build_utils.builtins.hugr
- class: SeleneCompileHUGRToLLVMBitcodeStringStep
  module: selene_helios_qis_plugin.build
- class: LLVMBitcodeStringToLLVMBitcodeFileStep
  module: selene_core.build_utils.builtins.helios
- class: HeliosLLVMBitcodeFileToHeliosObjectFileStep
  moydule: selene_core.build_utils.builtins.helios
- class: HeliosObjectFileToSeleneObjectFileStep_Linux
  module: selene_core.build_utils.builtins.helios
- class: SeleneObjectToSeleneExecutable
  module: selene_core.build_utils.builtins.selene

A HUGR Envelope Bytes can be compiled to .bc or .ll based on a 'build_method' parameter. Passing build_method='via-llvm-ir' to selene_sim.build will thus provide human-readable LLVM IR in the build artifacts, which is great for inspection.

By doing so, you get these steps instead:

steps:
- class: HUGRPackageToHUGREnvelopeBytesStep
  module: selene_core.build_utils.builtins.hugr
- class: SeleneCompileHUGRToLLVMIRStringStep
  module: selene_helios_qis_plugin.build
- class: LLVMIRStringToLLVMIRFileStep
  module: selene_core.build_utils.builtins.helios
- class: HeliosLLVMIRFileToHeliosObjectFileStep
  module: selene_core.build_utils.builtins.helios
- class: HeliosObjectFileToSeleneObjectFileStep_Linux
  module: selene_core.build_utils.builtins.helios
- class: SeleneObjectToSeleneExecutable
  module: selene_core.build_utils.builtins.selene

Adding this capability to the guppylang emulator interface

This PR adds the ability to pass custom arguments to selene_sim.build function via the builder method.

Usage looks like:

builder = EmulatorBuilder() \
            .with_build_dir("./prefer_text") \
            .with_build_arg("build_method", "via-llvm-ir")

print(main.emulator(1, builder).run())

In ./prefer_text/artifacts LLVM IR rather than bitcode will be present. This demonstrates a customisation point - boring in itself, but the possibilities with such customisation are quite exciting. One can pass custom args to compilation (e.g. optimisation level, verbosity levels, or choose a different compiler entirely), steer builds to using other machine targets, etc.

@jake-arkinstall jake-arkinstall changed the title Feat: add custom emulator build arguments feat: add custom emulator build arguments Oct 2, 2025
Copy link
Contributor

github-actions bot commented Oct 2, 2025

🐰 Bencher Report

Branchfeat/emulator-build-args
TestbedLinux
Click to view all benchmark results
BenchmarkLatencyBenchmark Result
microseconds (µs)
(Result Δ%)
Upper Boundary
microseconds (µs)
(Limit %)
tests/benchmarks/test_big_array.py::test_big_array_check📈 view plot
🚷 view threshold
654,802.26 µs
(-14.08%)Baseline: 762,096.58 µs
800,201.41 µs
(81.83%)
tests/benchmarks/test_big_array.py::test_big_array_compile📈 view plot
🚷 view threshold
3,133,473.66 µs
(-2.83%)Baseline: 3,224,628.61 µs
3,385,860.04 µs
(92.55%)
tests/benchmarks/test_big_array.py::test_big_array_executable📈 view plot
🚷 view threshold
9,054,368.37 µs
(-1.64%)Baseline: 9,204,876.29 µs
9,665,120.11 µs
(93.68%)
tests/benchmarks/test_ctrl_flow.py::test_many_ctrl_flow_check📈 view plot
🚷 view threshold
47,423.95 µs
(-21.19%)Baseline: 60,171.84 µs
63,180.43 µs
(75.06%)
tests/benchmarks/test_ctrl_flow.py::test_many_ctrl_flow_compile📈 view plot
🚷 view threshold
89,058.04 µs
(-11.45%)Baseline: 100,573.32 µs
105,601.99 µs
(84.33%)
tests/benchmarks/test_ctrl_flow.py::test_many_ctrl_flow_executable📈 view plot
🚷 view threshold
673,298.89 µs
(-17.16%)Baseline: 812,797.08 µs
853,436.93 µs
(78.89%)
tests/benchmarks/test_prelude.py::test_import_guppy📈 view plot
🚷 view threshold
24.46 µs
(-8.44%)Baseline: 26.71 µs
28.05 µs
(87.20%)
🐰 View full continuous benchmarking report in Bencher

Copy link
Contributor

github-actions bot commented Oct 2, 2025

🐰 Bencher Report

Branchfeat/emulator-build-args
TestbedLinux
Click to view all benchmark results
Benchmarkhugr_bytesBenchmark Result
bytes x 1e3
(Result Δ%)
Upper Boundary
bytes x 1e3
(Limit %)
hugr_nodesBenchmark Result
nodes
(Result Δ%)
Upper Boundary
nodes
(Limit %)
tests/benchmarks/test_big_array.py::test_big_array_compile📈 view plot
🚷 view threshold
129.06 x 1e3
(+0.00%)Baseline: 129.06 x 1e3
130.35 x 1e3
(99.01%)
📈 view plot
🚷 view threshold
4,873.00
(0.00%)Baseline: 4,873.00
4,921.73
(99.01%)
tests/benchmarks/test_ctrl_flow.py::test_many_ctrl_flow_compile📈 view plot
🚷 view threshold
21.99 x 1e3
(+0.02%)Baseline: 21.99 x 1e3
22.21 x 1e3
(99.03%)
📈 view plot
🚷 view threshold
693.00
(0.00%)Baseline: 693.00
699.93
(99.01%)
🐰 View full continuous benchmarking report in Bencher

@codecov-commenter
Copy link

codecov-commenter commented Oct 2, 2025

Codecov Report

❌ Patch coverage is 88.88889% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 93.49%. Comparing base (b56e056) to head (754178c).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
guppylang/src/guppylang/emulator/builder.py 88.88% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1282   +/-   ##
=======================================
  Coverage   93.49%   93.49%           
=======================================
  Files         121      121           
  Lines       11202    11228   +26     
=======================================
+ Hits        10473    10498   +25     
- Misses        729      730    +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jake-arkinstall jake-arkinstall marked this pull request as ready for review October 2, 2025 10:21
@jake-arkinstall jake-arkinstall requested a review from a team as a code owner October 2, 2025 10:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants