Skip to content

Commit ad4945f

Browse files
committed
[Perf] EnlargedCorner optimizations (#214)
* Store `dir` in `EnlargedCorner` * Manually fix enlarged corner contractions * Update contractions --- Co-authored-by: Olivier Gauthe <olivier.gauthe.2011+github@polytechnique.org>
1 parent 2b8403d commit ad4945f

File tree

4 files changed

+81
-39
lines changed

4 files changed

+81
-39
lines changed

src/algorithms/contractions/ctmrg_contractions.jl

Lines changed: 62 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,20 @@ const CTMRGCornerTensor{T,S} = AbstractTensorMap{T,S,1,1}
66
# Enlarged corner contractions
77
# ----------------------------
88

9+
#=
10+
These contractions are hand-optimized by the following heuristics:
11+
12+
1. ensure contraction order gives minimal scaling in χ = D²
13+
2. ensure dominant permutation is as efficient as possible by making large legs contiguous,
14+
ie moving them to the front
15+
16+
This second part is mostly important for dealing with non-abelian symmetries, where the
17+
permutations are strongly non-negligable.
18+
19+
For a small benchmark study:
20+
https://gist.github.com/lkdvos/a562c2b09ef461398729ccefdab34745
21+
=#
22+
923
"""
1024
$(SIGNATURES)
1125
@@ -25,12 +39,18 @@ function enlarge_northwest_corner(
2539
E_north::CTMRG_PEPS_EdgeTensor,
2640
A::PEPSSandwich,
2741
)
28-
return @autoopt @tensor corner[χ_S D_Sabove D_Sbelow; χ_E D_Eabove D_Ebelow] :=
29-
E_west[χ_S D1 D2; χ1] *
30-
C_northwest[χ1; χ2] *
31-
E_north[χ2 D3 D4; χ_E] *
32-
ket(A)[d; D3 D_Eabove D_Sabove D1] *
33-
conj(bra(A)[d; D4 D_Ebelow D_Sbelow D2])
42+
return @tensor begin
43+
EC[χS DWt DWb; χ2] := E_west[χS DWt DWb; χ1] * C_northwest[χ1; χ2]
44+
45+
# already putting χE in front here to make next permute cheaper
46+
ECE[χS χE DWb DNb; DWt DNt] := EC[χS DWt DWb; χ2] * E_north[χ2 DNt DNb; χE]
47+
48+
ECEket[χS χE DEt DSt; DWb DNb d] :=
49+
ECE[χS χE DWb DNb; DWt DNt] * ket(A)[d; DNt DEt DSt DWt]
50+
51+
corner[χS DSt DSb; χE DEt DEb] :=
52+
ECEket[χS χE DEt DSt; DWb DNb d] * conj(bra(A)[d; DNb DEb DSb DWb])
53+
end
3454
end
3555
function enlarge_northwest_corner(
3656
E_west::CTMRG_PF_EdgeTensor,
@@ -61,12 +81,18 @@ function enlarge_northeast_corner(
6181
E_east::CTMRG_PEPS_EdgeTensor,
6282
A::PEPSSandwich,
6383
)
64-
return @autoopt @tensor corner[χ_W D_Wabove D_Wbelow; χ_S D_Sabove D_Sbelow] :=
65-
E_north[χ_W D1 D2; χ1] *
66-
C_northeast[χ1; χ2] *
67-
E_east[χ2 D3 D4; χ_S] *
68-
ket(A)[d; D1 D3 D_Sabove D_Wabove] *
69-
conj(bra(A)[d; D2 D4 D_Sbelow D_Wbelow])
84+
return @tensor begin
85+
EC[χW DNt DNb; χ2] := E_north[χW DNt DNb; χ1] * C_northeast[χ1; χ2]
86+
87+
# already putting χE in front here to make next permute cheaper
88+
ECE[χW χS DNb DEb; DNt DEt] := EC[χW DNt DNb; χ2] * E_east[χ2 DEt DEb; χS]
89+
90+
ECEket[χW χS DSt DWt; DNb DEb d] :=
91+
ECE[χW χS DNb DEb; DNt DEt] * ket(A)[d; DNt DEt DSt DWt]
92+
93+
corner[χW DWt DWb; χS DSt DSb] :=
94+
ECEket[χW χS DSt DWt; DNb DEb d] * conj(bra(A)[d; DNb DEb DSb DWb])
95+
end
7096
end
7197
function enlarge_northeast_corner(
7298
E_north::CTMRG_PF_EdgeTensor,
@@ -97,12 +123,18 @@ function enlarge_southeast_corner(
97123
E_south::CTMRG_PEPS_EdgeTensor,
98124
A::PEPSSandwich,
99125
)
100-
return @autoopt @tensor corner[χ_N D_Nabove D_Nbelow; χ_W D_Wabove D_Wbelow] :=
101-
E_east[χ_N D1 D2; χ1] *
102-
C_southeast[χ1; χ2] *
103-
E_south[χ2 D3 D4; χ_W] *
104-
ket(A)[d; D_Nabove D1 D3 D_Wabove] *
105-
conj(bra(A)[d; D_Nbelow D2 D4 D_Wbelow])
126+
return @tensor begin
127+
EC[χN DEt DEb; χ2] := E_east[χN DEt DEb; χ1] * C_southeast[χ1; χ2]
128+
129+
# already putting χE in front here to make next permute cheaper
130+
ECE[χN χW DEb DSb; DEt DSt] := EC[χN DEt DEb; χ2] * E_south[χ2 DSt DSb; χW]
131+
132+
ECEket[χN χW DNt DWt; DEb DSb d] :=
133+
ECE[χN χW DEb DSb; DEt DSt] * ket(A)[d; DNt DEt DSt DWt]
134+
135+
corner[χN DNt DNb; χW DWt DWb] :=
136+
ECEket[χN χW DNt DWt; DEb DSb d] * conj(bra(A)[d; DNb DEb DSb DWb])
137+
end
106138
end
107139
function enlarge_southeast_corner(
108140
E_east::CTMRG_PF_EdgeTensor,
@@ -133,12 +165,18 @@ function enlarge_southwest_corner(
133165
E_west::CTMRG_PEPS_EdgeTensor,
134166
A::PEPSSandwich,
135167
)
136-
return @autoopt @tensor corner[χ_E D_Eabove D_Ebelow; χ_N D_Nabove D_Nbelow] :=
137-
E_south[χ_E D1 D2; χ1] *
138-
C_southwest[χ1; χ2] *
139-
E_west[χ2 D3 D4; χ_N] *
140-
ket(A)[d; D_Nabove D_Eabove D1 D3] *
141-
conj(bra(A)[d; D_Nbelow D_Ebelow D2 D4])
168+
return @tensor begin
169+
EC[χE DSt DSb; χ2] := E_south[χE DSt DSb; χ1] * C_southwest[χ1; χ2]
170+
171+
# already putting χE in front here to make next permute cheaper
172+
ECE[χE χN DSb DWb; DSt DWt] := EC[χE DSt DSb; χ2] * E_west[χ2 DWt DWb; χN]
173+
174+
ECEket[χE χN DNt DEt; DSb DWb d] :=
175+
ECE[χE χN DSb DWb; DSt DWt] * ket(A)[d; DNt DEt DSt DWt]
176+
177+
corner[χE DEt DEb; χN DNt DNb] :=
178+
ECEket[χE χN DNt DEt; DSb DWb d] * conj(bra(A)[d; DNb DEb DSb DWb])
179+
end
142180
end
143181
function enlarge_southwest_corner(
144182
E_south::CTMRG_PF_EdgeTensor,

src/algorithms/ctmrg/sequential.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ function sequential_projectors(
9595
)
9696
_, r, c = coordinate
9797
r′ = _prev(r, size(env, 2))
98-
Q1 = TensorMap(EnlargedCorner(network, env, (SOUTHWEST, r, c)), SOUTHWEST)
99-
Q2 = TensorMap(EnlargedCorner(network, env, (NORTHWEST, r′, c)), NORTHWEST)
98+
Q1 = TensorMap(EnlargedCorner(network, env, (SOUTHWEST, r, c)))
99+
Q2 = TensorMap(EnlargedCorner(network, env, (NORTHWEST, r′, c)))
100100
return compute_projector((Q1, Q2), coordinate, alg)
101101
end
102102
function sequential_projectors(
@@ -107,10 +107,10 @@ function sequential_projectors(
107107
coordinate_ne = _next_coordinate(coordinate_nw, rowsize, colsize)
108108
coordinate_se = _next_coordinate(coordinate_ne, rowsize, colsize)
109109
ec = (
110-
TensorMap(EnlargedCorner(network, env, coordinate_se), SOUTHEAST),
111-
TensorMap(EnlargedCorner(network, env, coordinate), SOUTHWEST),
112-
TensorMap(EnlargedCorner(network, env, coordinate_nw), NORTHWEST),
113-
TensorMap(EnlargedCorner(network, env, coordinate_ne), NORTHEAST),
110+
TensorMap(EnlargedCorner(network, env, coordinate_se)),
111+
TensorMap(EnlargedCorner(network, env, coordinate)),
112+
TensorMap(EnlargedCorner(network, env, coordinate_nw)),
113+
TensorMap(EnlargedCorner(network, env, coordinate_ne)),
114114
)
115115
return compute_projector(ec, coordinate, alg)
116116
end

src/algorithms/ctmrg/simultaneous.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ CTMRG_SYMBOLS[:simultaneous] = SimultaneousCTMRG
3838

3939
function ctmrg_iteration(network, env::CTMRGEnv, alg::SimultaneousCTMRG)
4040
enlarged_corners = dtmap(eachcoordinate(network, 1:4)) do idx
41-
return TensorMap(EnlargedCorner(network, env, idx), idx[1])
41+
return TensorMap(EnlargedCorner(network, env, idx))
4242
end # expand environment
4343
projectors, info = simultaneous_projectors(enlarged_corners, env, alg.projector_alg) # compute projectors on all coordinates
4444
env′ = renormalize_simultaneously(enlarged_corners, projectors, network, env) # renormalize enlarged corners

src/algorithms/ctmrg/sparse_environments.jl

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ struct EnlargedCorner{TC,TE,TA}
2020
E_1::TE
2121
E_2::TE
2222
A::TA
23+
dir::Int
2324
end
2425
function EnlargedCorner(network::InfiniteSquareNetwork, env, coordinates)
2526
dir, r, c = coordinates
@@ -29,45 +30,48 @@ function EnlargedCorner(network::InfiniteSquareNetwork, env, coordinates)
2930
env.edges[WEST, r, _prev(c, end)],
3031
env.edges[NORTH, _prev(r, end), c],
3132
network[r, c],
33+
dir,
3234
)
3335
elseif dir == NORTHEAST
3436
return EnlargedCorner(
3537
env.corners[NORTHEAST, _prev(r, end), _next(c, end)],
3638
env.edges[NORTH, _prev(r, end), c],
3739
env.edges[EAST, r, _next(c, end)],
3840
network[r, c],
41+
dir,
3942
)
4043
elseif dir == SOUTHEAST
4144
return EnlargedCorner(
4245
env.corners[SOUTHEAST, _next(r, end), _next(c, end)],
4346
env.edges[EAST, r, _next(c, end)],
4447
env.edges[SOUTH, _next(r, end), c],
4548
network[r, c],
49+
dir,
4650
)
4751
elseif dir == SOUTHWEST
4852
return EnlargedCorner(
4953
env.corners[SOUTHWEST, _next(r, end), _prev(c, end)],
5054
env.edges[SOUTH, _next(r, end), c],
5155
env.edges[WEST, r, _prev(c, end)],
5256
network[r, c],
57+
dir,
5358
)
5459
end
5560
end
5661

5762
"""
58-
TensorMap(Q::EnlargedCorner, dir::Int)
63+
TensorMap(Q::EnlargedCorner)
5964
60-
Instantiate enlarged corner as `TensorMap` where `dir` selects the correct contraction
61-
direction, i.e. the way the environment and PEPS tensors connect.
65+
Instantiate enlarged corner as a `TensorMap`.
6266
"""
63-
function TensorKit.TensorMap(Q::EnlargedCorner, dir::Int)
64-
if dir == NORTHWEST
67+
function TensorKit.TensorMap(Q::EnlargedCorner)
68+
if Q.dir == NORTHWEST
6569
return enlarge_northwest_corner(Q.E_1, Q.C, Q.E_2, Q.A)
66-
elseif dir == NORTHEAST
70+
elseif Q.dir == NORTHEAST
6771
return enlarge_northeast_corner(Q.E_1, Q.C, Q.E_2, Q.A)
68-
elseif dir == SOUTHEAST
72+
elseif Q.dir == SOUTHEAST
6973
return enlarge_southeast_corner(Q.E_1, Q.C, Q.E_2, Q.A)
70-
elseif dir == SOUTHWEST
74+
elseif Q.dir == SOUTHWEST
7175
return enlarge_southwest_corner(Q.E_1, Q.C, Q.E_2, Q.A)
7276
end
7377
end

0 commit comments

Comments
 (0)