From 570c8a081e338714153b666634880bd8edaac855 Mon Sep 17 00:00:00 2001 From: Kaonan Micadei Date: Fri, 11 Oct 2024 19:29:08 +0200 Subject: [PATCH 01/26] add some examples of possible IR compilations --- docs/examples.md | 186 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 docs/examples.md diff --git a/docs/examples.md b/docs/examples.md new file mode 100644 index 0000000..01df2c8 --- /dev/null +++ b/docs/examples.md @@ -0,0 +1,186 @@ +## 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), + }, + instrunctions = [ + + # 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": "from_inputs", + } + }, + settings = {}, + inputs = { + "theta": Alloc(4, trainable=False) + "duration": Alloc(1, trainable=True, attrs={"time_parameter": 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 = { # for QPU options + "rydberg_level": 65, + "max_amplitude": 5.5, + "max_abs_detuning": 70.0, + + "dmm": { + "targets": [0, 3], + "weights": [0.5, 1.0], + } + }, + settings = { # for building options + "prioritize_speed": True, + "multiplex": "max" + }, + 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 = { # for QPU options + + "rydberg_level": 65, + "max_amplitude": 5.5, + "max_abs_detuning": 70.0, + + "dmm": { + "targets": [0, 3], + "weights": [0.5, 1.0], + } + }, + settings = { # for building options + "prioritize_speed": True, + }, + 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": [2]}}, + inputs={'t': Alloc(1, trainable=True)}, + instructions=[ + Assign(‘%0’, Mul(1.57, Load(‘t’)), + QuInstruct(‘x', Support(target=(2,))), + QuInstruct('dyn_pulse’, target_all(), Load(‘%0’), 1.0), + ], +) + +instructions =[ + Assign("%0", Call("mul", 0.5, Load("theta")), + QuInstruct("rx", Support(target=(0)), Load("%0")), + QuInstruct("dyn_interact", Support.target_all(), 2.5), +] +``` \ No newline at end of file From 031ee29e6a5a1e9cf543d58e1b8490cf1c6d5915 Mon Sep 17 00:00:00 2001 From: Kaonan Micadei Date: Fri, 11 Oct 2024 19:52:08 +0200 Subject: [PATCH 02/26] fix examples --- docs/examples.md | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/docs/examples.md b/docs/examples.md index 01df2c8..6b89f8e 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -30,13 +30,13 @@ Model( directives = { "dmm": { "targets": [0, 1, 2, 3], - "weights": "from_inputs", + "weights": "equal", } }, settings = {}, inputs = { "theta": Alloc(4, trainable=False) - "duration": Alloc(1, trainable=True, attrs={"time_parameter": True}) + "duration": Alloc(1, trainable=True) "omega": Alloc(5, trainable=True) }, instrunctions = [ @@ -69,20 +69,12 @@ Model( grid_type = "triangular", grid_scale = 1.0, ), - directives = { # for QPU options - "rydberg_level": 65, - "max_amplitude": 5.5, - "max_abs_detuning": 70.0, - + directives = { "dmm": { "targets": [0, 3], "weights": [0.5, 1.0], } }, - settings = { # for building options - "prioritize_speed": True, - "multiplex": "max" - }, inputs = { "duration": Alloc(1, trainable=False, attrs={"time_parameter": True}), "omega": Alloc(4, trainable=True), @@ -123,20 +115,12 @@ Model( (2, 3): 2.1, } ), - directives = { # for QPU options - - "rydberg_level": 65, - "max_amplitude": 5.5, - "max_abs_detuning": 70.0, - + directives = { "dmm": { "targets": [0, 3], "weights": [0.5, 1.0], } }, - settings = { # for building options - "prioritize_speed": True, - }, inputs = { "duration": Alloc(1, trainable=False, attrs={"time_parameter": True}), "omega": Alloc(4, trainable=True), From a84e07a4dc85f91dca3eb8c8de0f9eac962e3e9d Mon Sep 17 00:00:00 2001 From: Kaonan Micadei Date: Fri, 11 Oct 2024 19:53:41 +0200 Subject: [PATCH 03/26] fix example --- docs/examples.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/docs/examples.md b/docs/examples.md index 6b89f8e..534e40a 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -156,15 +156,9 @@ Model( directives={"dmm": {"targets": [2]}}, inputs={'t': Alloc(1, trainable=True)}, instructions=[ - Assign(‘%0’, Mul(1.57, Load(‘t’)), + Assign('%0', Mul(1.57, Load('t')), QuInstruct(‘x', Support(target=(2,))), - QuInstruct('dyn_pulse’, target_all(), Load(‘%0’), 1.0), + QuInstruct('dyn_pulse', target_all(), Load('%0'), 1.0), ], ) - -instructions =[ - Assign("%0", Call("mul", 0.5, Load("theta")), - QuInstruct("rx", Support(target=(0)), Load("%0")), - QuInstruct("dyn_interact", Support.target_all(), 2.5), -] ``` \ No newline at end of file From 6158bbe53822bab76551402334720227d916e7ee Mon Sep 17 00:00:00 2001 From: Kaonan Micadei Date: Fri, 11 Oct 2024 19:55:55 +0200 Subject: [PATCH 04/26] fix last example --- docs/examples.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/examples.md b/docs/examples.md index 534e40a..0d89cb8 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -149,16 +149,16 @@ Model( ```python Model( - register=AllocQubits( - num_qubits=3, - connectivity={(0,1): 1., (0,2): .5, (1,2): .5}, - ), - directives={"dmm": {"targets": [2]}}, - inputs={'t': Alloc(1, trainable=True)}, - instructions=[ - Assign('%0', Mul(1.57, Load('t')), - QuInstruct(‘x', Support(target=(2,))), - QuInstruct('dyn_pulse', target_all(), Load('%0'), 1.0), - ], + register=AllocQubits( + num_qubits=3, + connectivity={(0,1): 1., (0,2): .5, (1,2): .5}, + ), + directives={"dmm": {"targets": [2]}}, + inputs={'t': Alloc(1, trainable=True)}, + instructions=[ + Assign('%0', Mul(1.57, Load('t')), + QuInstruct('x', Support(target=(2,))), + QuInstruct('dyn_pulse', target_all(), Load('%0'), 1.0), + ], ) ``` \ No newline at end of file From 5197c31b4665921abfdff38abae4cdde9070b480 Mon Sep 17 00:00:00 2001 From: Kaonan Micadei Date: Fri, 11 Oct 2024 20:28:07 +0200 Subject: [PATCH 05/26] fix last example --- docs/examples.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/examples.md b/docs/examples.md index 0d89cb8..40a00a8 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -153,11 +153,18 @@ Model( num_qubits=3, connectivity={(0,1): 1., (0,2): .5, (1,2): .5}, ), - directives={"dmm": {"targets": [2]}}, - inputs={'t': Alloc(1, trainable=True)}, + directives={ + "dmm": {"targets": [0, 1]} + }, + inputs={ + 't': Alloc(1, trainable=True) + }, instructions=[ - Assign('%0', Mul(1.57, Load('t')), + # 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), ], ) From 7302c7bb821ad89147368d1323a2769cc384c2a0 Mon Sep 17 00:00:00 2001 From: Kaonan Micadei Date: Mon, 14 Oct 2024 16:32:59 +0200 Subject: [PATCH 06/26] add IR structure and purpose documentation --- README.md | 16 +------- docs/index.md | 86 +++++++++++++++++++++++++++++++++++----- docs/qadence2_stack.png | Bin 0 -> 151510 bytes 3 files changed, 79 insertions(+), 23 deletions(-) create mode 100644 docs/qadence2_stack.png diff --git a/README.md b/README.md index 688cb6b..879d1d2 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,3 @@ -# Qadence 2 IR +# Qadence IR -Qadence 2 Intermediate Representation (IR) components. - -## Installation -Installation guidelines - -## Usage -Usage guidelines - -## Documentation -Documentation guidelines - -## Contribute -Contribution guidelines +Qadence 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 the 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 IR allows digital and analog instructions to work together, extending its usability to the digital-analog paradigm. The static single-assignment simplifies differentiability when running simulations. diff --git a/docs/index.md b/docs/index.md index ef5de15..80ed611 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,12 +1,80 @@ -# "qadence2 ir" -## Installation -Installation guidelines +# Qadence2 IR -## Usage -Usage guidelines +# About +Qadence 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 the 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 IR allows digital and analog instructions to work together, extending its usability to the digital-analog paradigm. The static single-assignment simplifies differentiability when running simulations. -## Documentation -Documentation guidelines +## Compute Stack +Pasqal’s compute stack comprises four layers, as shown in Figure 1. A user defines the quantum computation using one of the frontends: Qadence 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. -## Contribute -Contribution guidelines +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 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 specific backend. The backend itself takes care of executing the computation on the hardware. + +It's important to note that the Qadence IR layer spreads over the full width of the stack, meaning that all frontends 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. + +![](qadence2_stack.png) + +## IR Structure +The idea for the Qadence IR is to provide an abstract neutral atom device model. + +Neutral atom devices usually rely on absolute values like laser power, atomic spacing in micrometres, 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 labels instead of fixed primitives (see 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. + +## Example +Below is an example of a simple analog algorithm represented in Qadence IR. + +```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), + ], +) +``` + +More examples can be found [here](https://github.com/pasqal-io/qadence2-ir/blob/km/docs/docs/examples.md). + + +## Challenges +As pointed out above, digital and analog algorithms diverge in how they handle register topology. Contrary to classical computing, where the resource allocation can be left to the OS to control, the quantum resources must be explicit in analog quantum computation. + +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. diff --git a/docs/qadence2_stack.png b/docs/qadence2_stack.png new file mode 100644 index 0000000000000000000000000000000000000000..31112b673061a1d8647dba3cc9c5461319da654a GIT binary patch literal 151510 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 z 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

8X8h z*RRonD^R(|RnEi?)c^**ez=uI5M5i~ua3+|&`pmZ_rWGZlZ8+E>N_oVY6kCkt0gQ| z1ql#69@nWXYPyqi=e=f5B%6`pekUb_vut~44!TNSI<)d9ibuuKBELjpD|xZsTU;7h z<3j(7XIY0w;LwD&3+Ip$^m4udX^J)gy8)Zhg!3gw{?3G`UQlB~u1n}kzA}Vdnoa#{ z5dL^ac6?;tv-^~52uo(QYWfsFrWT}!W)R2&!aj+^z?g1=c?M>|QOz~kMwF}@zd(qZ z;IR`lwY|F=Z`A#u1s1!vIvAyzm3xf5>sH2nylWJQuYpo5e5Dq3H&+sRu%+4)lUmx} z9qr`W<&`-6@2-3aNL4-k3_TU=2@*NRM0wUq3qW!tjypZQEId zHKnG)u19CE2q_r2X}TGXg-G;vkA9u+w`L7al)>5q+cXk(yBD$-UP|jU`$P@GT8Sa0 zjwd;DHDSSiZ=v4UCIcaTXK14gD$3N~CI7{-!o{B)f7(DsC4G6d^hP_Ip^bp{lc&p$ zQz^nBq8&^VI*js+!UcJjPyPGwWh-To&<2I>S z&1-Mpun;`p*5jACV5$=EOO}!2LSiG;R`%`VR?!T}7uUS*AzJMwEm36*p<{bF*Ndsn z;lpRuRC_9Ook~%LsO5^P^J*MeNxO<>k3OafYlaQDFMC==?3Ak#BU~z+2R^Kathovj z?msqWv>LEJ!?gBTk=>ZLyJ`dH2>f@9x#Dp>Bt)n8#Xy9fuj-$@m8C*9+A0izWCCPD zqXi6k2d9aqT6#Fc$Ei=dx*At#onq0Opp^ek{rNii@u_{F1JH zfgc4ojUq;Ct7M58G_=*;VP-%4vkeGAR0`B9=xp7FHp54q$uClEh#t{VO`gH z8JEHzTr7JQY>(%H0>I{LKdbbAuza}Ula9?gWbu6 z^TpBOVn9kB8Y*eU$)rg_amp6=7q!-%43$wBQ)yrB>gEzi9%{QUX#YZ!i!$T$6CWdN z0;CQJn&iR9DdJOg{m~Mi~37xJI{|KLYQhqlp)f`xL>aUE=IyMsE={~rc zmt&hz1=JxlWc}sBm3)PQ?w$KE=MXRCXZL&bR|SgpM0h|Y!)!%*6Xse5_FDO_OmC)n z#+$gbba`W^t#my-O+7KaqPGI^eLeD=w#J5C;bz$k2AkXT5iOH;hXG7O9DDgn#97V4 zt}dFh*KeeXdsakuBCiLIxlkxb-AzpqCTVVqYHe=3h=r;a}W27E2n zZF*r?I_?E(e$Lcsv{FZ_b(x=wu;Qu>e1)4pBQ(uF^QboSa~~rEPk>|aT2<^aX*Mz` zHNP%FOIWOH&iM5-^AZ{jB|6Oq)jxJPe;fLFO^*i1rtzt=&$G9;QJ|?w@(@NqlqIX1 zt)d)JYV59@U&3_>O|T3<%5{6y$Lz~7JhO$;6eCMOljkL3EsznOwus~rX(h1~fKpjU z)c}6%fidHH@#5EHu+7GRIf~+F^8OOAeTMiwBFlYmfj081+ zIPj_xbK6H=MLmoc2F_47`jubPAeg5dvu6(MJ>!07_9Bv41@al*SAz4x>Rw|`N`G|} zvxa!2(?`V6gs?r>Bt*cIPLUmr{MxLBAT1-Ptbd&S1S*uPxAB_#x}iPn79k0Xr?~t6 zQuc0yiYUhZ@`C}uhxQvGa2+1&am(3>4UIR-cv|KHdGF5Qft$#9|Ab!gquTTU*^|ja zAk4%0mPhgnq1DD#SH{DFe3G%2dEfFz5zXJ8TPy~-R04um#8YYFMn-nSKmyKon2QCB zpK2nC1q4t<8RK_G%JhZ-;9r@UsyVoadYQVRG2>;GB@4=iP;yqMh&akhqER%MZQxt;Z}Okw@ufJ z5ALsp`%azK7cGfLK{GSVj0%cpMu$W}bynpUcH=Xk^6+55soa~@HmRLSn$j-Id|c#e zbxL28C6HFVF)8hlZ)xe(n!L*(E%3%3b**f9xCL_PnyD)xGG)dJR9ambW$sFw&wHCQ z0!$=Btxr}!#9lZ85#OX>lGJ=tyS&5pH3#p)iwv1z-`CY*C_Wui_0yRtn^EPFm-hTA zxJ#Z?J#kH5s~Z!d)WtEQ2e%Wxo3O379$Ty2(6VOYxen9ZKN1-ZUpSSS5^{3b7%T1X z%`QwC@uBD#hS)Sp{!w{QofTxVSXu*;WAbY)GgDLfvkbBzEuXz8?J!E_9Z2L}ED?BI z3fZd|Mo^rF_pczQ5m0lcDg_!-A33U>BO+n_?lr0yMCA>uv0D0IG@<82dkkj|oDLkd zGWR2|ea2SagV3z1^i(Y&mLF6bWiWi|2gwpfJY)W9Wo(UWZG0`8$f7kmLwIPyl<^%C zGk2lU+^XeHrx#q!s-uazILZY`J%eZ=g9=GD1z~#)QN?Uiu!T=2x;FNf3p08wh*Cb) zT<6sqr!a2#uYC;hW0z}v(k7uoY|UEkDg2s*qpC;Bt1PQ;8tP_VvB05XcfeMe18Ft0 zKmc@| z2et$u#7QmK3$%Q*;fPXQ9i|a z25ybP$OmN;_<0X%D>FmqDBZY`mq!wE-D27Ywubjho81lz z%{&~L3T`(h?~R(Q;R$3Hr|@2BN#JpY-=#A?e&2hVLdRnd-t;%L} zwntdu+n8d&V7IJ3zufPO$elb4DHiE%{bI%V9n@J_kx?*VPovHYPM{xj+8*I->k8T@ zw&n*#v5_9<2lt*dFpg7drw#_+3 z5;nbWxj81?Y%nR+;~;(*@%EBx=!b{W>`wI}azEMYRgX-F!t#T)zlyY%obNpuOkbEt z8#{P;vw4!Km^%A4dF}Xg{X>mgrgurXDW^JHtt4`amX%#cD5c6$3T9W;p|q9zDL8pO zc}Nl+xYUc! zv0E|7h0;B8G;jpnDIDuhxnA#+r#xaSy=SPIp1pQ$GKF&CB|TL7muEanYjGLH{0)LHiCe(=&KPcA<$aeh+P zX88Nj9v9`PMtM$yU!1VK(R>5({!$Z*eo)+s6IQ$Uz?a)ZH`MzcLzpMXbWEFnsHM(~ zJM0NIV^$#y8yd{FGkP5TMcrvCb-2^$V2%{TuDP~-6N+{iiDaCHwyBwgT$9qd`-QZs zd}dQeq%|Hl6%6!HM<%6?(5tkz-24-TdUPkH)Q0O6ZF!#I=w#+|qgpZ_xOzN=5 z)Cld(hI%FpV)bz5qtoW52MN@;O4^C^+~`N6Lg5W#q#qt(y!B@gSbpek!=vDkICDKB zORv;1gKP*BoQ1PR6msUGM3Gc9B_$JL7S9U_?W!I|+Kybu>q){Tou;eD#S?*uMu%@( ztwq+*YU3^hQ1C?#i=+Y89)k^vx6$WXW3gLWq#LEZuNIR&<@{)3ji~p-Q*HJJa)FOZ ztUJBw$rA-18eEP$qbF71Eab-RYYuah#lfWaK?!)%$b;9a8k7EU6^}m*ofatNKpU(L zJ2Ddzt}9}sURIL0?;ozD*Z)dKM?NS7sNmAt(J$Dpf-|GW+daf4SP(mvmGZb2L5LN| zNfg77rd!S`)NVr9b&VzKHYJC>>HZv|4dG-kg#L}R$YmmJkW9>1-#9H`CB!4BoQo5N zoKRMQc zg1wma06i-9s;i~$a#}?JGhsjB+NiQJ^@ZTZ{QuY9bw)Lrv~3qbWl?cgq)JhcBGQzm zk)jBQbdWAZB8&7UCDe_$SZE5!B1jVv3B8BVR7#`?NR{3Ri6jsVC6v66DNOs zU-D~Co-*@XbGMnf=NjepBt4DuZlAAUFO>k<-AV@?!+!Zw;<1=~%CU3pET)etPe4f4 zqo$P>m=@z}b{q;uo*DMFv(Xu~nMX6CFr8WM$pt=#nDe+Z1Q_FNL?B#$KZ%Gf2w1NS z*PziZ%5?&bv**!)_n;f=BupC|P^?$aJFd(hQRs}$&^#>Rlb3ahoqN!mr*2umJ3Q%z zL&I4|ANTNQ&w2Ol)k=~`=eq<=_jf6rHcO~9y1&eQZQ7mxIp9zKo+^|t2(6K*Q*1^D zt>mQUSuESOs&W3~2m}pB6*dxT4(?y#hJS2L_Qyol#wYaL__XxGgT{OHt$p-<;>yxuqz8(C7?(n%4IN$v1D99!>=$(-Z)Hsma^SsH2hXX0@|uB_EMVp=d@Q)E=dW{~gvE{-ziRBZ(Ukus-sa|7gVRk+h{#xb zbuch*ab6=)DhI>q@V)(~c(wxvZv$`LOPrH|eBV$VU+AMpkMdntUkqA$czDQqPdl=j z=$jLd&OX`Mv~T|ad7#1j>dt6>m%s^Bg*pah{UZ3jzzCHX^B>Q~gaflQg%DxQd;f6* zm4t0!9g_?^g7?#Ieei#OWVe=G#CBzDS6`^?-%i7_{m-t2*|o|4U;m;was&?WT@o7< zffEg!buVoc-c0?jmysko%8~diXOm$sy|IJ;%W0~T9)dq$JX0NHa zR+w))Y6K}{!m>{{K8BrMtl2LW`_eLTTadR4UlgDWIf22~enRH)mH9MYzjig`J2DSR z>6bOhlR-hV=oS2$-FuL>(ONgv=A5k%C4~eK8A->G26RaYy0{4A6flkm0+HjFJ#fL{kA!5!#t%T@K!GDnr%p!_MByBza?f^{PL5dg90^X~{-Iy1B~v=rR05ZBc0Z3U!NBC?%5 z?*Jr*hMuRt5A(iuP?Oo{dii2%L8^pQ;}ghoyB^4?SQuDbFh99}8%BVohz+WCR3QCu zq)C`ok}SY7N6sWhX+qOfBLHSI(l>S(scs;JC;w(9GZO#dX}{gS15_ZH<_sM^C{^r(OfK7GlIDUP8ZP8B; zUTIugeo9L7YSem3wZgrH4^&>*_493j^M?K?|2-h8lLrlNii-n$Z)4_XRVZQKhK7~< z@S)8Bza>Hu8>{Fy=z-Cf#K0G5z<#~XW)e24|5Ic5dbK|znlGhxhv?eyJSHXRY`Un} zh}Ux^-&I6%33y+oynjke+yz_N#pmrj@}$3X8!-{+-ZjR1i!*INC%I@5E53G;%-0&? zeo%v8zK0ocxNp7E&(=nE$~ieo5$P=8MMJ4%ueQ~~JLOC@+)$N_q_iY8H<%I+Np%|7 z^LS4;P35VhU?_{I7Qw&|A$=U=d&a=_2VLV&hsL1aJ*idIJK92O6)fpgxex5g@_Nun zy?fz~iq+e7x>ReO`ltME58sOkA?E58xr&h1JW*sY|$8fPYU&y&|?y>2QbU>Ktb|v#AFcT1$UIIY(7pg zQ#(z8(i7Xl$M1R(((cuU^wUc-_2`W6D*Z9Hn(G|eLCMBu>S@|IzB?~3V56y&OkfC2 zV!G|@|BLT*KQT6Um zsCZz|kXvr2Od0bjf@lD`#jy~FJQ8W3Vo@Ng3B>qj!~&(lenq1!^`T;s;9ZVj@D0~X zx+for|0XPYO6^(w!wWWg;LS(Ru4&p|i+-jX4X-+0$rA6z2#_9C&7-YjU|VkOEqYUBtzwtKA zW(?W@KN$&}1#vy`-5C9W3tUMF-sG_|VDsAdL(4s;Rq#qd%RQArLCyxqk|E_FvOcRS zr{t7~80Pt$Cz#kKx*0xSFNxOo{Oe3hk|%^uCh(3+Bf2Nc!t|5*m%n#}l2(uD`FfN4 z2L}8;z>13{r(2Rb^_Rxq)6#NAwzO?i1p=ZWdry&oLd)6`!@7RUip>erR#=s!Ab`?_ zJ{8M((4fts&+Rrh2+4F$WvCSnL1u^ArpIeyQ6uF6wlFQ|&gw@Qy5?Y^Mur(IYjKdx z7T|2j*U%t$w)1;0A;S*dbEcSZ)@+)^+-m6(7}&wVp>qB+>2Ob{r^Pp!RcxSTN29?6 z{1^L(POSvyXnrm9a*~B-z08a3?Ccqj3n0+MYDRMSEl*VrvV+=g%A3*OzOwG>_4-F4 z4JD&gi9KP}} zBMtav%tnnz!B@>>2r+Am_3xkXf&;OyBKMYY4tUk|8#o-!#{YXVhey$B4?|_Cm$@Tk zd83Q1CGngL>~xl%=dY^#JSd-Afx}d^LyFwA%%X5nm4n<#7u*+)YS#num4Rj=yT-qm zj7ul$Uk~Xe*t>r?=3%Wth`Vkc#2nR@#busId@xcoU(sh#Awuaps&Aa9l^HK7);)?R zXomwA=Zpy-o385{JbelgKJ)4@>i%UrH9P;cX=UB(*Sk7>3qMXyFv>A&`X%^&$HuUw zCalIZYs#*ytU$w+zrR_{Lh9Dg?3$?N*&4#OS}OEAf~~m&Zic1pLl8 zyo|Z+WT)9JOp!b?KDR7Wa&knts!6FU@ahxYpUxM})S1{me+JVR4Er+$eDin-mC^p% zNkhegxQ_5fd-XOTng5QL*HS9oHgn=(5uLIuQ5GJ5ahGls2XmmXeM9eYV(SLndsAwW zm;NFbd~UFsH*hga6^|t<%(Lc^m3_-f1D{-Ys=cG*H|@!!9^DEX2N?LM1AiT1~b8S0hu&#|pT@X+Z98->zX- zlly91EMX6C8O#Dl4W2acE@r5&uV1LeZFpP{Og~HLz*QHOJJ=v&r(>^I(d^JD#U)x( zGqZ^&mh#74ocx8m%a5ug9r0ctjSv(O0+40WQfx19jWyjS8vueTMj9{-Sr>_|6mANM zNsq7~5iQ5Z_H#XoWmdpvSZ&ERRG!{(_>0y>S6skXQ|r0@EF+n%OcWtyuxxV-I5w5d zdxVfDVZAbcon?4r-C~fmxMqz@lB0;_w$AT?em=n0n;5tnx_>;eOgjC76hQiy>mV#8Ux-dd-pQ^8l&q(0#+> zTit&gLz5h^WRiWO^kgh)GhKE?Zw8<=9~V$SfSQ_{&ea!}csZ;Ov~9}8CnV@^u)D24 zfRDv;fPn?8AGTD?D8)EgmXcwtr``PBtILqleTatt=^qMbX?)_Fh|{*viFN!1Gh zOnoao4e*&7T&r1q!JVsiH>yVCSBP{o%79PeHuGTpcCTwTJs(SKa^UAoAD6`nNJb#B zxO2kNx#CH0MX=gAkivo!s3Aaxp-{bul(4&-V90o9Hm~${`BV|BX^c@iMD7B_Aj?-hZIPFp~_|1>$~+cqrcM#{rQ z%1ArE2PMC>?thknv@x>a0&8(~VgktvM^ruf*Rd5;FeA7=RM@(fDC6togO15`8}JS~ z!W+r`33y_Imj~6SkZVd=qEj4Y__f%(7#SU!9LDmu7>1CjHoDLw5_S%mCH11@$uFHqNDJoDXD_BiJ_`$Z{UP>x3%R!)@T7utY=WHFbD(!H-0=- zu(E24=Yn<(;q)`K9xmD@aYtu7AAiy_B)Iu~RzA@FU-=#nTCHJUwH7$HW&x+4xGeYE zbH}~{lovD5XZ-=W~u~1ay%@?)85m= zJW%S4K`a$-5^Cy(<@`w43S>AZOQ^FcQ#8NEdIhqtqXtmK4NR6Nm0%xMN~x-ni>+L# z@VVK@(9z%H`<^+9dl}i=Rfm#DOT)i}y}pon7C5T-MRw)Iru(rBm$>xWwElU){Hb5> zs1%o$s;H~0e|51VUbqM%BINe#JRIW9;6Pd?Bi5;PC4P`@+RXah3jKZ@d;Sz(dpVjh z%X-11?Mi3$E2Sh=H8r)c95$A2FwA2F3PV&ggtJOi&iLur+0C99aoKUCi&Z`YU(NYb zy-B7Xy(v*V-~epDz7m$b>pn;Uh1l2K(cyOW?nDGgG&h0N3jZ9{oIUPyHFI-B2-Qbw zkf)06ptVf52a5z^tBWN8YJM&t@8$ldM`c^#Y_O)4HTJ_Q#HclN);3YDPb+7}e@O-x zc}y%XEWJ5aWg@8|$ybaV%uu`?(bDP)Hj~}RBG9HKNeUE|pElRba^%iB9;wJkb@$3~ zXu#T1eY1lhGTx}S?gOJ&;D-*ctzlBIuGRa;CnUhcF!-(MdI`^_uD3pqs*>~z(Nq1N z4&YW{hlwf?9Kkn?D*cTt1@8{1FzW+HyPB1|`L0idd5ptTkxN616=<*e zth_3Aj^RO8GyAeD_&5i0^g`vu#~7GcSX5i#3vLa?=f*2N+CtGC-SAniy*xu|WZB%z|H12C6)tH~oO%3XJ>mS#C@CNjR z(lzjHEU~j4p9(~olCIiU+LYQm_{cHbPM5XgpR>ZF;C6kXgOP{WPl>H zRDwzMEKd<2H@h|b7@Tck-$iK~ik}pAQThou+n07x+J@pMg0?ziOU6i(=_(@?G zrJsPaeQ6h^Z76dc`UyDOmjIMV`;o!zheA`h5AFeeYRXzy JaxYum{U7j*R4M=f literal 0 HcmV?d00001 From 0bfc4c7d2fd13d67a120391d39c8f42a88fad85f Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 29 Nov 2024 08:49:17 +0100 Subject: [PATCH 07/26] Fix wrong repo mentioned in README License --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 571f956..bf91bb5 100644 --- a/README.md +++ b/README.md @@ -56,4 +56,4 @@ Before making a contribution, please review our [code of conduct](docs/getting_s ## License -Qadence Expressions is a free and open source software package, released under the Apache License, Version 2.0. +Qadence 2 IR is a free and open source software package, released under the Apache License, Version 2.0. From 714348b7dc54ffda144317b8eb1c1ebfe5c836ca Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 29 Nov 2024 10:27:12 +0100 Subject: [PATCH 08/26] Add titles to API pages --- docs/api/factory.md | 2 ++ docs/api/factory_tools.md | 3 ++- docs/api/irast.md | 2 ++ docs/api/irbuilder.md | 2 ++ docs/api/types.md | 2 ++ 5 files changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/api/factory.md b/docs/api/factory.md index 48fe167..f801a18 100644 --- a/docs/api/factory.md +++ b/docs/api/factory.md @@ -1,3 +1,5 @@ +# Factory + !!! warning This page is under construction. diff --git a/docs/api/factory_tools.md b/docs/api/factory_tools.md index f55ec98..552a6cd 100644 --- a/docs/api/factory_tools.md +++ b/docs/api/factory_tools.md @@ -1,5 +1,6 @@ +# Factory Tools + !!! warning This page is under construction. - ::: qadence2_ir.factory_tools diff --git a/docs/api/irast.md b/docs/api/irast.md index 3f3bc7c..0d7a891 100644 --- a/docs/api/irast.md +++ b/docs/api/irast.md @@ -1,3 +1,5 @@ +# IRAST + !!! warning This page is under construction. diff --git a/docs/api/irbuilder.md b/docs/api/irbuilder.md index 1227aa1..d96e910 100644 --- a/docs/api/irbuilder.md +++ b/docs/api/irbuilder.md @@ -1,3 +1,5 @@ +# IR Builder + !!! warning This page is under construction. diff --git a/docs/api/types.md b/docs/api/types.md index 37bbcc5..6a24b9c 100644 --- a/docs/api/types.md +++ b/docs/api/types.md @@ -1,3 +1,5 @@ +# Types + !!! warning This page is under construction. From 3f99b9a2eea79bec083025357ece2c0bdc49c4c8 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 29 Nov 2024 11:54:04 +0100 Subject: [PATCH 09/26] Update docstrings in irbuilder.py --- qadence2_ir/irbuilder.py | 55 +++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/qadence2_ir/irbuilder.py b/qadence2_ir/irbuilder.py index a9fb2a4..d39b17e 100644 --- a/qadence2_ir/irbuilder.py +++ b/qadence2_ir/irbuilder.py @@ -1,3 +1,11 @@ +"""Defines an ABC for implementing IR builders. + +This module defines the interface to be used by Qadence 2 IR front-ends to compile to IR. A front- +end must implement an `IRBuilder` for the front-end specific input type, so that +`ir_compiler_factory`, defined in `qadence2-ir.factory` can generate a compiler function specific +to the front-end. +""" + from __future__ import annotations from abc import ABC, abstractmethod @@ -8,32 +16,61 @@ class IRBuilder(ABC, Generic[InputType]): - """A base class to help create new input forms for Qadence2-IR. + """Defines the interface of Qadence 2 IR builders for building IR code from front-end input. - Implementing this class allows the function `ir_compiler_factory` to generate - the `compile_to_model` function for a new custom input format. + An `IRBuilder` implementation can be used by the `ir_compiler_factory` function, defined in + `qadence2-ir.factory` to build a compiler function that generates IR code from a specific + input type as created by a Qadence 2 front-end. + When subclassing this class, specify the `InputType` that is expected for the implementation, + i.e. the object type that the specific front-end generates. + This class is responsible for extracting information about the register, directives, other + settings and the AST from front-end generated input. """ @staticmethod @abstractmethod def set_register(input_obj: InputType) -> AllocQubits: - """Used by the factory to define/extract/infere the qubits register primarily from the - `input_obj`. + """Returns a register definition based on an input object. + + Args: + input_obj: Input for the compilation to IR native to a specific front-end. + + Returns: + A register definition that is extracted or inferred from `input_obj`. """ @staticmethod @abstractmethod def set_directives(input_obj: InputType) -> Attributes: - """Use by the factory to set the QPU directives from the input.""" + """Returns directives based on an input object. + + Args: + input_obj: Input for the compilation to IR native to a specific front-end. + + Returns: + A specification of all directives that could be extracted from `input_obj`. + """ @staticmethod @abstractmethod def settings(input_obj: InputType) -> Attributes: - """Used by the factory to define general settings for simulation and data purposes.""" + """Returns settings based on an input object. + + Args: + input_obj: Input for the compilation to IR native to a specific front-end. + + Returns: + A specification of all settings that could be extracted from `input_obj`. + """ @staticmethod @abstractmethod def parse_sequence(input_obj: InputType) -> AST: - """Used by the factory to parse a sequence operations acting on the qubit - register (e.g., quantum circuits, pulse sequences, etc). + """Returns an AST definition that represents the operations in input object. + + Args: + input_obj: Input for the compilation to IR native to a specific front-end. + + Returns: + An AST definition that represents the operations defined in `input_obj`. """ From ccb3d7435bf313b796c588105d7d7b5cacbbeb60 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 29 Nov 2024 11:55:18 +0100 Subject: [PATCH 10/26] Fix minor spelling mistake --- qadence2_ir/irbuilder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qadence2_ir/irbuilder.py b/qadence2_ir/irbuilder.py index d39b17e..eb7278a 100644 --- a/qadence2_ir/irbuilder.py +++ b/qadence2_ir/irbuilder.py @@ -72,5 +72,5 @@ def parse_sequence(input_obj: InputType) -> AST: input_obj: Input for the compilation to IR native to a specific front-end. Returns: - An AST definition that represents the operations defined in `input_obj`. + An AST definition that represents the operations defined in an `input_obj`. """ From d5c59f33c9a176d90ef23389f6fe779eb3c02dd9 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 29 Nov 2024 11:55:53 +0100 Subject: [PATCH 11/26] Remove warning from IR Builder page --- docs/api/irbuilder.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/api/irbuilder.md b/docs/api/irbuilder.md index d96e910..e9faa9f 100644 --- a/docs/api/irbuilder.md +++ b/docs/api/irbuilder.md @@ -1,6 +1,3 @@ # IR Builder -!!! warning - This page is under construction. - ::: qadence2_ir.irbuilder From 63646762b130dabcabf0aa13265ff564ba1ba440 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 29 Nov 2024 14:28:27 +0100 Subject: [PATCH 12/26] Update docstrings in types.py --- docs/api/types.md | 3 -- qadence2_ir/types.py | 89 +++++++++++++++++++++++++++++++------------- 2 files changed, 63 insertions(+), 29 deletions(-) diff --git a/docs/api/types.md b/docs/api/types.md index 6a24b9c..de2fc1b 100644 --- a/docs/api/types.md +++ b/docs/api/types.md @@ -1,6 +1,3 @@ # Types -!!! warning - This page is under construction. - ::: qadence2_ir.types diff --git a/qadence2_ir/types.py b/qadence2_ir/types.py index fde8777..13fd668 100644 --- a/qadence2_ir/types.py +++ b/qadence2_ir/types.py @@ -1,16 +1,38 @@ +"""Definition of all types supported in the IR. + +This module is the defacto definition of the IR. A unit of IR code can only consist of instances of +the classes defined in this module. An IR `Model` defines a complete set of instructions for a +backend to execute as a task. The instructions a `Model` can take can be divided into two groups; +classical and quantum related instructions: + +- Classical: + - `Alloc`: Allocates memory for holding variable values. + - `Assign`: Assigns a value to a variable. + - `Load`: Retrieves a value from a variable. + - `Call`: Executes a classical function. +- Quantum: + - `AllocQubits`: Allocates qubits for the computation. + - `QuInstruct`: Executes a quantum instruction. + - `Support`: Defines on which qubit(s) and with what role, target or control, a `QuInstruct` + should act. +""" + from __future__ import annotations from typing import Any, Literal class Alloc: - """ - Reserve one slot for a scaler parameter in the environment and n-slots for an array. The type of - the parameter is defined by the backend. + """Memory allocation for a parameter that is either a scalar value or an array of values. + + With this class an allocation of memory is made for a parameter that is a scalar value, if + `size = 1` or an array of values of length `n` if `size = n`. The type for the allocation is + defined by the backend, therefor it is not defined in the IR. Args: - size: Space occupied by the parameter. - trainable: Flag if the parameter can change during a training loop. + size: Number of values stored in the parameter, if `size = 1` the parameter is a scalar + value if `size > 1` the parameter is an array of values. + trainable: Indicates whether the parameter can be changed during a training loop. attributes: Extra flags and information to be used as instructions/suggestions by the backend. """ @@ -36,7 +58,12 @@ def __eq__(self, value: object) -> bool: class Assign: - """Push a variable to the environment and assign a value to it.""" + """Assignment of a value to a variable. + + Args: + variable_name: The name of the variable to assign a value to. + value: The value to be assigned to the variable. + """ def __init__(self, variable_name: str, value: Any) -> None: self.variable = variable_name @@ -55,7 +82,11 @@ def __eq__(self, value: object) -> bool: class Load: - """To recover the value of a given variable.""" + """Instruction to load the value of a variable. + + Args: + variable_name: The name of the variable to load. + """ def __init__(self, variable_name: str) -> None: self.variable = variable_name @@ -71,7 +102,12 @@ def __eq__(self, value: object) -> bool: class Call: - """Indicates the call of classical functions only.""" + """Instruction to call a classical function. + + Args: + identifier: The identifier of the function to call, i.e. its name. + args: The arguments that the function should be called with. + """ def __init__(self, identifier: str, *args: Any) -> None: self.identifier = identifier @@ -94,14 +130,15 @@ def __eq__(self, value: object) -> bool: class Support: - """Generic representation of the qubit support. For single qubit operations, a multiple index - support indicates apply the operation for each index in the support. + """Instruction that specifies the target and optionally control of a `QuInstruct`. - Both target and control lists must be ordered! + Generic representation of qubit support, specifying a target and control for a quantum + instruction. For single qubit operations, a multiple index support indicates apply the + operation for each index in the support. Both target and control lists must be ordered! Args: - target = Index or indices where the operation is applied. - control = Index or indices to which the operation is conditioned to. + target = Index or indices of qubits to which the operation is applied. + control = Index or indices of qubits which to which the operation is conditioned to. """ def __init__( @@ -136,7 +173,7 @@ def __eq__(self, value: object) -> bool: class QuInstruct: - """An abstract representation of a QPU instruction. + """Instruction to apply a quantum operation to one or more qubit(s). Args: name: The instruction name compatible with the standard instruction set. @@ -171,14 +208,13 @@ def __eq__(self, value: object) -> bool: class AllocQubits: - """ - Describes the register configuration in a neutral-atoms device. + """Allocation of qubit in a register of a neutral-atom QPU. Args: - num_qubits: Number of atoms to be allocated. - qubit_positions: A list of discrete coordinates for 2D grid with (0,0) position at center - of the grid. A list of indices in a linear register. An empty list will indicate the - backend is free to define the topology for devices that implement logical qubits. + num_qubits: Number of qubits, i.e atoms, to be allocated. + qubit_positions: A list of discrete coordinates for 2D grid, where (0,0) is the position at + center of the grid. An empty list will indicate the backend is free to define the + topology for devices that implement logical qubits. grid_type: Allows to select the coordinates sets for 2D grids as "square" (orthogonal) or "triangular" (skew). A "linear" will allow the backend to define the shape of the register. When the `grid_type` is `None` the backend uses its default structure @@ -238,14 +274,15 @@ def __eq__(self, value: object) -> bool: class Model: - """Aggregates the minimal information to construct sequence of instructions in a quantum device. - The structure is mainly focused in neutral atoms devices but its agnostic nature may make it - suitable for any quantum device. + """Aggregates the minimal information to construct sequence of instructions to execute on a QPU. + + This class defines a unit of IR code. The structure of the class is mainly focused in neutral + atoms devices but its agnostic nature may make it suitable for any quantum device. Args: - register: Describe the atomic arrangement of the neutral atom register. - instructions: A list of abstract instructions with their arguments with which a backend - can execute a sequence. + register: Describes the atomic arrangement of the neutral atom register. + instructions: A list of abstract instructions with their arguments that a backend can use + to execute a sequence. directives: A dictionary containing QPU related options. For instance, it can be used to set the Rydberg level to be used or whether to allow digital-analog operations in the sequence. From a8666ba1beb447a102de794481847fd08a10055a Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 29 Nov 2024 14:45:39 +0100 Subject: [PATCH 13/26] Update docstrings in factory.py --- docs/api/factory.md | 3 --- qadence2_ir/factory.py | 15 +++++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/docs/api/factory.md b/docs/api/factory.md index f801a18..2558776 100644 --- a/docs/api/factory.md +++ b/docs/api/factory.md @@ -1,6 +1,3 @@ # Factory -!!! warning - This page is under construction. - ::: qadence2_ir.factory diff --git a/qadence2_ir/factory.py b/qadence2_ir/factory.py index ee6e791..3e7e08b 100644 --- a/qadence2_ir/factory.py +++ b/qadence2_ir/factory.py @@ -1,3 +1,10 @@ +"""This module defines a factory method that creates a compiler function based on an `IRBuilder`. + +The compiler function, that can be generated using the factory, should be used to to compile a +certain type of input, based on the front-end that is being used, to IR code. This is the first +step of compilation, which is followed by a compilation from IR to the targeted backend. +""" + from __future__ import annotations from typing import Callable @@ -9,11 +16,11 @@ def ir_compiler_factory(builder: IRBuilder[InputType]) -> Callable[[InputType], Model]: - """Use an IRBuilder[InputType] to create an IR compiler function that converts an input of type - `InputType` and returns a Model. + """Constructs an IR compiler function for a specific input type by using an `IRBuilder`. - The IR compiler must be named 'compile_to_model' by convention to ensure accessibility to other - engines in the framework. + The factory function uses an `IRBuilder[InputType]` to create an IR compiler function that + converts an input of type `InputType` and returns a Model. The IR compiler must be named + 'compile_to_model' by convention to ensure accessibility to other engines in the framework. Args: builder: A concrete implementation of the generic class `IRBuilder` for a particular From 1d631d908f9b4963c068445beec35681385bc07f Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 29 Nov 2024 15:01:16 +0100 Subject: [PATCH 14/26] Fix spelling mistake in returns header --- qadence2_ir/factory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qadence2_ir/factory.py b/qadence2_ir/factory.py index 3e7e08b..26f776e 100644 --- a/qadence2_ir/factory.py +++ b/qadence2_ir/factory.py @@ -26,7 +26,7 @@ def ir_compiler_factory(builder: IRBuilder[InputType]) -> Callable[[InputType], builder: A concrete implementation of the generic class `IRBuilder` for a particular `InputType`. - Return: + Returns: A function that compiles an `InputType` object to the Qadence-IR (`Model`). """ From bdf276659602290614a93a71a7e7edb0928fd1a8 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 29 Nov 2024 15:05:51 +0100 Subject: [PATCH 15/26] Fix syntax issue in Support docstring --- qadence2_ir/types.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qadence2_ir/types.py b/qadence2_ir/types.py index 13fd668..f18b0e0 100644 --- a/qadence2_ir/types.py +++ b/qadence2_ir/types.py @@ -137,8 +137,8 @@ class Support: operation for each index in the support. Both target and control lists must be ordered! Args: - target = Index or indices of qubits to which the operation is applied. - control = Index or indices of qubits which to which the operation is conditioned to. + target: Index or indices of qubits to which the operation is applied. + control: Index or indices of qubits which to which the operation is conditioned to. """ def __init__( From ce428cad86b46aa918f5a7c4c1edbf93f8352fb2 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 29 Nov 2024 15:38:50 +0100 Subject: [PATCH 16/26] Update docstrings in factory_tools.py --- docs/api/factory_tools.md | 3 -- qadence2_ir/factory_tools.py | 56 +++++++++++++++++++----------------- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/docs/api/factory_tools.md b/docs/api/factory_tools.md index 552a6cd..48a10a3 100644 --- a/docs/api/factory_tools.md +++ b/docs/api/factory_tools.md @@ -1,6 +1,3 @@ # Factory Tools -!!! warning - This page is under construction. - ::: qadence2_ir.factory_tools diff --git a/qadence2_ir/factory_tools.py b/qadence2_ir/factory_tools.py index f1a6f0a..629864d 100644 --- a/qadence2_ir/factory_tools.py +++ b/qadence2_ir/factory_tools.py @@ -1,3 +1,9 @@ +"""Tools to process an `AST` as used by the compiler factory in `qadence2-ir.factory`. + +This module defines a collection of functions that manipulate an `AST`. Using these AST manipulation +tools the factory function in `qadence2-ir.factory` can build the instruction list from a given AST. +""" + from __future__ import annotations from functools import reduce @@ -8,23 +14,23 @@ def filter_ast(predicate: Callable[[AST], bool], ast: AST) -> Iterable[AST]: - """Filter the elements of the AST according to the `predicate` function. + """Filters the elements of the AST according to the `predicate` function. Args: - predicate: A function to check if a specific property is present in the `ast`. - ast: A parsed tree containing the sequence of instructions to be added to the `Model`. + predicate: A function that checks if a specific property is present in the `ast`. + ast: A parsed AST containing the sequence of instructions to be added to the `Model`. - Return: + Returns: An iterable and flattened version of the AST that contains the selected elements. Example: - ``` - >>> ast = AST.binar_op("/", AST.numeric(2), AST.callable("fn", AST.numeric(3))) + + ```python + >>> ast = AST.div(AST.numeric(2), AST.callable("fn", AST.numeric(3))) >>> list(filter_ast(lambda x: x.is_numeric, ast)) [AST.numeric(2), AST.numeric(3)] - ```` + ``` """ - # TODO edit example: binar_op is not available in AST if predicate(ast): yield ast @@ -37,18 +43,18 @@ def filter_ast(predicate: Callable[[AST], bool], ast: AST) -> Iterable[AST]: def flatten_ast(ast: AST) -> Iterable[AST]: - """Returns an interable and flattened version of the AST. + """Returns an iterable and flattened version of the AST. Args: ast: A parsed tree containing the sequence of instructions to be added to the `Model`. - Return: + Returns: An iterable and flattened version of the AST. The arguments of operations/functions will appear before the operation/function. Example: - ``` - >>> ast = AST.binar_op("/", AST.numeric(2), AST.callable("fn", AST.numeric(3))) + ```python + >>> ast = AST.div(AST.numeric(2), AST.callable("fn", AST.numeric(3))) >>> list(flatten_ast(ast)) [ AST.numeric(2), @@ -74,7 +80,7 @@ def extract_inputs_variables(ast: AST) -> dict[str, Alloc]: Args: ast: A parsed tree containing the sequence of instructions to be added to the `Model`. - Return: + Returns: A dictionary with the variables names as keys and their respective allocation instructions as values. """ @@ -83,11 +89,11 @@ def extract_inputs_variables(ast: AST) -> dict[str, Alloc]: def to_alloc(inputs: dict[str, Alloc], ast: AST) -> dict[str, Alloc]: - """If the `ast` is an input variable, add it to the inputs to be allocated - if not present yet. + """If the `ast` is an input variable, add it to the inputs to be allocated if not present yet. Args: - inputs: A dictionary containing pairs of variables and their allocation instructions. + inputs: A dictionary containing pairs of variables and their allocation instructions, which + are already allocated. ast: A parsed tree containing the sequence of instructions to be added to the `Model`. Return @@ -107,13 +113,12 @@ def to_alloc(inputs: dict[str, Alloc], ast: AST) -> dict[str, Alloc]: def build_instructions(ast: AST) -> list[QuInstruct | Assign]: - """Converts a sequence of instructions in the AST form into a list of Model - instructions. + """Converts an AST into a list of `Model` instructions. Args: ast: A parsed tree containing the sequence of instructions to be added to the `Model`. - Return: + Returns: A list of quantum operations and temporary static single-assigned variables. Temporary variables store the outcomes of classical operations and are used as arguments for parametric quantum operations. @@ -131,12 +136,11 @@ def to_instruct( memoise: dict[AST, Load], single_assign_index: int, ) -> tuple[list[QuInstruct | Assign], dict[AST, Load], int]: - """Add the `ast` to the `instructions_list` if `ast` is a classical function - or a quantum instruction. + """Adds the `ast` to the `instructions_list` if it is a `Call` or `QuInstruct`. - When the `ast` is a classical function, it uses the `single_assign_index` to - assign the call to a temporary variable using memoisation to avoid duplicated - assignments. + When the `ast` is a classical function, it uses the `single_assign_index` to assign the call to + a temporary variable using memoisation to avoid duplicated assignments. If the `ast` is a + quantum instruction, the instruction will be added to the instruction list. Args: ast: A parsed tree containing the sequence of instructions to be added to the `Model`. @@ -147,8 +151,8 @@ def to_instruct( single_assign_index: The index to be used by the next temporary variable assignement. Tempmorary variables are labled from "%0" to "%n". - Return: - A tuple consists of an updated list of instructions and assignments, a dictionary of pairs + Returns: + A tuple consisting of an updated list of instructions and assignments, a dictionary of pairs of AST objects and temporary variables, and the updated index for the next assignment. """ From 5f381646fb854cdc370aa2c6d87562e526bacbc3 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Mon, 2 Dec 2024 15:39:01 +0100 Subject: [PATCH 17/26] Update docstrings in irast.py --- docs/api/irast.md | 3 -- qadence2_ir/irast.py | 99 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 78 insertions(+), 24 deletions(-) diff --git a/docs/api/irast.md b/docs/api/irast.md index 0d7a891..3b38975 100644 --- a/docs/api/irast.md +++ b/docs/api/irast.md @@ -1,6 +1,3 @@ # IRAST -!!! warning - This page is under construction. - ::: qadence2_ir.irast diff --git a/qadence2_ir/irast.py b/qadence2_ir/irast.py index 681582a..1a40fe3 100644 --- a/qadence2_ir/irast.py +++ b/qadence2_ir/irast.py @@ -1,3 +1,11 @@ +"""Definition of the abstract syntax tree (AST) for Qadence 2 IR. + +This module defines the abstract syntax tree (AST) in Qadence 2 IR. The AST is used in the front- +end to IR compilation. Implementations of `IRBuilder`, defined in `qadence2-ir.irbuilder`, +translate front-end code to the AST defined here. Then, the tools in `qadence2-ir.factory_tools` +can be used to manipulate an `AST` instance and build valid IR instructions from the AST. +""" + from __future__ import annotations from enum import Flag, auto @@ -9,24 +17,24 @@ class AST: - """A class to keep a clean version of the instruction sequence to be converted - into a list of Model instructions. + """Represents an instruction sequence as an abstract syntax tree (AST). - The initilization of this class must be done using the specific constructors. + The initialization of this class must be done using the specific constructors. Constructors: - AST.numeric(value): For numerical values. - AST.input_variable(name, size, trainable): For literal variables. - AST.callable(fn_name, *args): For classical functions. - AST.support(target, control): For qubit indices. - AST.quantum_op(name, support, *args): For quantum operators with and without parameters. - AST.sequence(*q_ops): For sequences of quantum operations. - AST.add(lhs, rhs): For addition, lhs + rhs. - AST.sub(lhs, rhs): For subtraction, lhs - rhs. - AST.mul(lhs, rhs): For multiplication, lhs * rhs. - AST.div(lhs, rhs): For division, lhs / rhs. - AST.rem(lhs, rhs): For remainder, lhs % rhs. - AST.pow(base, power): For power, base ** power. + + - AST.numeric(value): For numerical values. + - AST.input_variable(name, size, trainable): For literal variables. + - AST.callable(fn_name, *args): For classical functions. + - AST.support(target, control): For qubit indices. + - AST.quantum_op(name, support, *args): For quantum operators with and without parameters. + - AST.sequence(*q_ops): For sequences of quantum operations. + - AST.add(lhs, rhs): For addition, lhs + rhs. + - AST.sub(lhs, rhs): For subtraction, lhs - rhs. + - AST.mul(lhs, rhs): For multiplication, lhs * rhs. + - AST.div(lhs, rhs): For division, lhs / rhs. + - AST.rem(lhs, rhs): For remainder, lhs % rhs. + - AST.pow(base, power): For power, base ** power. """ class Tag(Flag): @@ -61,8 +69,21 @@ def attrs(self) -> dict[Any, Any]: # Constructors @classmethod def __construct__(cls, tag: Tag, head: str, *args: Any, **attrs: Any) -> AST: - """To void arbitrary initialisation, the user must use one of the standard constructors - provided. This method hides the initilisation from the regular `__new__` to enforce that. + """Base constructor method. + + To void arbitrary initialization, this class must be initialized with one of the standard + constructors provided. This method hides the initialization from the regular `__new__` to + enforce that. + + Args: + tag: A Tag indicating the AST type. Has one of the following values: `QuantumOperator`, + `Sequence`, `Support`, `Call`, `InputVariable`, `Numeric`. + head: A string identifier of the AST object. + args: Optional arguments for specific constructors. + attrs: Optional attributes for specific constructors. + + Returns: + ast: A newly constructed AST object. """ token = super().__new__(cls) @@ -78,6 +99,9 @@ def numeric(cls, value: complex | float) -> AST: Args: value: Numerical value to be converted in the Qadence-IR AST. + + Returns: + ast: A numerical value AST. """ return cls.__construct__(cls.Tag.Numeric, "", value) @@ -87,13 +111,16 @@ def input_variable(cls, name: str, size: int, trainable: bool, **attributes: Any """Create an AST-input variable. Args: - name: Variable's name. + name: The variable's name. size: Number of slots to be reserved for the variable, 1 for scalar values and n>1 for array variables. - trainable: A boolean flag to indicate if the variable is intend to be optimised or - used as a constand during the run. + trainable: A boolean flag to indicate if the variable is intend to be optimized or + used as a constant during the run. attributes: Extra flags, values or dictionaries that can provide more context to the backends. + + Returns: + ast: An input variable AST. """ return cls.__construct__(cls.Tag.InputVariable, name, size, trainable, **attributes) @@ -103,8 +130,11 @@ def callable(cls, name: str, *args: AST) -> AST: """Create an AST-function object. Args: - name: Function name. + name: The function name. args: Arguments to be passed to the function. + + Returns: + ast: A callable AST. """ return cls.__construct__(cls.Tag.Call, name, *args) @@ -117,6 +147,9 @@ def support(cls, target: tuple[int, ...], control: tuple[int, ...]) -> AST: Args: target: A tuple of indices a quantum operator is acting on. control: A tuple of indices a quantum operator uses as control qubits. + + Returns: + ast: A support AST. """ return cls.__construct__(cls.Tag.Support, "", target, control) @@ -140,6 +173,9 @@ def quantum_op( operators like Puali gates are treated as a parametric operator with no arguments. attributes: Extra flags, values or dictionaries that can provide more context to the backends. + + Returns: + ast: A quantum operator AST. """ support = cls.support(target, control) @@ -152,6 +188,9 @@ def sequence(cls, *quantum_operators: Any) -> AST: Args: quantum_operators: Sequence of quantum operators to be applied by the backend in the given order. + + Returns: + ast: An AST-sequence of quantum operators. """ return cls.__construct__(cls.Tag.Sequence, "", *quantum_operators) @@ -164,6 +203,9 @@ def add(cls, lhs: AST, rhs: AST) -> AST: Args: lhs: Left-hand side operand. rhs: Right-hand side operand. + + Returns: + ast: An AST callable adding `lhs` and `rhs`. """ return cls.callable("add", lhs, rhs) @@ -175,6 +217,9 @@ def sub(cls, lhs: AST, rhs: AST) -> AST: Args: lhs: Left-hand side operand. rhs: Right-hand side operand. + + Returns: + ast: An AST callable subtracting `rhs` from `lhs`. """ return cls.callable("sub", lhs, rhs) @@ -186,6 +231,9 @@ def mul(cls, lhs: AST, rhs: AST) -> AST: Args: lhs: Left-hand side operand. rhs: Right-hand side operand. + + Returns: + ast: An AST callable multiplying `lhs` and `rhs`. """ return cls.callable("mul", lhs, rhs) @@ -197,6 +245,9 @@ def div(cls, lhs: AST, rhs: AST) -> AST: Args: lhs: Left-hand side operand. rhs: Right-hand side operand. + + Returns: + ast: An AST callable dividing `lhs` by `rhs`. """ return cls.callable("div", lhs, rhs) @@ -208,6 +259,9 @@ def rem(cls, lhs: AST, rhs: AST) -> AST: Args: lhs: Left-hand side operand. rhs: Right-hand side operand. + + Returns: + ast: An AST callable; remainder or `lhs` and `rhs`. """ return cls.callable("rem", lhs, rhs) @@ -219,6 +273,9 @@ def pow(cls, base: AST, power: AST) -> AST: Args: base: Base operand. power: Power operand. + + Returns: + ast: An AST callable of `base` to the power `power`. """ return cls.callable("pow", base, power) From 2a51d5b56b4151624abf7acf7273bdeba4844d7f Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Tue, 3 Dec 2024 10:02:49 +0100 Subject: [PATCH 18/26] Fix reference to qadence 2 instead of 1 Co-authored-by: RolandMacDoland <9250798+RolandMacDoland@users.noreply.github.com> --- qadence2_ir/irast.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qadence2_ir/irast.py b/qadence2_ir/irast.py index 1a40fe3..8485384 100644 --- a/qadence2_ir/irast.py +++ b/qadence2_ir/irast.py @@ -98,7 +98,7 @@ def numeric(cls, value: complex | float) -> AST: """Create an AST-numeric object. Args: - value: Numerical value to be converted in the Qadence-IR AST. + value: Numerical value to be converted in the Qadence2-IR AST. Returns: ast: A numerical value AST. From 34d2cb51df792a9a6e37fc0cd337c7b3e6f6d696 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Tue, 3 Dec 2024 10:03:32 +0100 Subject: [PATCH 19/26] Fix typo Co-authored-by: RolandMacDoland <9250798+RolandMacDoland@users.noreply.github.com> --- qadence2_ir/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qadence2_ir/types.py b/qadence2_ir/types.py index f18b0e0..028a97c 100644 --- a/qadence2_ir/types.py +++ b/qadence2_ir/types.py @@ -27,7 +27,7 @@ class Alloc: With this class an allocation of memory is made for a parameter that is a scalar value, if `size = 1` or an array of values of length `n` if `size = n`. The type for the allocation is - defined by the backend, therefor it is not defined in the IR. + defined by the backend, therefore it is not defined in the IR. Args: size: Number of values stored in the parameter, if `size = 1` the parameter is a scalar From ba8f5796cdba90b4e9e9b5946e2947d128b845b3 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Tue, 3 Dec 2024 16:16:12 +0100 Subject: [PATCH 20/26] Split up in multiple files --- docs/contents/challenges.md | 13 ++++ docs/contents/compute_stack.md | 10 +++ docs/contents/index.md | 2 + docs/contents/ir_structure.md | 25 ++++++++ docs/{ => contents}/qadence2_stack.png | Bin docs/contents/tbd.md | 83 ------------------------- 6 files changed, 50 insertions(+), 83 deletions(-) create mode 100644 docs/contents/challenges.md create mode 100644 docs/contents/compute_stack.md create mode 100644 docs/contents/index.md create mode 100644 docs/contents/ir_structure.md rename docs/{ => contents}/qadence2_stack.png (100%) delete mode 100644 docs/contents/tbd.md diff --git a/docs/contents/challenges.md b/docs/contents/challenges.md new file mode 100644 index 0000000..881fce4 --- /dev/null +++ b/docs/contents/challenges.md @@ -0,0 +1,13 @@ +# Challenges + +As pointed out above, digital and analog algorithms diverge in how they handle register topology. Contrary to classical computing, where the resource allocation can be left to the OS to control, the quantum resources must be explicit in analog quantum computation. + +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. diff --git a/docs/contents/compute_stack.md b/docs/contents/compute_stack.md new file mode 100644 index 0000000..54c0ca6 --- /dev/null +++ b/docs/contents/compute_stack.md @@ -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. + +![Qadence 2 stack](qadence2_stack.png) +Figure 1: The Qadence 2 software stack. diff --git a/docs/contents/index.md b/docs/contents/index.md new file mode 100644 index 0000000..43624d6 --- /dev/null +++ b/docs/contents/index.md @@ -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. diff --git a/docs/contents/ir_structure.md b/docs/contents/ir_structure.md new file mode 100644 index 0000000..9fb5f2f --- /dev/null +++ b/docs/contents/ir_structure.md @@ -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. diff --git a/docs/qadence2_stack.png b/docs/contents/qadence2_stack.png similarity index 100% rename from docs/qadence2_stack.png rename to docs/contents/qadence2_stack.png diff --git a/docs/contents/tbd.md b/docs/contents/tbd.md deleted file mode 100644 index 8c7b4d5..0000000 --- a/docs/contents/tbd.md +++ /dev/null @@ -1,83 +0,0 @@ -!!! warning - This page is under construction. - -# Qadence2 IR - -# About -Qadence 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 the 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 IR allows digital and analog instructions to work together, extending its usability to the digital-analog paradigm. The static single-assignment simplifies differentiability when running simulations. - -## Compute Stack -Pasqal’s compute stack comprises four layers, as shown in Figure 1. A user defines the quantum computation using one of the frontends: Qadence 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 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 specific backend. The backend itself takes care of executing the computation on the hardware. - -It's important to note that the Qadence IR layer spreads over the full width of the stack, meaning that all frontends 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. - -![](qadence2_stack.png) - -## IR Structure -The idea for the Qadence IR is to provide an abstract neutral atom device model. - -Neutral atom devices usually rely on absolute values like laser power, atomic spacing in micrometres, 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 labels instead of fixed primitives (see 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. - -## Example -Below is an example of a simple analog algorithm represented in Qadence IR. - -```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), - ], -) -``` - -More examples can be found [here](https://github.com/pasqal-io/qadence2-ir/blob/km/docs/docs/examples.md). - - -## Challenges -As pointed out above, digital and analog algorithms diverge in how they handle register topology. Contrary to classical computing, where the resource allocation can be left to the OS to control, the quantum resources must be explicit in analog quantum computation. - -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. From 6b4e88f44b0d7738e138245bb92fcbf75be4a40b Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Tue, 3 Dec 2024 16:25:24 +0100 Subject: [PATCH 21/26] Add subpages to content in mkdocs config --- mkdocs.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index 318b58b..2d4e9b6 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -13,7 +13,10 @@ nav: - License: getting_started/LICENSE.md - Contents: - - TBD: contents/tbd.md + - contents/index.md + - Compute Stack: contents/compute_stack.md + - IR Structure: contents/ir_structure.md + - Challenges: contents/challenges.md - Tutorials: - Tutorials: tutorials/index.md From bcd8e848ef072e0d4d87f65360b21787ee597169 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 6 Dec 2024 10:19:30 +0100 Subject: [PATCH 22/26] Make figure number bold --- docs/contents/compute_stack.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contents/compute_stack.md b/docs/contents/compute_stack.md index 54c0ca6..e817a77 100644 --- a/docs/contents/compute_stack.md +++ b/docs/contents/compute_stack.md @@ -7,4 +7,4 @@ The top layer is user-facing, with the highest level of abstraction. For each fr 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. ![Qadence 2 stack](qadence2_stack.png) -Figure 1: The Qadence 2 software stack. +**Figure 1:** The Qadence 2 software stack. From d3322abe72fa44524738b1c88be7645ea3db6970 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 6 Dec 2024 10:56:54 +0100 Subject: [PATCH 23/26] Add API reference index page contents --- docs/api/index.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/api/index.md b/docs/api/index.md index aea97e4..6b7d184 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -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. From 1dfc5611f78f61368408d82feb7729e8afd5b78b Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 6 Dec 2024 13:30:02 +0100 Subject: [PATCH 24/26] Improve challenges based on @doosmk input --- docs/contents/challenges.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contents/challenges.md b/docs/contents/challenges.md index 881fce4..62110d6 100644 --- a/docs/contents/challenges.md +++ b/docs/contents/challenges.md @@ -1,6 +1,6 @@ # Challenges -As pointed out above, digital and analog algorithms diverge in how they handle register topology. Contrary to classical computing, where the resource allocation can be left to the OS to control, the quantum resources must be explicit in analog quantum computation. +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. From 923604dfbfaa3db7c439dacc7f1d4d6b821ced2e Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 6 Dec 2024 13:31:08 +0100 Subject: [PATCH 25/26] Fix typos in challenges --- docs/contents/challenges.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contents/challenges.md b/docs/contents/challenges.md index 62110d6..107c431 100644 --- a/docs/contents/challenges.md +++ b/docs/contents/challenges.md @@ -10,4 +10,4 @@ Besides the register, other elements like the SLM used to target individual qubi 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. +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. From dcae4fa1abee18f496e9b749fa3ca0d06666e346 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Mon, 9 Dec 2024 09:03:47 +0100 Subject: [PATCH 26/26] Move tutorial files around --- docs/{ => tutorials}/examples.md | 14 +++++++------- docs/tutorials/index.md | 2 -- mkdocs.yml | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) rename docs/{ => tutorials}/examples.md (96%) delete mode 100644 docs/tutorials/index.md diff --git a/docs/examples.md b/docs/tutorials/examples.md similarity index 96% rename from docs/examples.md rename to docs/tutorials/examples.md index 40a00a8..df5c0a5 100644 --- a/docs/examples.md +++ b/docs/tutorials/examples.md @@ -1,8 +1,8 @@ -## Examples +# 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. +## Example digital input. ```python Model( register = AllocQubits(2), @@ -11,7 +11,7 @@ Model( inputs = { "x": Alloc(1, trainable=True), }, - instrunctions = [ + instructions = [ # data encoding Assign("%0", Call("mul", 0.5, Load("x"))), @@ -23,7 +23,7 @@ Model( ) ``` -### Example digital-analog input. +## Example digital-analog input. ```python Model( register = AllocQubits(4), @@ -56,7 +56,7 @@ Model( ) ``` -### Example analog input. +## Example analog input. ```python Model( register = AllocQubits( @@ -101,7 +101,7 @@ Model( ) ``` -### Example analog input (alternative) +## 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 @@ -168,4 +168,4 @@ Model( QuInstruct('dyn_pulse', target_all(), Load('%0'), 1.0), ], ) -``` \ No newline at end of file +``` diff --git a/docs/tutorials/index.md b/docs/tutorials/index.md deleted file mode 100644 index 1d66995..0000000 --- a/docs/tutorials/index.md +++ /dev/null @@ -1,2 +0,0 @@ -!!! warning - This page is under construction. diff --git a/mkdocs.yml b/mkdocs.yml index 2d4e9b6..e054ba5 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -19,7 +19,7 @@ nav: - Challenges: contents/challenges.md - Tutorials: - - Tutorials: tutorials/index.md + - Tutorials: tutorials/examples.md - API: - api/index.md