Program Pasqal backends using QoolQit
Pasqal is a full-stack quantum computing company based in France, pioneering the use of Neutral Atoms (manipulated by optical tweezers) to build quantum processors.
Pasqal processors operate primarily in Analog Mode (applying pulses to the whole system to evolve the Hamiltonian), making them exceptionally powerful for quantum simulation and combinatorial optimization.
The base SDK for programming Pasqal processors is Pulser, but QoolQit adds an abstraction layer on top of it providing dimensionless programming, so you can write hardware-agnostic algorithms in the Rydberg Analog Model.
Access Pasqal with Scaleway for QoolQit programs
The following example shows how to create a remote emulator and run your computation on it. You can do the same with a QPU, see QoolQit reference.
Before you start
To complete the actions presented below, you must have:
- A Scaleway account with a valid Project ID
- A Scaleway API key (secret key)
- Python installed
-
Install pulser-scaleway and QoolQit.
pip install pulser-scaleway qoolqit -
Create a file and set up a Scaleway connection. Replace
$SCW_PROJECT_IDand$SCW_SECRET_KEYwith your Scaleway Project ID and secret key (or set them as environment variables).from pulser_scaleway import ScalewayProvider from qoolqit.devices import Device # Initiate provider qaas_connection = ScalewayProvider( project_id="$SCW_PROJECT_ID", secret_key="$SCW_SECRET_KEY", ) # Retrieve all QPU devices (emulated or real) and select the one you desire (see the Pasqal processors information page for more information: https://www.scaleway.com/en/docs/quantum-computing/additional-content/pasqal-qpus/) devices = qaas_connection.fetch_available_devices() device = Device.from_connection(qaas_connection, name="EMU-MPS-PASQAL") # Use the device you want. In this example we use an MPS emulator. -
Write and compile a QuantumProgram to your Device.
from qoolqit import Register, Drive, QuantumProgram register = Register(...) driver = Drive(...) program = QuantumProgram(register, drive) program.compile_to(device, profile="max_energy") -
Configure the remote executor (in this case, an emulator — but you can swap to QPU() if you want).
from qoolqit.execution import EmulationConfig, RemoteEmulator from pasqal_cloud.backends import RemoteMPSBackend # Adjust the backend to your chosen device configuration = EmulationConfig(...) emulator = RemoteEmulator( backend_type=RemoteMPSBackend, connection=qaas_connection, emulation_config=configuration # Adjust the backend to your chosen device ) -
Run your program and fetch the job result.
job = emulator.run(program) results = job.results()
Full example
The following example is adapted from the QoolQit quickstart documentation to work on Scaleway.
-
Install matplotlib
pip install matplotlib. -
Replace
$SCW_PROJECT_IDand$SCW_SECRET_KEYwith your Scaleway Project ID and secret key (or set them as environment variables). Also replace theSCALEWAY_PLATFORMwith the emulator or QPU of your choice.
import os
import time
import numpy as np
from qoolqit import Drive, QuantumProgram, Register
from qoolqit.devices import Device
from qoolqit.execution import BitStrings, EmulationConfig, JobStatus, RemoteEmulator
from qoolqit.waveforms import ConstantWaveform
from pasqal_cloud.backends import RemoteMPSBackend
from pulser_scaleway import ScalewayProvider
PROJECT_ID = os.environ["SCALEWAY_PROJECT_ID"]
SECRET_KEY = os.environ["SCALEWAY_SECRET_KEY"]
PLATFORM = os.environ["SCALEWAY_PLATFORM"]
NUM_SHOTS = 1000
qaas_connection = ScalewayProvider(
project_id=PROJECT_ID,
secret_key=SECRET_KEY,
)
print(qaas_connection.fetch_available_devices()) # Sanity check
# Two qubits at unit distance => maximum interaction J = 1
register = Register.from_coordinates([(0, 0), (1, 0)])
duration = 10
# Blockade regime: Omega << J => double excitation is suppressed
drive_blockade = Drive(
amplitude=ConstantWaveform(duration, 0.3), # Omega = 0.3 << 1
detuning=ConstantWaveform(duration, 0.0)
)
# Non-blockade regime: Omega >> J => drive dominates, both atoms can be excited
drive_no_blockade = Drive(
amplitude=ConstantWaveform(duration, 2.0), # Omega = 2.0 >> 1
detuning=ConstantWaveform(duration, 0.0)
)
# Build and compile programs
program_blockade = QuantumProgram(register, drive_blockade)
program_no_blockade = QuantumProgram(register, drive_no_blockade)
device = Device.from_connection(qaas_connection, name=PLATFORM)
print(device)
program_blockade.compile_to(device, profile="max_energy")
program_no_blockade.compile_to(device, profile="max_energy")
# Configure emulation: sample bitstrings at 81 evaluation times
eval_times = np.linspace(0.0, 1.0, 81)
bitstrings = BitStrings(evaluation_times=list(eval_times), num_shots=NUM_SHOTS)
configuration = EmulationConfig(observables=[bitstrings])
emulator = RemoteEmulator(connection=qaas_connection, emulation_config=configuration)
print("Running Blockade Job...", flush=True, end='')
job_blockade = emulator.run(program_blockade)
while not job_blockade.has_ended():
print('.', flush=True, end='')
time.sleep(1)
assert job_blockade.get_status() == JobStatus.DONE
print("Done!")
result_blockade = job_blockade.results()
print("Running No-Blockade Job...", flush=True, end='')
job_no_blockade = emulator.run(program_no_blockade)
while not job_no_blockade.has_ended():
print('.', flush=True, end='')
time.sleep(1)
assert job_no_blockade.get_status() == JobStatus.DONE
print("Done!")
result_no_blockade = job_no_blockade.results()
import matplotlib.pyplot as plt
times=result_blockade.get_result_times(bitstrings)
occupation=[result_blockade.get_result(bitstrings.tag,time=t).get("11", 0)/NUM_SHOTS
for k,t in enumerate(times)]
plt.plot(times,occupation,
label="Blockade",
color="navy")
times=result_no_blockade.get_result_times(bitstrings)
occupation=[result_no_blockade.get_result(bitstrings.tag,time=t).get("11", 0)/NUM_SHOTS
for k,t in enumerate(times)]
plt.plot(times,occupation,
label="No Blockade",
color="crimson")
plt.xlabel(r"$t$",fontsize=22)
plt.ylabel(r"$P_{rr}$",fontsize=22)
plt.xticks(fontsize=18)
plt.yticks(fontsize=18)
plt.legend(fontsize=16)
plt.show()