Skip to navigationSkip to main contentSkip to footerScaleway Docs HomepageAsk our AI
Ask our AI

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.

Note

See the Pasqal processors information page for more details.

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
  1. Install pulser-scaleway and QoolQit.

    pip install pulser-scaleway qoolqit
  2. Create a file and set up a Scaleway connection. Replace $SCW_PROJECT_ID and $SCW_SECRET_KEY with 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.
  3. 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")
  4. 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
    )
  5. 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.

  1. Install matplotlib pip install matplotlib.

  2. Replace $SCW_PROJECT_ID and $SCW_SECRET_KEY with your Scaleway Project ID and secret key (or set them as environment variables). Also replace the SCALEWAY_PLATFORM with 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()
Still need help?

Create a support ticket
No Results