qasm/README.md

128 lines
7.6 KiB
Markdown

```
qbits n
cbits n
qregs n
cregs n
mem n
<code>
```
The order of the headers is important and should not be changed. The `qbits` header specifies the number of
qubits in each quantum register. The `cbits` header specifies the number of classical bits in each classical
register. The `qregs` header specifies the number of quantum registers. The `cregs` header specifies the number
of classical registers. The `n` after each header is any integer number. Operands/arguments for all
instructions are delimited by spaces and not commas.
Code execution should always end at a `hlt` instruction. If the emulator reaches the end of code but does not
encounter a `hlt` instruction, it will end with a "PC out of bounds" error.
## Quantum Instructions
The general format for quantum instructions are:
```
op qn <other arguments>
```
Where `op` is the name/opcode, `qn` specifies a specific qubit `n` of the currently selected quantum register.
`<other arguments>` can include more qubits as arguments, or in the case of some instructions, a rotation expressed
as a rational multiple of pi, in the format `[n]pi[/n]`, where `n` can be any integer number, and items
in `[]` are optional. Quantum registers can be selected via the `qsel` instruction, which has the general format
`qsel qrn` where `n` is any non-negative number.
List of currently implemented quantum instructions:
| Quantum Gate | Instruction name | Syntax example | Explanation |
| ------------------- | ---------------- | ------------------- | ----------- |
| Hadamard | h | `h q0` | Applies a Hadamard to qubit 0 |
| CNOT | cnot | `cnot q0 q1` | Applies a CNOT to qubit 1 with qubit 0 being the control |
| CCNOT/Toffoli | ccnot | `ccnot q0 q1 q2` | Applies a Toffoli to qubit 2 with qubit 0 and qubit 1 being the controls |
| Pauli X | x | `x q0` | Applies a Pauli X to qubit 0 |
| Pauli Y | y | `y q0` | Applies a Pauli Y to qubit 0 |
| Pauli Z | z | `z q0` | Applies a Pauli Z to qubit 0 |
| Rx | rx | `rx q0 pi/3` | Rotates the statevector of qubit 0 by pi/3 radians along X axis on bloch sphere |
| Ry | ry | `ry q0 pi` | Rotates the statevector of qubit 0 by pi radians along Y axis on bloch sphere |
| Rz | rz | `rz q0 pi/4` | Rotates the statevector of qubit 0 by pi/4 radians along Z axis on bloch sphere |
| U gate | u | `u q0 pi pi/3 pi/6` | Rotates the statevector of qubit 0 by the 3 Euler angles pi, pi/3, pi/6 |
| S gate | s | `s q0` | Applies an S gate to qubit 0 |
| T gate | t | `t q0` | Applies a T gate to qubit 0 |
| S-dagger | sdg | `sdg q0` | Applies a S-dagger or the inverse of S gate to qubit 0 |
| T-dagger | tdg | `tdg q0` | Applies a T-dagger or the inverse of T gate to qubit 0 |
| Phase gate | p | `p q0 pi/3` | Applies a relative phase of pi/3 radians to qubit 0 |
| Controlled Hadamard | ch | `ch q0 q1` | Applies a controlled Hadamard to qubit 1 with qubit 0 being the control |
| Controlled Pauli Y | cy | `cy q0 q1` | Applies a controlled Pauli Y to qubit 1 with qubit 0 being the control |
| Controlled Pauli Z | cz | `cz q0 q1` | Applies a controlled Pauli Z to qubit 1 with qubit 0 being the control |
| Controlled Phase | cp | `cp q0 q1 pi/2` | Applies a controlled Phase gate to qubit 1 of pi/2 radians with qubit 0 being the control |
| Swap | swap | `swap q0 q1` | Swaps the state of qubits 0 and 1 |
| Square Root NOT | sqrtx | `sqrtx q0 ` | Applies a sqrt(NOT)/sqrt(X) to qubit 0 |
| Square Root Swap | sqrtswp | `sqrtswp q0 q1` | Applies a sqrt(Swap) to qubits 0 and 1, halfway swapping their state |
| Controlled Swap | cswap | `cswap q0 q1 q2` | Swaps the state of qubits 1 and 2 with qubit 0 being the control |
| Measure | m | `m q0 cr1 c3` | Measures the state of qubit 0 into 3rd bit of classical register 1 |
*Note: Remove any measurement operations before running the emulator with `--print-state` (or `-p`) as the emulator does not ignore them currently when run with that flag set*
## Classical Instructions
General format for classical instructions are:
```
op <operands>
```
Where `op` is the name/opcode, operands may include `crn`, which specifies a specific classical register `n`, or
an immediate literal value (for now non-negative due to not implemented in parser yet) Other than these differences,
they behave basically the same as any other assembly language instructions.
List of currently implemented classical instructions:
*Note: The value of a register refers to the value stored in the register. The value of an immediate is the immediate number itself.*
*Note 2: An operand can either be a register or immediate unless a restriction is specified.*
| Instruction name | Description |
| ---------------- | ----------- |
| add | op1 = op2 + op3. op1 is always a register. |
| sub | op1 = op2 - op3. op1 is always a register. |
| mult | op1 = op2 * op3. op1 is always a register. All values are treated unsigned. |
| umult | op1 = (op2 * op3) >> (cbits/2). op1 is always a register. All values are treated unsigned. |
| div | op1 = op2 / op3. op1 is always a register. Performs integer division. All values are treated unsigned. |
| smult | op1 = op2 * op3. op1 is always a register. All values are treated signed. |
| sumult | op1 = (op2 * op3) >> (cbits/2). op1 is always a register. All values are treated signed. |
| sdiv | op1 = op2 / op3. op1 is always a register. Performs integer division. All values are treated signed. |
| not | op1 = ~op2. op1 is always a register. |
| and | op1 = op2 & op3. op1 is always a register. |
| or | op1 = op2 \| op3. op1 is always a register. |
| xor | op1 = op2 ^ op3. op1 is always a register. |
| nand | op1 = ~(op2 & op3). op1 is always a register. |
| nor | op1 = ~(op2 \| op3). op1 is always a register. |
| xnor | op1 = ~(op2 ^ op3). op1 is always a register. |
## Misc. Instructions
These instructions are here because.
| Instruction name | Description |
| ---------------- | ----------- |
| qsel | Selects a quantum register so that proceeding quantum instructions act on that qreg. |
| cmp | Updates flags based on comparing values in op1 and op2. op1 is always a register. |
| jmp | Unconditionally jump to a label. |
| jeq | Jump to label if comparison resulted in EQ flag set. |
| jne | Jump to label if comparsion did not result in EQ flag set. |
| jg | Jump to label if comparison resulted in GREATER flag set. |
| jge | Jump to label if comparison resulted in GREATER or EQ flag set. |
| jl | Jump to label if comparison resulted in LESSER flag set. |
| jle | Jump to label if comparison resulted in LESSER or EQ flag set. |
| hlt | Halt the program. |
# Examples
This program simulates the $\ket{\Phi^+}$ bell state:
```
qbits 2
cbits 2
qregs 1
cregs 1
qsel qr0
h q0
cnot q0 q1
m q0 cr0 c0
m q1 cr0 c1
hlt
```