Skip to content

Commit

Permalink
Compiler Redo (#1856)
Browse files Browse the repository at this point in the history
* Compiler redo

* Compiler redo

* More changes

* Linting

* Linting

* Update qiskit/compiler/synthesizer.py

Co-Authored-By: jaygambetta <[email protected]>

* Update qiskit/compiler/assembler.py

Co-Authored-By: jaygambetta <[email protected]>

* Update qiskit/compiler/assembler.py

Co-Authored-By: jaygambetta <[email protected]>

* Update qiskit/runner_wrapper.py

Co-Authored-By: jaygambetta <[email protected]>

* Renaming for ali

* Cleaning up

* Listing. And doc

* Making compile work with pass manager.

* Style fixes

* Moving around

* Limiting and passing

* naming

* Doctoring

* rename assemble() to assemble_circuits(), update warning messages

* add a changelog

* add qobj_header as an arg to execute() as well

* move schema to models folder like other qiskit components

* add tests for assembler

* qiskit.compiler.transpile -> qiskit.compiler.transpiler

* update teleport example

* update rippleadd example

* fix misleading try-except statements in the examples

* update level 1 example to be transpile then assemble

* bring run_config arg to second position in assemble_circuits()

* remove compile from tests and a bunch of pylint ignores
  • Loading branch information
jaygambetta authored and ajavadia committed Mar 11, 2019
1 parent 2403985 commit 89ceb19
Show file tree
Hide file tree
Showing 39 changed files with 830 additions and 401 deletions.
20 changes: 17 additions & 3 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,27 @@ Added
- New EnlargeWithAncilla pass for adding ancilla qubits after a Layout
selection pass (#1603).
- New Unroll2Q pass for unrolling gates down to just 1q or 2q gates (#1614).
- Added a RunConfig object for configurations for run configurations to be used
in compile and circuits_to_qobj. (#1629)
- Added support for register slicing when applying operations to a register (#1643).
- Added in new parameter ``justify`` to the text circuit drawer to say how the
circuit should be aligned. (#1725)
- Added function for purity of a mixed state in ``qiskit.quantum_information``
(#1733)
- Added in methods to remove a specific DAG edge and to see if a specific edge exists
- Added parameter to the TextProgressBar to allow the output to be sent to a
different output stream
different output stream
- Added a ``RunConfig`` object for configurations related to running an
experiment (e.g. shots, memory) (#1856)
- Added a ``TranspileConfig`` object for configurations related to transforming
circuits (e.g. basis_gates, coupling_map, initial_layout) (#1856)
- Added a ``qiskit.compiler`` namespace for all functions that transpile, schedule
and assemble circuits and pulses (#1856)
- Added a ``qiskit.compiler.assemble_circuits()`` function to generate qobj from some
circuits and a RunConfig (#1856)
- Added an ``execute_circuits()`` function that takes a list of circuits along with a
TranspileConfig and RunConfig. The ``execute()`` function remains as a wrapper of this,
and later as a wrapper of ``execute_pulses()``.
- ``execute_circuits()`` and ``assemble_circuits()`` allow setting a qobj_header of type
QobjHeader to add extra information to the qobj (and thus result).

Changed
-------
Expand Down Expand Up @@ -83,6 +94,9 @@ Deprecated
- Unroller bases must now be explicit, and violation raises an informative
``QiskitError`` (#1802).
- The ``qiskit.tools.qcvv`` package is deprecated in favor of Qiskit Ignis (#1884).
- The ``qiskit.compile()`` function is now deprecated in favor of explicitly
using the ``qiskit.compiler.transpile()`` function to transform a circuit followed
by ``qiskit.compiler.assemble_circuits()`` to make a qobj out of it.

Fixed
-----
Expand Down
17 changes: 9 additions & 8 deletions examples/python/hello_quantum.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,17 @@
# Compile and run the Quantum Program on a real device backend
try:
least_busy_device = least_busy(IBMQ.backends(simulator=False))
print("Running on current least busy device: ", least_busy_device)

#running the job
job_exp = execute(qc, least_busy_device, shots=1024, max_credits=10)
result_exp = job_exp.result()

# Show the results
print(result_exp.get_counts(qc))
except:
print("All devices are currently unavailable.")

print("Running on current least busy device: ", least_busy_device)

#running the job
job_exp = execute(qc, least_busy_device, shots=1024, max_credits=10)
result_exp = job_exp.result()

# Show the results
print(result_exp.get_counts(qc))

except QiskitError as ex:
print('There was an error in the circuit!. Error = {}'.format(ex))
9 changes: 4 additions & 5 deletions examples/python/rippleadd.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"""

from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
from qiskit import compile, BasicAer
from qiskit import BasicAer
from qiskit import execute

###############################################################
# Set the backend name and coupling map.
Expand Down Expand Up @@ -76,14 +77,12 @@ def unmajority(p, a, b, c):
###############################################################

# First version: not mapped
qobj = compile(qc, backend=backend, coupling_map=None, shots=1024)
job = backend.run(qobj)
job = execute(qc, backend=backend, coupling_map=None, shots=1024)
result = job.result()
print(result.get_counts(qc))

# Second version: mapped to 2x8 array coupling graph
qobj = compile(qc, backend=backend, coupling_map=coupling_map, shots=1024)
job = backend.run(qobj)
job = execute(qc, backend=backend, coupling_map=coupling_map, shots=1024)
result = job.result()
print(result.get_counts(qc))

Expand Down
15 changes: 5 additions & 10 deletions examples/python/teleport.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"""

from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
from qiskit import compile, BasicAer
from qiskit import BasicAer
from qiskit import execute

###############################################################
# Set the backend name and coupling map.
Expand Down Expand Up @@ -58,20 +59,14 @@
###############################################################

# First version: not mapped
initial_layout = {("q", 0): ("q", 0), ("q", 1): ("q", 1),
("q", 2): ("q", 2)}
qobj = compile(qc, backend=backend, coupling_map=None, shots=1024, initial_layout=initial_layout)
job = backend.run(qobj)
qobj_exp = qobj.experiments[0]
initial_layout = [q[0], q[1], q[2]]
job = execute(qc, backend=backend, coupling_map=None, shots=1024, initial_layout=initial_layout)

result = job.result()
print(result.get_counts(qc))

# Second version: mapped to 2x8 array coupling graph
qobj = compile(qc, backend=backend, coupling_map=coupling_map, shots=1024,initial_layout=initial_layout)
qobj_exp = qobj.experiments[0]
qobj_exp.header.compiled_circuit_qasm = ""
job = backend.run(qobj)
job = execute(qc, backend=backend, coupling_map=coupling_map, shots=1024,initial_layout=initial_layout)
result = job.result()
print(result.get_counts(qc))
# Both versions should give the same distribution
22 changes: 12 additions & 10 deletions examples/python/using_qiskit_terra_level_0.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,20 @@
try:
# select least busy available device and execute.
least_busy_device = least_busy(IBMQ.backends(simulator=False))
print("Running on current least busy device: ", least_busy_device)
except:
print("All devices are currently unavailable.")

# running the job
job_exp = execute([qc1, qc2], backend=least_busy_device, shots=1024, max_credits=10)
print("Running on current least busy device: ", least_busy_device)

job_monitor(job_exp)
exp_result = job_exp.result()
# running the job
job_exp = execute([qc1, qc2], backend=least_busy_device, shots=1024, max_credits=10)

job_monitor(job_exp)
exp_result = job_exp.result()

# Show the results
print(exp_result.get_counts(qc1))
print(exp_result.get_counts(qc2))

# Show the results
print(exp_result.get_counts(qc1))
print(exp_result.get_counts(qc2))
except:
print("All devices are currently unavailable.")
except QiskitError as ex:
print('There was an error in the circuit!. Error = {}'.format(ex))
84 changes: 52 additions & 32 deletions examples/python/using_qiskit_terra_level_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,28 @@
"""
Example showing how to use Qiskit at level 1 (intermediate).
This example shows how an intermediate user interacts with Terra. It builds some circuits
and compiles them from compile parameters. It makes a qobj object which is just and container to be
run on a backend. The same qobj can run on many backends (as shown). It is the
user responsibility to make sure it can be run. This is useful when you want to compare the same
circuits on different backends or change the compile parameters.
To control the passes and we have a pass manager for level 2 user.
This example shows how an intermediate user interacts with Terra.
It builds some circuits and transpiles them with transpile options.
It then makes a qobj object which is just a container to be run on a backend.
The same qobj can be submitted to many backends (as shown).
It is the user's responsibility to make sure it can be run (i.e. it conforms
to the restrictions of the backend, if any).
This is useful when you want to compare the same
circuit on different backends without recompiling the whole circuit,
or just want to change some runtime parameters.
To control the passes that transform the circuit, we have a pass manager
for the level 2 user.
"""

import pprint, time

# Import the Qiskit modules
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister, QiskitError
from qiskit import compile, IBMQ, BasicAer
from qiskit import IBMQ, BasicAer
from qiskit import QiskitError
from qiskit.circuit import QuantumCircuit, ClassicalRegister, QuantumRegister
from qiskit.compiler import transpile, assemble_circuits
from qiskit.compiler import TranspileConfig, RunConfig
from qiskit.providers.ibmq import least_busy
from qiskit.tools.monitor import job_monitor

Expand All @@ -33,7 +41,7 @@
For now, there's only access to local simulator backends...""")

try:
# Create a Quantum and Classical Register and giving a name.
# Create a Quantum and Classical Register and give them names.
qubit_reg = QuantumRegister(2, name='q')
clbit_reg = ClassicalRegister(2, name='c')

Expand All @@ -52,31 +60,48 @@
print("(Aer Backends)")
for backend in BasicAer.backends():
print(backend.status())
my_backend = BasicAer.get_backend('qasm_simulator')
qasm_simulator = BasicAer.get_backend('qasm_simulator')
print("(QASM Simulator configuration) ")
pprint.pprint(my_backend.configuration())
pprint.pprint(qasm_simulator.configuration())
print("(QASM Simulator properties) ")
pprint.pprint(my_backend.properties())
pprint.pprint(qasm_simulator.properties())


print("\n(IMQ Backends)")
# Compile and run the circuit on a real device backend
# See a list of available remote backends
print("\n(IBMQ Backends)")
for backend in IBMQ.backends():
print(backend.status())

# select least busy available device and execute.
least_busy_device = least_busy(IBMQ.backends(simulator=False))
try:
# select least busy available device and execute.
least_busy_device = least_busy(IBMQ.backends(simulator=False))
except:
print("All devices are currently unavailable.")

print("Running on current least busy device: ", least_busy_device)
print("(with configuration) ")
pprint.pprint(least_busy_device.configuration())
print("(with properties) ")
pprint.pprint(least_busy_device.properties())

# Transpile the circuits to make them compatible with the experimental backend
[qc1_new, qc2_new] = transpile(circuits=[qc1, qc2],
transpile_config=TranspileConfig(backend=least_busy_device))
print("Bell circuit before transpile:")
print(qc1)
print("Bell circuit after transpile:")
print(qc1_new)
print("Superposition circuit before transpile:")
print(qc2)
print("Superposition circuit after transpile:")
print(qc2_new)

# Compiling the job for the experimental backend
qobj = compile([qc1, qc2], backend=least_busy_device, shots=1024, max_credits=10)
# Assemble the two circuits into a runnable qobj
qobj = assemble_circuits([qc1_new, qc2_new], run_config=RunConfig(shots=1000))

# Running the job
sim_job = my_backend.run(qobj)
# Running qobj on the simulator
sim_job = qasm_simulator.run(qobj)

# Getting the result
sim_result=sim_job.result()
Expand All @@ -85,20 +110,15 @@
print(sim_result.get_counts(qc1))
print(sim_result.get_counts(qc2))

# Compile and run the Quantum Program on a real device backend
# See a list of available remote backends
try:
# Running the job.
exp_job = least_busy_device.run(qobj)
# Running the job.
exp_job = least_busy_device.run(qobj)

job_monitor(exp_job)
exp_result = exp_job.result()
job_monitor(exp_job)
exp_result = exp_job.result()

# Show the results
print(exp_result.get_counts(qc1))
print(exp_result.get_counts(qc2))
except:
print("All devices are currently unavailable.")
# Show the results
print(exp_result.get_counts(qc1))
print(exp_result.get_counts(qc2))

except QiskitError as ex:
print('There was an error in the circuit!. Error = {}'.format(ex))
9 changes: 6 additions & 3 deletions qiskit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

# pylint: disable=wrong-import-order


"""Main Qiskit public functionality."""

import pkgutil
Expand All @@ -21,7 +22,9 @@
from qiskit.circuit import ClassicalRegister
from qiskit.circuit import QuantumRegister
from qiskit.circuit import QuantumCircuit
from .tools.compiler import (compile, execute)
# pylint: disable=redefined-builtin
from qiskit.tools.compiler import compile # TODO remove after 0.8
from qiskit.execute import (execute_circuits, execute)

# The qiskit.extensions.x imports needs to be placed here due to the
# mechanism for adding gates dynamically.
Expand All @@ -38,12 +41,12 @@
# Please note these are global instances, not modules.
from qiskit.providers.basicaer import BasicAer

# Try to import the Aer provider if the Aer element is installed.
# Try to import the Aer provider if installed.
try:
from qiskit.providers.aer import Aer
except ImportError:
pass
# Try to import the IBQM provider if the IBMQ element is installed.
# Try to import the IBMQ provider if installed.
try:
from qiskit.providers.ibmq import IBMQ
except ImportError:
Expand Down
15 changes: 15 additions & 0 deletions qiskit/compiler/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-

# Copyright 2019, IBM.
#
# This source code is licensed under the Apache License, Version 2.0 found in
# the LICENSE.txt file in the root directory of this source tree.

"""Helper module for Qiskit compiler.
"""

from .run_config import RunConfig
from .transpile_config import TranspileConfig
from .assembler import assemble_circuits
from .transpiler import transpile
Loading

0 comments on commit 89ceb19

Please sign in to comment.