<jupyter_start><jupyter_text>Trusted Notebook" width="500 px" align="left">  _*Working with Different Backends*_ In this tutorial, we will first describe the various [backends](backends) available in Qiskit and how to find out more information about each of them, then we will explore how Qiskit allows you to compile and run the same quantum circuit on different backends with different topology. The latest version of this notebook is available on https://github.com/qiskit/qiskit-tutorial.*** Contributors<NAME>, <NAME>, <NAME>, <NAME>  Qiskit's Backend ArchitectureAt the core of Qiskit is the ability to access different backends to run your quantum programs. These backends are real devices, online simulators, and local simulators. As we continue to increase the flexibility of Qiskit we expect there to be many different backends. These will include new hardware with different number of qubits, connectivity, different gate sets, and simulators with different properties. Current devices can be found on the (devices page)[https://quantumexperience.ng.bluemix.net/qx/devices] of the IBM Q Experience.The simulators are grouped by functionality:* QASM simulators - these simulate a quantum circuit and predict the outcomes of a quantum experiment. * Unitary simulators – predicts the unitary of a quantum circuit without measurement and conditional operations.* Statevector simulators - predicts the statevector output resulting from the evolution of the zero state through a quantum circuit, without measurement and conditional operations.The three important parts defining Qiskit's backends are: the `provider`, the `backend`, and the `job` object. * The *provider* is responsible for providing access to some backends. Qiskit comes with a `LocalProvider` by default, giving you access to local simualtors. Using a simple `register` command, you are able to access the backends available from IBMQ, including its devices and online simulators. Once the correct authentication with a provider is performed, all of its backends are available for running jobs.* The *backend* is responsible for running a `Qobj` (compiled program), and reporting a result.* The *job* is the result of an execution. Jobs in Qiskit are launched asynchronously, meaning you get control of your Python program after you launch an execution, with a handle to the job that was submitted. You may then continue to inquire about the status of a job, or once complete, see the result from a job.<jupyter_code>import sys, time, getpass
try:
    sys.path.append("../../") # go to parent dir
    import Qconfig
    qx_config = {
        "APItoken": Qconfig.APItoken,
        "url": Qconfig.config['url']}
    print('Qconfig loaded from %s.' % Qconfig.__file__)
except:
    APItoken = getpass.getpass('Please input your token and hit enter: ')
    qx_config = {
        "APItoken": APItoken,
        "url":"https://quantumexperience.ng.bluemix.net/api"}
    print('Qconfig.py not found in qiskit-tutorial directory; Qconfig loaded using user input.')
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
from qiskit import available_backends, execute, register, get_backend, compile

from qiskit.tools.visualization import plot_histogram
from pprint import pprint<jupyter_output><empty_output><jupyter_text>The Local and IBMQ providersA provider must be registered and it must support three funtions: `available_backends()` and `get_backend()` and a method to register the provider.```available_backends() - list all the backends of the resistered backends``````get_backend('name') - get a backend instance from a name ```Lets start with the  `available_backends()` command<jupyter_code>available_backends()<jupyter_output><empty_output><jupyter_text>This list is compact and picks the best of the diffent types. To list all the backends not just group names, you can use:<jupyter_code>available_backends(compact=False)<jupyter_output><empty_output><jupyter_text>To add the IBMQ provider you need to register it using```register(arg,...)```<jupyter_code>register(qx_config['APItoken'], qx_config['url'])
available_backends()<jupyter_output><empty_output><jupyter_text>The `available_backends` function can also use filters.Filter: show remote backends only<jupyter_code>available_backends({'local': False})<jupyter_output><empty_output><jupyter_text>Filter: show only local backends<jupyter_code>available_backends({'local': True})<jupyter_output><empty_output><jupyter_text>Filer: show only simulators<jupyter_code>available_backends({'simulator': True})<jupyter_output>Got a 400 code response to https://quantumexperience.ng.bluemix.net/api/Backends?access_token=GWHI8WFVHz2dkwx84OIWpmdVSZd6QeRHWax1xK1M9KnG4EG16AraVzFA81mHuJsL: {"error":{"status":400,"message":"Generic error","code":"GENERIC_ERROR"}}
Got a 400 code response to https://quantumexperience.ng.bluemix.net/api/Backends/ibmqx5/queue/status: {"error":{"status":400,"message":"Generic error","code":"GENERIC_ERROR"}}<jupyter_text>Fileter: show only real devices<jupyter_code>available_backends({'simulator': False})<jupyter_output><empty_output><jupyter_text>Filter: show both a remote backend and a simulator backend<jupyter_code>available_backends({'local': False, 'simulator': True})<jupyter_output><empty_output><jupyter_text>Filter: show currently operational devices (devices that are actively running jobs)<jupyter_code>available_backends({'operational': True, 'simulator': False})<jupyter_output>Got a 400 code response to https://quantumexperience.ng.bluemix.net/api/Backends?access_token=<KEY>: {"error":{"status":400,"message":"Generic error","code":"GENERIC_ERROR"}}<jupyter_text>Filter: show devices with more than 10 qubits<jupyter_code>available_backends(lambda x: x.configuration['n_qubits'] > 10 and not x.configuration['simulator'])<jupyter_output><empty_output><jupyter_text>Filter: show the least busy device (in terms of pending jobs in the queue)<jupyter_code>from qiskit import least_busy
least_busy(available_backends({'simulator': False}))<jupyter_output><empty_output><jupyter_text>The above filters can be combined as desired.The second function `get_backend()` allows you to make a backend instance<jupyter_code>backends = []
for backend in available_backends():
    backends.append(get_backend(backend))
backends<jupyter_output><empty_output><jupyter_text>The BackendsThe next part is the backend instances. These backends must support the following functions:```configuration - gets the configuration of the backend.``````properties -  gets the properties of the backend (currently calibrations and parameters, but will be combined).``````schema -  returns the schema for the qobj object supported by this backend (not implemented yet).``````status - gets the status of the backend.``````jobs  -  returns a list of previous jobs executed by this user on this backend.``````run  - runs a qobj on the backend.``` Lets start with the `status`:    `available` lets us know that the backend is taking jobs    `pending_jobs` lets you know how many jobs are in the queue<jupyter_code>for backend in backends:
    pprint(backend.status)<jupyter_output>{'pending_jobs': 0, 'name': 'ibmq_qasm_simulator', 'operational': True}
{'pending_jobs': 330, 'name': 'ibmq_5_yorktown', 'operational': False}
{'pending_jobs': 15, 'name': 'ibmq_5_tenerife', 'operational': True}
{'pending_jobs': 23, 'name': 'ibmq_16_rueschlikon', 'operational': True}
{'name': 'local_qasm_simulator_cpp', 'operational': True, 'pending_jobs': 0}
{'name': 'local_statevector_simulator_cpp',
 'operational': True,
 'pending_jobs': 0}
{'name': 'local_unitary_simulator_py', 'operational': True, 'pending_jobs': 0}<jupyter_text>The next is `configuration`<jupyter_code>for backend in backends:
    pprint(backend.configuration)
for backend in backends:
    pprint(backend.parameters)
for backend in backends:
    pprint(backend.calibration)<jupyter_output>{}
{'backend': 'ibmq_5_yorktown',
 'last_update_date': '2018-04-13T15:53:48.000Z',
 'multi_qubit_gates': [{'gateError': {'date': '2018-04-13T15:53:48Z',
                                      'value': 0.02724902259050041},
                        'name': 'CX0_1',
                        'qubits': [0, 1],
                        'type': 'CX'},
                       {'gateError': {'date': '2018-04-13T15:53:48Z',
                                      'value': 0.041787588869506564},
                        'name': 'CX0_2',
                        'qubits': [0, 2],
                        'type': 'CX'},
                       {'gateError': {'date': '2018-04-13T15:53:48Z',
                                      'value': 0.03767722967662601},
                        'name': 'CX1_2',
                        'qubits': [1, 2],
                        'type': 'CX'},
                       {'gateError': {'date': '2018-04-13T15:53:48Z',
                                      'value': 0.03973092259282[...]<jupyter_text>The Job objectTo get a job first we must get a `qobj` (quantum object code). This is a list of circuits compiled to a backend. To get this we have made a `compile` funtion that converts an array of circuits into a `qobj`. The reason this is an array is for current hardware lists of circuits are loaded onto the equipment at once and it is much more efficent to run this in a batch mode. The methods of the jobs object are:```status - returns the status.``````done - returns a bool true if done.``````id  - gets the job_id (not supported in the local provider yet).``````cancel - cancels the job (not supported on remote-public or local. Only supported on IBM Q premium devices).``````result - gets the results from the circuit run.```<jupyter_code>qr = QuantumRegister(3)
cr = ClassicalRegister(3)
circuit = QuantumCircuit(qr, cr)
circuit.x(qr[0])
circuit.x(qr[1])
circuit.ccx(qr[0], qr[1], qr[2])
circuit.cx(qr[0], qr[1])
circuit.measure(qr, cr)
my_backend = get_backend('local_qasm_simulator')
qobj = compile(circuit, backend=my_backend, shots=1024)
job = my_backend.run(qobj)
job.status
job.done
result = job.result()
counts = result.get_counts()
print(counts)
device_name = least_busy(available_backends({'simulator': False}))
my_backend = get_backend(device_name)
qobj = compile(circuit, backend=my_backend, shots=1024)
job = my_backend.run(qobj)
lapse = 0
interval = 10
while not job.done:
    print('Status @ {} seconds'.format(interval * lapse))
    print(job.status)
    time.sleep(interval)
    lapse += 1
print(job.status)
job.id
result = job.result()
counts = result.get_counts()
print(counts)
plot_histogram(counts)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10824352429570808, 'fraction_numerical': 0.021837776517300057, 'mean_word_length': 4.913359418669648, 'pattern_counts': {'":': 16, '<': 66, '<?xml version=': 0, '>': 68, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '16', 'dir': 'jupyter-structured-clean-dedup', 'id': '178149', 'license': 'Apache-2.0', 'n_tokens_mistral': 3336, 'n_tokens_neox': 3057, 'n_words': 1024, 'path': 'reference/tools/working_with_backends.ipynb', 'repo_name': 'BrooklynZN/qiskit-tutorial', 'size': '10656'}