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.14815496385502214, 0.5287359445837116], [0.2825677404697452 0.7899754447041192; 0.5070364282196299 0.9009668337799854], [0.0622305141297157 0.3817466341577661; 0.1464183265819211 0.7765498477127911]])
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([...])