Skip to content

Commit

Permalink
ProjectQ v0.3.4
Browse files Browse the repository at this point in the history
  • Loading branch information
thomashaener authored Sep 11, 2017
2 parents e7eb0ff + 4101e7c commit f8e1a70
Show file tree
Hide file tree
Showing 135 changed files with 2,248 additions and 138 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ install:
- pip$PY install -e .

# command to run tests
script: export OMP_NUM_THREADS=1 && pytest projectq --cov projectq
script: export OMP_NUM_THREADS=1 && pytest -W error projectq --cov projectq

after_success:
- coveralls
6 changes: 6 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ ProjectQ - An open source software framework for quantum computing
:target: http://projectq.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status

.. image:: https://badge.fury.io/py/projectq.svg
:target: https://badge.fury.io/py/projectq

.. image:: https://img.shields.io/badge/python-2.7%2C%203.3%2C%203.4%2C%203.5%2C%203.6-brightgreen.svg


ProjectQ is an open source effort for quantum computing.

It features a compilation framework capable of
Expand Down
27 changes: 27 additions & 0 deletions docs/README.rst
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.
3 changes: 3 additions & 0 deletions docs/tutorials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ ProjectQ comes with a high-performance quantum simulator written in C++. Please
.. note::
Please use pip version v6.1.0 or higher as this ensures that dependencies are installed in the `correct order <https://pip.pypa.io/en/stable/reference/pip_install/#installation-order>`_.

.. note::
ProjectQ should be installed on each computer individually as the C++ simulator compilation creates binaries which are optimized for the specific hardware on which it is being installed (potentially using our AVX version and `-march=native`). Therefore, sharing the same ProjectQ installation across different hardware can cause problems.


Detailed instructions and OS-specific hints
-------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions examples/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ Examples and tutorials in this folder
2. Take a look at the *simulator_tutorial.ipynb* for a detailed introduction to most of the features of our high performance quantum simulator.

3. Running on the IBM QE chip is explained in more details in *ibm_entangle.ipynb*.

4. A small tutorial on the compiler is available in *compiler_tutorial.ipynb* which explains how to compile to a specific gate set.
323 changes: 323 additions & 0 deletions examples/compiler_tutorial.ipynb
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
}
Loading

0 comments on commit f8e1a70

Please sign in to comment.