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.08474785477459634, 0.9334205743133138], [0.17846462517980877 0.1896106119234685; 0.9300961982311634 0.5449649766862518], [0.5240504203812376 0.6750587617620961; 0.4347697216692238 0.12391343017477974]])
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([...])