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.5969825514602165, 0.37576429039103376], [0.13811407774037487 0.010116934862832383; 0.15407162871997415 0.032107998298183005], [0.7583955449327293 0.07987009731976535; 0.19905565780923662 0.3477155998951039]])
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([...])