Matrix Product States (MPS)
EMU-MPS is a Pulser backend, designed to EMUlate the dynamics of programmable arrays of neutral atoms, with matrix product states (MPS). MPSs are a way of encoding quantum states such that the memory required to represent the wavefunction depends on its entanglement, roughly, how much quantum information is stored in it. For product states, an MPS only takes d*N numbers to store the state for N d-level qudits, while for maximally entangled states, it’ll take a multiple of the memory in a state vector. For systems of interest, MPSs are expected to be more efficient than state-vectors, allowing the user to simulate more qubits. For more information, see the official documentation on EMU-MPS (external) . EMU-MPS is built on PyTorch, and in the future we intend to make it differentiable. Follow the links for more details about our emulator (external)
-
GPU acceleration
-
Supports all Pulser sequences that use only the rydberg channel.
-
Serialised configuration parameters
-
Customisable output
- Bitstrings
- The fidelity with respect to a given state
- The expectation of a given operator
- The qubit density (magnetization)
- The correlation matrix
- The mean, second moment and variance of the energy
-
Support for a noise model (via serialised configuration)
Example
Section titled “Example”This example assumes you have created a Pulser sequence using the Pasqal Pulser library and that you are using the Pasqal Cloud SDK version 0.12.7
or higher. See our SDK CHANGELOG (external)
here.
pip install pulser
More information in Pulser can be found in the official Github repo (external) .
Then using the EmulatorType
property from pasqal_cloud.device
, we can select EMU_MPS
as our desired emulator.
from pasqal_cloud import SDKfrom pasqal_cloud.device import EmulatorType
sdk = SDK( username="your username", password="your password", project_id="your project id")# Two jobs providing alternate shot/run count and omega_max valuesfirst = {"runs": 20, "variables": {"omega_max": 6}}second = {"runs": 50, "variables": {"omega_max": 10.5}}
batch = sdk.create_batch( serialized_sequence=serialized_sequence, jobs=[first, second], device_type=EmulatorType.EMU_MPS,)
Then using our batch object we can wait for our results to return and populate our object.
We can do this one of two ways:
You can pass the wait
argument to create_batch
which will poll Pasqal’s cloud service on a loop until your results are calculated
batch = sdk.create_batch( serialized_sequence=serialized_sequence, jobs=[first, second], device_type=EmulatorType.EMU_MPS, wait=True)
or
You can use an alternate method in our SDK to call at your own leisure
batch = sdk.get_batch("your-batch-id-here")
To retrieve the results of your MPS emulation, you can currently read the bitstrings from each job inside the batch.
If you iterate over the ordered_jobs
property of your batch, you can call full_results
to access a dictionary containing a bitstrings
field.
for job in batch.ordered_jobs: print(job.full_result)
The output
{'raw': None, 'counter': None, 'bitstring': {'100': {'0100': 3, '0000': 12, '0001': 2, '1000': 2, '0010': 1}}}{'raw': None, 'counter': None, 'bitstring': {'100': {'1000': 17, '0010': 9, '0001': 3, '0100': 7, '1001': 1, '0000': 12, '0110': 1}}}
Submitting a batch with a serialised configuration
Section titled “Submitting a batch with a serialised configuration”With EMU_MPS, you can submit custom configuration values that can impact the emulation and results. You can generate and then serialise a configuration before submitting, so it’s included when your submission executes.
Below is an example generating a simple MPSConfig
instance. It contains an instance of a Pulser NoiseModel
and a BitStrings
import pulserfrom emu_mps import MPS, BitStrings, Fidelity, MPSBackend, MPSConfig
# Create noise modelnoise = pulser.NoiseModel(relaxation_rate=1, dephasing_rate=1.0)
# set up mpsdt = 100sampling_times = 1000
bitstrings = BitStrings(evaluation_times=[1.0], num_shots=sampling_times)
serialised_configuration = MPSConfig( noise_model=noise, dt=dt, observables=[bitstrings],).to_abstract_repr()
The critical part in this example is the use of .to_abstract_repr()
. This serializes the entire MPSConfig
into a string value, which can be converted back using .from_abstract_repr()
.
When using the Pasqal Cloud SDK to submit your batch, you can pass your serialised configuration as the backend_configuration
value in the create_batch
function.
batch = sdk.create_batch( serialized_sequence=serialized_sequence, jobs=[first], device_type=EmulatorType.EMU_MPS, backend_configuration=serialised_configuration)