Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
Expand Down Expand Up @@ -28,7 +29,6 @@
import projectq.setups.default
import projectq.setups.grid
import projectq.setups.ibm
import projectq.setups.ibm16
import projectq.setups.linear
import projectq.setups.restrictedgateset
import projectq.setups.decompositions
Expand Down
11 changes: 9 additions & 2 deletions examples/bellpair_circuit.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import matplotlib.pyplot as plt

from projectq import MainEngine
from projectq.backends import CircuitDrawer
from projectq.setups.default import get_engine_list
from projectq.libs.hist import histogram

from teleport import create_bell_pair

# create a main compiler engine
drawing_engine = CircuitDrawer()
eng = MainEngine(drawing_engine)
eng = MainEngine(engine_list = get_engine_list() + [drawing_engine])

create_bell_pair(eng)
qb0, qb1 = create_bell_pair(eng)

eng.flush()
print(drawing_engine.get_latex())

histogram(eng.backend, [qb0, qb1])
plt.show()
28 changes: 17 additions & 11 deletions examples/ibm.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import projectq.setups.ibm
import matplotlib.pyplot as plt
import getpass

from projectq import MainEngine
from projectq.backends import IBMBackend
from projectq.libs.hist import histogram
from projectq.ops import Measure, Entangle, All
from projectq import MainEngine
import getpass
import projectq.setups.ibm


def run_entangle(eng, num_qubits=3):
Expand All @@ -29,21 +32,24 @@ def run_entangle(eng, num_qubits=3):
eng.flush()

# access the probabilities via the back-end:
results = eng.backend.get_probabilities(qureg)
for state in results:
print("Measured {} with p = {}.".format(state, results[state]))
# results = eng.backend.get_probabilities(qureg)
# for state in results:
# print("Measured {} with p = {}.".format(state, results[state]))
# or plot them directly:
histogram(eng.backend, qureg)
plt.show()

# return one (random) measurement outcome.
return [int(q) for q in qureg]


if __name__ == "__main__":
#devices commonly available :
#ibmq_16_melbourne (15 qubit)
#ibmq_essex (5 qubit)
#ibmq_qasm_simulator (32 qubits)
device = None #replace by the IBM device name you want to use
token = None #replace by the token given by IBMQ
# ibmq_16_melbourne (15 qubit)
# ibmq_essex (5 qubit)
# ibmq_qasm_simulator (32 qubits)
device = None # replace by the IBM device name you want to use
token = None # replace by the token given by IBMQ
if token is None:
token = getpass.getpass(prompt='IBM Q token > ')
if device is None:
Expand Down
90 changes: 72 additions & 18 deletions examples/ibmq_tutorial.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"collapsed": false
},
"source": [
"# Running ProjectQ code on IBM Q devices"
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"collapsed": false
},
"source": [
"In this tutorial, we will see how to run code on IBM Q devices directly from within ProjectQ. All that is needed is an IBM Q Experience user account. To sign up, visit https://quantumexperience.ng.bluemix.net/.\n",
"\n",
Expand All @@ -19,10 +23,24 @@
"First, we import all necessary operations (`Entangle`, measurement), the back-end (`IBMBackend`), and the main compiler engine (`MainEngine`). The Entangle operation is defined as a Hadamard gate on the first qubit (creates an equal superposition of |0> and |1>), followed by controlled NOT gates acting on all other qubits controlled on the first."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import projectq.setups.ibm\n",
Expand All @@ -33,15 +51,19 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"collapsed": false
},
"source": [
"Next, we instantiate a main compiler engine using the IBM Q back-end and the predefined compiler engines which take care of the qubit placement, translation of operations, etc.:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"eng = MainEngine(IBMBackend(use_hardware=True, num_runs=1024,\n",
Expand All @@ -51,7 +73,9 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"collapsed": false
},
"source": [
"If `use_hardware` is set to `False`, it will use the IBM Q simulator instead. `num_runs` specifies the number of samples to collect for statistics, `verbose=True` would output additional information which may be helpful for debugging, and the device parameter lets users choose between the two devices (\"ibmqx4\" and \"ibmqx5\").\n",
"\n",
Expand All @@ -61,7 +85,9 @@
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
Expand Down Expand Up @@ -105,9 +131,12 @@
" eng.flush()\n",
"\n",
" # access the probabilities via the back-end:\n",
" results = eng.backend.get_probabilities(qureg)\n",
" for state in results:\n",
" print(\"Measured {} with p = {}.\".format(state, results[state]))\n",
" # results = eng.backend.get_probabilities(qureg)\n",
" # for state in results:\n",
" # print(\"Measured {} with p = {}.\".format(state, results[state]))\n",
" # or plot them directly:\n",
" histogram(eng.backend, qureg)\n",
" plt.show()\n",
"\n",
" # return one (random) measurement outcome.\n",
" return [int(q) for q in qureg]\n",
Expand All @@ -117,23 +146,29 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"collapsed": false
},
"source": [
"## Retrieving a timed-out execution\n",
"Sometimes, the queue is very long and the waiting times may exceed the limit of 5 minutes. In this case, ProjectQ will raise an exception which contains the job ID, as could be seen above, where the job ID was `5b557df2306393003b746da2`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"collapsed": false
},
"source": [
"In order to still retrieve all results at a later point in time, one can simply re-run the entire program using a slightly modified back-end:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
Expand Down Expand Up @@ -193,7 +228,9 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"collapsed": false
},
"source": [
"## Entangling more qubits: Using ibmqx5\n",
"\n",
Expand All @@ -209,7 +246,9 @@
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import projectq.setups.ibm16 # import setup which contains the grid mapper\n",
Expand All @@ -220,15 +259,19 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"collapsed": false
},
"source": [
"and then re-run the example from before via `run_entangle(eng, num_qubits)`. If an execution times out, it can also be retrieved at a later point by providing the additional `retrieve_execution=\"execution_id\"` parameter to the IBMBackend (but this time with `device='ibmqx5'`)."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
Expand Down Expand Up @@ -488,8 +531,18 @@
],
"metadata": {
"kernelspec": {
"argv": [
"python",
"-m",
"ipykernel_launcher",
"-f",
"{connection_file}"
],
"display_name": "Python 3",
"env": null,
"interrupt_mode": "signal",
"language": "python",
"metadata": null,
"name": "python3"
},
"language_info": {
Expand All @@ -503,7 +556,8 @@
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
}
},
"name": "ibmq_tutorial.ipynb"
},
"nbformat": 4,
"nbformat_minor": 2
Expand Down
20 changes: 20 additions & 0 deletions projectq/libs/hist/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2020 ProjectQ-Framework (www.projectq.ch)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
contains a function to plot measurement outcome probabilities
as a histogram for the simulator
"""

from ._histogram import histogram
78 changes: 78 additions & 0 deletions projectq/libs/hist/_histogram.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Copyright 2020 ProjectQ-Framework (www.projectq.ch)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import print_function
import matplotlib.pyplot as plt

from projectq.backends import Simulator


def histogram(backend, qureg):
"""
Make a measurement outcome probability histogram for the given qubits.

Args:
backend (BasicEngine): A ProjectQ backend
qureg (list of qubits and/or quregs): The qubits,
for which to make the histogram

Returns:
A tuple (fig, axes, probabilities), where:
fig: The histogram as figure
axes: The axes of the histogram
probabilities (dict): A dictionary mapping outcomes as string
to their probabilities

Note:
Don't forget to call eng.flush() before using this function.
"""
qubit_list = []
for q in qureg:
if isinstance(q, list):
qubit_list.extend(q)
else:
qubit_list.append(q)

if len(qubit_list) > 5:
print('Warning: For {0} qubits there are 2^{0} different outcomes'.
format(len(qubit_list)))
print("The resulting histogram may look bad and/or take too long.")
print("Consider calling histogram() with a sublist of the qubits.")

if hasattr(backend, 'get_probabilities'):
probabilities = backend.get_probabilities(qureg)
elif isinstance(backend, Simulator):
outcome = [0] * len(qubit_list)
n_outcomes = (1 << len(qubit_list))
probabilities = {}
for i in range(n_outcomes):
for pos in range(len(qubit_list)):
if (1 << pos) & i:
outcome[pos] = 1
else:
outcome[pos] = 0
probabilities[''.join([str(bit) for bit in outcome
])] = backend.get_probability(
outcome, qubit_list)
else:
raise RuntimeError('Unable to retrieve probabilities from backend')

# Empirical figure size for up to 5 qubits
fig, axes = plt.subplots(figsize=(min(21.2, 2
+ 0.6 * (1 << len(qubit_list))), 7))
names = list(probabilities.keys())
values = list(probabilities.values())
axes.bar(names, values)
fig.suptitle('Measurement Probabilities')
return (fig, axes, probabilities)
Loading