Skip to content

Getting Started

This guide will help you install pasqal-cloud, authenticate, and submit your first job to Pasqal Cloud Services.

Prerequisites

  • Python 3.9 or higher
  • A Pasqal Cloud account with valid credentials (username & password), see the documentation.
  • A project ID you are a member of, see the documentation.

Installation

Install the latest release from PyPI:

pip install pasqal-cloud

Authentication

Create a connection by providing your credentials and project ID:

from pasqal_cloud import PasqalCloudConnection

connection = PasqalCloudConnection(
    username="your_username",       # Your Pasqal platform email
    password="your_password",       # Your Pasqal platform password
    project_id="your_project_id",  # Your project ID from the portal
)

Warning

Never hard-code your password in source files. Prefer using environment variables instead

If you omit the password argument, you will be prompted to enter it interactively in your terminal.

For more authentication options (custom token providers, OVH), see Authentication.

Running a sequence on a QPU

See the Pulser sequence documentation for the full sequence-writing reference.

from pasqal_cloud import PasqalCloudConnection
from pulser.pulse import Pulse
from pulser import QPUBackend, Sequence, Register

connection = PasqalCloudConnection(...)

# Retrieve all QPU devices
devices = connection.fetch_available_devices()
device = devices["FRESNEL_CAN1"]

# Create a register of trapped atoms before performing operation on them
register = Register.square(5, 5).with_automatic_layout(device)

# Declare the sequence of pulses to perform on the register
sequence = Sequence(register, device)
sequence.declare_channel("rydberg", "rydberg_global")
omega_max = sequence.declare_variable("omega_max")

# Add a pulse to that channel with the amplitude omega_max
generic_pulse = Pulse.ConstantPulse(100, omega_max, 2, 0.0)
sequence.add(generic_pulse, "rydberg")

# Declare a backend based on the sequence and remote connection
backend = QPUBackend(sequence=sequence, connection=connection)

# Run jobs with different arguments over the same sequence and register
results = backend.run(
    job_params=[
        {"runs": 5, "variables": {"omega_max": 12}},
        {"runs": 10, "variables": {"omega_max": 6}},
    ],
    wait=True,
)
print(results.results)

Running on emulators

The package exposes several remote emulator backends:

Use them in place of QPUBackend to run the same sequences without consuming real QPU time:

from pasqal_cloud import PasqalCloudConnection, RemoteMPSBackend
from pulser.pulse import Pulse
from pulser import Sequence, Register

connection = PasqalCloudConnection(...)

# Retrieve all QPU devices
devices = connection.fetch_available_devices()
device = devices["FRESNEL_CAN1"]

# Create a register of trapped atoms before performing operation on them
register = Register.square(5, 5).with_automatic_layout(device)

# Declare the sequence of pulses to perform on the register
sequence = Sequence(register, device)
sequence.declare_channel("rydberg", "rydberg_global")
omega_max = sequence.declare_variable("omega_max")

# Add a pulse to that channel with the amplitude omega_max
generic_pulse = Pulse.ConstantPulse(100, omega_max, 2, 0.0)
sequence.add(generic_pulse, "rydberg")

# Declare a backend based on the sequence and remote connection
backend = RemoteMPSBackend(sequence=sequence, connection=connection)

# Run jobs with different arguments over the same sequence and register
results = backend.run(
    job_params=[
        {"runs": 5, "variables": {"omega_max": 12}},
        {"runs": 10, "variables": {"omega_max": 6}},
    ],
    wait=True,
)
print(results.results)

Using open batch feature

Open batches let you submit jobs whose variables depend on the results of previous jobs, all while retaining control of the backend until the batch is closed. See the documentation.

from pasqal_cloud import PasqalCloudConnection
from pulser.pulse import Pulse
from pulser import QPUBackend, Sequence, Register

connection = PasqalCloudConnection(...)

# Retrieve all QPU devices
devices = connection.fetch_available_devices()
device = devices["FRESNEL_CAN1"]

# Create a register of trapped atoms before performing operation on them
register = Register.square(5, 5).with_automatic_layout(device)

# Declare the sequence of pulses to perform on the register
sequence = Sequence(register, device)
sequence.declare_channel("rydberg", "rydberg_global")
omega_max = sequence.declare_variable("omega_max")

# Add a pulse to that channel with the amplitude omega_max
generic_pulse = Pulse.ConstantPulse(100, omega_max, 2, 0.0)
sequence.add(generic_pulse, "rydberg")

# Declare a backend based on the sequence and remote connection
backend = QPUBackend(sequence=sequence, connection=connection)

results = []

# Run jobs in the same batch
with backend.open_batch():
    results.append(
        backend.run(
            job_params=[
                {"runs": 1, "variables": {"omega_max": 12}},
                {"runs": 1, "variables": {"omega_max": 6}},
            ],
            wait=True,
        )
    )
    results.append(
        backend.run(
            job_params=[
                {"runs": 1, "variables": {"omega_max": 5}},
            ],
            wait=True,
        )
    )


for result in results:
    print(result.results)