@@ -5,8 +5,9 @@ using YaoBlocks
5
5
using DelegatorTraits
6
6
import DelegatorTraits: DelegatorTrait
7
7
8
- struct Circuit <: Tangles.AbstractTensorNetwork
8
+ @kwdef struct Circuit <: Tangles.AbstractTensorNetwork
9
9
tn:: Tangles.GenericTensorNetwork
10
+ last_t:: Dict{Site,Int} = Dict {Site,Int} ()
10
11
end
11
12
12
13
DelegatorTrait (:: Networks.Network , :: Circuit ) = DelegateToField {:tn} ()
@@ -15,7 +16,7 @@ DelegatorTrait(::Tangles.TensorNetwork, ::Circuit) = DelegateToField{:tn}()
15
16
DelegatorTrait (:: Tangles.Pluggable , :: Circuit ) = DelegateToField {:tn} ()
16
17
DelegatorTrait (:: Tangles.Lattice , :: Circuit ) = DelegateToField {:tn} ()
17
18
18
- Base. copy (circ:: Circuit ) = Circuit (copy (circ. tn))
19
+ Base. copy (circ:: Circuit ) = Circuit (copy (circ. tn), Dict {Site,Int} () )
19
20
20
21
function flatten_circuit (x)
21
22
if any (i -> i isa ChainBlock, subblocks (x))
@@ -25,12 +26,24 @@ function flatten_circuit(x)
25
26
end
26
27
end
27
28
29
+ struct LaneAt{S}
30
+ site:: S
31
+ t:: Int
32
+ end
33
+
34
+ function Base. show (io:: IO , lane:: LaneAt )
35
+ print (io, lane. site)
36
+ return print (io, " @$(lane. t) " )
37
+ end
38
+
39
+ moment (circuit:: Circuit , site:: Site ) = circuit. last_t[site]
40
+
28
41
"""
29
42
Convert a Yao circuit to a Circuit.
30
43
"""
31
44
function Base. convert (:: Type{Circuit} , yaocirc:: AbstractBlock )
32
45
tn = GenericTensorNetwork ()
33
- circuit = Circuit (tn)
46
+ circuit = Circuit (tn, Dict {Site,Int} () )
34
47
35
48
for gate in flatten_circuit (yaocirc)
36
49
# if gate isa Swap
@@ -45,7 +58,7 @@ function Base.convert(::Type{Circuit}, yaocirc::AbstractBlock)
45
58
# NOTE `YaoBlocks.mat` on m-site qubits still returns the operator on the full Hilbert space
46
59
m = length (occupied_locs (gate))
47
60
operator = if gate isa YaoBlocks. ControlBlock
48
- control ((1 : (m- 1 )). .. , m => content (gate))(m)
61
+ control ((1 : (m - 1 )). .. , m => content (gate))(m)
49
62
else
50
63
content (gate)
51
64
end
60
73
61
74
function Tangles. addtensor! (circuit:: Circuit , tensor:: Tensor )
62
75
target_plugs = plugs (tensor)
76
+ target_plugs_in = filter (isdual, target_plugs)
77
+ target_plugs_out = filter (! isdual, target_plugs)
78
+ target_sites = unique! (site .(target_plugs))
63
79
64
- for plug in filter (isdual, target_plugs) .| > adjoint
80
+ # if lane is not present, add an identity gate
81
+ for plug in adjoint .(target_plugs_in)
65
82
if ! hasplug (circuit, plug)
66
- input, out = Index (gensym ( :tmp )) , Index (gensym ( :tmp ))
83
+ input, out = Index (LaneAt ( site (plug), 1 )) , Index (LaneAt ( site (plug), 2 ))
67
84
addtensor! (circuit. tn, Tensor ([1 0 ; 0 1 ], [input, out]))
68
85
setplug! (circuit, input, plug' )
69
86
setplug! (circuit, out, plug)
87
+ circuit. last_t[site (plug)] = 2
70
88
end
71
89
end
72
90
73
- tensor = replace (tensor, [Index (plug " i'" ) => ind_at (circuit, plug " i" ) for i in unique (site .(plugs (tensor)))]. .. )
74
- # for all the normal plugs in the operator
75
- # new_ind = Index(gensym(:tmp)) # Index((; layer=..., site=...))
76
- new_inds = Dict (plug " i" => Index (gensym (:tmp )) for i in unique (site .(plugs (tensor))))
77
- tensor = replace (tensor, [Index (k) => v for (k, v) in new_inds]. .. )
91
+ # align gate tensor with the circuit
92
+ tensor = replace (
93
+ tensor,
94
+ [
95
+ Index (plug) => Index (LaneAt (site (plug), moment (circuit, site (plug)))) for
96
+ plug in target_plugs_in
97
+ ]. .. ,
98
+ [
99
+ Index (plug) => Index (LaneAt (site (plug), moment (circuit, site (plug)) + 1 )) for
100
+ plug in target_plugs_out
101
+ ]. .. ,
102
+ )
78
103
79
104
addtensor! (circuit. tn, tensor)
80
105
81
- for (plug, new_ind) in new_inds
106
+ # update plug tags mapping
107
+ for plug in target_plugs_out
82
108
unsetplug! (circuit, plug)
83
- setplug! (circuit, new_ind, plug)
109
+ setplug! (circuit, Index (LaneAt (site (plug), moment (circuit, site (plug)) + 1 )), plug)
110
+ end
111
+
112
+ # update the last_t for each site
113
+ for site in target_sites
114
+ circuit. last_t[site] = circuit. last_t[site] + 1
84
115
end
85
116
86
117
return circuit
0 commit comments