pyttb
pyttb copied to clipboard
ktensor.full() improvements
The current implementation of .full()
for ktensors is extremely memory and compute intensive. It's easy to run out of memory with tensor of modest size but high rank, since the current algorithm requires memory proportional to rank.
I believe an einsum
based approach would be much more efficient.
Consider the timing results for the code below.
n = 1000:
full tensor size: ~8 GB
current .full() profiling: 107 s, 120 GB peak memory usage
einsum based .full(): 65 s, 8 GB peak memory usage
n = 100: (as evidence that einsum outperforms for small tensors too)
current .full() profiling: 0.1s
einsum based .full(): 0.06s
import pyttb
import numpy as np
import time
def einfull(w,fm_list):
return np.einsum('r,ir,jr,kr->ijk',w,*fm_list)
n = 1000
r = 10
w = np.random.rand(r)
A = np.random.rand(n,r)
B = np.random.rand(n,r)
C = np.random.rand(n,r)
K = pyttb.ktensor()
K.weights = w
K.factor_matrices = [A,B,C]
t_0 = time.perf_counter()
T = K.full()
# T = einfull(w,[A,B,C])
t_1 = time.perf_counter()
print(t_1 - t_0)