Skip to content

Cached field

The CachedField mechanism was introduced to alleviate the overhead of repeatedly calling tensors. Some parts of the code (e.g. the Reactant linearization of a TensorNetwork) require that the no-kwarg tensors(::AbstractTensorNetwork) method, which returns all the tensors present in an AbstractTensorNetwork, to always return the Tensors in the same order if it hasn't been modified.

To fulfill such requirement, we sort the Tensors by their inds but the overhead of it is big when their number is in order of 100-1000s and tensors is called repeatedly.

julia
A = Tensor(rand(2,2), [:i, :j])
B = Tensor(rand(2,2), [:j, :k])
C = Tensor(rand(2,), [:a])
tn = TensorNetwork([A,B,C])
tensors(tn) .|> inds
3-element Vector{Tuple{Symbol, Vararg{Symbol}}}:
 (:a,)
 (:i, :j)
 (:j, :k)

In order to avoid the repeated cost, we cache the results of tensors(::AbstractTensorNetwork) in a field of [TensorNetwork] with type CachedField. Such type just stores the result of the last call and a invalidation flag.

julia
tn.sorted_tensors
Tenet.CachedField{Vector{Tensor}}(true, Tensor[[0.43002666763931063, 0.6852365169273837], [0.3271600041037288 0.12851210328727702; 0.25647027213696005 0.6908341394400429], [0.4224428822364513 0.9961516049353629; 0.20993173963246292 0.7952046660618851]])

Calling push! or pop! invalidates the CachedField, so the next time tensors(::AbstractTensorNetwork) is called, it will reconstruct the cache. Because any other method that can modify the result of tensors(::AbstractTensorNetwork) relies on push! or pop!, the cache is always invalidated correctly.

julia
delete!(tn, C)
tn.sorted_tensors.isvalid
false

DocumenterMermaid.MermaidScriptBlock([...])

Made with DocumenterVitepress.jl