RobinKa / tfga

Python package for Geometric / Clifford Algebra with TensorFlow
MIT License
48 stars 7 forks source link

Improve geometric product performance #13

Open RobinKa opened 4 years ago

RobinKa commented 4 years ago

Right now the geometric product is basically done by using a 3-Tensor C_ijk which is very sparse:

a_i b_j C_ijk -> y_k

Initially in this project we attempted to exploit this sparsity by slicing out all the zeroes of the 3-tensor. However this turned out to be ~50 times slower on GPU for full mv mv products in STA. Find a better, GPU-friendly way to exploit this sparsity.

RobinKa commented 4 years ago

Another idea:

Example (but with cached get_partial_cayley):

def get_partial_cayley(cayley, blade_indices_a, blade_indices_b, blade_indices_out):
    cayley = tf.gather(cayley, blade_indices_a, axis=0)
    cayley = tf.gather(cayley, blade_indices_b, axis=1)
    cayley = tf.gather(cayley, blade_indices_out, axis=2)
    return cayley

# e01 e02 e03
# 5 6 7
a = tf.ones([3, 4, 3])

# e0 e1
# 1 2
b = tf.ones([3, 4, 2])

# e1, e012, e013
# 1, 11, 12

"""
s
0

e0 e1 e2 e3
1  2  3  4

e01 e02 e03 e12 e13 e23
5   6   7   8   9   10

e012 e013 e023 e123
11   12   13   14

e0123
15
"""

partial_cayley = get_partial_cayley(ga.cayley, [5, 6, 7], [1, 2], [1, 11, 12])

print(partial_cayley.shape)

x = ga.geom_prod(ga.from_tensor(a, [5, 6, 7]), ga.from_tensor(b, [1, 2]))
y = tfga.mv_ops.mv_multiply(a, b, partial_cayley)

print(x[0, 0])
print(y[0, 0])
RobinKa commented 4 years ago

Started some initial work here https://github.com/RobinKa/tfga/tree/feature/faster-cayley-prod

Initial results for PGA (16 basis blades), runtime of multiplying two even-graded multivectors (8 basis blades):

hugohadfield commented 4 years ago

Wow, that is a really nice speedup