Skip to content

refactor: Split ArrayBorrowCompiler off from ArrayGetitemCompiler#1303

Open
acl-cqc wants to merge 1 commit intomainfrom
acl/array_borrow_getitem
Open

refactor: Split ArrayBorrowCompiler off from ArrayGetitemCompiler#1303
acl-cqc wants to merge 1 commit intomainfrom
acl/array_borrow_getitem

Conversation

@acl-cqc
Copy link
Contributor

@acl-cqc acl-cqc commented Oct 16, 2025

The goal here is to (a) make it clearer what's going on, (b) give a bit more protection, via asserts, against changes elsewhere in the compiler accidentally generating bad code.

ArrayGetitemCompiler compiles classical and linear variants separately; and has two uses: for fn __getitem__ of class array and for fn _array_unsafe_getitem (used only in ArrayIter).

First thought was that these can now be separate: ArrayIter ends in discard_all_borrowed, so just a borrow would suffice even in the classical case. In fact it turns out that the ArrayIter code only ever uses the linear case, because it's output as polymorphic in Hugr; so outputting get for the classical case would be just as efficient - it never happens. But that would be quite misleading, I argue this refactor makes it clearer what's going on.

Passes mypy. Not done any execution/integration tests yet...

@acl-cqc acl-cqc requested a review from tatiana-s October 16, 2025 15:53
(In the linear, non-owned, case they will be replaced afterwards.)"""

def _build_classical_getitem(self, array: Wire, idx: Wire) -> CallReturnWires:
"""Constructs `__getitem__` for classical arrays."""
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could become (borrow_)array::get following Quantinuum/tket2#1181 but looks like that's non-conflicting/orthogonal (yay!)

@tatiana-s
Copy link
Contributor

I am not sure I like this because in my opinion it muddles where we are borrow array specific or just generally reason about arrays in Guppy, but I would welcome other opinions. I don't think this is necessarily blocking to getting borrow arrays deployed as it is just a refactor (though not sure if breaking?)

@acl-cqc
Copy link
Contributor Author

acl-cqc commented Oct 20, 2025

I was thinking before you wrote this that the first commit was maybe better - a smaller change just to make clearer what was already happening. I think your comment sounds like the same conclusion, so I've gone back to that, maybe have another look.

I am not sure I like this because in my opinion it muddles where we are borrow array specific or just generally reason about arrays in Guppy, but I would welcome other opinions.

Well, I think all of this has become borrow-array specific now??

I don't think this is necessarily blocking to getting borrow arrays deployed as it is just a refactor (though not sure if breaking?)

Shouldn't break anything, should just verify what's happening already, indeed, so might come later. (I felt I needed to understand what was going on before I could approve your PR, and having figured it out, it seemed like a good idea to make that more obvious...)

@acl-cqc acl-cqc marked this pull request as ready for review October 21, 2025 09:34
@acl-cqc acl-cqc requested a review from a team as a code owner October 21, 2025 09:34
@acl-cqc acl-cqc force-pushed the acl/array_borrow_getitem branch from 582778a to 927ca0c Compare October 21, 2025 14:27
Base automatically changed from ts/borrow-arrays to main October 21, 2025 14:28
@github-actions
Copy link
Contributor

github-actions bot commented Oct 21, 2025

🐰 Bencher Report

Branchacl/array_borrow_getitem
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
664,646.11 µs
(-13.43%)Baseline: 767,756.80 µs
806,144.65 µs
(82.45%)
tests/benchmarks/test_big_array.py::test_big_array_compile📈 view plot
🚷 view threshold
1,582,129.33 µs
(-49.45%)Baseline: 3,130,080.96 µs
3,286,585.01 µs
(48.14%)
tests/benchmarks/test_big_array.py::test_big_array_executable📈 view plot
🚷 view threshold
7,366,556.08 µs
(-18.99%)Baseline: 9,093,616.17 µs
9,548,296.98 µs
(77.15%)
tests/benchmarks/test_ctrl_flow.py::test_many_ctrl_flow_check📈 view plot
🚷 view threshold
48,389.17 µs
(-29.37%)Baseline: 68,515.50 µs
71,941.27 µs
(67.26%)
tests/benchmarks/test_ctrl_flow.py::test_many_ctrl_flow_compile📈 view plot
🚷 view threshold
85,520.58 µs
(-15.09%)Baseline: 100,722.69 µs
105,758.82 µs
(80.86%)
tests/benchmarks/test_ctrl_flow.py::test_many_ctrl_flow_executable📈 view plot
🚷 view threshold
581,039.26 µs
(-25.68%)Baseline: 781,849.23 µs
820,941.70 µs
(70.78%)
tests/benchmarks/test_prelude.py::test_import_guppy📈 view plot
🚷 view threshold
24.65 µs
(-7.47%)Baseline: 26.63 µs
27.97 µs
(88.13%)
🐰 View full continuous benchmarking report in Bencher

@acl-cqc acl-cqc force-pushed the acl/array_borrow_getitem branch from 927ca0c to c1bc728 Compare October 21, 2025 14:30
@github-actions
Copy link
Contributor

github-actions bot commented Oct 21, 2025

🐰 Bencher Report

Branchacl/array_borrow_getitem
TestbedLinux

🚨 2 Alerts

BenchmarkMeasure
Units
ViewBenchmark Result
(Result Δ%)
Upper Boundary
(Limit %)
tests/benchmarks/test_big_array.py::test_big_array_compilehugr_nodes
nodes x 1e3
📈 plot
🚷 threshold
🚨 alert (🔔)
6.59 x 1e3
(+32.64%)Baseline: 4.97 x 1e3
5.02 x 1e3
(131.33%)

tests/benchmarks/test_big_array.py::test_big_array_compilehugr_bytes
bytes x 1e3
📈 plot
🚷 threshold
🚨 alert (🔔)
135.90 x 1e3
(+4.99%)Baseline: 129.44 x 1e3
130.74 x 1e3
(103.95%)

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
🚨 view alert (🔔)
135.90 x 1e3
(+4.99%)Baseline: 129.44 x 1e3
130.74 x 1e3
(103.95%)

📈 view plot
🚷 view threshold
🚨 view alert (🔔)
6,590.00
(+32.64%)Baseline: 4,968.39
5,018.07
(131.33%)

tests/benchmarks/test_ctrl_flow.py::test_many_ctrl_flow_compile📈 view plot
🚷 view threshold
19.77 x 1e3
(-9.60%)Baseline: 21.86 x 1e3
22.08 x 1e3
(89.51%)
📈 view plot
🚷 view threshold
606.00
(-11.94%)Baseline: 688.17
695.05
(87.19%)
🐰 View full continuous benchmarking report in Bencher

@codecov-commenter
Copy link

Codecov Report

❌ Patch coverage is 80.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 93.44%. Comparing base (f9ef42b) to head (c1bc728).

Files with missing lines Patch % Lines
guppylang/src/guppylang/std/array.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1303   +/-   ##
=======================================
  Coverage   93.44%   93.44%           
=======================================
  Files         123      123           
  Lines       11432    11434    +2     
=======================================
+ Hits        10683    10685    +2     
  Misses        749      749           

☔ 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.

"""Compiler for the `array.__getitem__` function."""
"""Compiler for the `array.__getitem__` function, used for both classical and
linear arrays e.g. when pulling out arguments to pass to a function.
(In the linear, non-owned, case they will be replaced afterwards.)"""
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have just been looking at how this happens in the frontend - check_place_assignable filling in the getitem_call field of a SubscriptAccess - it is nontrivial, otherwise I would love to have separated out the two different kinds of GetItem (linear with setitem to follow, vs classical without) first

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