-
Notifications
You must be signed in to change notification settings - Fork 69
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
Is opt_einsum.paths.optimal algorithm correct? #167
Comments
Hi @igtrnt yes I think you're right - the algorithm was written with 'standard' einsums in mind where two different intermediates sharing the exact same indices is not possible. Out of interest, do you have any more complex examples where this might be important? Inputs with single indices that can/should be immediately summed over (i and k here) are a known suboptimal edge case - #112, #114. A workaround is just to use the @dgasmith maybe this would be a good time to replace |
@jcmgray Here is a bigger example:
Inside
total: 2309 FLOP. Correct costs of contracting along the above path are:
total: 4448 FLOP. So starting from third contraction, optimal gets wrong costs due to wrong stuff in cache. BTW, I think you also have a bug in computing
So there is a discrepancy between |
Apologies I'm a bit swamped at work at the moment and slow to respond here. @igtrnt is there a quick proposed fix? Otherwise we can look at deprecating |
I don't see how cache can be fixed. The purpose of cache is to avoid recomputing resulting However, I ported I also feel that you might have a similar issue with If user-provided cost function is not monotone (i.e. |
I think with greedy, the optimizer actively performs 'deduplication' as the first step i.e. repeated terms I think also then that I'd definitely be interested if you have any numbers on a C++ version vs optimal and the 'dp' algorithm. A compiled version of the 'dp' algorithm would be most useful, but not so simple to re-write. |
Yes, deduplication is done, but that's when
At first iteration, greedy chooses to contract
First and second queue entries have same |
Ah I see, you are right! I think I was overestimating A preprocessor that does do both so that the inputs are generally unique with shared indices only might be useful, and has been discussed before #114. Else for greedy specifically, one would need to change the representation so that terms were e.g. frozensets of ints representing initial tensor positions, this is what |
Is opt_einsum.paths.optimal supposed to support non-standard Einstein summations (when an index occurs in more than two tensors)?
Consider contracting 3 tensors:
ij,j,jk->
:First, DFS looks at
ij,j
contraction. Resulting tensor isj
(sincejk
is still in the remaining list).So it caches
{ij,j} -> [j, cost1]
Now, remaining contains:
jk
andj
. Contracting them results in empty tensor.So it caches
{j,jk} -> [, cost2]
.Now DFS goes into another branch, starting with
j,jk
contraction. It should result inj
tensor, becauseij
is still in the remaining list.But cache contains
{j,jk} -> [, cost2]
instead of{j,jk} -> [j, *]
.This simple example shows, that caching with key, based on two tensors participating in contraction, may not work correctly.
Cache key should also contain the contraction result. (E.g.,
{j, jk, j}
and{j, jk, }
would be two different cache keys). But this defeats the purpose of caching - contraction result needs to be calculated every time...For larger examples, it's easy to end up with non-optimal "optimal" path and, moreover, completely wrong cost for that path.
The text was updated successfully, but these errors were encountered: