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

Use fewer allocations and more performant functions in runcircuit #304

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

jlapeyre
Copy link
Contributor

@jlapeyre jlapeyre commented Aug 3, 2023

  • Use isodd. It is more readable and more performant.
  • Avoid allocations in a few places
  • Correct spelling in the README.

The performance of the code in question has been improved significantly. It was probably not a performance bottle neck. But it's as easy or easier to write non-allocating code (in this case). And the result is more readable (again in this case). So I think its good to promote it as a habit.

I did the following

any(isodd, (length(inds(g)) for layer in layers for g in layer))

An alternative is

any(isodd, (length(inds(g)) for g in Iterators.flatten(layers)))

* Use `isodd`. It is more readable and more performant
* Avoid allocations in a few places

It's good practice to habitually code this way because:
* The code is more concise, clean, and readable.
* In cases where this is a bottleneck (probably not here) the increase in performance is very significant.
* The code serves as model for future development so that the benefits above accrue.
Note: If the lines were wrapped. Or written one sentence per line, etc.,
the edits and diffs to the README would be easier to read. (But I think
GH will highlight changed characters)
@codecov-commenter
Copy link

codecov-commenter commented Aug 3, 2023

Codecov Report

Patch coverage: 73.68% and project coverage change: -0.03% ⚠️

Comparison is base (c168b10) 87.67% compared to head (ae9343b) 87.64%.
Report is 5 commits behind head on master.

❗ Current head ae9343b differs from pull request most recent head 789f85b. Consider uploading reports for the commit 789f85b to get more accurate results

❗ Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #304      +/-   ##
==========================================
- Coverage   87.67%   87.64%   -0.03%     
==========================================
  Files          22       22              
  Lines        2491     2485       -6     
==========================================
- Hits         2184     2178       -6     
  Misses        307      307              
Files Changed Coverage Δ
src/PastaQ.jl 100.00% <ø> (ø)
src/io.jl 71.08% <0.00%> (ø)
src/optimizers.jl 97.05% <80.00%> (-0.09%) ⬇️
src/tomography/quantumtomography.jl 80.83% <87.50%> (-0.47%) ⬇️
src/circuits/runcircuit.jl 86.66% <100.00%> (-0.20%) ⬇️

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

inds_sizes = vcat([[length(inds(g)) for g in layer] for layer in circuit_tensors]...)
end
noiseflag = any(x -> x % 2 == 1, inds_sizes)
layers = circuit_tensors isa Vector{<:ITensor} ? (circuit_tensors,) : circuit_tensors
Copy link
Collaborator

Choose a reason for hiding this comment

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

Even better would be to split off into a function:

to_layers(ts::Vector{ITensor}) = [ts]
to_layers(ts::Vector{Vector{ITensor}}) = ts

I'm weary of using a Tuple since our convention is that a layered circuit is nested layers of Vector, though I understand it avoids an allocation. I don't think we're worried about the performance of this part of the code though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That makes sense. I'm guessing that allocating here would change the efficiency of computing noise_flags very little if at all.

Would to_layers be more generally useful? You could use it elsewhere to support the convention a bit. If not, you might consider [circuit_tensors] : circuit_tensors.

In any case, part of the point of this PR is that code serves as an example. Even though using a Tuple doesn't affect the behavior here, someone could copy the code or idea to another location where your convention is expected to be followed. So using an Array makes sense.

Furthermore, there are plans to add more escape analysis to the Julia compiler in the not too distant future. I imagine the compiler will do [x] $\rightarrow$ (x,) for you in simple cases like this.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it's better to move into a function, I could imagine that would be useful in other places (and I could imagine expanding the functionality to convert other structures into our standard layered circuit format).

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