Skip to content
Pasqal Documentation

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)

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.

Terminal window
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 SDK
from 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 values
first = {"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

Terminal window
{'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 pulser
from emu_mps import MPS, BitStrings, Fidelity, MPSBackend, MPSConfig
# Create noise model
noise = pulser.NoiseModel(relaxation_rate=1, dephasing_rate=1.0)
# set up mps
dt = 100
sampling_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
)

Last updated: