gacore is a high-performance Geometric Algebra (Clifford Algebra) library for Python.
It is designed as a drop-in replacement for the standard clifford library but features a completely rewritten core engine powered by OpenAI Triton (for NVIDIA & AMD GPUs) and Apple MLX (for Apple Silicon).
- Universal Acceleration: Runs ultra-fast on standard GPUs, Apple Silicon (M series), and CPUs.
- Dynamic Custom Kernel:
- Directly mapped Bitwise XOR product calculations.
- Popcount-based sign evaluation (no large lookup tables).
- Just-In-Time (JIT) compilation for specialized metric signatures.
- Zero-Copy Fallback: Seamlessly handles arbitrary dimensions via optimized CPU fallbacks when hardware acceleration isn't available.
- Drop-In Compatibility: Supports the full
CliffordAPI. Existing code works instantly.
gacore uses specialized kernels for 5D (Conformal Geometric Algebra) and 4D (Projective, Spacetime) algebras that are significantly faster than standard table-based implementations.
Measured on Apple Silicon (M4) vs Standard clifford (PyGAE) library. To ensure real-world reliability, these benchmarks were performed by integrating gacore into a cloned version of the Geometric Algebra Transformer (GATr) repository, replacing its standard clifford backend.
| Engine | Throughput (ops/sec) | Speedup |
|---|---|---|
Standard clifford (Iterative) |
455,655 | 1.0x |
| gacore (CPU/Torch) | 3,459,619 | 7.6x |
| gacore (GPU/MLX) | 6,230,213 | 13.7x |
Important
Performance Note: These speedups only apply when using batched operations. GACORE is optimized for functional, vectorized processing of multivector arrays. Individual, iterative multivector operations (e.g., in a Python loop) will not see significant gains as the overhead of function calls and tensor creation dominates.
For massive workloads, the GPU throughput is truly transformative. In a stress test of 100 million operations:
- Total throughput: ~10+ Million geometric products / second.
- Speedup: 1,550x faster than standard Python implementations and over 20.6x faster than Numba-accelerated tables.
The speedup
Where:
-
$t_{legacy}$ : Persistent per-op cost of table lookups (CPU). -
$t_{accelerated}$ : The marginal cost of a bitwise fused product (GPU/Apple Silicon). -
$K$ : Fixed overhead (kernel launch and memory dispatch).
As
pip install gacoreRequirements:
- Python 3.8+
- For NVIDIA GPU support:
torch+triton - For Apple Silicon support:
mlx
You can use gacore exactly like you used clifford.
import gacore as cf
from gacore.g3 import e1, e2, e3
import numpy as np
# Create MultiVectors
a = e1 + 2*e2
b = e3
# Geometric Product (Accelerated)
c = a * b
print(f"Product: {c}")
# Rotors works as expected
R = np.e**(np.pi/4 * (e1^e2))
rotated = R * a * ~R
print(f"Rotated: {rotated}")gacore allows you to pass native tensors directly to algebra functions for maximum speed in deep learning pipelines.
import torch
from gacore import geometry_product, set_metric
# Define a metric signature (e.g., Cl(3,0) Euclidean)
signature = torch.tensor([1, 1, 1], device='cuda')
# Batch of multivectors (BatchSize=1024, Dims=8)
x = torch.randn(1024, 8, device='cuda')
y = torch.randn(1024, 8, device='cuda')
# High-speed product
z = geometric_product(x, y, signature)Traditional GA libraries use Cayley multiplication tables which grow as
- Bitwise Indexing: Basis blades are represented as integers bits. The index of the product is simply
i ^ j(XOR). - Sign Computation: The sign is computed on-the-fly using
popcount(Hamming weight) operations to determine the number of basis vector swaps. - Unified Backend: A smart dispatcher routes operations to Triton (CUDA), Metal (MLX), or NumPy/Torch (CPU) based on input data types.
MIT License. Based on the original work of the clifford project contributors.
Goal: Derive a closed-form bitwise expression for the geometric product
We prove that the geometric product in
We define an isomorphism
where
Let the basis vectors
Example: The bivector 00011).
The geometric product of two blades is defined by the juxtaposition of their basis vectors. Vectors appearing in both blades contract, while unique vectors remain. This is equivalent to the Symmetric Difference of the sets of basis indices.
This proves that the resulting blade's basis is always found at the XORed index, eliminating the need for search or hash maps.
The sign
- Let
$e_i = e_{a_1} e_{a_2} \dots e_{a_m}$ and$e_j = e_{b_1} e_{b_2} \dots e_{b_n}$ . - Each move incurs a sign change
$(-1)$ due to$e_a e_b = -e_b e_a$ . - The total number of swaps
$N$ is the count of pairs$(k,l)$ such that$\text{index}(a_k) > \text{index}(b_l)$ .
Bitwise Optimization:
Summing over all bits in
The sign is then:
The metric
- Contraction occurs only for basis vectors present in both
$i$ and$j$ , defined by the bitwise AND:mask_intersect = i & j. - Since
$\eta_{kk} = -1$ only for the 5th basis vector ($e_-$ at index 4), the metric sign$\eta(i,j)$ is:
The coefficient for the product of two multivectors
Let
-
The Matrix Method (
$T_{matrix}$ ): Standard frameworks (PyTorch/TensorFlow) often represent multivectors as$D \times D$ matrices.-
Complexity:
$D \times D \times D = D^3$ . -
For CGA:
$32^3 = 32,768$ FLOPs.
-
Complexity:
-
The Bit-Masked Method (
$T_{bit}$ ): We iterate through all$D^2$ pairs. For each pair, we compute the sign and index using bit-logic.-
Complexity:
$n \cdot D^2$ . -
For CGA:
$5 \cdot 32^2 = 5,120$ ops. -
Theoretical Speedup (
$\alpha$ ):$\frac{D^3}{n \cdot D^2} = \frac{D}{n} = 6.4 \times$
-
Complexity:
In modern GPU architectures, math is "cheap" but memory is "expensive."
-
Cayley Table Method: Fetching
SignTable[i][j]from memory incurs latency. L1 cache latency is$\sim 20$ –$80$ cycles. Shared Memory can face bank conflicts. -
Bit-Masked Method: Zero table lookups. Sign and index are computed using register-local bitwise instructions (
xor,and,vpopcnt) with$\sim 1$ cycle latency. -
Latency Speedup (
$\beta$ ):$\frac{\text{Latency}_{\text{Mem}}}{n \cdot \text{Latency}_{\text{ALU}}} \approx 8 \times$ .
The Roofline Model defines performance by "Operations per Byte" (
-
Cayley Method:
$I_{cayley} = \frac{1 \text{ op}}{16 \text{ bytes}} = 0.0625$ . -
Bit-Masked Method:
$I_{bit} = \frac{1 \text{ op}}{8 \text{ bytes}} = 0.125$ . - Conclusion: Our method is 200% more efficient at utilizing memory bandwidth.
The primary barrier to GA adoption is computational complexity. Accessing a sparse Cayley tensor
We implemented custom kernels in OpenAI Triton and Apple MLX that compute the sign
Algorithm 1: Bit-Masked Geometric Product Kernel (Fused)
-
Input: Multivectors
$A, B \in \mathbb{R}^{B \times 32}$ -
Output:
$C \in \mathbb{R}^{B \times 32}$ - Load
$A$ and$B$ into Shared Memory -
for
$i \gets 0$ to 31 do $\quad acc \gets 0$ -
$\quad$ for$j \gets 0$ to 31 do -
$\quad \quad k \gets i \oplus j$ // Inverse XOR to find target -
$\quad \quad s \gets \text{ComputeSign}(j, k)$ // Bitwise Popcount $\quad \quad acc \gets acc + s \cdot A[j] \cdot B[k]$ -
$\quad$ end $\quad C[i] \gets acc$ - end
The sign of
// Triton Pseudocode
int target_idx = a ^ b;
int swaps = __popc(a & (b >> 1)); // Simplified parity check
int metric_sign = lookup_metric_table[target_idx];
float sign = (swaps % 2 == 0) ? 1.0 : -1.0;
accumulator += sign * metric_sign * A[a] * B[b];Table 2: Geometric Product Layer Latency & Memory (Batch Size = 32)
| Implementation | Latency (ms) | VRAM Delta (MB) | Efficiency |
|---|---|---|---|
| Standard PyTorch (Table Lookup) | 37.67 | 257.62 | 1.0x |
| Versor Optimized Kernel | 13.47 | 13.31 | 19.4x reduction |
| Speedup Factor | 2.8x | 19.4x | - |
By computing structure constants on-the-fly, we reduce memory consumption by 19.4x. On GPU (Triton), this speedup extends to ~38x due to massive parallelism.