-
Notifications
You must be signed in to change notification settings - Fork 279
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
135 changed files
with
2,248 additions
and
138 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
Documentation | ||
============= | ||
|
||
.. image:: https://readthedocs.org/projects/projectq/badge/?version=latest | ||
:target: http://projectq.readthedocs.io/en/latest/?badge=latest | ||
:alt: Documentation Status | ||
|
||
|
||
Our detailed code documentation can be found online at `Read the Docs <http://projectq.readthedocs.io/en/latest/>`__ and gets updated automatically. Besides the latest code documentation, there are also previous and offline versions available for download. | ||
|
||
Building the docs locally | ||
------------------------- | ||
|
||
Before submitting new code, please make sure that the new or changed docstrings render nicely by building the docs manually. To this end, one has to install sphinx and the Read the Docs theme: | ||
|
||
.. code-block:: bash | ||
python -m pip install sphinx | ||
python -m pip install sphinx_rtd_theme | ||
To build the documentation, navigate to this folder and execute: | ||
|
||
.. code-block:: bash | ||
make clean html | ||
Open _build/html/index.html to view the docs. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,323 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"collapsed": true, | ||
"deletable": true, | ||
"editable": true | ||
}, | ||
"source": [ | ||
"# ProjectQ Compiler Tutorial\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"deletable": true, | ||
"editable": true | ||
}, | ||
"source": [ | ||
"The aim of this short tutorial is to give a first introduction to the ProjectQ compiler. In particular, we will show how to specify the gate set to which the compiler should translate a quantum program. A more extended tutorial will follow soon. Please check out our [ProjectQ paper](http://arxiv.org/abs/1612.08091) for an introduction to the basic concepts behind our compiler." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"deletable": true, | ||
"editable": true | ||
}, | ||
"source": [ | ||
"## The default compiler" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"deletable": true, | ||
"editable": true | ||
}, | ||
"source": [ | ||
"To compile a quantum program, we begin by creating a compiler called `MainEngine` and specify the backend for which the compiler should translate the program. For the purpose of this tutorial, we will use a `CommandPrinter` as a backend to display the compiled algorithm. It works the same for all other backends such as, e.g., the simulator or an interface to real hardware.\n", | ||
"\n", | ||
"Let's write a small program:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 1, | ||
"metadata": { | ||
"collapsed": false, | ||
"deletable": true, | ||
"editable": true | ||
}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"Allocate | Qureg[1]\n", | ||
"Allocate | Qureg[0]\n", | ||
"Allocate | Qureg[2]\n", | ||
"Allocate | Qureg[3]\n", | ||
"Cexp(-0.1j * (0.5 X0 Y1 Z2)) | ( Qureg[0], Qureg[1-3] )\n", | ||
"QFT | Qureg[1-3]\n", | ||
"Rx(0.1) | Qureg[0]\n", | ||
"CX | ( Qureg[0], Qureg[1] )\n", | ||
"Measure | Qureg[1]\n", | ||
"Measure | Qureg[2]\n", | ||
"Measure | Qureg[3]\n", | ||
"Measure | Qureg[0]\n", | ||
"Deallocate | Qureg[0]\n", | ||
"Deallocate | Qureg[3]\n", | ||
"Deallocate | Qureg[2]\n", | ||
"Deallocate | Qureg[1]\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"import projectq\n", | ||
"from projectq.backends import CommandPrinter\n", | ||
"from projectq.meta import Control\n", | ||
"from projectq.ops import All, CNOT, Measure, QFT, QubitOperator, Rx, TimeEvolution, X\n", | ||
"\n", | ||
"# create the compiler and specify the backend:\n", | ||
"eng = projectq.MainEngine(backend=CommandPrinter(accept_input=False))\n", | ||
"\n", | ||
"def my_quantum_program(eng):\n", | ||
" qubit = eng.allocate_qubit()\n", | ||
" qureg = eng.allocate_qureg(3)\n", | ||
" with Control(eng, qubit):\n", | ||
" hamiltonian = 0.5 * QubitOperator(\"X0 Y1 Z2\")\n", | ||
" TimeEvolution(0.1, hamiltonian) | qureg\n", | ||
" QFT | qureg\n", | ||
" Rx(0.1) | qubit\n", | ||
" CNOT | (qubit, qureg[0])\n", | ||
" All(Measure) | qureg\n", | ||
" Measure | qubit\n", | ||
" eng.flush()\n", | ||
"my_quantum_program(eng)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"deletable": true, | ||
"editable": true | ||
}, | ||
"source": [ | ||
"In the above example, the compiler did nothing because the default compiler (when `MainEngine` is called without a specific `engine_list` parameter) translates the individual gates to the gate set supported by the backend. In our case, the backend is a `CommandPrinter` which supports any type of gate.\n", | ||
"\n", | ||
"We can check what happens when the backend is a `Simulator` by inserting a `CommandPrinter` as a last compiler engine before the backend so that every command is printed before it gets sent to the Simulator: " | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"metadata": { | ||
"collapsed": false, | ||
"deletable": true, | ||
"editable": true | ||
}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"Allocate | Qureg[1]\n", | ||
"Allocate | Qureg[0]\n", | ||
"Allocate | Qureg[2]\n", | ||
"Allocate | Qureg[3]\n", | ||
"Cexp(-0.1j * (0.5 X0 Y1 Z2)) | ( Qureg[0], Qureg[1-3] )\n", | ||
"H | Qureg[3]\n", | ||
"CR(1.5707963267948966) | ( Qureg[2], Qureg[3] )\n", | ||
"CR(0.7853981633974483) | ( Qureg[1], Qureg[3] )\n", | ||
"H | Qureg[2]\n", | ||
"CR(1.5707963267948966) | ( Qureg[1], Qureg[2] )\n", | ||
"H | Qureg[1]\n", | ||
"Rx(0.1) | Qureg[0]\n", | ||
"CX | ( Qureg[0], Qureg[1] )\n", | ||
"Measure | Qureg[1]\n", | ||
"Measure | Qureg[2]\n", | ||
"Measure | Qureg[3]\n", | ||
"Measure | Qureg[0]\n", | ||
"Deallocate | Qureg[0]\n", | ||
"Deallocate | Qureg[3]\n", | ||
"Deallocate | Qureg[2]\n", | ||
"Deallocate | Qureg[1]\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"from projectq.backends import Simulator\n", | ||
"\n", | ||
"# Use the default compiler engines with a CommandPrinter in the end:\n", | ||
"engines2 = projectq.default_engines() + [CommandPrinter()]\n", | ||
"\n", | ||
"eng2 = projectq.MainEngine(backend=Simulator(), engine_list=engines2)\n", | ||
"my_quantum_program(eng2)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"deletable": true, | ||
"editable": true | ||
}, | ||
"source": [ | ||
"As one can see, in this case the compiler had to do a little work because the Simulator does not support a QFT gate. Therefore, it automatically replaces the QFT gate by a sequence of lower-level gates." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"deletable": true, | ||
"editable": true | ||
}, | ||
"source": [ | ||
"## Specifying a particular gate set" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"deletable": true, | ||
"editable": true | ||
}, | ||
"source": [ | ||
"In this short example, we want to explore how to specify a particular gate set, which may be even more restrictive than what the backend naturally supports. This is useful, e.g., to obtain resource estimates for running a given program on actual quantum hardware which, in this example, can only perform CNOT and single qubit gates. All one has to do is insert an `InstructionFilter` into the `engine_list`:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 3, | ||
"metadata": { | ||
"collapsed": false, | ||
"deletable": true, | ||
"editable": true | ||
}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"Allocate | Qureg[3]\n", | ||
"Allocate | Qureg[2]\n", | ||
"Rx(1.5707963267948966) | Qureg[2]\n", | ||
"Allocate | Qureg[1]\n", | ||
"H | Qureg[1]\n", | ||
"CX | ( Qureg[1], Qureg[2] )\n", | ||
"CX | ( Qureg[2], Qureg[3] )\n", | ||
"Rz(0.05) | Qureg[3]\n", | ||
"Allocate | Qureg[0]\n", | ||
"CX | ( Qureg[0], Qureg[3] )\n", | ||
"Rz(12.516370614359172) | Qureg[3]\n", | ||
"CX | ( Qureg[0], Qureg[3] )\n", | ||
"CX | ( Qureg[2], Qureg[3] )\n", | ||
"CX | ( Qureg[1], Qureg[2] )\n", | ||
"H | Qureg[1]\n", | ||
"R(0.39269908169872414) | Qureg[1]\n", | ||
"H | Qureg[3]\n", | ||
"Rz(0.7853981633974483) | Qureg[3]\n", | ||
"Rx(10.995574287564276) | Qureg[2]\n", | ||
"R(0.7853981633974483) | Qureg[2]\n", | ||
"CX | ( Qureg[2], Qureg[3] )\n", | ||
"Rz(11.780972450961723) | Qureg[3]\n", | ||
"CX | ( Qureg[2], Qureg[3] )\n", | ||
"Rz(0.39269908169872414) | Qureg[3]\n", | ||
"CX | ( Qureg[1], Qureg[3] )\n", | ||
"Rz(12.173671532660448) | Qureg[3]\n", | ||
"CX | ( Qureg[1], Qureg[3] )\n", | ||
"R(0.7853981633974483) | Qureg[1]\n", | ||
"H | Qureg[2]\n", | ||
"Rz(0.7853981633974483) | Qureg[2]\n", | ||
"CX | ( Qureg[1], Qureg[2] )\n", | ||
"Rz(11.780972450961723) | Qureg[2]\n", | ||
"CX | ( Qureg[1], Qureg[2] )\n", | ||
"H | Qureg[1]\n", | ||
"Rx(0.1) | Qureg[0]\n", | ||
"CX | ( Qureg[0], Qureg[1] )\n", | ||
"Measure | Qureg[1]\n", | ||
"Measure | Qureg[2]\n", | ||
"Measure | Qureg[3]\n", | ||
"Measure | Qureg[0]\n", | ||
"Deallocate | Qureg[0]\n", | ||
"Deallocate | Qureg[3]\n", | ||
"Deallocate | Qureg[2]\n", | ||
"Deallocate | Qureg[1]\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"from projectq.cengines import InstructionFilter\n", | ||
"from projectq.ops import ClassicalInstructionGate\n", | ||
"\n", | ||
"# Write a function which, given a Command object, returns whether the command is supported:\n", | ||
"def is_supported(eng, cmd):\n", | ||
" if isinstance(cmd.gate, ClassicalInstructionGate):\n", | ||
" # This is required to allow Measure, Allocate, Deallocate, Flush\n", | ||
" return True\n", | ||
" elif isinstance(cmd.gate, X.__class__) and len(cmd.control_qubits) == 1:\n", | ||
" # Allows a CNOT gate which is an X gate with one control qubit\n", | ||
" return True\n", | ||
" elif (len(cmd.control_qubits) == 0 and \n", | ||
" len(cmd.qubits) == 1 and\n", | ||
" len(cmd.qubits[0]) == 1):\n", | ||
" # Gate which has no control qubits, applied to 1 qureg consisting of 1 qubit\n", | ||
" return True\n", | ||
" else:\n", | ||
" return False\n", | ||
"\n", | ||
"supported_gate_set_filter = InstructionFilter(is_supported)\n", | ||
"\n", | ||
"# Append the instruction filter to the list of compiler engines:\n", | ||
"engines3 = projectq.default_engines() + [supported_gate_set_filter]\n", | ||
"\n", | ||
"eng3 = projectq.MainEngine(backend=CommandPrinter(accept_input=False), engine_list=engines3)\n", | ||
"my_quantum_program(eng3)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"deletable": true, | ||
"editable": true | ||
}, | ||
"source": [ | ||
"As we can see, the compiler now needs to do a little more work. In some cases, the compiler does not know how to translate a command according to the specified gate set and it will throw a `NoGateDecompositionError`. This means one needs to implement a rule specifying how to decompose said command. See projectq/setups/decompositions for a few examples. This will be explained in a more extended tutorial." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": { | ||
"collapsed": true, | ||
"deletable": true, | ||
"editable": true | ||
}, | ||
"outputs": [], | ||
"source": [] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.4.3" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
Oops, something went wrong.