diff --git a/.github/workflows/Benchmarks.yml b/.github/workflows/Benchmarks.yml index 43d3f565..f7c920ac 100644 --- a/.github/workflows/Benchmarks.yml +++ b/.github/workflows/Benchmarks.yml @@ -37,7 +37,17 @@ jobs: with: version: '1' arch: x64 - - uses: julia-actions/cache@v1 + # - uses: julia-actions/cache@v1 + - 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 }}- - name: Run benchmark run: | cd benchmarks @@ -50,7 +60,7 @@ jobs: - name: Parse & Upload Benchmark Results uses: benchmark-action/github-action-benchmark@v1 with: - name: Benchmark results + name: Benchmark Results tool: "julia" output-file-path: benchmarks/benchmarks_output.json summary-always: true diff --git a/benchmarks/correlations_and_spectrum.jl b/benchmarks/correlations_and_spectrum.jl new file mode 100644 index 00000000..2d15d200 --- /dev/null +++ b/benchmarks/correlations_and_spectrum.jl @@ -0,0 +1,18 @@ +function benchmark_correlations_and_spectrum() + N = 15 + ω = 1 + γ = 0.1 + nth = 0.02 + + a = destroy(N) + H = ω * a' * a + c_ops = [sqrt(γ * (nth + 1)) * a, sqrt(γ * nth) * a'] + + ω_l = range(0, 3, length=1000) + + SUITE["Correlations and Spectrum"]["FFT Correlation"] = @benchmarkable spectrum($H, $ω_l, $(a'), $a, $c_ops, solver=FFTCorrelation(), progress_bar=false) + + SUITE["Correlations and Spectrum"]["Exponential Series"] = @benchmarkable spectrum($H, $ω_l, $(a'), $a, $c_ops) +end + +benchmark_correlations_and_spectrum() \ No newline at end of file diff --git a/benchmarks/dynamical_fock_dimension.jl b/benchmarks/dynamical_fock_dimension.jl new file mode 100644 index 00000000..b37f0180 --- /dev/null +++ b/benchmarks/dynamical_fock_dimension.jl @@ -0,0 +1,33 @@ +function H_dfd2(dims, p) + Δ = p.Δ + F = p.F + J = p.J + a = tensor(destroy(dims[1]), qeye(dims[2])) + b = tensor(qeye(dims[1]), destroy(dims[2])) + Δ * a' * a + F * (a + a') + Δ * b' * b + J * (a' * b + a * b') +end +function c_ops_dfd2(dims, p) + κ = p.κ + a = tensor(destroy(dims[1]), qeye(dims[2])) + b = tensor(qeye(dims[1]), destroy(dims[2])) + [√κ * a, √κ * b] +end +function e_ops_dfd2(dims, p) + a = tensor(destroy(dims[1]), qeye(dims[2])) + b = tensor(qeye(dims[1]), destroy(dims[2])) + [a' * a, b' * b] +end + +function benchmark_dfd() + F, Δ, κ, J = 1, 0.25, 1, 0.05 + maxdims = [50, 50] + + ψ0 = tensor(fock(3, 0), fock(20, 15)) + dfd_params = (Δ=Δ, F=F, κ=κ, J=J) + + tlist = range(0, 15 / κ, 100) + + SUITE["Time Evolution"]["Dynamical Fock Dimension"] = @benchmarkable dfd_mesolve(H_dfd2, $ψ0, $tlist, c_ops_dfd2, $maxdims, $dfd_params, e_ops=e_ops_dfd2, progress_bar=false) +end + +benchmark_dfd() \ No newline at end of file diff --git a/benchmarks/eigenvalues.jl b/benchmarks/eigenvalues.jl new file mode 100644 index 00000000..dcb48e2c --- /dev/null +++ b/benchmarks/eigenvalues.jl @@ -0,0 +1,22 @@ +function benchmark_eigenvalues() + N = 5 + a = tensor(destroy(N), qeye(N)) + a_d = a' + b = tensor(qeye(N), destroy(N)) + b_d = b' + + ωc = 1 + ωb = 1 + g = 0.2 + κ = 0.01 + n_thermal = 0.1 + + H = ωc * a_d * a + ωb * b_d * b + g * (a + a_d) * (b + b_d) + c_ops = [√((1+n_thermal)*κ) * a, √κ * b, √(n_thermal*κ) * a_d] + L = liouvillian(H, c_ops) + + SUITE["Eigenvalues"]["eigenstates"]["dense"] = @benchmarkable eigenstates($L) + SUITE["Eigenvalues"]["eigenstates"]["sparse"] = @benchmarkable eigenstates($L, sparse=true, sigma=0.01, k=5) +end + +benchmark_eigenvalues() \ No newline at end of file diff --git a/benchmarks/runbenchmarks.jl b/benchmarks/runbenchmarks.jl index dea58b58..6dc699d5 100644 --- a/benchmarks/runbenchmarks.jl +++ b/benchmarks/runbenchmarks.jl @@ -1,28 +1,18 @@ using BenchmarkTools using QuantumToolbox -suite = BenchmarkGroup() +BLAS.set_num_threads(1) -suite["steadystate"] = BenchmarkGroup(["steadystate"]) +const SUITE = BenchmarkGroup() +include("correlations_and_spectrum.jl") +include("dynamical_fock_dimension.jl") +include("eigenvalues.jl") +include("steadystate.jl") +include("timeevolution.jl") -## steadystate ## - -N = 50 -Δ = 0.1 -F = 2 -γ = 1 -a = destroy(N) -H = Δ * a' * a + F * (a + a') -c_ops = [sqrt(γ) * a] - -suite["steadystate"]["driven-dissipative harmonic oscillator"] = @benchmarkable steadystate($H, $c_ops) - -## end ## - - -BenchmarkTools.tune!(suite) -results = run(suite, verbose = true) +BenchmarkTools.tune!(SUITE) +results = BenchmarkTools.run(SUITE, verbose = true) display(median(results)) -BenchmarkTools.save(joinpath(@__DIR__, "benchmarks_output.json"), median(results)) \ No newline at end of file +BenchmarkTools.save("benchmarks_output.json", median(results)) \ No newline at end of file diff --git a/benchmarks/steadystate.jl b/benchmarks/steadystate.jl new file mode 100644 index 00000000..84379b91 --- /dev/null +++ b/benchmarks/steadystate.jl @@ -0,0 +1,15 @@ +function benchmark_steadystate() + N = 50 + Δ = 0.1 + F = 2 + γ = 1 + nth = 5 + + a = destroy(N) + H = Δ * a' * a + F * (a + a') + c_ops = [sqrt(γ * (nth + 1)) * a, sqrt(γ * nth) * a'] + + SUITE["Steadystate"]["Direct"] = @benchmarkable steadystate($H, $c_ops) +end + +benchmark_steadystate() \ No newline at end of file diff --git a/benchmarks/timeevolution.jl b/benchmarks/timeevolution.jl new file mode 100644 index 00000000..aa9e47fc --- /dev/null +++ b/benchmarks/timeevolution.jl @@ -0,0 +1,47 @@ +function benchmark_timeevolution() + ωc = 1 + ωq = 1 + g = 0.1 + ωd = 0.99 + F = 0.07 + + Δc = ωc - ωd + Δq = ωq - ωd + + # Operators definition + N = 20 # cutoff for the cavity Hilbert space + a = tensor(destroy(N), qeye(2)) + σm = tensor(qeye(N), sigmam()) + σz = tensor(qeye(N), sigmaz()) + + # Hamiltonian + H = Δc * a' * a + Δq * σz / 2 + g * (a' * σm + a * σm') + F * (a + a') + + e_ops = [a'*a, σz] + + # Initial state + ψ0 = tensor(coherent(N, 0), fock(2, 1)) + + ## sesolve ## + + tlist = range(0, 2π * 10 / g, 1000) + + SUITE["Time Evolution"]["time-independent"]["sesolve"] = @benchmarkable sesolve($H, $ψ0, $tlist, e_ops=$e_ops, progress_bar=false) + + ## mesolve ## + + nth = 0.01 + γ = 0.05 + c_ops = [sqrt(γ * (nth + 1)) * a, sqrt(γ * nth) * a', sqrt(γ) * σm] + + tlist = range(0, 10/γ, 100) + + SUITE["Time Evolution"]["time-independent"]["mesolve"] = @benchmarkable mesolve($H, $ψ0, $tlist, $c_ops, e_ops=$e_ops, progress_bar=false) + + ## mcsolve ## + + SUITE["Time Evolution"]["time-independent"]["mcsolve"]["Serial"] = @benchmarkable mcsolve($H, $ψ0, $tlist, $c_ops, n_traj=100, e_ops=$e_ops, progress_bar=false, ensemble_method=EnsembleSerial()) + SUITE["Time Evolution"]["time-independent"]["mcsolve"]["Multithreaded"] = @benchmarkable mcsolve($H, $ψ0, $tlist, $c_ops, n_traj=100, e_ops=$e_ops, progress_bar=false, ensemble_method=EnsembleThreads()) +end + +benchmark_timeevolution() \ No newline at end of file diff --git a/docs/make.jl b/docs/make.jl index 5e0dd525..6edc551e 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -8,7 +8,6 @@ DocMeta.setdocmeta!(QuantumToolbox, :DocTestSetup, :(using QuantumToolbox); recu makedocs(; modules=[QuantumToolbox], authors="Alberto Mercurio", - # repo="https://github.com/albertomercurio/QuantumToolbox.jl/blob/{commit}{path}#{line}", repo = Remotes.GitHub("albertomercurio", "QuantumToolbox.jl"), sitename="QuantumToolbox.jl", format=Documenter.HTML(; @@ -30,6 +29,9 @@ makedocs(; "api.md", "Users Guide" => [ "Low Rank Master Equation" => "lowrank.md", + ], + "Benchmarks" => [ + "Benchmark History" => "benchmarks/benchmark_history.md", ] ], ) diff --git a/docs/src/benchmarks/benchmark_history.md b/docs/src/benchmarks/benchmark_history.md new file mode 100644 index 00000000..d0dc9682 --- /dev/null +++ b/docs/src/benchmarks/benchmark_history.md @@ -0,0 +1 @@ + \ No newline at end of file