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 Tensor
s in the same order if it hasn't been modified.
To fulfill such requirement, we sort the Tensor
s by their inds
but the overhead of it is big when their number is in order of 100-1000s and tensors
is called repeatedly.
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.
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.
delete!(tn, C)
tn.sorted_tensors.isvalid
false
DocumenterMermaid.MermaidScriptBlock([...])