Skip to content

Commit

Permalink
Merge branch 'master' into compathelper/new_version/2024-06-13-00-12-…
Browse files Browse the repository at this point in the history
…18-544-03881401723
  • Loading branch information
david-pl authored Sep 23, 2024
2 parents 134c475 + e1fe96b commit 52b0ce4
Show file tree
Hide file tree
Showing 22 changed files with 746 additions and 139 deletions.
64 changes: 64 additions & 0 deletions .github/workflows/benchmark-comment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# To workaroud https://github.com/actions/first-interaction/issues/10 in a secure way,
# we take the following steps to generate and comment a performance benchmark result:
# 1. first "performance tracking" workflow will generate the benchmark results in an unprivileged environment triggered on `pull_request` event
# 2. then this "performance tracking (comment)" workflow will show the result to us as a PR comment in a privileged environment
# Note that this workflow can only be modifed by getting checked-in to the default branch
# and thus is secure even though this workflow is granted with write permissions, etc.
# xref: https://securitylab.github.com/research/github-actions-preventing-pwn-requests/

name: Performance tracking (comment)

on:
workflow_run:
workflows:
- performance tracking
types:
- completed

jobs:
comment:
runs-on: ubuntu-latest
#runs-on: self-hosted
if: >
${{ github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@v4

# restore records from the artifacts
- uses: dawidd6/action-download-artifact@v6
with:
workflow: benchmark.yml
name: performance-tracking
workflow_conclusion: success
- name: output benchmark result
id: output-result-markdown
run: |
echo ::set-output name=body::$(cat ./benchmark-result.artifact)
- name: output pull request number
id: output-pull-request-number
run: |
echo ::set-output name=body::$(cat ./pull-request-number.artifact)
# check if the previous comment exists
- name: find comment
uses: peter-evans/find-comment@v3
id: fc
with:
issue-number: ${{ steps.output-pull-request-number.outputs.body }}
comment-author: 'github-actions[bot]'
body-includes: Benchmark Result

# create/update comment
- name: create comment
if: ${{ steps.fc.outputs.comment-id == 0 }}
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@v4
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
body: ${{ steps.output-result-markdown.outputs.body }}
57 changes: 57 additions & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
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
- uses: julia-actions/setup-julia@latest
with:
version: '1.10'
- uses: julia-actions/julia-buildpkg@latest
- name: install dependencies
run: julia -e 'using Pkg; pkg"add PkgBenchmark BenchmarkCI@0.1"'

# run the benchmark suite
- name: run benchmarks
run: |
julia -e '
using BenchmarkCI
BenchmarkCI.judge()
BenchmarkCI.displayjudgement()
'
# generate and record the benchmark result as markdown
- name: generate benchmark result
run: |
body=$(julia -e '
using BenchmarkCI
let
judgement = BenchmarkCI._loadjudge(BenchmarkCI.DEFAULT_WORKSPACE)
title = "Benchmark Result"
ciresult = BenchmarkCI.CIResult(; judgement, title)
BenchmarkCI.printcommentmd(stdout::IO, ciresult)
end
')
body="${body//'%'/'%25'}"
body="${body//$'\n'/'%0A'}"
body="${body//$'\r'/'%0D'}"
echo $body > ./benchmark-result.artifact
# record the pull request number
- name: record pull request number
run: echo ${{ github.event.pull_request.number }} > ./pull-request-number.artifact

# save as artifacts (performance tracking (comment) workflow will use it)
- uses: actions/upload-artifact@v4
with:
name: performance-tracking
path: ./*.artifact
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ jobs:
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v1
- uses: codecov/codecov-action@v4
with:
file: lcov.info
15 changes: 9 additions & 6 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
name = "QuantumOptics"
uuid = "6e0679c1-51ea-5a7c-ac74-d61b76210b0c"
version = "1.0.16"
version = "1.1.1"

[deps]
Arpack = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97"
DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e"
DiffEqCallbacks = "459566f4-90b8-5000-8ac3-15dfb0a30def"
DiffEqNoiseProcess = "77a26b50-5914-5dd7-bc55-306e6241c503"
FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153"
Expand All @@ -25,24 +26,26 @@ WignerSymbols = "9f57e263-0b3d-5e2e-b1be-24f2bb48858b"
Arpack = "0.5.1 - 0.5.3"
DiffEqBase = "6.113"
DiffEqCallbacks = "2, 3"
DiffEqNoiseProcess = "5.23.0"
FFTW = "1"
ForwardDiff = "0.10"
IterativeSolvers = "0.9"
KrylovKit = "0.6, 0.8"
KrylovKit = "0.6, 0.7, 0.8"
LinearMaps = "3"
OrdinaryDiffEq = "5, 6"
QuantumOpticsBase = "0.3, 0.4"
QuantumOpticsBase = "0.3, 0.4, 0.5"
RecursiveArrayTools = "2, 3"
Reexport = "0.2, 1.0"
StochasticDiffEq = "6"
StochasticDiffEq = "6.68.0"
WignerSymbols = "1, 2"
julia = "1.3"
julia = "1.10"

[extras]
FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["LinearAlgebra", "SparseArrays", "Random", "Test"]
test = ["FiniteDiff", "LinearAlgebra", "SparseArrays", "Random", "Test"]
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"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
PkgBenchmark = "32113eaa-f34f-5b0d-bd6c-c81e245fc73d"
QuantumOptics = "6e0679c1-51ea-5a7c-ac74-d61b76210b0c"
StochasticDiffEq = "789caeaf-c7a9-5a7d-9973-96adeb23e2a0"
113 changes: 113 additions & 0 deletions benchmark/benchmarks.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
using BenchmarkTools
using QuantumOptics
using OrdinaryDiffEq
using StochasticDiffEq
using LinearAlgebra
using PkgBenchmark


const SUITE = BenchmarkGroup()

prob_list = ("schroedinger", "master", "stochastic_schroedinger", "stochastic_master")
for prob in prob_list
SUITE[prob] = BenchmarkGroup([prob])
for type in ("qo types", "base array types")
SUITE[prob][type] = BenchmarkGroup()
end
end

function bench_schroedinger(dim; pure=true)
b = SpinBasis(dim)
t₀, t₁ = (0.0, pi)
H = sigmax(b)
psi0 = spindown(b)
if pure
obj = psi0.data
Hobj = H.data
else
obj = psi0
Hobj = H
end
schroed!(dpsi, psi, p, t) = timeevolution.dschroedinger!(dpsi, Hobj, psi)
prob = ODEProblem(schroed!, obj, (t₀, t₁))
end
function bench_master(dim; pure=true)
b = SpinBasis(dim)
t₀, t₁ = (0.0, pi)
H = sigmax(b)
psi0 = spindown(b)
J = sigmam(b)
rho0 = dm(psi0)
rates = [0.3]
if pure
obj = rho0.data
Jobj, Jdag = (J.data, dagger(J).data)
Hobj = H.data
else
obj = rho0
Jobj, Jdag = (J, dagger(J))
Hobj = H
end
master!(drho, rho, p, t) = timeevolution.dmaster_h!(drho, Hobj, [Jobj], [Jdag], rates, rho, copy(obj))
prob = ODEProblem(master!, obj, (t₀, t₁))
end
function bench_stochastic_schroedinger(dim; pure=true)
b = SpinBasis(dim)
t₀, t₁ = (0.0, pi)
H = sigmax(b)
Hs = sigmay(b)
psi0 = spindown(b)
if pure
obj = psi0.data
Hobj = H.data
Hsobj = Hs.data
else
obj = psi0
Hobj = H
Hsobj = Hs
end
schroed!(dpsi, psi, p, t) = timeevolution.dschroedinger!(dpsi, Hobj, psi)
stoch_schroed!(dpsi, psi, p, t) = timeevolution.dschroedinger!(dpsi, Hsobj, psi)
prob = SDEProblem(schroed!, stoch_schroed!, obj, (t₀, t₁))
end
function bench_stochastic_master(dim; pure=true)
b = SpinBasis(dim)
t₀, t₁ = (0.0, pi)
H = sigmax(b)
Hs = sigmay(b)
psi0 = spindown(b)
J = sigmam(b)
rho0 = dm(psi0)
rates = [0.3]
if pure
obj = rho0.data
Jobj, Jdag = (J.data, dagger(J).data)
Hobj = H.data
Hsobj = Hs.data
else
obj = rho0
Jobj, Jdag = (J, dagger(J))
Hobj = H
Hsobj = Hs
end
master!(drho, rho, p, t) = timeevolution.dmaster_h!(drho, Hobj, [Jobj], [Jdag], rates, rho, copy(obj))
stoch_master!(drho, rho, p, t) = timeevolution.dmaster_h!(drho, Hsobj, [Jobj], [Jdag], rates, rho, copy(obj))
prob = SDEProblem(master!, stoch_master!, obj, (t₀, t₁))
end

for dim in (1//2, 20//1, 50//1, 100//1)
for solver in zip(("schroedinger", "master"), (:(bench_schroedinger), :(bench_master)))
name, bench = (solver[1], solver[2])
# benchmark solving ODE problems on data of QO types
SUITE[name]["base array types"][string(dim)] = @benchmarkable solve(prob, DP5(); save_everystep=false) setup=(prob=eval($bench)($dim; pure=true))
# benchmark solving ODE problems on custom QO types
SUITE[name]["qo types"][string(dim)] = @benchmarkable solve(prob, DP5(); save_everystep=false) setup=(prob=eval($bench)($dim; pure=false))
end
for solver in zip(("stochastic schroedinger", "stochastic master"), (:(bench_stochastic_schroedinger), :(bench_stochastic_master)))
name, bench = (solver[1], solver[2])
# benchmark solving ODE problems on data of QO types
SUITE[name]["base array types"][string(dim)] = @benchmarkable solve(prob, EM(), dt=1/100; save_everystep=false) setup=(prob=eval($bench)($dim; pure=true))
# benchmark solving ODE problems on custom QO types
SUITE[name]["qo types"][string(dim)] = @benchmarkable solve(prob, EM(), dt=1/100; save_everystep=false) setup=(prob=eval($bench)($dim; pure=false))
end
end
1 change: 1 addition & 0 deletions src/QuantumOptics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module QuantumOptics
using Reexport
@reexport using QuantumOpticsBase
using SparseArrays, LinearAlgebra
import RecursiveArrayTools

export
ylm,
Expand Down
4 changes: 2 additions & 2 deletions src/bloch_redfield_master.jl
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,8 @@ end

# Integrate with given fout
function integrate_br(tspan, dmaster_br, rho,
transf_op, inv_transf_op, fout::Function;
kwargs...)
transf_op, inv_transf_op, fout::F;
kwargs...) where {F}
# Pre-allocate for in-place back-transformation from eigenbasis
rho_out = copy(transf_op)
tmp = copy(transf_op)
Expand Down
12 changes: 9 additions & 3 deletions src/master.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ function master_h(tspan, rho0::Operator, H::AbstractOperator, J;
_check_const.(J)
_check_const.(Jdagger)
check_master(rho0, H, J, Jdagger, rates)
tspan, rho0 = _promote_time_and_state(rho0, H, J, tspan)
tmp = copy(rho0)
dmaster_(t, rho, drho) = dmaster_h!(drho, H, J, Jdagger, rates, rho, tmp)
integrate_master(tspan, dmaster_, rho0, fout; kwargs...)
Expand Down Expand Up @@ -41,6 +42,7 @@ function master_nh(tspan, rho0::Operator, Hnh::AbstractOperator, J;
_check_const.(J)
_check_const.(Jdagger)
check_master(rho0, Hnh, J, Jdagger, rates)
tspan, rho0 = _promote_time_and_state(rho0, Hnh, J, tspan)
tmp = copy(rho0)
dmaster_(t, rho, drho) = dmaster_nh!(drho, Hnh, Hnhdagger, J, Jdagger, rates, rho, tmp)
integrate_master(tspan, dmaster_, rho0, fout; kwargs...)
Expand Down Expand Up @@ -86,6 +88,7 @@ function master(tspan, rho0::Operator, H::AbstractOperator, J;
_check_const(H)
_check_const.(J)
_check_const.(Jdagger)
tspan, rho0 = _promote_time_and_state(rho0, H, J, tspan)
isreducible = check_master(rho0, H, J, Jdagger, rates)
if !isreducible
tmp = copy(rho0)
Expand Down Expand Up @@ -124,6 +127,7 @@ function master(tspan, rho0::Operator, L::SuperOperator; fout=nothing, kwargs...
b = GenericBasis(dim)
rho_ = Ket(b,reshape(rho0.data, dim))
L_ = Operator(b,b,L.data)
tspan, rho_ = _promote_time_and_state(rho_, L_, tspan)
dmaster_(t,rho,drho) = dmaster_liouville!(drho,L_,rho)

# Rewrite into density matrix when saving
Expand Down Expand Up @@ -215,7 +219,9 @@ function master_dynamic(tspan, rho0::Operator, f;
fout=nothing,
kwargs...)
tmp = copy(rho0)
dmaster_(t, rho, drho) = dmaster_h_dynamic!(drho, f, rates, rho, tmp, t)
dmaster_ = let f = f, tmp = tmp
dmaster_(t, rho, drho) = dmaster_h_dynamic!(drho, f, rates, rho, tmp, t)
end
integrate_master(tspan, dmaster_, rho0, fout; kwargs...)
end

Expand Down Expand Up @@ -395,7 +401,7 @@ returned from `f`.
See also: [`master_dynamic`](@ref), [`dmaster_h!`](@ref), [`dmaster_nh!`](@ref),
[`dmaster_nh_dynamic!`](@ref)
"""
function dmaster_h_dynamic!(drho, f, rates, rho, drho_cache, t)
function dmaster_h_dynamic!(drho, f::F, rates, rho, drho_cache, t) where {F}
result = f(t, rho)
QO_CHECKS[] && @assert 3 <= length(result) <= 4
if length(result) == 3
Expand All @@ -418,7 +424,7 @@ equation. Optionally, rates can also be returned from `f`.
See also: [`master_dynamic`](@ref), [`dmaster_h!`](@ref), [`dmaster_nh!`](@ref),
[`dmaster_h_dynamic!`](@ref)
"""
function dmaster_nh_dynamic!(drho, f, rates, rho, drho_cache, t)
function dmaster_nh_dynamic!(drho, f::F, rates, rho, drho_cache, t) where {F}
result = f(t, rho)
QO_CHECKS[] && @assert 4 <= length(result) <= 5
if length(result) == 4
Expand Down
Loading

0 comments on commit 52b0ce4

Please sign in to comment.