From e7236cd88fc269a02afce4990a70995b29dfe5be Mon Sep 17 00:00:00 2001 From: Dhruva Sambrani <44899822+DhruvaSambrani@users.noreply.github.com> Date: Sun, 29 Jan 2023 19:21:56 +0530 Subject: [PATCH 1/4] add circuit_depth --- lib/YaoBlocks/src/blocktools.jl | 36 +++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/lib/YaoBlocks/src/blocktools.jl b/lib/YaoBlocks/src/blocktools.jl index 261fa7ce..51cf83ff 100644 --- a/lib/YaoBlocks/src/blocktools.jl +++ b/lib/YaoBlocks/src/blocktools.jl @@ -1,4 +1,4 @@ -export postwalk, prewalk, blockfilter!, blockfilter, collect_blocks, gatecount +export postwalk, prewalk, blockfilter!, blockfilter, collect_blocks, gatecount, circuit_depth """ parse_block(n, ex) @@ -102,7 +102,7 @@ function expect(op::AbstractBlock, dm::DensityMatrix) end function expect(op::AbstractAdd, reg::DensityMatrix) # NOTE: this is faster in e.g. when the op is Heisenberg - invoke(expect, Tuple{AbstractBlock, DensityMatrix}, op, reg) + invoke(expect, Tuple{AbstractBlock,DensityMatrix}, op, reg) end function expect(op::Scale, reg::DensityMatrix) factor(op) * expect(content(op), reg) @@ -135,7 +135,7 @@ end function conjsumprod1(A::AbstractArray, C::AbstractArray) Na, B = size(A) res = zeros(eltype(C), B) - @inbounds for b=1:B, i=1:Na + @inbounds for b = 1:B, i = 1:Na res[b] += conj(A[i, b]) * C[i, b] end res @@ -145,7 +145,7 @@ end function conjsumprod2(A::AbstractArray, C::AbstractArray) B, Na = size(A) res = zeros(eltype(C), B) - @inbounds for i=1:Na, b=1:B + @inbounds for i = 1:Na, b = 1:B res[b] += conj(A[b, i]) * C[b, i] end res @@ -155,7 +155,7 @@ end function conjsumprod13(A::AbstractArray, C::AbstractArray) Nr, B, Na = size(A) res = zeros(eltype(C), B) - @inbounds for i=1:Na, b=1:B, r=1:size(C, 1) + @inbounds for i = 1:Na, b = 1:B, r = 1:size(C, 1) res[b] += conj(A[r, b, i]) * C[r, b, i] end res @@ -213,7 +213,7 @@ function gatecount!(c::RepeatedBlock, storage::AbstractDict) end # NOTE: static scale defines a gate, dynamic scale is parameter. -function gatecount!(c::Scale{S}, storage::AbstractDict) where S +function gatecount!(c::Scale{S}, storage::AbstractDict) where {S} if S <: Val k = typeof(c) storage[k] = get(storage, k, 0) + 1 @@ -229,3 +229,27 @@ function gatecount!(c::AbstractBlock, storage::AbstractDict) storage[k] = get(storage, k, 0) + 1 storage end + +""" + circuit_depth(c::ChainBlock, count_measure::Bool=true) -> Int64 + +The depth of a circuit is a metric that calculates the longest path between the data input and the output. +Each Block counts as taking the same depth (1 unit). + +If `count_measure` is true, `Measure` blocks are also counted. +""" +# TODO: define a TimedBlock that wraps around other blocks, and adds that much time to `currdepth` + +function circuit_depth(c::ChainBlock, count_measure::Bool=true) + deptharr = fill(0, c.n) + touches = collect ∘ occupied_locs + for g in c + if !count_measure && g isa Measure + continue + end + r = touches(g) + currdepth = maximum(getindex.(Ref(deptharr), r)) + deptharr[r] .= currdepth + 1 + end + return maximum(deptharr) +end From 4e03d090e7c2d6ec2dd004490972d342745a9b7d Mon Sep 17 00:00:00 2001 From: Dhruva Sambrani <44899822+DhruvaSambrani@users.noreply.github.com> Date: Mon, 30 Jan 2023 21:17:40 +0530 Subject: [PATCH 2/4] add circuit depth tests --- lib/YaoBlocks/test/blocktools.jl | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/lib/YaoBlocks/test/blocktools.jl b/lib/YaoBlocks/test/blocktools.jl index b818e7ac..54da33c6 100644 --- a/lib/YaoBlocks/test/blocktools.jl +++ b/lib/YaoBlocks/test/blocktools.jl @@ -97,3 +97,38 @@ end res = gatecount(repeat(5, X, (2, 3))) @test res |> values |> sum == 2 end + +@testset "circuit depth" begin + @const_gate U4 = rand(ComplexF64, 4, 4) + @const_gate U2 = rand(ComplexF64, 4, 4) + @const_gate U = rand(ComplexF64, 4, 4) + test_circuit = chain( + 5, + put(1=>X), + put(2=>X), + put(3=>X), + control(1, (4, 5)=>U4), + control(2, (4,5)=>U2), + put(1=>H), + control(1, 2=>T), + put(2=>H), + control(3, (4,5)=>U), + control(1, 3=>T), + control(2, 3=>T), + put(3=>H), + Measure(locs=[1,2,3]) + ) + GHZ = chain( + 4, + put(1=>X), + repeat(H, 2:4), + control(2, 1=>X), + control(4, 3=>X), + control(3, 1=>X), + control(4, 3=>X), + repeat(H, 1:4), + ) + @test circuit_depth(GHZ) == 5 + @test circuit_depth(test_circuit) == 8 + @test circuit_depth(test_circuit, false) == 7 +end From 3e2030871d6da44b05a8ccb15f92292b40676e68 Mon Sep 17 00:00:00 2001 From: Dhruva Sambrani <44899822+DhruvaSambrani@users.noreply.github.com> Date: Mon, 30 Jan 2023 22:57:02 +0530 Subject: [PATCH 3/4] make count_measure kwarg --- lib/YaoBlocks/src/blocktools.jl | 2 +- lib/YaoBlocks/test/blocktools.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/YaoBlocks/src/blocktools.jl b/lib/YaoBlocks/src/blocktools.jl index 51cf83ff..fb9425cf 100644 --- a/lib/YaoBlocks/src/blocktools.jl +++ b/lib/YaoBlocks/src/blocktools.jl @@ -240,7 +240,7 @@ If `count_measure` is true, `Measure` blocks are also counted. """ # TODO: define a TimedBlock that wraps around other blocks, and adds that much time to `currdepth` -function circuit_depth(c::ChainBlock, count_measure::Bool=true) +function circuit_depth(c::ChainBlock; count_measure::Bool=true) deptharr = fill(0, c.n) touches = collect ∘ occupied_locs for g in c diff --git a/lib/YaoBlocks/test/blocktools.jl b/lib/YaoBlocks/test/blocktools.jl index 54da33c6..46a8f71c 100644 --- a/lib/YaoBlocks/test/blocktools.jl +++ b/lib/YaoBlocks/test/blocktools.jl @@ -130,5 +130,5 @@ end ) @test circuit_depth(GHZ) == 5 @test circuit_depth(test_circuit) == 8 - @test circuit_depth(test_circuit, false) == 7 + @test circuit_depth(test_circuit, count_measure=false) == 7 end From 3012da0d4fb6455c1ff0d980c5ce9cf9c782dd4c Mon Sep 17 00:00:00 2001 From: Dhruva Sambrani <44899822+DhruvaSambrani@users.noreply.github.com> Date: Tue, 31 Jan 2023 14:56:06 +0530 Subject: [PATCH 4/4] fix tests so that they pass --- lib/YaoBlocks/test/blocktools.jl | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/YaoBlocks/test/blocktools.jl b/lib/YaoBlocks/test/blocktools.jl index 46a8f71c..8aa5c8df 100644 --- a/lib/YaoBlocks/test/blocktools.jl +++ b/lib/YaoBlocks/test/blocktools.jl @@ -99,26 +99,26 @@ end end @testset "circuit depth" begin - @const_gate U4 = rand(ComplexF64, 4, 4) - @const_gate U2 = rand(ComplexF64, 4, 4) - @const_gate U = rand(ComplexF64, 4, 4) - test_circuit = chain( + @const_gate cd_U4 = rand(ComplexF64, 4, 4) + @const_gate cd_U2 = rand(ComplexF64, 4, 4) + @const_gate cd_U = rand(ComplexF64, 4, 4) + cd_test_circuit = chain( 5, put(1=>X), put(2=>X), put(3=>X), - control(1, (4, 5)=>U4), - control(2, (4,5)=>U2), + control(1, (4, 5)=>cd_U4), + control(2, (4,5)=>cd_U2), put(1=>H), control(1, 2=>T), put(2=>H), - control(3, (4,5)=>U), + control(3, (4,5)=>cd_U), control(1, 3=>T), control(2, 3=>T), put(3=>H), Measure(locs=[1,2,3]) ) - GHZ = chain( + cd_test_GHZ = chain( 4, put(1=>X), repeat(H, 2:4), @@ -128,7 +128,7 @@ end control(4, 3=>X), repeat(H, 1:4), ) - @test circuit_depth(GHZ) == 5 - @test circuit_depth(test_circuit) == 8 - @test circuit_depth(test_circuit, count_measure=false) == 7 + @test circuit_depth(cd_test_GHZ) == 5 + @test circuit_depth(cd_test_circuit) == 8 + @test circuit_depth(cd_test_circuit, count_measure=false) == 7 end