I have a set of contractions that I would like to optimize; for the contractions I am using np.einsum()
from the NumPy module. The minimal reproducible example is here:
import numpy as np
from time import time
d1=2
d2=3
d3=100
a = np.random.rand( d1,d1,d1,d1,d2,d2,d2,d2,d3,d3 ) + 1j*np.random.rand( d1,d1,d1,d1,d2,d2,d2,d2,d3,d3 )
b = np.random.rand( d1,d1, d2,d2,d3,d3 ) + 1j*np.random.rand( d1,d1,d2,d2,d3,d3 )
c = np.random.rand( d1,d1, d2,d2,d3,d3 ) + 1j*np.random.rand( d1,d1,d2,d2,d3,d3 )
path_1 = 'abcdefghij,ckgojs,dlhpjs,klmnopqrst->abmnefqrit'
path_2 = 'abcdefghij,ckgoji,nbrfji,klmnopqrij->almdepqhij'
ts = time()
einsum_pathinfo = np.einsum_path(path_1, a, b, c, a )
term_a = np.einsum(path_1, a, b, c, a, optimize=einsum_pathinfo[0])
print("took", time()-ts)
ts = time()
einsum_pathinfo = np.einsum_path( path_2, a, b, c , a )
term_a = np.einsum(path_2, a, b, c, a, optimize=einsum_pathinfo[0])
print("took", time()-ts)
The times seem to be around ~2 seconds. I have also observed that einsum
is generally not multithreaded, and a single core is used instead. Is there any other efficient way to perform such contractions? (Perhaps with Numba?).