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:
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:
RemoteSVBackend— state vector emulatorRemoteMPSBackend— matrix product states emulatorRemoteEmuFreeBackend— qutip emulator
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)