Skip to content

Commit 2d7ce3c

Browse files
committed
Add a disamgiguating conversion
1 parent 0b3278f commit 2d7ce3c

4 files changed

Lines changed: 46 additions & 15 deletions

File tree

Project.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Aqua = "0.8"
2727
BlockArrays = "1"
2828
Combinatorics = "1"
2929
Compat = "4.13"
30+
JLArrays = "0.3"
3031
LinearAlgebra = "1"
3132
MatrixAlgebraKit = "0.6"
3233
Random = "1"
@@ -44,10 +45,11 @@ julia = "1.10"
4445
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
4546
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
4647
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
48+
JLArrays = "27aeb0d3-9eb9-45fb-866b-73c2ecf80fcb"
4749
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
4850
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
4951
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
5052
TestExtras = "5ed8adda-3752-4e41-b88a-e8b09835ee3a"
5153

5254
[targets]
53-
test = ["Test", "TestExtras", "Random", "Combinatorics", "SafeTestsets", "Aqua", "Adapt"]
55+
test = ["Test", "TestExtras", "Random", "Combinatorics", "SafeTestsets", "Aqua", "Adapt", "JLArrays"]

src/tensors/abstractblocktensor/conversion.jl

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,50 @@
11
# Conversion
22
# ----------
3-
function Base.convert(::Type{TensorMap}, t::AbstractBlockTensorMap)
4-
S = spacetype(t)
5-
N₁, N₂ = numout(t), numin(t)
6-
cod = ProductSpace{S, N₁}(oplus.(codomain(t).spaces))
7-
dom = ProductSpace{S, N₂}(oplus.(domain(t).spaces))
8-
tdst = similar(t, cod dom)
9-
10-
issparse(t) && zerovector!(tdst)
113

4+
function _copy_subblocks!(tdst, tsrc)
5+
S = spacetype(tsrc)
6+
N₁, N₂ = numout(tsrc), numin(tsrc)
127
for ((f₁, f₂), arr) in subblocks(tdst)
138
blockax = ntuple(N₁ + N₂) do i
149
return if i <= N₁
15-
blockedrange(map(Base.Fix2(dim, f₁.uncoupled[i]), space(t, i)))
10+
blockedrange(map(Base.Fix2(dim, f₁.uncoupled[i]), space(tsrc, i)))
1611
else
17-
blockedrange(map(Base.Fix2(dim, f₂.uncoupled[i - N₁]), space(t, i)'))
12+
blockedrange(map(Base.Fix2(dim, f₂.uncoupled[i - N₁]), space(tsrc, i)'))
1813
end
1914
end
2015

21-
for (k, v) in nonzero_pairs(t)
16+
for (k, v) in nonzero_pairs(tsrc)
2217
indices = getindex.(blockax, Block.(Tuple(k)))
2318
arr_slice = arr[indices...]
2419
# need to check for empty since fusion tree pair might not be present
2520
isempty(arr_slice) || copy!(arr_slice, v[f₁, f₂])
2621
end
2722
end
23+
return tdst
24+
end
2825

26+
function Base.convert(::Type{TensorMap}, t::AbstractBlockTensorMap)
27+
S = spacetype(t)
28+
N₁, N₂ = numout(t), numin(t)
29+
cod = ProductSpace{S, N₁}(oplus.(codomain(t).spaces))
30+
dom = ProductSpace{S, N₂}(oplus.(domain(t).spaces))
31+
tdst = TensorKit.TensorMapWithStorage{scalartype(t), storagetype(t)}(undef, cod, dom)
32+
33+
issparse(t) && zerovector!(tdst)
34+
_copy_subblocks!(tdst, t)
2935
return tdst
3036
end
3137

32-
function Base.convert(::Type{T}, t::AbstractBlockTensorMap) where {T <: TensorMap}
33-
tdst = convert(TensorMap, t)
34-
return convert(T, tdst)
38+
function Base.convert(::Type{TT}, t::AbstractBlockTensorMap) where {TT <: TensorKit.TensorMap}
39+
S = spacetype(t)
40+
N₁, N₂ = numout(t), numin(t)
41+
cod = ProductSpace{S, N₁}(oplus.(codomain(t).spaces))
42+
dom = ProductSpace{S, N₂}(oplus.(domain(t).spaces))
43+
tdst = TT(undef, cod dom)
44+
issparse(t) && zerovector!(tdst)
45+
46+
_copy_subblocks!(tdst, t)
47+
return tdst
3548
end
3649

3750
function Base.convert(::Type{TT}, t::AbstractTensorMap) where {TT <: AbstractBlockTensorMap}

src/tensors/tensoroperations.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ function TO.tensoradd_type(TC, A::AdjointBlockTensorMap, pA::Index2Tuple, conjA:
1515
return TO.tensoradd_type(TC, A', adjointtensorindices(A, pA), !conjA)
1616
end
1717

18+
# copy blocks back to CPU/collect them into an array
19+
# seems necessary for GPU-backed BlockTensorMaps but
20+
# maybe not the most efficient approach?
21+
function TO.tensorscalar(t::AbstractBlockTensorMap{T, S, 0, 0}) where {T, S}
22+
return prod(TO.tensorscalar, nonzero_values(t))
23+
end
24+
1825
# tensoralloc_contract
1926
# --------------------
2027
for TTA in (:AbstractTensorMap, :AbstractBlockTensorMap), TTB in (:AbstractTensorMap, :AbstractBlockTensorMap)

test/abstracttensor/blocktensor.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ using BlockTensorKit
55
using Random
66
using Combinatorics
77
using Adapt
8+
using JLArrays
89

910
Vtr = (
1011
SumSpace(ℂ^3),
@@ -82,6 +83,14 @@ end
8283
t2″ = @inferred BlockTensorMap(t2′, W)
8384
@test t1 t1″
8485
@test t2 t2″
86+
# test conversion to TensorMap that isn't backed by a Vector
87+
jl_bt1 = rand(JLVector{T}, W)
88+
TT = TensorKit.TensorMap{T, spacetype(t1′), numout(t1′), numin(t1′), JLVector{T}}
89+
JLArrays.@allowscalar begin # to avoid scalar indexing error in Strided
90+
jl_bt1′ = @constinferred convert(TT, jl_bt1)
91+
jl_bt1″ = @inferred BlockTensorMap(jl_bt1′, W)
92+
end
93+
@test jl_bt1 jl_bt1″
8594
end
8695
end
8796

0 commit comments

Comments
 (0)