-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Docs] Add contents to the docs (#21)
In this PR the contents of the documentation pages will be filled. - [x] Improve docstrings - [x] Write general documentation pages --------- Co-authored-by: Kaonan Micadei <[email protected]> Co-authored-by: RolandMacDoland <[email protected]>
- Loading branch information
1 parent
8e501c0
commit b600f7f
Showing
21 changed files
with
476 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
!!! warning | ||
This page is under construction. | ||
# Factory | ||
|
||
::: qadence2_ir.factory |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
!!! warning | ||
This page is under construction. | ||
|
||
# Factory Tools | ||
|
||
::: qadence2_ir.factory_tools |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,14 @@ | ||
!!! warning | ||
This page is under construction. | ||
# API Reference | ||
|
||
Here you can find the API specification for Qadence 2 IR. | ||
There is a page for each module in the Qadence 2 IR package, in which all class and function definitions are documented. | ||
The API reference is particularly useful to check the behavior of classes and functions, and to get information on arguments, attributes and other details. | ||
|
||
Qadence 2 IR has 5 modules that are each responsible for different aspects of the IR. | ||
For more information, see their dedicated pages: | ||
|
||
- [`qadence2-ir.factory`](./factory.md): Defines a factory function that creates a compile function. | ||
- [`qadence2-ir.types`](./types.md): Defines the valid types to be used in Qadence 2 IR code. | ||
- [`qadence2-ir.irast`](./irast.md): Defines the AST that is used in front-end to IR compilation. | ||
- [`qadence2-ir.irbuilder`](./irbuilder.md): Defines the interface for front-ends compilation. | ||
- [`qadence2-ir.factory_tools`](./factory_tools.md): Defines tools for processing AST objects during compilation. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
!!! warning | ||
This page is under construction. | ||
# IRAST | ||
|
||
::: qadence2_ir.irast |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
!!! warning | ||
This page is under construction. | ||
# IR Builder | ||
|
||
::: qadence2_ir.irbuilder |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
!!! warning | ||
This page is under construction. | ||
# Types | ||
|
||
::: qadence2_ir.types |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Challenges | ||
|
||
As pointed out [here](./ir_structure.md), digital and analog algorithms diverge in how they handle register topology. Contrary to classical computing, where the resource allocation is typically left to the OS to control, the quantum resources are explicit in this analog quantum computating IR. | ||
|
||
For digital devices and circuit-based algorithms, the register topology is important mostly during the compilation phase to reduce the number of SWAP gates applied. Analog algorithms and devices, on the other hand, rely on the topology to ensure the proper interaction between qubits regarding connectivity and strength. That led us to consider including the abstract representation of the register (either by unitless coordinates or connectivity graph) as part of the IR. | ||
|
||
However, register preparation doesn’t represent an instruction in the sense of runtime since it needs to be loaded before the sequence starts and (for analog algorithms) cannot be changed during execution. Even if shuttling is available, the initial register configuration needs to be known to properly evaluate the atoms’ movement since such action will affect the connectivity of the register. | ||
|
||
Besides the register, other elements like the SLM used to target individual qubits are part of the “booting”/resources allocation that is not directly connected to the register but cannot be addressed as regular instructions. Still, its presence may affect the behavior of specific pulses, which motivated the inclusion of a “Directives” section on the IR. | ||
|
||
Primitive operations are another challenge in neutral atoms. The analog nature of the algorithms and device makes it difficult to clearly define “primitive operations”. Elementary structures like a pulse corresponding to the neutral atom Hamiltonian and an idle/wait instruction to let the qubits interact under free coupling (without drive). | ||
|
||
To avoid define a fixed set of operations that may not reflect the hardware capabilities and to avoid constant changes in the IR definition to include new primitives, the instructions’ names are passed as labels like `QuInstrunct("dyn_pulse", …)` and `QuInstruct("rx", …)` instead of `Pulse(…)` and `RX(…)`. This may change in the future. However, right now, this flexibility allows us to explore the hardware's capabilities without being held by a particular set of instructions. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Compute Stack | ||
|
||
Pasqal’s compute stack comprises four layers, as shown in Figure 1. A user defines the quantum computation using one of the front-ends: Qadence 2 Expressions or PQL. The computation to be executed is processed from layer to layer and eventually executed on the hardware. In each layer, a quantum computation is expressed in a specific data structure. The higher up the layer is in the stack, the more hardware details are abstracted away. | ||
|
||
The top layer is user-facing, with the highest level of abstraction. For each front-end, a compiler exists that compiles the computation in Qadence 2 IR. See the section IR structure for more details on its definition. The low-level compilation process targets a backend, either a QPU or a simulator, and compiles the computation into code that can run on the targeted backend. The backend itself takes care of executing the computation on the hardware. | ||
|
||
It's important to note that the Qadence 2 IR layer spreads over the full width of the stack, meaning that all front-ends can compile to it and any backend can be targeted from it. The two-step compilation approach reduces the coupling between elements in the stack significantly and makes the codebase, therefore, more maintainable. | ||
|
||
 | ||
**Figure 1:** The Qadence 2 software stack. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Qadence2 IR | ||
Qadence 2 IR is a Pasqal initiative, to define an intermediate representation structure for neutral atom devices. The structure captures the key elements of the platform while remaining agnostic regarding hardware specifications. The goal is to simplify instruction building of analog quantum algorithms, enabling optimized instructions and compilation processes of task-specific algorithms to different platforms. By using an agnostic instruction set, Qadence 2 IR allows digital and analog instructions to work together, extending its usability to the digital-analog paradigm. The IR uses static single-assignment to simplify differentiability when running simulations. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# IR Structure | ||
The main idea for Qadence 2 IR is to provide an abstract neutral atom device model. | ||
|
||
Neutral atom devices usually rely on absolute values like laser power, atomic spacing in micrometers, and nanosecond pulse duration. Since the interaction between atoms and, therefore, the execution of algorithms in such devices are heavily influenced by those parameters, having a well-tuned algorithm for a specific device is desired. With that in mind, the IR definition should be independent of device-specific parameters, leaving their implementation to the backend. At the same time, the front-end compilation pipeline must build the IR from the algorithm and bridges with the backend at the low-level compilation pipeline, accessing its runtime resources. | ||
|
||
Analog-relevant data such as the qubit register, parametric symbols and quantum instructions are wrapped in the IR, enabling each backend to handle them case-by-case. In particular, the instructions will provide only minimal information, such as the qubit support and the instruction label, i.e., which quantum operator or instruction is being applied, and the backend must provide some implementation for it. | ||
|
||
The IR Model is split in four sections: | ||
|
||
- Inputs | ||
- Instructions | ||
- Register | ||
- Directives | ||
|
||
The *Inputs* section is responsible for declaring the classical data and flagging them as trainable or not. This information is desired to ensure that only the parameters used in the machine learning training steps are considered for differentiability. | ||
|
||
The *Instruction* section holds the sequence of classical computation via static single-assignment to avoid duplicate computation and help the differentiability instructions. | ||
|
||
Quantum operations are passed as labels instead of fixed primitives (see the Challenges section). The IR definition is independent of device-specific parameters and leaves their configuration to the compiler, which builds an IR algorithm into instructions that contain the device-specific parameters. | ||
|
||
The *Register* section holds either an abstract description of how the atoms are placed on the register or a connectivity graph, depending on the type of algorithm. Algorithms that don’t require customized registers are allowed to pass only the number of qubits. This process is delegated to the backend compiler to decide the best strategies to organize the atoms whenever possible. | ||
|
||
The *Directives* section holds other device critical information for resource allocation like SLM mask target for individual qubit addressability. | ||
|
||
Resource allocation, such as Registers and Directives, is usually not expected in an intermediate representation. However, as described before, those elements can affect algorithm design and pulse execution. The Challenges section presents more details about them. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
# Examples | ||
The following examples were generate to present some possible algorithms and may not be | ||
fully implementable in the hardware at the moment. | ||
|
||
## Example digital input. | ||
```python | ||
Model( | ||
register = AllocQubits(2), | ||
directives = { # for QPU options | ||
}, | ||
inputs = { | ||
"x": Alloc(1, trainable=True), | ||
}, | ||
instructions = [ | ||
|
||
# data encoding | ||
Assign("%0", Call("mul", 0.5, Load("x"))), | ||
QuInstruction("rx", Support(target=(0,)), Load("%0")), | ||
|
||
# cnot | ||
QuInstruction("x", Support(target=(1,), control=(0,))), | ||
], | ||
) | ||
``` | ||
|
||
## Example digital-analog input. | ||
```python | ||
Model( | ||
register = AllocQubits(4), | ||
directives = { | ||
"dmm": { | ||
"targets": [0, 1, 2, 3], | ||
"weights": "equal", | ||
} | ||
}, | ||
settings = {}, | ||
inputs = { | ||
"theta": Alloc(4, trainable=False) | ||
"duration": Alloc(1, trainable=True) | ||
"omega": Alloc(5, trainable=True) | ||
}, | ||
instrunctions = [ | ||
# Tower feature map | ||
Assign("%0", Call("mul", 0.31831, Load("theta")), | ||
QuInstruct("set_dmm", Support.target_all(), Load("%0")) | ||
QuInstruct("rx", Support.target_all(), 1.570796), | ||
QuInstruct("dyn_local_pulse", Support.target_all(), 2.0), | ||
QuInstruct("rx", Support.target_all(), -1.570796), | ||
|
||
# Entanglement | ||
QuInstruct("dyn_interact", Support.target_all(), 2.5), | ||
|
||
# Trainable layer | ||
QuInstruct("dyn_pulse", Support.target_all(), Load("duration"), Load("omega"), 0.0, 0.0), | ||
], | ||
) | ||
``` | ||
|
||
## Example analog input. | ||
```python | ||
Model( | ||
register = AllocQubits( | ||
num_qubits = 4, | ||
qubits_positions = [ | ||
(-2, 1), (-1, 0), (0, 0), (1, -1) | ||
], | ||
|
||
# optional parameters | ||
grid_type = "triangular", | ||
grid_scale = 1.0, | ||
), | ||
directives = { | ||
"dmm": { | ||
"targets": [0, 3], | ||
"weights": [0.5, 1.0], | ||
} | ||
}, | ||
inputs = { | ||
"duration": Alloc(1, trainable=False, attrs={"time_parameter": True}), | ||
"omega": Alloc(4, trainable=True), | ||
"delta": Alloc(3, trainable=True), | ||
}, | ||
instrunctions = [ | ||
QuInstruct( | ||
"dyn_pulse", | ||
Support.target_all(), | ||
Load("duration"), | ||
Load("omega"), | ||
Load("delta"), | ||
0.0, # phase | ||
), | ||
QuInstruction( | ||
"dyn_local_phase", | ||
Support(target=(0, 1)), # match with dmm targets | ||
1.2, # duration | ||
attrs={ | ||
"concurrent": True, # starts with the previous pulse | ||
} | ||
), | ||
], | ||
) | ||
``` | ||
|
||
## Example analog input (alternative) | ||
This example is intend to be used with backends that either support crossing-lattice or similar | ||
algorithms, or gridless backends (e.g. PyQ). | ||
```python | ||
Model( | ||
register = AllocQubits( | ||
num_qubits = 4, | ||
connectivity = { | ||
(0, 1): 1.2, | ||
(0, 3): 0.9, | ||
(1, 2): 1.4, | ||
(2, 3): 2.1, | ||
} | ||
), | ||
directives = { | ||
"dmm": { | ||
"targets": [0, 3], | ||
"weights": [0.5, 1.0], | ||
} | ||
}, | ||
inputs = { | ||
"duration": Alloc(1, trainable=False, attrs={"time_parameter": True}), | ||
"omega": Alloc(4, trainable=True), | ||
"delta": Alloc(3, trainable=True), | ||
}, | ||
instrunctions = [ | ||
QuInstruct( | ||
"dyn_pulse", | ||
Support.target_all(), | ||
Load("duration"), | ||
Load("omega"), | ||
Load("delta"), | ||
0.0, # phase | ||
), | ||
QuInstruction( | ||
"dyn_local_phase", | ||
Support(target=(0, 1)), # match with dmm targets | ||
attrs={ | ||
"concurrent": True, # starts with the previous pulse | ||
"duration": 1.2, | ||
} | ||
), | ||
], | ||
) | ||
``` | ||
|
||
```python | ||
Model( | ||
register=AllocQubits( | ||
num_qubits=3, | ||
connectivity={(0,1): 1., (0,2): .5, (1,2): .5}, | ||
), | ||
directives={ | ||
"dmm": {"targets": [0, 1]} | ||
}, | ||
inputs={ | ||
't': Alloc(1, trainable=True) | ||
}, | ||
instructions=[ | ||
# The presence of the `dmm` allows a single qubit operation by | ||
# dynamic decoupling the others two qubits. | ||
QuInstruct('x', Support(target=(2,))), | ||
|
||
Assign('%0', Mul(1.57, Load('t')), | ||
QuInstruct('dyn_pulse', target_all(), Load('%0'), 1.0), | ||
], | ||
) | ||
``` |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.