From ea45e192ceff7f0bfb093140ba56da9f6f326e03 Mon Sep 17 00:00:00 2001 From: Katharine Hyatt Date: Wed, 4 Nov 2026 07:29:09 -0500 Subject: [PATCH] Add an adapt method for SectorVector --- src/tensors/sectorvector.jl | 2 ++ test/amd/tensors.jl | 17 +++++++++++++++++ test/cuda/tensors.jl | 17 +++++++++++++++++ test/tensors/sectorvector.jl | 14 ++++++++++++++ 4 files changed, 50 insertions(+) diff --git a/src/tensors/sectorvector.jl b/src/tensors/sectorvector.jl index 5c11c66e3..2eceaba2d 100644 --- a/src/tensors/sectorvector.jl +++ b/src/tensors/sectorvector.jl @@ -41,6 +41,8 @@ Base.similar(v::SectorVector, ::Type{T}, V::ElementarySpace) where {T} = SectorV Base.copy(v::SectorVector) = SectorVector(copy(v.data), v.structure) +Adapt.adapt_structure(to, v::SectorVector) = SectorVector(Adapt.adapt(to, parent(v)), v.structure) + # AbstractDict interface # ---------------------- Base.keytype(v::SectorVector) = keytype(typeof(v)) diff --git a/test/amd/tensors.jl b/test/amd/tensors.jl index 9bf1d1997..a8da66b01 100644 --- a/test/amd/tensors.jl +++ b/test/amd/tensors.jl @@ -97,6 +97,23 @@ for V in spacelist @test domain(t2) == one(W) end end + @timedtestset "Adapt SectorVector" begin + for T in (Float32, ComplexF64) + v = TensorKit.SectorVector{T}(undef, V1) + rand!(parent(v)) + v_gpu = @constinferred adapt(ROCArray, v) + @test v_gpu isa TensorKit.SectorVector{T, I, <:ROCArray{T}} + @test v_gpu.structure == v.structure + v_cpu = @constinferred adapt(Array, v_gpu) + @test v_cpu isa TensorKit.SectorVector{T, I, Vector{T}} + @test parent(v_cpu) == parent(v) + t = AMDGPU.randn(T, V1 ⊗ V2 ← V3) + s = svd_vals(t) + s_cpu = adapt(Array, s) + @test parent(s_cpu) == collect(parent(s)) + @test all(c -> block(s_cpu, c) == collect(block(s, c)), blocksectors(s)) + end + end @timedtestset "Tensor Dict conversion" begin W = V1 ⊗ V2 ← (V3 ⊗ V4 ⊗ V5)' for T in (Int, Float32, ComplexF64) diff --git a/test/cuda/tensors.jl b/test/cuda/tensors.jl index 68e3bfa8f..7e66ad762 100644 --- a/test/cuda/tensors.jl +++ b/test/cuda/tensors.jl @@ -115,6 +115,23 @@ for V in spacelist @test storagetype(t_cpu) <: Array{T} end end + @timedtestset "Adapt SectorVector" begin + for T in (Float32, ComplexF64) + v = TensorKit.SectorVector{T}(undef, V1) + rand!(parent(v)) + v_gpu = @constinferred adapt(CuArray, v) + @test v_gpu isa TensorKit.SectorVector{T, I, <:CuArray{T}} + @test v_gpu.structure == v.structure + v_cpu = @constinferred adapt(Array, v_gpu) + @test v_cpu isa TensorKit.SectorVector{T, I, Vector{T}} + @test parent(v_cpu) == parent(v) + t = CUDA.randn(T, V1 ⊗ V2 ← V3) + s = svd_vals(t) + s_cpu = adapt(Array, s) + @test parent(s_cpu) == collect(parent(s)) + @test all(c -> block(s_cpu, c) == collect(block(s, c)), blocksectors(s)) + end + end @timedtestset "Tensor Dict conversion" begin W = V1 ⊗ V2 ← (V3 ⊗ V4 ⊗ V5)' for T in (Int, Float32, ComplexF64) diff --git a/test/tensors/sectorvector.jl b/test/tensors/sectorvector.jl index 22832404c..1ff8e3dbb 100644 --- a/test/tensors/sectorvector.jl +++ b/test/tensors/sectorvector.jl @@ -1,6 +1,7 @@ using Test, TestExtras using TensorKit using TensorKit: SectorVector, diagonalblockstructure +using Adapt: adapt spacelist = ( (ℂ^4)', @@ -29,6 +30,19 @@ spacelist = ( @test length(v3) == reduceddim(V) end + @timedtestset "Adapt ($T)" begin + v = SectorVector{T}(undef, V) + rand!(parent(v)) + w = @testinferred adapt(Array, v) + @test w isa SectorVector{T, I, Vector{T}} + @test parent(w) == parent(v) + @test w.structure == v.structure + T′ = T <: Complex ? ComplexF64 : Float64 + w′ = @testinferred adapt(Array{T′}, v) + @test w′ isa SectorVector{T′, I, Vector{T′}} + @test parent(w′) ≈ parent(v) + end + @timedtestset "AbstractVector interface ($T)" begin v = SectorVector{T}(undef, V) rand!(parent(v))