My question is basically the best way to compute the matrix exponential in parallel. I've got a sequential code written in Python (https://github.com/hadsed/AdiaQC) and I need to extend it to run in a high performance environment (cluster, supercomputer, maybe GPU).
The code simulates adiabatic quantum computation, and the main things to worry about is a complex-valued vector representing the quantum state, and a Hamiltonian matrix which I do an eigendecomposition on, as well as an exponent for the matrix exponential operator that I apply to the state vector. Hamiltonian and exponent are dense, and it grows as $2^n\times 2^n$, and state vector of course is $2^n$ as well. Here $n$ is the number of qubits.
There seems to be some development in SLEPc for a matrix exponential module, but I don't think I can wait for it.
I'm thinking that the eigendecomposition method for the matrix exponential probably isn't the most efficient, but I'm not exactly sure how to efficiently do the other methods (and if they really are better). Any suggestions? I have gotten petsc4py and slepc4py working finally, so I'd like to exploit that as much as I can.
Let me know if I need to be more specific about the actual problem.
EDIT: Thought it might be helpful to explain more about Hamiltonian.
This is my Ising Hamiltonian: $H = \sum\limits_{ij} \beta_{ij} z_i z_j + \sum\limits_{i} \alpha_i z_i + \sum\limits_i \delta_i x_i$ where
$$ z_i = I \otimes ... \otimes ~ \sigma^z_i ~ \otimes ... \otimes I $$
$\sigma^z$ is the Pauli-z matrix, 2x2, and basically the identity but the lower diagonal element is -1. $I$ is just the identity, 2x2. So $\sigma^z_i$ is at the $i$th position of this bunch of Kronecker products. We cycle through i := {0, 1, ... , n} where n is the number of qubits. You do the same thing for $x_i$ (this time with the Pauli-x matrix, which is a 2x2 matrix, ones on the antidiagonal. With the two $z$s you just shift the position of two Pauli-z matrices instead of one in this big Kronecker product thing and sum those.
But this Hamiltonian is time-dependent. $\alpha$, $\beta$, and $\delta$ are the only time-dependent components. Actually, they are coefficient matrices/vectors, but they are multiplied by something that makes it time-dependent. So,
$$ H_{exponent} = \frac{t}{T} H_{\alpha \beta} + (1 - \frac{t}{T}) H_{\delta} $$
where $H_{\alpha \beta}$ is just the first two sums in the Ising Hamiltonian, and same for the $H_{\delta}$. This is what I take the exponential of to apply to my state vector $\psi$ (I'm slightly lying here to simplify, it's not as simple as $t/T$ but it doesn't matter, they're just numbers that change with time).
Something to notice is that $H_{\alpha \beta}$ is completely diagonal. Really convenient, but unfortunately $H_{\delta}$ is completely the opposite of diagonal (read: dense as hell). In the beginning, $H_{exponent} = H_{\delta}$, and at the end it's $H_{\alpha \beta}$.
Anyway, explaining all this in the hopes that maybe someone can spot some exploitable structure.