Skip to content

v.1.9.8

Latest
Compare
Choose a tag to compare
@kottmanj kottmanj released this 14 Nov 10:16
eb36f43

Overview

  • oo more flexible (#366)
  • Fix current Qiskit versions
  • Update ci_backends.yml
  • Add Qiskit GPU simulator
  • Refactor QubitWaveFunction, add support for Numpy array backed dense representation (#370)
  • Fix some tests
  • Reactivate QASM tests
  • Enable arbitrary state initialization for Qulacs and Qiskit backends (#371)

Details:

  • Enable arbitrary state initialization for Qulacs and Qiskit backends (#371) (Oliver Huettenhofer )

For the Qulacs and Qiskit backend, it makes it possible to initialize circuits with arbitrary wavefunctions instead of only basis states.
This also adds the parameter for sampling and to tq.simulate.

I have added boolean flags to the backend circuit objects that indicate which backends support this and throw an error message when necessary. This doesn't seem ideal, but I didn't want to change the other backends that I can't test.

Also, combining initial states with a keymap is awkward, I think it only makes sense if we assume that all states on the inactive qubits are the same. For now I disabled it and throw an error message.
I noticed that there's no keymap for sampling, can we get rid of it for simulating too?

Example usage:

import numpy as np
import tequila as tq
from tequila import QubitWaveFunction

U = tq.gates.H(target=0)
state = QubitWaveFunction.from_array(np.array([1.0, 1.0])).normalize()

result = tq.simulate(U, initial_state=state, backend="qulacs")
assert result.isclose(QubitWaveFunction.from_basis_state(n_qubits=1, basis_state=0))

result = tq.simulate(U, initial_state=state, backend="qulacs", samples=100)
assert result.isclose(QubitWaveFunction.from_array(np.array([100.0, 0.0])))
  • Refactor QubitWaveFunction, add support for Numpy array backed dense representation (#370) (Oliver Huettenhofer)

When running simulate to get the output wavefunction of a circuit, currently the conversion from the array that the backend returns to the dictionary format that Tequila uses can be a bottleneck.
This pull request fixes this by refactoring the QubitWaveFunction class and allowing it to either use a dictionary for sparse wavefunctions, or a Numpy array for dense wavefunctions.

To see the performance improvement, consider the code from my previous pull request, but increase the number of qubits to 22:

import tequila as tq
from math import pi
import time

SIZE = 22

def qft(size: int, inverse: bool = False) -> tq.QCircuit():
    U = tq.QCircuit()
    for i in range(size):
        U += tq.gates.H(target=i)
        for j in range(size - i - 1):
            U += tq.gates.Phase(target=i + j + 1, angle=(-1 if inverse else 1) * pi / 2 ** (j + 2))
            U += tq.gates.CRz(target=i, control=i + j + 1, angle=(-1 if inverse else 1) * pi / 2 ** (j + 1))
    return U

U = qft(SIZE)
V = qft(SIZE) + qft(SIZE, inverse=True)

start = time.time()
wfn = tq.simulate(U, backend="qulacs")
print(f"QFT time: {time.time() - start} s")

start = time.time()
wfn = tq.simulate(V, backend="qulacs")
print(f"QFT + inverse QFT time: {time.time() - start} s")

On the current devel branch, this takes around 10 seconds for only the QFT, and around 2.4 seconds for the QFT combined with the inverse. With this pull request, this is reduced to around 0.95s / 1.85s. Not only is it faster, but the larger circuit is now slower, unlike before where the larger circuit was faster because the result was a sparse wavefunction. The time spent in the Qulacs update_quantum_state method is around 0.7s / 1.4s, so now the simulation actually makes up the majority of the runtime.

In theory, both sparse and dense representations should be functionally equivalent, and the only difference should be a space-time tradeoff.
Most of the time, the sparse representation is used by default to preserve the previous behaviour.
The dense representation is used when the wavefunction is constructed from an array, or when it is chosen explicitly.

I also made various other changes to the wavefunction API.

  • Add Qiskit GPU simulator (Oliver Huettenhofer)

I added support for running the Qiskit simulator on the GPU by creating a subclass that changes the device name. I used the same structure as for the Qulacs GPU simulator.

Using this requires the qiskit-aer-gpu package.

I also commented out the package check for qulacs-gpu, because that package is not maintained, instead you have to compile Qulacs with GPU support, see qulacs/qulacs#623 (comment).


Co-authored-by: Oliver Huettenhofer [email protected]