Skip to content

Commit

Permalink
Merge branch 'QuantumSavory:master' into query_docs
Browse files Browse the repository at this point in the history
  • Loading branch information
ba2tro authored Feb 13, 2024
2 parents 3b9d885 + 1a0b40d commit 81e93de
Show file tree
Hide file tree
Showing 25 changed files with 750 additions and 136 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/benchmark-comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ on:
jobs:
comment:
runs-on: ubuntu-latest
#runs-on: self-hosted
if: >
${{ github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success' }}
Expand All @@ -41,7 +42,7 @@ jobs:
# check if the previous comment exists
- name: find comment
uses: peter-evans/find-comment@v2
uses: peter-evans/find-comment@v3
id: fc
with:
issue-number: ${{ steps.output-pull-request-number.outputs.body }}
Expand All @@ -51,13 +52,13 @@ jobs:
# create/update comment
- name: create comment
if: ${{ steps.fc.outputs.comment-id == 0 }}
uses: peter-evans/create-or-update-comment@v3
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{ steps.output-pull-request-number.outputs.body }}
body: ${{ steps.output-result-markdown.outputs.body }}
- name: update comment
if: ${{ steps.fc.outputs.comment-id != 0 }}
uses: peter-evans/create-or-update-comment@v3
uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
body: ${{ steps.output-result-markdown.outputs.body }}
5 changes: 4 additions & 1 deletion .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
name: Performance tracking

on:
pull_request:

env:
PYTHON: ~

jobs:
performance-tracking:
runs-on: ubuntu-latest
#runs-on: self-hosted
steps:
# setup
- uses: actions/checkout@v4
Expand Down
15 changes: 15 additions & 0 deletions .github/workflows/changelog-enforcer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: "Changelog Enforcer"
on:
pull_request:
# The specific activity types are listed here to include "labeled" and "unlabeled"
# (which are not included by default for the "pull_request" trigger).
# This is needed to allow skipping enforcement of the changelog in PRs with specific labels,
# as defined in the (optional) "skipLabels" property.
types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled]

jobs:
# Enforces the update of a changelog file on every pull request
changelog:
runs-on: ubuntu-latest
steps:
- uses: dangoslen/changelog-enforcer@v3
18 changes: 6 additions & 12 deletions .github/workflows/ci-julia-nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ on:
branches: [master, main]
tags: ["*"]
pull_request:
env:
PYTHON: ~
jobs:
test:
name: Julia ${{ matrix.version }} - t=${{ matrix.threads }} - jet=${{ matrix.jet }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
Expand All @@ -28,22 +30,14 @@ jobs:
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: actions/cache@v4
env:
cache-name: cache-artifacts
with:
path: ~/.julia/artifacts
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
restore-keys: |
${{ runner.os }}-test-${{ env.cache-name }}-
${{ runner.os }}-test-
${{ runner.os }}-
- uses: julia-actions/cache@v1
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
env:
JULIA_NUM_THREADS: ${{ matrix.threads }}
JET_TEST: ${{ matrix.jet }}
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v3
- uses: codecov/codecov-action@v4
with:
file: lcov.info
file: lcov.info
token: ${{ secrets.CODECOV_TOKEN }}
17 changes: 6 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ on:
branches: [master, main]
tags: ["*"]
pull_request:
env:
PYTHON: ~
jobs:
test:
name: Julia ${{ matrix.version }} - t=${{ matrix.threads }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
Expand All @@ -26,24 +28,16 @@ jobs:
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: actions/cache@v4
env:
cache-name: cache-artifacts
with:
path: ~/.julia/artifacts
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
restore-keys: |
${{ runner.os }}-test-${{ env.cache-name }}-
${{ runner.os }}-test-
${{ runner.os }}-
- uses: julia-actions/cache@v1
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
env:
JULIA_NUM_THREADS: ${{ matrix.threads }}
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v3
- uses: codecov/codecov-action@v4
with:
file: lcov.info
token: ${{ secrets.CODECOV_TOKEN }}
docs:
name: Documentation
runs-on: ubuntu-latest
Expand All @@ -52,6 +46,7 @@ jobs:
- uses: julia-actions/setup-julia@v1
with:
version: '1'
- uses: julia-actions/cache@v1
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-docdeploy@v1
env:
Expand Down
29 changes: 29 additions & 0 deletions .github/workflows/downgrade.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Downgrade
on:
pull_request:
branches: [master, main]
paths-ignore:
- 'docs/**'
push:
branches: [master, main]
paths-ignore:
- 'docs/**'
env:
PYTHON: ~
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
version: ['1.9']
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v1
with:
version: ${{ matrix.version }}
- uses: cjdoris/julia-downgrade-compat-action@v1
with:
skip: Pkg,TOML,InteractiveUtils,Random,LinearAlgebra
- uses: julia-actions/cache@v1
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
1 change: 1 addition & 0 deletions .github/workflows/invalidations.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jobs:
with:
version: '1'
- uses: actions/checkout@v4
- uses: julia-actions/cache@v1
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-invalidations@v1
id: invs_pr
Expand Down
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "QuantumSavory"
uuid = "2de2e421-972c-4cb5-a0c3-999c85908079"
authors = ["Stefan Krastanov <[email protected]>"]
version = "0.3.2"
version = "0.3.3"

[deps]
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
Expand Down Expand Up @@ -51,7 +51,7 @@ QuantumOpticsBase = "0.4.17"
QuantumSymbolics = "0.2.5"
Random = "1"
Reexport = "1.2.2"
ResumableFunctions = "0.6.1 - 0.6.6"
ResumableFunctions = "0.6"
Statistics = "1"
SumTypes = "0.5.1"
julia = "1.9"
7 changes: 7 additions & 0 deletions benchmark/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[deps]
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
QuantumClifford = "0525e862-1e90-11e9-3e4d-1b39d7109de1"
QuantumOptics = "6e0679c1-51ea-5a7c-ac74-d61b76210b0c"
QuantumOpticsBase = "4f57444f-1401-5e15-980d-4471b28d5678"
QuantumSavory = "2de2e421-972c-4cb5-a0c3-999c85908079"
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
125 changes: 125 additions & 0 deletions benchmark/benchmarks.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
using BenchmarkTools
using Pkg
using StableRNGs
using QuantumSavory
using QuantumSavory: tag_types
using QuantumOpticsBase: Ket, Operator
using QuantumClifford: MixedDestabilizer

const SUITE = BenchmarkGroup()

rng = StableRNG(42)

M = Pkg.Operations.Context().env.manifest
V = M[findfirst(v -> v.name == "QuantumSavory", M)].version

SUITE["register"] = BenchmarkGroup(["register"])
SUITE["register"]["creation_and_initialization"] = BenchmarkGroup(["creation_and_initialization"])
function register_creation_and_initialization()
traits = [Qubit(), Qubit(), Qubit()]
reg1 = Register(traits)
qc_repr = [QuantumOpticsRepr(), CliffordRepr(), CliffordRepr()]
reg2 = Register(traits, qc_repr)
qmc_repr = [QuantumOpticsRepr(), QuantumMCRepr(), QuantumMCRepr()]
reg3 = Register(traits, qmc_repr)
net = RegisterNet([reg1, reg2, reg3])

i = 1
initialize!(net[i,2])
@assert nsubsystems(net[i].staterefs[2]) == 1
initialize!(net[i,3],X1)
@assert nsubsystems(net[i].staterefs[2]) == 1
apply!([net[i,2], net[i,3]], CNOT)
@assert net[i].staterefs[2].state[] isa Ket
@assert nsubsystems(net[i].staterefs[2]) == 2

i = 2
initialize!(net[i,2])
@assert nsubsystems(net[i].staterefs[2]) == 1
initialize!(net[i,3],X1)
@assert nsubsystems(net[i].staterefs[2]) == 1
apply!([net[i,2], net[i,3]], CNOT)
@assert net[i].staterefs[2].state[] isa MixedDestabilizer
@assert nsubsystems(net[i].staterefs[2]) == 2

i = 3
initialize!(net[i,2])
@assert nsubsystems(net[i].staterefs[2]) == 1
initialize!(net[i,3],X1)
@assert nsubsystems(net[i].staterefs[2]) == 1
apply!([net[i,2], net[i,3]], CNOT)
@assert net[i].staterefs[2].state[] isa Ket
@assert nsubsystems(net[i].staterefs[2]) == 2

##
# with backgrounds
traits = [Qubit(), Qubit(), Qubit()]
backgrounds = [T2Dephasing(1.0),T2Dephasing(1.0),T2Dephasing(1.0)]
reg1 = Register(traits, backgrounds)
qc_repr = [QuantumOpticsRepr(), CliffordRepr(), CliffordRepr()]
reg2 = Register(traits, qc_repr, backgrounds)
qmc_repr = [QuantumOpticsRepr(), QuantumMCRepr(), QuantumMCRepr()]
reg3 = Register(traits, qmc_repr, backgrounds)
net = RegisterNet([reg1, reg2, reg3])

i = 1
initialize!(net[i,2], time=1.0)
@assert nsubsystems(net[i].staterefs[2]) == 1
initialize!(net[i,3],X1, time=2.0)
@assert nsubsystems(net[i].staterefs[2]) == 1
apply!([net[i,2], net[i,3]], CNOT, time=3.0)
@assert net[i].staterefs[2].state[] isa Operator
@assert nsubsystems(net[i].staterefs[2]) == 2

i = 2
initialize!(net[i,2], time=1.0)
@assert nsubsystems(net[i].staterefs[2]) == 1
initialize!(net[i,3],X1, time=2.0)
@assert nsubsystems(net[i].staterefs[2]) == 1
apply!([net[i,2], net[i,3]], CNOT, time=3.0)
@assert net[i].staterefs[2].state[] isa MixedDestabilizer
@assert nsubsystems(net[i].staterefs[2]) == 2

i = 3
initialize!(net[i,2], time=1.0)
@assert nsubsystems(net[i].staterefs[2]) == 1
initialize!(net[i,3],X1, time=2.0)
@assert nsubsystems(net[i].staterefs[2]) == 1
apply!([net[i,2], net[i,3]], CNOT, time=3.0)
@assert nsubsystems(net[i].staterefs[2]) == 2
end
SUITE["register"]["creation_and_initialization"]["from_tests"] = @benchmarkable register_creation_and_initialization()

SUITE["tagquery"] = BenchmarkGroup(["tagquery"])
SUITE["tagquery"]["misc"] = BenchmarkGroup(["misc"])
function tagquery_interfacetest()
r = Register(10)
tag!(r[1], :symbol1, 2, 3)
tag!(r[2], :symbol1, 4, 5)
tag!(r[5], Int, 4, 5)

@assert Tag(:symbol1, 2, 3) == tag_types.SymbolIntInt(:symbol1, 2, 3)
@assert query(r, :symbol1, 4, ❓) == (slot=r[2], tag=tag_types.SymbolIntInt(:symbol1, 4, 5))
@assert query(r, :symbol1, 4, 5) == (slot=r[2], tag=tag_types.SymbolIntInt(:symbol1, 4, 5))
@assert query(r, :symbol1, ❓, ❓) == (slot=r[1], tag=tag_types.SymbolIntInt(:symbol1, 2, 3))
@assert query(r, :symbol2, ❓, ❓) == nothing
@assert query(r, Int, 4, 5) == (slot=r[5], tag=tag_types.TypeIntInt(Int, 4, 5))
@assert query(r, Float32, 4, 5) == nothing
@assert query(r, Int, 4, >(5)) == nothing
@assert query(r, Int, 4, <(6)) == (slot=r[5], tag=tag_types.TypeIntInt(Int, 4, 5))

@assert queryall(r, :symbol1, ❓, ❓) == [(slot=r[1], tag=tag_types.SymbolIntInt(:symbol1, 2, 3)), (slot=r[2], tag=tag_types.SymbolIntInt(:symbol1, 4, 5))]
@assert isempty(queryall(r, :symbol2, ❓, ❓))

@assert query(r[2], Tag(:symbol1, 4, 5)) == (depth=1, tag=Tag(:symbol1, 4, 5))
@assert queryall(r[2], Tag(:symbol1, 4, 5)) == [(depth=1, tag=Tag(:symbol1, 4, 5))]
@assert query(r[2], :symbol1, 4, 5) == (depth=1, tag=Tag(:symbol1, 4, 5))
@assert queryall(r[2], :symbol1, 4, 5) == [(depth=1, tag=Tag(:symbol1, 4, 5))]

@assert query(r[2], :symbol1, 4, ❓) == (depth=1, tag=Tag(:symbol1, 4, 5))
@assert queryall(r[2], :symbol1, 4, ❓) == [(depth=1, tag=Tag(:symbol1, 4, 5))]

@assert querydelete!(r[2], :symbol1, 4, ❓) == Tag(:symbol1, 4, 5)
@assert querydelete!(r[2], :symbol1, 4, ❓) === nothing
end
SUITE["tagquery"]["misc"]["from_tests"] = @benchmarkable tagquery_interfacetest()
8 changes: 8 additions & 0 deletions docs/src/tutorial/message_queues.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ DocTestSetup = quote
end
```

!!! warning

This section is rather low-level, created before a lot of user-friendly tools were added.
The approach described here still functions well, however we now provide a more convenient interface and pre-build message passing channels.
In particular, the tagging & querying system (based on `tag!` and `query`), the [`messagebuffer`](@ref), and the available [`channel`](@ref), [`qchannel`](@ref) and [`QuantumChannel`](@ref)
probably cover all your needs.
You might still be interested in reading this section in order to learn some of the low-level tooling on which the more recent developments were built.

In network simulations, a convenient synchronization primitive is the passing of messages between nodes.
The `ResumableFunctions` and `ConcurrentSim` libraries provide such primitives, convenient to use with `QuatumSavory`.

Expand Down
18 changes: 11 additions & 7 deletions docs/src/visualizations.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,7 @@ using CairoMakie # or GLMakie for interactive plots
using QuantumSavory
# create a network of qubit registers
sizes = [2,3,2,5]
registers = Register[]
for s in sizes
traits = [Qubit() for _ in 1:s]
push!(registers, Register(traits))
end
network = RegisterNet(registers)
network = RegisterNet([Register(2),Register(3),Register(2),Register(5)])
# add some states, entangle a few slots, perform some gates
initialize!(network[1,1])
Expand All @@ -41,6 +35,16 @@ _, _, plt, obs = registernetplot_axis(fig[1,1],network)
fig
```

The tall rectangles are registers, the gray squares are the slots of these registers, and the (connected) black diamonds denote when a slot is occupied by some subsystem (of a potentially larger) quantum state.

The visualization is capable of showing tooltips when hovering over different components of the plot, particularly valuable for debugging. Quantum observables can be directly calculated and plotted as well (through the `observables` keyword).

Other configuration options are available as well (the ones ending on `plot` let you access the subplot objects used to create the visualization and the ones ending on `backref` provide convenient inverse mapping from graphical elements to the registers or states being visualized):

```@example vis
propertynames(plt)
```

## The state of locks and various metadata in the network

The [`resourceplot_axis`](@ref) function can be used to draw all locks and resources stored in a meta-graph governing a discrete event simulation. Metadata stored at the vertices is plotted as colored or grayed out dots depending on their state. Metadata stored at the edges is shown as lines.
Expand Down
2 changes: 1 addition & 1 deletion examples/firstgenrepeater_v2/2_swapper_example.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ for (;src, dst) in edges(network)
@process eprot()
end
for node in vertices(network)
sprot = SwapperProt(sim, network, node; nodeL = <(node), nodeR = >(node))
sprot = SwapperProt(sim, network, node; nodeL = <(node), nodeH = >(node), chooseL = argmin, chooseH = argmax)
@process sprot()
end

Expand Down
Loading

0 comments on commit 81e93de

Please sign in to comment.