Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with contract handling EinExpr with multiple unconnected tensors #16

Closed
jofrevalles opened this issue May 30, 2023 · 4 comments · Fixed by bsc-quantic/Tensors.jl#31
Labels
bug Something isn't working

Comments

@jofrevalles
Copy link
Member

Summary

The contract function is encountering issues when processing EinExpr structures containing more than two unconnected tensors. In a tensor network with interconnected tensors, the optimizer produces a binary tree of contractions executed by Tensors.contract. However, unconnected tensors are overlooked by the optimizer, resulting in more than two tensors being passed to the contract function. Since the contract function currently only supports pairwise contractions, this leads to an error.

Example

To illustrate this issue, consider the following scenario where we are creating an EinExpr with three tensors that are not interconnected:

julia> using EinExprs

julia> using Tensors

julia> tensor_vector = [
           Tensor(rand(2, 2), (:i, :j)),
           Tensor(rand(2, 2), (:k, :l)),
           Tensor(rand(2, 2), (:m, :n))]
3-element Vector{Tensor{Float64, 2, Matrix{Float64}}}: ...

julia> expr = einexpr(Greedy, EinExpr(tensor_vector))
EinExpr((:i, :j, :k, :l, :m, :n), Any[[0.933825756822585 0.08849284100391408; 0.6687884342507102 0.07328036746016686], [0.09743169734991863 0.2589449583415957; 0.9895176422398294 0.3901868918218132], [0.8604998512862905 0.053831101742811915; 0.05133466907086315 0.5293947978388226]])

julia> contract(expr)
ERROR: MethodError: no method matching contract(::Tensor{Float64, 2, Matrix{Float64}}, ::Tensor{Float64, 2, Matrix{Float64}}, ::Tensor{Float64, 2, Matrix{Float64}}; dims=Symbol[])
Closest candidates are:
  contract(::Tensor, ::Tensor; dims) at ~/.julia/packages/Tensors/bcSKh/src/Numerics.jl:10
  contract(::Tensor, ::TensorNetwork; kwargs...) at ~/git/Tenet.jl/src/TensorNetwork.jl:334
  contract(::Tensor{T, N, A} where {N, A<:AbstractArray{T, N}}, ::Union{AbstractArray{T, 0}, T}) where T at ~/.julia/packages/Tensors/bcSKh/src/Numerics.jl:24 got unsupported keyword argument "dims"
  ...
Stacktrace:
 [1] contract(expr::EinExpr)
   @ EinExprs ~/.julia/packages/EinExprs/YiZXb/src/EinExpr.jl:183
 [2] top-level scope
   @ REPL[53]:1

Upon running contract(expr), we observe an error as the function does not support contractions involving more than two tensors. A potential resolution may be to enhance the contract function's capability to manage multiple tensors.

@jofrevalles jofrevalles added the bug Something isn't working label May 30, 2023
@jofrevalles
Copy link
Member Author

@mofeing What do you think of this? Should we modify EinExprs or change the Tensors.contract function?
For me it makes sense that EinExprs only return pair-wise contractions, even if the tensors are not connected.

@mofeing
Copy link
Member

mofeing commented Jun 22, 2023

Currently, Tensors.contract only performs single and pairwise contractions. If more than two tensors are provided, it should perform a reduction in order.

So probably we need to write a method of Tensors.contract with varargs arguments.

@jofrevalles
Copy link
Member Author

Currently, Tensors.contract only performs single and pairwise contractions. If more than two tensors are provided, it should perform a reduction in order.

But this reduction maybe could be done directly in EinExprs, since it may return a contraction of some tensors which two are connected and the others are not, then it makes sense to follow the order chosen by EinExprs.

@mofeing
Copy link
Member

mofeing commented Jun 22, 2023

But this reduction maybe could be done directly in EinExprs, since it may return a contraction of some tensors which two are connected and the others are not, then it makes sense to follow the order chosen by EinExprs.

Then this should be implemented as an Optimizer pass, that groups connected tensors into EinExprs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants