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.AnalogDeviceis an example of a QPU implementing an Ising Hamiltonian.The possibility to define a device without some physical constraints using the
VirtualDeviceclass. An example of such a virtual device is theMockDeviceprovided in thepulser.devices, which gives full liberty to write a quantum program.VirtualDeviceis 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, min_layout_filling=0.0, 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
Deviceinstance holds the characteristics of a physical device, which when associated with apulser.Sequencecondition 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.min_layout_filling (
float, default:0.0) – The smallest fraction of a layout that must be filled with atoms. Only enforced when the layout has more traps than ‘min_layout_traps’.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:
dimensionsmax_atom_nummax_radial_distancemin_atom_distance
The
rydberg_leveldetermines the Ising interaction coefficient \(C_6\) of the Ising Hamiltonian. The quantity \(\frac{C_6}{\hbar}\) is accessible via theinteraction_coeffattribute of theDevice.The
Channelsin thechannel_objectsparameter 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_durationconstrains 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_runslimits 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
LocalorGlobalclassmethods.- 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
Channeldefines the states that can be addressed by the driving Hamiltonian if this channel is picked. All the child classes ofChannelcan be found here.The addressing of the
Channeldetermines what atoms experience the driving Hamiltonian. In general, physicalChannelshave aGlobaladdressability, 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_durationandmax_duration, as well asclock_period(it has to be a multiple of the clock period).the amplitude is limited by the maximum amplitude
max_ampandmin_avg_amp.the detuning is limited by the maximum absolute detuning
max_abs_det. It has to be between -max_abs_detandmax_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
- Minimum layout filling fraction: 0.0
- 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_durationof the channel.The value of \(\Omega\) can go between 0 and
max_ampand the value of \(\delta\) can go between -max_abs_detuningandmax_abs_detuning.