Skip to content

Commit 455bcc2

Browse files
committed
Merge branch 'master' into ProjectTo-for-DiagonalTensorMap
2 parents 2732f66 + 33f10bc commit 455bcc2

File tree

6 files changed

+112
-108
lines changed

6 files changed

+112
-108
lines changed

.github/workflows/CI.yml

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,11 @@ jobs:
2727
- ubuntu-latest
2828
- macOS-latest
2929
- windows-latest
30-
arch:
31-
- x64
32-
# - x86
33-
# exclude:
34-
# - os: macOS-latest
35-
# arch: x86
3630
steps:
3731
- uses: actions/checkout@v4
3832
- uses: julia-actions/setup-julia@v2
3933
with:
4034
version: ${{ matrix.version }}
41-
arch: ${{ matrix.arch }}
4235
- uses: julia-actions/cache@v2
4336
- uses: julia-actions/julia-buildpkg@latest
4437
- uses: julia-actions/julia-runtest@latest
@@ -49,7 +42,7 @@ jobs:
4942
env:
5043
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
5144
with:
52-
file: lcov.info
45+
files: lcov.info
5346
test-nightly:
5447
needs: test
5548
name: Julia nightly - ${{ matrix.os }} - ${{ matrix.arch }}
@@ -62,15 +55,12 @@ jobs:
6255
- ubuntu-latest
6356
- macOS-latest
6457
- windows-latest
65-
arch:
66-
- x64
6758
continue-on-error: true
6859
steps:
6960
- uses: actions/checkout@v4
7061
- uses: julia-actions/setup-julia@v2
7162
with:
7263
version: ${{ matrix.version }}
73-
arch: ${{ matrix.arch }}
7464
- uses: julia-actions/cache@v2
7565
- uses: julia-actions/julia-buildpkg@latest
7666
- uses: julia-actions/julia-runtest@latest

.github/workflows/Documentation.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,11 @@ jobs:
1919
- '1' # automatically expands to the latest stable 1.x release of Julia
2020
os:
2121
- ubuntu-latest
22-
arch:
23-
- x64
2422
steps:
2523
- uses: actions/checkout@v4
2624
- uses: julia-actions/setup-julia@latest
2725
with:
2826
version: ${{ matrix.version }}
29-
arch: ${{ matrix.arch }}
3027
- name: Install dependencies
3128
run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
3229
- name: Build and deploy

.github/workflows/FormatCheck.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,10 @@ jobs:
1818
- '1' # automatically expands to the latest stable 1.x release of Julia
1919
os:
2020
- ubuntu-latest
21-
arch:
22-
- x64
2321
steps:
2422
- uses: julia-actions/setup-julia@latest
2523
with:
2624
version: ${{ matrix.version }}
27-
arch: ${{ matrix.arch }}
2825

2926
- uses: actions/checkout@v4
3027
- name: Install JuliaFormatter and format

ext/TensorKitChainRulesCoreExt/linalg.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@ function ChainRulesCore.rrule(::typeof(adjoint), A::AbstractTensorMap)
7777
return adjoint(A), adjoint_pullback
7878
end
7979

80+
function ChainRulesCore.rrule(::typeof(twist), A::AbstractTensorMap, is; inv::Bool=false)
81+
tA = twist(A, is; inv)
82+
twist_pullback(ΔA) = NoTangent(), twist(unthunk(ΔA), is; inv=!inv), NoTangent()
83+
return tA, twist_pullback
84+
end
85+
8086
function ChainRulesCore.rrule(::typeof(dot), a::AbstractTensorMap, b::AbstractTensorMap)
8187
dot_pullback(Δd) = NoTangent(), @thunk(b * Δd'), @thunk(a * Δd)
8288
return dot(a, b), dot_pullback

test/ad.jl

Lines changed: 100 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,18 @@ Vlist = ((ℂ^2, (ℂ^3)', ℂ^3, ℂ^2, (ℂ^2)'),
127127
ℂ[SU2Irrep](0 => 1, 1 => 1),
128128
ℂ[SU2Irrep](1 // 2 => 1, 1 => 1)',
129129
ℂ[SU2Irrep](1 // 2 => 2),
130-
ℂ[SU2Irrep](0 => 1, 1 // 2 => 1, 3 // 2 => 1)'))
130+
ℂ[SU2Irrep](0 => 1, 1 // 2 => 1, 3 // 2 => 1)'),
131+
(ℂ[FibonacciAnyon](:I => 1, => 1),
132+
ℂ[FibonacciAnyon](:I => 1, => 2)',
133+
ℂ[FibonacciAnyon](:I => 3, => 2)',
134+
ℂ[FibonacciAnyon](:I => 2, => 3),
135+
ℂ[FibonacciAnyon](:I => 2, => 2)))
131136

132137
@timedtestset "Automatic Differentiation with spacetype $(TensorKit.type_repr(eltype(V)))" verbose = true for V in
133138
Vlist
139+
eltypes = isreal(sectortype(eltype(V))) ? (Float64, ComplexF64) : (ComplexF64,)
140+
symmetricbraiding = BraidingStyle(sectortype(eltype(V))) isa SymmetricBraiding
141+
134142
@timedtestset "Basic utility" begin
135143
T1 = randn(Float64, V[1] V[2] V[3] V[4])
136144
T2 = randn(ComplexF64, V[1] V[2] V[3] V[4])
@@ -142,7 +150,8 @@ Vlist = ((ℂ^2, (ℂ^3)', ℂ^3, ℂ^2, (ℂ^2)'),
142150
test_rrule(copy, T1)
143151
test_rrule(copy, T2)
144152
test_rrule(TensorKit.copy_oftype, T1, ComplexF64)
145-
test_rrule(TensorKit.permutedcopy_oftype, T1, ComplexF64, ((3, 1), (2, 4)))
153+
if symmetricbraiding
154+
test_rrule(TensorKit.permutedcopy_oftype, T1, ComplexF64, ((3, 1), (2, 4)))
146155

147156
test_rrule(convert, Array, T1)
148157
test_rrule(TensorMap, convert(Array, T1), codomain(T1), domain(T1);
@@ -189,7 +198,7 @@ Vlist = ((ℂ^2, (ℂ^3)', ℂ^3, ℂ^2, (ℂ^2)'),
189198
end
190199
end
191200

192-
@timedtestset "Basic Linear Algebra with scalartype $T" for T in (Float64, ComplexF64)
201+
@timedtestset "Basic Linear Algebra with scalartype $T" for T in eltypes
193202
A = randn(T, V[1] V[2] V[3] V[4] V[5])
194203
B = randn(T, space(A))
195204

@@ -207,14 +216,16 @@ Vlist = ((ℂ^2, (ℂ^3)', ℂ^3, ℂ^2, (ℂ^2)'),
207216
C = randn(T, domain(A), codomain(A))
208217
test_rrule(*, A, C)
209218

210-
test_rrule(permute, A, ((1, 3, 2), (5, 4)))
219+
symmetricbraiding && test_rrule(permute, A, ((1, 3, 2), (5, 4)))
220+
test_rrule(twist, A, 1)
221+
test_rrule(twist, A, [1, 3])
211222

212223
D = randn(T, V[1] V[2] V[3])
213224
E = randn(T, V[4] V[5])
214-
test_rrule(, D, E)
225+
symmetricbraiding && test_rrule(, D, E)
215226
end
216227

217-
@timedtestset "Linear Algebra part II with scalartype $T" for T in (Float64, ComplexF64)
228+
@timedtestset "Linear Algebra part II with scalartype $T" for T in eltypes
218229
for i in 1:3
219230
E = randn(T, (V[1:i]...) (V[1:i]...))
220231
test_rrule(LinearAlgebra.tr, E)
@@ -229,7 +240,7 @@ Vlist = ((ℂ^2, (ℂ^3)', ℂ^3, ℂ^2, (ℂ^2)'),
229240
test_rrule(LinearAlgebra.dot, A, B)
230241
end
231242

232-
@timedtestset "Matrix functions ($T)" for T in (Float64, ComplexF64)
243+
@timedtestset "Matrix functions ($T)" for T in eltypes
233244
for f in (sqrt, exp)
234245
check_inferred = false # !(T <: Real) # not type-stable for real functions
235246
t1 = randn(T, V[1] V[1])
@@ -244,97 +255,100 @@ Vlist = ((ℂ^2, (ℂ^3)', ℂ^3, ℂ^2, (ℂ^2)'),
244255
end
245256
end
246257

247-
@timedtestset "TensorOperations with scalartype $T" for T in (Float64, ComplexF64)
248-
atol = precision(T)
249-
rtol = precision(T)
250-
251-
@timedtestset "tensortrace!" begin
252-
for _ in 1:5
253-
k1 = rand(0:3)
254-
k2 = k1 == 3 ? 1 : rand(1:2)
255-
V1 = map(v -> rand(Bool) ? v' : v, rand(V, k1))
256-
V2 = map(v -> rand(Bool) ? v' : v, rand(V, k2))
258+
symmetricbraiding &&
259+
@timedtestset "TensorOperations with scalartype $T" for T in eltypes
260+
atol = precision(T)
261+
rtol = precision(T)
257262

258-
(_p, _q) = randindextuple(k1 + 2 * k2, k1)
259-
p = _repartition(_p, rand(0:k1))
260-
q = _repartition(_q, k2)
261-
ip = _repartition(invperm(linearize((_p, _q))), rand(0:(k1 + 2 * k2)))
262-
A = randn(T, permute(prod(V1) prod(V2) prod(V2), ip))
263-
264-
α = randn(T)
265-
β = randn(T)
266-
for conjA in (false, true)
267-
C = randn!(TensorOperations.tensoralloc_add(T, A, p, conjA, Val(false)))
268-
test_rrule(tensortrace!, C, A, p, q, conjA, α, β; atol, rtol)
263+
@timedtestset "tensortrace!" begin
264+
for _ in 1:5
265+
k1 = rand(0:3)
266+
k2 = k1 == 3 ? 1 : rand(1:2)
267+
V1 = map(v -> rand(Bool) ? v' : v, rand(V, k1))
268+
V2 = map(v -> rand(Bool) ? v' : v, rand(V, k2))
269+
270+
(_p, _q) = randindextuple(k1 + 2 * k2, k1)
271+
p = _repartition(_p, rand(0:k1))
272+
q = _repartition(_q, k2)
273+
ip = _repartition(invperm(linearize((_p, _q))), rand(0:(k1 + 2 * k2)))
274+
A = randn(T, permute(prod(V1) prod(V2) prod(V2), ip))
275+
276+
α = randn(T)
277+
β = randn(T)
278+
for conjA in (false, true)
279+
C = randn!(TensorOperations.tensoralloc_add(T, A, p, conjA,
280+
Val(false)))
281+
test_rrule(tensortrace!, C, A, p, q, conjA, α, β; atol, rtol)
282+
end
269283
end
270284
end
271-
end
272285

273-
@timedtestset "tensoradd!" begin
274-
A = randn(T, V[1] V[2] V[3] V[4] V[5])
275-
α = randn(T)
276-
β = randn(T)
277-
278-
# repeat a couple times to get some distribution of arrows
279-
for _ in 1:5
280-
p = randindextuple(length(V))
286+
@timedtestset "tensoradd!" begin
287+
A = randn(T, V[1] V[2] V[3] V[4] V[5])
288+
α = randn(T)
289+
β = randn(T)
281290

282-
C1 = randn!(TensorOperations.tensoralloc_add(T, A, p, false, Val(false)))
283-
test_rrule(tensoradd!, C1, A, p, false, α, β; atol, rtol)
291+
# repeat a couple times to get some distribution of arrows
292+
for _ in 1:5
293+
p = randindextuple(length(V))
284294

285-
C2 = randn!(TensorOperations.tensoralloc_add(T, A, p, true, Val(false)))
286-
test_rrule(tensoradd!, C2, A, p, true, α, β; atol, rtol)
295+
C1 = randn!(TensorOperations.tensoralloc_add(T, A, p, false,
296+
Val(false)))
297+
test_rrule(tensoradd!, C1, A, p, false, α, β; atol, rtol)
287298

288-
A = rand(Bool) ? C1 : C2
289-
end
290-
end
299+
C2 = randn!(TensorOperations.tensoralloc_add(T, A, p, true, Val(false)))
300+
test_rrule(tensoradd!, C2, A, p, true, α, β; atol, rtol)
291301

292-
@timedtestset "tensorcontract!" begin
293-
for _ in 1:5
294-
d = 0
295-
local V1, V2, V3
296-
# retry a couple times to make sure there are at least some nonzero elements
297-
for _ in 1:10
298-
k1 = rand(0:3)
299-
k2 = rand(0:2)
300-
k3 = rand(0:2)
301-
V1 = prod(v -> rand(Bool) ? v' : v, rand(V, k1); init=one(V[1]))
302-
V2 = prod(v -> rand(Bool) ? v' : v, rand(V, k2); init=one(V[1]))
303-
V3 = prod(v -> rand(Bool) ? v' : v, rand(V, k3); init=one(V[1]))
304-
d = min(dim(V1 V2), dim(V1' V2), dim(V2 V3), dim(V2' V3))
305-
d > 0 && break
302+
A = rand(Bool) ? C1 : C2
306303
end
307-
ipA = randindextuple(length(V1) + length(V2))
308-
pA = _repartition(invperm(linearize(ipA)), length(V1))
309-
ipB = randindextuple(length(V2) + length(V3))
310-
pB = _repartition(invperm(linearize(ipB)), length(V2))
311-
pAB = randindextuple(length(V1) + length(V3))
304+
end
312305

313-
α = randn(T)
314-
β = randn(T)
315-
V2_conj = prod(conj, V2; init=one(V[1]))
316-
317-
for conjA in (false, true), conjB in (false, true)
318-
A = randn(T, permute(V1 (conjA ? V2_conj : V2), ipA))
319-
B = randn(T, permute((conjB ? V2_conj : V2) V3, ipB))
320-
C = randn!(TensorOperations.tensoralloc_contract(T, A, pA,
321-
conjA,
322-
B, pB, conjB, pAB,
323-
Val(false)))
324-
test_rrule(tensorcontract!, C,
325-
A, pA, conjA, B, pB, conjB, pAB,
326-
α, β; atol, rtol)
306+
@timedtestset "tensorcontract!" begin
307+
for _ in 1:5
308+
d = 0
309+
local V1, V2, V3
310+
# retry a couple times to make sure there are at least some nonzero elements
311+
for _ in 1:10
312+
k1 = rand(0:3)
313+
k2 = rand(0:2)
314+
k3 = rand(0:2)
315+
V1 = prod(v -> rand(Bool) ? v' : v, rand(V, k1); init=one(V[1]))
316+
V2 = prod(v -> rand(Bool) ? v' : v, rand(V, k2); init=one(V[1]))
317+
V3 = prod(v -> rand(Bool) ? v' : v, rand(V, k3); init=one(V[1]))
318+
d = min(dim(V1 V2), dim(V1' V2), dim(V2 V3), dim(V2' V3))
319+
d > 0 && break
320+
end
321+
ipA = randindextuple(length(V1) + length(V2))
322+
pA = _repartition(invperm(linearize(ipA)), length(V1))
323+
ipB = randindextuple(length(V2) + length(V3))
324+
pB = _repartition(invperm(linearize(ipB)), length(V2))
325+
pAB = randindextuple(length(V1) + length(V3))
326+
327+
α = randn(T)
328+
β = randn(T)
329+
V2_conj = prod(conj, V2; init=one(V[1]))
330+
331+
for conjA in (false, true), conjB in (false, true)
332+
A = randn(T, permute(V1 (conjA ? V2_conj : V2), ipA))
333+
B = randn(T, permute((conjB ? V2_conj : V2) V3, ipB))
334+
C = randn!(TensorOperations.tensoralloc_contract(T, A, pA,
335+
conjA,
336+
B, pB, conjB, pAB,
337+
Val(false)))
338+
test_rrule(tensorcontract!, C,
339+
A, pA, conjA, B, pB, conjB, pAB,
340+
α, β; atol, rtol)
341+
end
327342
end
328343
end
329-
end
330344

331-
@timedtestset "tensorscalar" begin
332-
A = randn(T, ProductSpace{typeof(V[1]),0}())
333-
test_rrule(tensorscalar, A)
345+
@timedtestset "tensorscalar" begin
346+
A = randn(T, ProductSpace{typeof(V[1]),0}())
347+
test_rrule(tensorscalar, A)
348+
end
334349
end
335-
end
336350

337-
@timedtestset "Factorizations with scalartype $T" for T in (Float64, ComplexF64)
351+
@timedtestset "Factorizations with scalartype $T" for T in eltypes
338352
A = randn(T, V[1] V[2] V[3] V[4] V[5])
339353
B = randn(T, space(A)')
340354
C = randn(T, V[1] V[2] V[1] V[2])
@@ -427,13 +441,13 @@ Vlist = ((ℂ^2, (ℂ^3)', ℂ^3, ℂ^2, (ℂ^2)'),
427441

428442
c, = TensorKit.MatrixAlgebra._argmax(x -> sqrt(dim(x[1])) * maximum(diag(x[2])),
429443
blocks(S))
430-
U, S, V, ϵ = tsvd(C; trunc=truncdim(2 * dim(c)))
444+
trunc = truncdim(round(Int, 2 * dim(c)))
445+
U, S, V, ϵ = tsvd(C; trunc)
431446
ΔU = randn(scalartype(U), space(U))
432447
ΔS = randn(scalartype(S), space(S))
433448
ΔV = randn(scalartype(V), space(V))
434449
T <: Complex && remove_svdgauge_depence!(ΔU, ΔV, U, S, V)
435-
test_rrule(tsvd, C; atol, output_tangent=(ΔU, ΔS, ΔV, 0.0),
436-
fkwargs=(; trunc=truncdim(2 * dim(c))))
450+
test_rrule(tsvd, C; atol, output_tangent=(ΔU, ΔS, ΔV, 0.0), fkwargs=(; trunc))
437451
end
438452

439453
let D = LinearAlgebra.eigvals(C)

test/runtests.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ sectorlist = (Z2Irrep, Z3Irrep, Z4Irrep, Z3Irrep ⊠ Z4Irrep,
5555
Z2Irrep FibonacciAnyon FibonacciAnyon)
5656

5757
Ti = time()
58-
include("fusiontrees.jl")
59-
include("spaces.jl")
60-
include("tensors.jl")
61-
include("diagonal.jl")
62-
include("planar.jl")
58+
# include("fusiontrees.jl")
59+
# include("spaces.jl")
60+
# include("tensors.jl")
61+
# include("diagonal.jl")
62+
# include("planar.jl")
6363
# TODO: remove once we know AD is slow on macOS CI
6464
if !(Sys.isapple() && get(ENV, "CI", "false") == "true")
6565
include("ad.jl")

0 commit comments

Comments
 (0)