Hardware specifications
What you will learn:
what is a Device and why is a Device needed;
what are the available devices and where to find them;
what do a Device and a Channel enforce;
tips on how to pick a
Device
;
The Device
Section titled “The Device”As presented in the introduction to programming a neutral-atom QPU, the first step to writing a Pulser program is the selection of a Device.
The Device
is an object that stores all the physical constraints a quantum program written with Pulser should verify. The Device
enforces that each operation added to the quantum program (i.e. the pulser.Sequence
) respects its constraints.
Choosing a Device
Section titled “Choosing a Device”To choose a Device
for your Sequence
, the first question you should ask yourself is:
“How close do I want the physical constraints I program with to be to the QPU’s?”
If you want to program with the physical constraints of a QPU: Each QPU has an associated Device
, which you can get from the cloud provider you use to access this QPU.
There are several reasons for which you might want to feel less constrained by the features currently supported by real QPUs. For instance, you might want to design an algorithm for a QPU having better performances (supporting more qubits, longer sequences, …) or hardware components that have not been installed.
Pulser enables you to define your own devices, but a Device
object takes as input lots of parameters that have all to be defined. Therefore, for user convenience, Pulser
provides:
Examples of typical physical devices in
pulser.devices
. Notably,pulser.AnalogDevice
is an example of a QPU implementing an Ising Hamiltonian.The possibility to define a device without some physical constraints using the
VirtualDevice
class. An example of such a virtual device is theMockDevice
provided in thepulser.devices
, which gives full liberty to write a quantum program.VirtualDevice
is detailed in an advanced tutorial.
Reading through the Device
’s specifications
Section titled “Reading through the Device’s specifications”The second question you should ask yourself to choose your Device
is:
“Do its constraints allow me to program my Sequence
?”
The device specifications are here to guide your choice. Here are all the parameters in a Device
:
- class pulser.devices._device_datacls.Device(name, dimensions, rydberg_level, min_atom_distance, max_atom_num, max_radial_distance, interaction_coeff_xy=None, supports_slm_mask=False, max_layout_filling=0.5, optimal_layout_filling=None, min_layout_traps=1, max_layout_traps=None, max_sequence_duration=None, max_runs=None, requires_layout=True, channel_ids=None, channel_objects=<factory>, dmm_objects=<factory>, default_noise_model=None, short_description='', pre_calibrated_layouts=<factory>, accepts_new_layouts=True)
Specifications of a neutral-atom device.
Each
Device
instance holds the characteristics of a physical device, which when associated with apulser.Sequence
condition its development.Note
A Device instance is immutable and must have all of its parameters defined. For more unconstrained usage in emulations, it can be converted to a VirtualDevice through the Device.to_virtual() method.`
- Parameters:
name (
str
) – The name of the device.dimensions (
Literal
[2
,3
]) – Whether it supports 2D or 3D arrays.max_atom_num (
int
) – Maximum number of atoms supported in an array.max_radial_distance (
int
) – The furthest away an atom can be from the center of the array (in μm).min_atom_distance (
float
) – The closest together two atoms can be (in μm).requires_layout (
bool
, default:True
) – Whether the register used in the sequence must be created from a register layout. Only enforced in QPU execution.accepts_new_layouts (
bool
, default:True
) – Whether registers built from register layouts that are not already calibrated are accepted. Only enforced in QPU execution.max_layout_filling (
float
, default:0.5
) – The largest fraction of a layout that can be filled with atoms.optimal_layout_filling (
float
|None
, default:None
) – An optional value for the fraction of a layout that should be filled with atoms.min_layout_traps (
int
, default:1
) – The minimum number of traps a layout can have.max_layout_traps (
int
|None
, default:None
) – An optional value for the maximum number of traps a layout can have.pre_calibrated_layouts (
tuple
[RegisterLayout
,...
], default:<factory>
) – RegisterLayout instances that are already available on the Device.rydberg_level (
int
) – The value of the principal quantum number \(n\) when the Rydberg level used is of the form \(|nS_{1/2}, m_j = +1/2\rangle\).interaction_coeff_xy (
float
|None
, default:None
) – \(C_3/\hbar\) (in \(rad \cdot \mu s^{-1} \cdot \mu m^3\)), which sets the van der Waals interaction strength between atoms in different Rydberg states. Needed only if there is a Microwave channel in the device. If unsure, 3700.0 is a good default value.channel_objects (
tuple
[Channel
,...
], default:<factory>
) – The Channel subclass instances specifying each channel in the device.channel_ids (
tuple
[str
,...
] |None
, default:None
) – Custom IDs for each channel object. When defined, an ID must be given for each channel. If not defined, the IDs are generated internally based on the channels’ names and addressing.dmm_objects (
tuple
[DMM
,...
], default:<factory>
) – The DMM subclass instances specifying each channel in the device. They are referenced by their order in the list, with the ID “dmm_[index in dmm_objects]”.supports_slm_mask (
bool
, default:False
) – Whether the device supports the SLM mask feature.max_sequence_duration (
int
|None
, default:None
) – The maximum allowed duration for a sequence (in ns).max_runs (
int
|None
, default:None
) – The maximum number of runs allowed on the device. Only used for backend execution.default_noise_model (
NoiseModel
|None
, default:None
) – An optional noise model characterizing the default noise of the device. Can be used by emulator backends that support noise.
Tips on Device
selection
Section titled “Tips on Device selection”The Device
is going to constrain the next steps of your quantum program:
Some parameters are going to constrain the creation of your Register, and therefore, the interaction strength in the interaction Hamiltonian. Some of these parameters are:
dimensions
max_atom_num
max_radial_distance
min_atom_distance
The
rydberg_level
determines the Ising interaction coefficient \(C_6\) of the Ising Hamiltonian. The quantity \(\frac{C_6}{\hbar}\) is accessible via theinteraction_coeff
attribute of theDevice
.The
Channels
in thechannel_objects
parameter are going to determine what Channels are available for the computation. Knowing what states you want to use in your computation, you can first check that they are among theDevice.supported_states
, then find the bases and their associated channel that enable to use these states using the conventions page.The
max_sequence_duration
constrains the duration of the Pulses you can add, and therefore the Hamiltonian describing the system can at most be defined between 0 and this value.The
max_runs
limits the number of runs a quantum program can be executed on the QPU. See the section on Backends to read more about this.
The Channels
Section titled “The Channels”The third step to writing a Pulser program is the selection of Channels among the Device.
As a reminder, the selection of a Channel
defines the interaction Hamiltonian and the driving Hamiltonian \(H^D\).
The Channels
available for selection are stored in the channels
property of the Device
, a dictionnary associating a channel_id
to each Channel
in channel_objects
. For instance, AnalogDevice
only contains one channel, the rydberg_global
channel, which can be accessed with AnalogDevice.channels["rydberg_global"]
.
Reading through the Channel
’s specifications
Section titled “Reading through the Channel’s specifications”The Channel
is defined by:
- class pulser.channels.base_channel.Channel(addressing, max_abs_detuning, max_amp, min_retarget_interval=None, fixed_retarget_t=None, max_targets=None, clock_period=1, min_duration=1, max_duration=100000000, min_avg_amp=0, mod_bandwidth=None, custom_phase_jump_time=None, propagation_dir=None)
Base class of a hardware channel.
Not to be initialized itself, but rather through a child class and the
Local
orGlobal
classmethods.- Parameters:
addressing (
Literal
['Global'
,'Local'
]) – “Local” or “Global”.max_abs_detuning (
float
|None
) – Maximum possible detuning (in rad/µs), in absolute value.max_amp (
float
|None
) – Maximum pulse amplitude (in rad/µs).min_retarget_interval (
int
|None
, default:None
) – Minimum time required between the ends of two target instructions (in ns).fixed_retarget_t (
int
|None
, default:None
) – Time taken to change the target (in ns).max_targets (
int
|None
, default:None
) – How many qubits can be addressed at once by the same beam.clock_period (
int
, default:1
) – The duration of a clock cycle (in ns). The duration of a pulse or delay instruction is enforced to be a multiple of the clock cycle.min_duration (
int
, default:1
) – The shortest duration an instruction can take.max_duration (
int
|None
, default:100000000
) – The longest duration an instruction can take.min_avg_amp (
float
, default:0
) – The minimum average amplitude of a pulse (when not zero).mod_bandwidth (
float
|None
, default:None
) – The modulation bandwidth at -3dB (50% reduction), in MHz.custom_phase_jump_time (
int
|None
, default:None
) – An optional custom value for the phase jump time that overrides the default value estimated from the modulation bandwidth. It is not enforced in EOM mode.propagation_dir (
tuple
[float
,float
,float
] |None
, default:None
) – The propagation direction of the beam associated with the channel, given as a vector in 3D space.
Example
To create a channel targeting the ‘ground-rydberg’ transition globally, call
Rydberg.Global(...)
.
Tips on Channel
selection
Section titled “Tips on Channel selection”The Channel
is going to determine the computational basis used in the driving Hamiltonian, and what is the Hamiltonian each atom sees:
The type of the
Channel
defines the states that can be addressed by the driving Hamiltonian if this channel is picked. All the child classes ofChannel
can be found here.The addressing of the
Channel
determines what atoms experience the driving Hamiltonian. In general, physicalChannels
have aGlobal
addressability, which means that a Pulse added to this channel will implement the same driving Hamiltonian on all the atoms.
The Channel
also set constraints on the next stage of your quantum program, the addition of Pulses:
the duration of the pulse is constrained by
min_duration
andmax_duration
, as well asclock_period
(it has to be a multiple of the clock period).the amplitude is limited by the maximum amplitude
max_amp
andmin_avg_amp
.the detuning is limited by the maximum absolute detuning
max_abs_det
. It has to be between -max_abs_det
andmax_abs_det
.
The AnalogDevice
Section titled “The AnalogDevice”import pulser
print(pulser.AnalogDevice.specs)
A realistic device for analog sequence execution.
Register parameters:
- Dimensions: 2D
- Maximum number of atoms: 80
- Maximum distance from origin: 38 µm
- Minimum distance between neighbouring atoms: 5 μm
Layout parameters:
- Requires layout: Yes
- Accepts new layout: Yes
- Minimal number of traps: 1
- Maximum layout filling fraction: 0.5
Device parameters:
- Rydberg level: 60
- Ising interaction coefficient: 865723.02
- Channels can be reused: No
- Supported bases: ground-rydberg
- Supported states: r, g
- SLM Mask: No
- Maximum sequence duration: 6000 ns
- Maximum number of runs: 2000
Channels:
- 'rydberg_global': Rydberg(addressing='Global', max_abs_detuning=125.66370614359172, max_amp=12.566370614359172, min_retarget_interval=None, fixed_retarget_t=None, max_targets=None, clock_period=4, min_duration=16, max_duration=100000000, min_avg_amp=0, mod_bandwidth=8, custom_phase_jump_time=None, eom_config=RydbergEOM(limiting_beam=<RydbergBeam.RED: 2>, max_limiting_amp=188.49555921538757, intermediate_detuning=2827.4333882308138, controlled_beams=(<RydbergBeam.BLUE: 1>,), mod_bandwidth=40, custom_buffer_time=240, multiple_beam_control=True, blue_shift_coeff=1.0, red_shift_coeff=1.0), propagation_dir=None)
The pulser.AnalogDevice
only supports the \(\left|r\right>\) and \(\left|g\right>\) states, because it only supports one channel of type “Rydberg” (that can be declared using its name “rydberg_global”). It implements the Ising Hamiltonian:
There:
The number of atoms \(N\) is constrained by the Maximum number of atoms.
The distance between the atoms \(R_{ij}\) is at least the Minimum distance between neighbouring atoms and at most twice the Maximum distance from origin. The distances are defined by placing the atoms in a 2D-plane.
\(C_6\) is the Ising interaction coefficient. It is defined from the Rydberg level (i.e. changing the Rydberg level would change the Ising interaction coefficient).
The
"rydberg_global"
being a"Global"
channel, each pulse added to this channel is applied on all the atoms (the quantities \(\Omega\), \(\delta\), \(\phi\) are the same for each atom).The Hamiltonian (and the pulses with their time-dependent quantities \(\Omega\), \(\delta\), \(\phi\)) can be defined between 0 and the minimum of the Maximum sequence duration and the
maximum_duration
of the channel.The value of \(\Omega\) can go between 0 and
max_amp
and the value of \(\delta\) can go between -max_abs_detuning
andmax_abs_detuning
.