6969
7070
7171# Internal state of the IDMRG algorithm
72- struct IDMRGState{S, O, E, T}
72+ struct IDMRGState{S, O, E, T, B, A }
7373 mps:: S
7474 operator:: O
7575 envs:: E
7676 iter:: Int
7777 ϵ:: Float64 # TODO : Could be any <:Real
7878 energy:: T
7979 timeroutput:: TimerOutput
80+ backend:: B
81+ allocator:: A
8082end
8183function IDMRGState {T} (
8284 mps:: S , operator:: O , envs:: E , iter:: Int , ϵ:: Float64 , energy,
83- timeroutput:: TimerOutput ,
84- ) where {S, O, E, T}
85- return IDMRGState {S, O, E, T} (mps, operator, envs, iter, ϵ, T (energy), timeroutput)
85+ timeroutput:: TimerOutput , backend :: B , allocator :: A = BufferAllocator ()
86+ ) where {S, O, E, T, B, A }
87+ return IDMRGState {S, O, E, T, B, A } (mps, operator, envs, iter, ϵ, T (energy), timeroutput, backend, allocator )
8688end
8789
8890function find_groundstate! (
@@ -105,7 +107,7 @@ function find_groundstate!(
105107 end
106108 end
107109
108- state = IDMRGState (mps, operator, envs, iter, ϵ, E, timeroutput)
110+ state = IDMRGState (mps, operator, envs, iter, ϵ, E, timeroutput, DefaultBackend (), BufferAllocator () )
109111 it = IterativeSolver (alg, state)
110112
111113 return LoggingExtras. withlevel (; alg. verbosity) do
@@ -146,7 +148,7 @@ function Base.iterate(
146148
147149 # update state
148150 it. state = IDMRGState {T} (
149- mps, state. operator, envs, state. iter + 1 , ϵ, E_new, timeroutput,
151+ mps, state. operator, envs, state. iter + 1 , ϵ, E_new, timeroutput, state . backend, state . allocator
150152 )
151153
152154 return (mps, envs, ϵ, ΔE), it. state
@@ -160,7 +162,7 @@ function localupdate_step!(
160162 trscheme = updatetruncation (it. trscheme; iter = state. iter)
161163 return _localupdate_sweep_idmrg! (
162164 state. mps, state. operator, state. envs, alg_eigsolve, state. timeroutput,
163- trscheme, expscheme
165+ trscheme, expscheme, state . backend, state . allocator
164166 )
165167end
166168
@@ -173,46 +175,46 @@ function localupdate_step!(
173175 return _localupdate_sweep_idmrg2! (
174176 state. mps, state. operator, state. envs, alg_eigsolve,
175177 trscheme, it. alg_svd, state. timeroutput,
176- expscheme)
178+ expscheme, state . backend, state . allocator )
177179end
178180
179- function _localupdate_sweep_idmrg! (ψ, H, envs, alg_eigsolve, timeroutput:: TimerOutput , alg_trscheme, expscheme)
181+ function _localupdate_sweep_idmrg! (ψ, H, envs, alg_eigsolve, timeroutput:: TimerOutput , alg_trscheme, expscheme, backend = DefaultBackend (), allocator = BufferAllocator () )
180182 local E
181183 C_old = ψ. C[0 ]
182184
183185 # left to right sweep
184186 _idmrg_move_right! (ψ, H, envs, 1 , alg_trscheme, expscheme) # We don't update the first site, as the backwards sweep will update it!
185187 for pos in 2 : length (ψ)
186188 println (" Left: pos = $pos " )
187- h = AC_hamiltonian (pos, ψ, H, ψ, envs)
189+ h = AC_hamiltonian (pos, ψ, H, ψ, envs; backend, allocator )
188190 _, ψ. AC[pos] = fixedpoint (h, ψ. AC[pos], :SR , alg_eigsolve)
189191 _idmrg_move_right! (ψ, H, envs, pos, alg_trscheme, expscheme)
190192 end
191- _idmrg_move_left! (ψ, H, envs, length (ψ), alg_trscheme, expscheme)
193+ _idmrg_move_left! (ψ, H, envs, length (ψ), alg_trscheme, expscheme, backend, allocator )
192194
193195 # right to left sweep
194196 for pos in length (ψ)- 1 : - 1 : 1
195197 println (" Right: pos = $pos " )
196- h = AC_hamiltonian (pos, ψ, H, ψ, envs)
198+ h = AC_hamiltonian (pos, ψ, H, ψ, envs; backend, allocator )
197199 E, ψ. AC[pos] = fixedpoint (h, ψ. AC[pos], :SR , alg_eigsolve)
198200
199- _idmrg_move_left! (ψ, H, envs, pos, alg_trscheme, expscheme)
201+ _idmrg_move_left! (ψ, H, envs, pos, alg_trscheme, expscheme, backend, allocator )
200202 end
201203
202204
203205 return ψ, envs, C_old, E
204206end
205207
206- function _idmrg_move_right! (ψ, H,envs, pos, alg_trscheme, expscheme)
208+ function _idmrg_move_right! (ψ, H,envs, pos, alg_trscheme, expscheme, backend = DefaultBackend (), allocator = BufferAllocator () )
207209 ψ. AL[pos], ψ. C[pos] = left_orth! (ψ. AC[pos]; trunc = alg_trscheme)
208210 ψ. AL[pos], ψ. C[pos] = changebonds_left (ψ. AL[pos], ψ. C[pos], expscheme)
209211 ψ. AC[pos + 1 ] = _mul_front (ψ. C[pos], ψ. AR[pos + 1 ])
210212 if pos == length (ψ)
211213 ψ. AL[pos + 1 ] = ψ. AC[pos + 1 ] / ψ. C[pos + 1 ]
212214 end
213- transfer_leftenv! (envs, ψ, H, ψ, pos + 1 )
215+ transfer_leftenv! (envs, ψ, H, ψ, pos + 1 , backend, allocator )
214216end
215- function _idmrg_move_left! (ψ, H, envs, pos, alg_trscheme, expscheme)
217+ function _idmrg_move_left! (ψ, H, envs, pos, alg_trscheme, expscheme, backend = DefaultBackend (), allocator = BufferAllocator () )
216218 C, temp = right_orth! (_transpose_tail (ψ. AC[pos]); trunc = alg_trscheme)
217219 C, temp = changebonds_right (C, temp, expscheme)
218220 ψ. C[pos] = C
@@ -222,15 +224,15 @@ function _idmrg_move_left!(ψ, H, envs, pos, alg_trscheme, expscheme)
222224 ψ. AR[pos - 1 ] = ψ. AC[pos - 1 ] / ψ. C[pos - 2 ]
223225 end
224226
225- transfer_rightenv! (envs, ψ, H, ψ, pos - 1 )
227+ transfer_rightenv! (envs, ψ, H, ψ, pos - 1 , backend, allocator )
226228end
227229
228- function _localupdate_sweep_idmrg2! (ψ, H, envs, alg_eigsolve, alg_trscheme, alg_svd, expscheme, tol= 1e-8 )
230+ function _localupdate_sweep_idmrg2! (ψ, H, envs, alg_eigsolve, alg_trscheme, alg_svd, expscheme, tol= 1e-8 , backend = DefaultBackend (), allocator = BufferAllocator () )
229231 # sweep from left to right
230232 for pos in 1 : (length (ψ) - 1 )
231233 @timeit timeroutput " AC2_eigsolve" begin
232234 ac2 = AC2 (ψ, pos; kind = :ACAR )
233- h_ac2 = AC2_hamiltonian (pos, ψ, H, ψ, envs)
235+ h_ac2 = AC2_hamiltonian (pos, ψ, H, ψ, envs; backend, allocator )
234236 _, ac2′ = fixedpoint (h_ac2, ac2, :SR , alg_eigsolve)
235237 end
236238 @timeit timeroutput " svd_trunc" begin
@@ -244,8 +246,8 @@ function _localupdate_sweep_idmrg2!(ψ, H, envs, alg_eigsolve, alg_trscheme, alg
244246 ψ. AC[pos + 1 ] = _transpose_front (c * ar)
245247 end
246248 @timeit timeroutput " transfer_env" begin
247- transfer_leftenv! (envs, ψ, H, ψ, pos + 1 )
248- transfer_rightenv! (envs, ψ, H, ψ, pos)
249+ transfer_leftenv! (envs, ψ, H, ψ, pos + 1 , backend, allocator )
250+ transfer_rightenv! (envs, ψ, H, ψ, pos, backend, allocator )
249251 end
250252 end
251253
@@ -256,7 +258,7 @@ function _localupdate_sweep_idmrg2!(ψ, H, envs, alg_eigsolve, alg_trscheme, alg
256258 ψ. AC[1 ] = _mul_tail (ψ. AL[1 ], ψ. C[1 ])
257259 @timeit timeroutput " AC2_eigsolve" begin
258260 ac2 = AC2 (ψ, length (ψ); kind = :ALAC )
259- h_ac2 = AC2_hamiltonian (length (ψ), ψ, H, ψ, envs)
261+ h_ac2 = AC2_hamiltonian (length (ψ), ψ, H, ψ, envs; backend, allocator )
260262 _, ac2′ = fixedpoint (h_ac2, ac2, :SR , alg_eigsolve)
261263 end
262264 @timeit timeroutput " svd_trunc" begin
@@ -279,15 +281,15 @@ function _localupdate_sweep_idmrg2!(ψ, H, envs, alg_eigsolve, alg_trscheme, alg
279281
280282 # update environments
281283 @timeit timeroutput " transfer_env" begin
282- transfer_leftenv! (envs, ψ, H, ψ, 1 )
283- transfer_rightenv! (envs, ψ, H, ψ, 0 )
284+ transfer_leftenv! (envs, ψ, H, ψ, 1 , backend, allocator )
285+ transfer_rightenv! (envs, ψ, H, ψ, 0 , backend, allocator )
284286 end
285287
286288 # sweep from right to left
287289 for pos in (length (ψ) - 1 ): - 1 : 1
288290 @timeit timeroutput " AC2_eigsolve" begin
289291 ac2 = AC2 (ψ, pos; kind = :ALAC )
290- h_ac2 = AC2_hamiltonian (pos, ψ, H, ψ, envs)
292+ h_ac2 = AC2_hamiltonian (pos, ψ, H, ψ, envs; backend, allocator )
291293 _, ac2′ = fixedpoint (h_ac2, ac2, :SR , alg_eigsolve)
292294 end
293295 @timeit timeroutput " svd_trunc" begin
@@ -302,8 +304,8 @@ function _localupdate_sweep_idmrg2!(ψ, H, envs, alg_eigsolve, alg_trscheme, alg
302304 ψ. AC[pos + 1 ] = _transpose_front (c * ar)
303305 end
304306 @timeit timeroutput " transfer_env" begin
305- transfer_leftenv! (envs, ψ, H, ψ, pos + 1 )
306- transfer_rightenv! (envs, ψ, H, ψ, pos)
307+ transfer_leftenv! (envs, ψ, H, ψ, pos + 1 , backend, allocator )
308+ transfer_rightenv! (envs, ψ, H, ψ, pos, backend, allocator )
307309 end
308310 end
309311
@@ -314,7 +316,7 @@ function _localupdate_sweep_idmrg2!(ψ, H, envs, alg_eigsolve, alg_trscheme, alg
314316 ψ. AR[1 ] = _transpose_front (pinv (ψ. C[0 ]; atol= tol) * _transpose_tail (ψ. AC[1 ]))
315317
316318 ac2 = AC2 (ψ, 0 ; kind = :ACAR )
317- h_ac2 = AC2_hamiltonian (0 , ψ, H, ψ, envs)
319+ h_ac2 = AC2_hamiltonian (0 , ψ, H, ψ, envs; backend, allocator )
318320 E, ac2′ = fixedpoint (h_ac2, ac2, :SR , alg_eigsolve)
319321 end
320322 @timeit timeroutput " svd_trunc" begin
@@ -332,8 +334,8 @@ function _localupdate_sweep_idmrg2!(ψ, H, envs, alg_eigsolve, alg_trscheme, alg
332334 end
333335
334336 @timeit timeroutput " transfer_env" begin
335- transfer_leftenv! (envs, ψ, H, ψ, 1 )
336- transfer_rightenv! (envs, ψ, H, ψ, 0 )
337+ transfer_leftenv! (envs, ψ, H, ψ, 1 , backend, allocator )
338+ transfer_rightenv! (envs, ψ, H, ψ, 0 , backend, allocator )
337339 end
338340 return ψ, envs, C_old, E
339341end
0 commit comments