Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "TensorAlgebra"
uuid = "68bd88dc-f39d-4e12-b2ca-f046b68fcc6a"
version = "0.22.0"
version = "0.23.0"
authors = ["ITensor developers <support@itensor.org> and contributors"]

[workspace]
Expand Down
2 changes: 1 addition & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ path = ".."
Documenter = "1.8.1"
ITensorFormatter = "0.2.27"
Literate = "2.20.1"
TensorAlgebra = "0.22"
TensorAlgebra = "0.23"
2 changes: 1 addition & 1 deletion examples/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ TensorAlgebra = "68bd88dc-f39d-4e12-b2ca-f046b68fcc6a"
path = ".."

[compat]
TensorAlgebra = "0.22"
TensorAlgebra = "0.23"
8 changes: 4 additions & 4 deletions ext/TensorAlgebraTensorKitExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,10 @@ TensorAlgebra.zero!(t::AbstractTensorMap) = VectorInterface.zerovector!(t)

# A `TensorMap` is not an `AbstractArray`, so the generic in-place `TensorAlgebra` operations
# don't apply. Forward to TensorKit's `VectorInterface` methods, its primary interface for these.
# `add!` here is the non-permuting `y = α*x + β*y`. The permuting `bipermutedimsopadd!` handles a
# `scaleadd!` here is the non-permuting `y = α*x + β*y`. The permuting `bipermutedimsopadd!` handles a
# non-trivial codomain/domain permutation.
TensorAlgebra.scale!(t::AbstractTensorMap, β::Number) = VectorInterface.scale!(t, β)
function TensorAlgebra.add!(
function TensorAlgebra.scaleadd!(
y::AbstractTensorMap, x::AbstractTensorMap, α::Number, β::Number
)
return VectorInterface.add!(y, x, α, β)
Expand All @@ -320,7 +320,7 @@ end
# ================================== linear-combination broadcast =========================
# A `TensorMap` is not an `AbstractArray`, so it needs a `BroadcastStyle` to broadcast lazily
# (otherwise Base tries to `collect` it). A linear combination flattens (via `tryflattenlinear`)
# to a `LinearBroadcasted` that materializes through `add!`/`bipermutedimsopadd!` above; the
# to a `LinearBroadcasted` that materializes through `scaleadd!`/`bipermutedimsopadd!` above; the
# `copyto!` here is not piracy because `LinearBroadcasted` is TensorAlgebra-owned. Element-wise
# (nonlinear) broadcast is not a meaningful operation on a symmetric tensor, so it errors rather
# than dense-converting.
Expand All @@ -331,7 +331,7 @@ Base.Broadcast.BroadcastStyle(s::TensorMapStyle, ::Base.Broadcast.BroadcastStyle
Base.Broadcast.broadcastable(a::AbstractTensorMap) = a

function Base.copyto!(dest::AbstractTensorMap, src::TensorAlgebra.LinearBroadcasted)
return TensorAlgebra.add!(dest, src, true, false)
return TensorAlgebra.scaleadd!(dest, src, true, false)
end

# Allocation for a linear-combination `copy`/`copyto!`: seed the result off a `TensorMap` operand
Expand Down
2 changes: 1 addition & 1 deletion src/TensorAlgebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export contract, contract!, contractalign, dual, isdual, MatrixAlgebra
if VERSION >= v"1.11.0-DEV.469"
eval(
Meta.parse(
"public AbstractAlgorithm, add!, AddBroadcasted, addends, allocate_output, allocate_project, arguments, axes, bipartition, bipartition_axes, biperm, bipermutedims, bipermutedims!, bipermutedimsopadd!, cat_axis, cat_similar, check_input, concatenate, concatenate!, ConjBroadcasted, contractadd!, ContractAlgorithm, contractopadd!, contractperm, contractperm!, contractpermadd!, contractpermalign, contractpermopadd!, data, datatype, default_algorithm, dims2cat, directsum, eig_full, eig_trunc, eig_vals, eigh_full, eigh_trunc, eigh_vals, fill_map, flattenlinear, has_bipartition, infer_aux_space, invsqrth_safe, is_output_view, is_projected, isidentitybiperm, label_type, left_null, left_orth, left_polar, LinearBroadcasted, linearbroadcasted, lq_compact, lq_full, matricize, MatricizeContract, matricizeop, matricizeop!, matricizeopcopy, matricizeopview, MATRIX_FUNCTIONS, ndims, ndims_codomain, ndims_domain, one, ones_map, operation, output_axes, PermutedDims, permuteddims, permutedims, permutedims!, permutedimsadd!, permutedimsop, permutedimsopadd!, project, project!, project_aux, project_hermitian, projectto!, qr_compact, qr_full, rand_map, randn_map, right_null, right_orth, right_polar, scalar, scale!, ScaledBroadcasted, select_algorithm, similar_map, size, sqrth_invsqrth_safe, sqrth_safe, sum, svd_compact, svd_full, svd_trunc, svd_vals, TensorOperationsContract, to_range, tr, trivialrange, tryflattenlinear, tryproject, tryproject_aux, unchecked_project, unchecked_project_aux, ungrade, unmatricize, unmatricize!, unmatricize_factors, unmatricizeadd!, unproject, unscaled, zero!, zeros_map"
"public AbstractAlgorithm, add!, AddBroadcasted, addends, allocate_output, allocate_project, arguments, axes, bipartition, bipartition_axes, biperm, bipermutedims, bipermutedims!, bipermutedimsopadd!, cat_axis, cat_similar, check_input, concatenate, concatenate!, ConjBroadcasted, contractadd!, ContractAlgorithm, contractopadd!, contractperm, contractperm!, contractpermadd!, contractpermalign, contractpermopadd!, data, datatype, default_algorithm, dims2cat, directsum, eig_full, eig_trunc, eig_vals, eigh_full, eigh_trunc, eigh_vals, fill_map, flattenlinear, has_bipartition, infer_aux_space, invsqrth_safe, is_output_view, is_projected, isidentitybiperm, label_type, left_null, left_orth, left_polar, LinearBroadcasted, linearbroadcasted, lq_compact, lq_full, matricize, MatricizeContract, matricizeop, matricizeop!, matricizeopcopy, matricizeopview, MATRIX_FUNCTIONS, ndims, ndims_codomain, ndims_domain, one, ones_map, operation, output_axes, PermutedDims, permuteddims, permutedims, permutedims!, permutedimsadd!, permutedimsop, permutedimsopadd!, project, project!, project_aux, project_hermitian, projectto!, qr_compact, qr_full, rand_map, randn_map, right_null, right_orth, right_polar, scalar, scale!, scaleadd!, ScaledBroadcasted, select_algorithm, similar_map, size, sqrth_invsqrth_safe, sqrth_safe, sum, svd_compact, svd_full, svd_trunc, svd_vals, TensorOperationsContract, to_range, tr, trivialrange, tryflattenlinear, tryproject, tryproject_aux, unchecked_project, unchecked_project_aux, ungrade, unmatricize, unmatricize!, unmatricize_factors, unmatricizeadd!, unproject, unscaled, zero!, zeros_map"
)
)
end
Expand Down
8 changes: 4 additions & 4 deletions src/linearbroadcasted.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Abstract supertype for lazy linear broadcast expressions. Analogous to

Materializes via the protocol:
copy(lb) = copyto!(similar(lb), lb)
copyto!(dest, lb) → add!(dest, lb, 1, 0)
copyto!(dest, lb) → scaleadd!(dest, lb, 1, 0)
"""
abstract type LinearBroadcasted end

Expand Down Expand Up @@ -180,7 +180,7 @@ operation(::Mul) = *
arguments(a::Mul) = factors(a)

# ---------------------------------------------------------------------------- #
# Materialization protocol: copy, copyto!, add!
# Materialization protocol: copy, copyto!, scaleadd!
# ---------------------------------------------------------------------------- #

function Base.copy(a::LinearBroadcasted)
Expand All @@ -191,12 +191,12 @@ function Base.copy(a::Mul)
return copyto!(similar(a), a)
end

# copyto! for LinearBroadcasted dispatches to add!.
# copyto! for LinearBroadcasted dispatches to scaleadd!.
# Stays `AbstractArray`-bound: these overload `Base.copyto!`, so widening `dest` to `Any`
# collides with Base's own methods. A non-array destination (e.g. a wrapped `TensorMap`)
# gets an `AbstractTensorMap`-specific `copyto!` from the backend extension instead.
function Base.copyto!(dest::AbstractArray, src::LinearBroadcasted)
return add!(dest, src, true, false)
return scaleadd!(dest, src, true, false)
end

# copyto! for Mul dispatches to mul!. Materialize factors first since
Expand Down
6 changes: 3 additions & 3 deletions src/permutedimsadd.jl
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,11 @@ function permutedimsadd!(
end

"""
add!(dest, src, α, β)
scaleadd!(dest, src, α, β)

`dest = β * dest + α * src`.
"""
function add!(dest, src, α::Number, β::Number)
function scaleadd!(dest, src, α::Number, β::Number)
return permutedimsopadd!(dest, identity, src, ntuple(identity, ndims(src)), α, β)
end

Expand All @@ -185,7 +185,7 @@ end

`dest .+= src`.
"""
add!(dest, src) = add!(dest, src, true, true)
add!(dest, src) = scaleadd!(dest, src, true, true)

# ---------------------------------------------------------------------------- #
# permutedims — out-of-place, optional bipartition
Expand Down
2 changes: 1 addition & 1 deletion test/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Random = "1.10"
SafeTestsets = "0.1"
StableRNGs = "1.0.2"
Suppressor = "0.2"
TensorAlgebra = "0.22"
TensorAlgebra = "0.23"
TensorKit = "0.17"
TensorOperations = "5.1.4"
Test = "1.10"
Expand Down
6 changes: 3 additions & 3 deletions test/test_diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ using Test: @test, @test_throws, @testset
@test eltype(out) === elt
end

@testset "add! accumulates onto a Diagonal" begin
@testset "scaleadd! accumulates onto a Diagonal" begin
dest = Diagonal(elt[1, 1, 1])
# `add!(dest, src, α, β)` computes `α * src + β * dest`.
TensorAlgebra.add!(dest, d, elt(2), elt(1))
# `scaleadd!(dest, src, α, β)` computes `α * src + β * dest`.
TensorAlgebra.scaleadd!(dest, d, elt(2), elt(1))
@test dest isa Diagonal
@test dest == Diagonal(elt[5, 7, 9])
end
Expand Down
3 changes: 2 additions & 1 deletion test/test_exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ using Test: @test, @testset
:permutedimsadd!, :permutedimsop, :permutedimsopadd!, :project,
:project!, :project_aux, :project_hermitian, :projectto!, :qr_compact,
:qr_full, :rand_map, :randn_map, :right_null, :right_orth, :right_polar,
:scalar, :scale!, :ScaledBroadcasted, :select_algorithm, :similar_map,
:scalar, :scale!, :scaleadd!, :ScaledBroadcasted, :select_algorithm,
:similar_map,
:size, :sqrth_invsqrth_safe, :sqrth_safe, :sum, :svd_compact, :svd_full,
:svd_trunc, :svd_vals, :TensorOperationsContract, :to_range, :tr,
:trivialrange, :tryflattenlinear, :tryproject, :tryproject_aux,
Expand Down
18 changes: 9 additions & 9 deletions test/test_linearbroadcasted.jl
Original file line number Diff line number Diff line change
Expand Up @@ -161,28 +161,28 @@ using Test: @test, @test_throws, @testset
@test bc isa BC.Broadcasted
@test copy(bc) ≈ 2a + conj(b)
end
@testset "add! and copyto! with LinearBroadcasted" begin
@testset "scaleadd! and copyto! with LinearBroadcasted" begin
a = randn(ComplexF64, 3, 3)
b = randn(ComplexF64, 3, 3)

# add! with ScaledBroadcasted
# scaleadd! with ScaledBroadcasted
dest = zeros(ComplexF64, 3, 3)
TA.add!(dest, linearbroadcasted(*, 2, a), true, false)
TA.scaleadd!(dest, linearbroadcasted(*, 2, a), true, false)
@test dest ≈ 2a

# add! with AddBroadcasted
# scaleadd! with AddBroadcasted
dest = zeros(ComplexF64, 3, 3)
TA.add!(dest, linearbroadcasted(+, a, b), true, false)
TA.scaleadd!(dest, linearbroadcasted(+, a, b), true, false)
@test dest ≈ a + b

# add! with a ConjBroadcasted
# scaleadd! with a ConjBroadcasted
dest = zeros(ComplexF64, 3, 3)
TA.add!(dest, linearbroadcasted(conj, a), true, false)
TA.scaleadd!(dest, linearbroadcasted(conj, a), true, false)
@test dest ≈ conj(a)

# add! with β accumulation
# scaleadd! with β accumulation
dest = ones(ComplexF64, 3, 3)
TA.add!(dest, linearbroadcasted(*, 2, a), 3, 1)
TA.scaleadd!(dest, linearbroadcasted(*, 2, a), 3, 1)
@test dest ≈ ones(ComplexF64, 3, 3) + 6a
end
@testset "0-dimensional permutedimsopadd!" begin
Expand Down
21 changes: 12 additions & 9 deletions test/test_permutedimsadd.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Adapt: adapt
using JLArrays: JLArray
using TensorAlgebra: TensorAlgebra, ConjBroadcasted, PermutedDims, add!,
bipermutedimsopadd!, permuteddims, permutedimsadd!, permutedimsopadd!
bipermutedimsopadd!, permuteddims, permutedimsadd!, permutedimsopadd!, scaleadd!
using Test: @test, @testset

# A non-`AbstractArray` operand, to check that `permuteddims` falls back to `PermutedDims`.
Expand All @@ -10,26 +10,29 @@ struct NotAnArray{P}
end

@testset "[permutedims]add!" begin
@testset "add!(b, a, α, β) (arraytype=$arrayt)" for arrayt in (Array, JLArray)
@testset "scaleadd!(b, a, α, β) (arraytype=$arrayt)" for arrayt in (Array, JLArray)
dev = adapt(arrayt)
a = dev(randn(2, 2, 2))
α = 2
for β in (0, 3)
b = dev(randn(2, 2, 2))
b′ = copy(b)
add!(b′, a, α, β)
scaleadd!(b′, a, α, β)
@test b′ ≈ β * b + α * a
end
end
@testset "add!(b, a::PermutedDimsArray, α, β) (arraytype=$arrayt)" for arrayt in
(Array, JLArray)
@testset "scaleadd!(b, a::PermutedDimsArray, α, β) (arraytype=$arrayt)" for arrayt in
(
Array,
JLArray,
)
dev = adapt(arrayt)
a = dev(randn(2, 2, 2))
α = 2
for β in (0, 3)
b = dev(randn(2, 2, 2))
b′ = copy(b)
add!(b′, PermutedDimsArray(a, (3, 1, 2)), α, β)
scaleadd!(b′, PermutedDimsArray(a, (3, 1, 2)), α, β)
@test b′ ≈ β * b + α * permutedims(a, (3, 1, 2))
end
end
Expand Down Expand Up @@ -131,7 +134,7 @@ end
end
end
end
@testset "add!(b, ConjBroadcasted(a)) matches eager conj (arraytype=$arrayt)" for arrayt in
@testset "scaleadd!(b, ConjBroadcasted(a)) matches eager conj (arraytype=$arrayt)" for arrayt in
(
Array,
JLArray,
Expand All @@ -143,8 +146,8 @@ end
b = dev(randn(ComplexF64, 2, 3, 4))
b_lazy = copy(b)
b_eager = copy(b)
add!(b_lazy, ConjBroadcasted(a), α, β)
add!(b_eager, conj(a), α, β)
scaleadd!(b_lazy, ConjBroadcasted(a), α, β)
scaleadd!(b_eager, conj(a), α, β)
@test b_lazy ≈ b_eager
end
end
Expand Down
Loading