├── LICENSE ├── README.md ├── dynamicCircuits.py ├── iq.py └── run_openqasm3.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Pourya 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IBM-Quantum-Lab 2 | 3 | 4 | Qiskit_Runtime_architecture1 5 | 6 | 7 | 8 | 9 | Plans for 4 new quantum processors, breakthrough technologies and leaps forward in scale, quality and speed. Jay Gambetta and team take us on a journey to 2025 and the era of the quantum-centric supercomputer. 10 | 11 | 12 | 13 | 14 | ![ibm-q-hr](https://user-images.githubusercontent.com/13979489/180872278-3e3100d7-8976-4643-a61c-af084f3be245.jpg) 15 | 16 | 17 | 18 | 19 | 20 | ### VQE 21 | The Variational Quantum Eigensolver (VQE) is a central algorithm in many applications from e.g. quantum chemistry or optimization. This tutorial shows you how to run the VQE as a Qiskit Runtime program. We'll start off by defining the algorithm settings, such as the Hamiltonian and ansatz, and then run a VQE both locally, on your machine, and remotely, using the Qiskit Runtime. 22 | 23 | Note: You can find tutorials on solving more comprehensive problems, such as finding the ground state of the lithium hydride molecule, using the VQE (and Qiskit Runtime) within the tutorials of Qiskit Nature. 24 | 25 | ### System Hamiltonian 26 | 27 | Let's start by defining the operator of which we want to determine the ground state. Here we'll chose a simple diagonal Hamiltonian 𝐻̂ acting with Pauli-Z operators on the first two qubits 28 | 29 | 𝐻̂ =𝑍̂ 0⊗𝑍̂ 1. 30 | 31 | We can construct this Hamiltonian with Qiskit's opflow module: 32 | 33 | ```python 34 | from qiskit.opflow import Z, I 35 | 36 | num_qubits = 4 37 | hamiltonian = (Z ^ Z) ^ (I ^ (num_qubits - 2)) 38 | ``` 39 | 40 | This Hamiltonian has a ground state energy of -1. 41 | 42 | ```python 43 | target_energy = -1 44 | ``` 45 | 46 | ### Parameterized Ansatz Circuit 47 | Next, we choose a parameterized quantum circuit 𝑈̂ (𝜃) to prepare the ansatz wavefunction 48 | 49 | |𝜓(𝜃)⟩=𝑈̂ (𝜃)|0⟩. 50 | 51 | We'll use the EfficientSU2 circuit from Qiskit's circuit library, which is a hardware efficient, heuristic ansatz with alternating rotation and entanglement layers. 52 | 53 | ```python 54 | from qiskit.circuit.library import EfficientSU2 55 | 56 | # the rotation gates are chosen randomly, so we set a seed for reproducibility 57 | ansatz = EfficientSU2(num_qubits, reps=1, entanglement="linear", insert_barriers=True) 58 | ansatz.draw("mpl", style="iqx") 59 | ``` 60 | 61 | ![download](https://user-images.githubusercontent.com/13979489/180871441-08a39087-a752-40e0-a889-31b28edc2aa6.png) 62 | 63 | ### Solve with the VQE 64 | Now that we have the problem and ansatz specified we can use the Variational Quantum Eigensolver (VQE) to solve for the minimal eigenvalue of our Hamiltonian. 65 | 66 | The VQE requires a classical optimization routine, along with an initial point, to calculate the parameter updates. 67 | 68 | -------------------------------------------------------------------------------- /dynamicCircuits.py: -------------------------------------------------------------------------------- 1 | import os 2 | from typing import Any, List, Dict, Union 3 | 4 | import numpy as np 5 | import matplotlib.pyplot as plt 6 | 7 | from qiskit import IBMQ, QuantumCircuit, QuantumRegister, ClassicalRegister, quantum_info as qi 8 | from qiskit.providers.ibmq import RunnerResult 9 | from qiskit.result import marginal_counts 10 | import qiskit.tools.jupyter 11 | 12 | %matplotlib inline 13 | 14 | import warnings 15 | warnings.filterwarnings("ignore") 16 | -------------------------------------------------------------------------------- /iq.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | # Importing standard Qiskit libraries 4 | from qiskit import QuantumCircuit, transpile, Aer, IBMQ 5 | from qiskit.tools.jupyter import * 6 | from qiskit.visualization import * 7 | from ibm_quantum_widgets import * 8 | from qiskit.providers.aer import QasmSimulator 9 | 10 | # Loading your IBM Quantum account(s) 11 | provider = IBMQ.load_account() 12 | -------------------------------------------------------------------------------- /run_openqasm3.py: -------------------------------------------------------------------------------- 1 | """Helper methods for running OpenQASM 3 programs. 2 | 3 | (C) Copyright IBM 2021. 4 | 5 | """ 6 | 7 | from typing import List, Optional, Union 8 | 9 | from qiskit import QuantumCircuit, qasm3 10 | 11 | from qiskit.providers.ibmq import IBMQJob, IBMQBackend, RunnerResult 12 | 13 | QASM3_INPUT = Union[QuantumCircuit, str] 14 | 15 | from qiskit.providers.ibmq.job import IBMQJob 16 | 17 | Program = Union[QuantumCircuit, str] 18 | def run_openqasm3( 19 | circuits: Union[Program, List[Program]], 20 | backend, 21 | verbose: bool = True, 22 | draw: bool = True, 23 | runtime_image: Optional[str] = None, 24 | merge_circuits: bool = True, 25 | init_circuit: Optional[QuantumCircuit] = None, 26 | init_num_resets: int = 3, 27 | init_delay: float = 0., 28 | 29 | **run_config, 30 | ) -> List[IBMQJob]: 31 | """Run a list of Qiskit circuits or OpenQASM 3 strings through the Qiskit runtime. 32 | 33 | Args: 34 | circuits: QuantumCircuit or OpenQASM 3 source strings to run. 35 | backend: Backend to run on. 36 | verbose: Print out execution information 37 | draw: Draw the circuit. 38 | runtime_image: The Qiskit runtime base image to launch the runtime from. If not set this 39 | release. If you are using a different branch of Qiskit you may need to select another 40 | image such as "terra-main:latest". This is because Qiskit Terra's QPY is used to 41 | serialize and deserialize circuits to the runtime service. Having different versions 42 | of Qiskit Terra on your local machine compared to the remote Qiskit Runtime image 43 | may result in serialization/deserialization incompatibilities. Note: This is primarily 44 | for internal development purposes. 45 | merge_circuits: Whether to merge multiple QuantumCircuits into one single QuantumCircuit 46 | containing each individual circuit separated by an initialization circuit. 47 | This will greatly improve the performance of your runtime program and should 48 | almost always be used. The default initialization circuit is a series of qubit resets 49 | (the number of which may be configured with "init_num_resets" ) on qubits used 50 | in your experiment followed by a relaxation delay (Which may be specified with 51 | "init_delay". You may also provide your own initialization circuit through "init_circuit" 52 | init_num_resets: The number of qubit resets to insert before each circuit execution. 53 | init_delay: The number of microseconds of delay to insert before each circuit execution. 54 | run_config: Extra compilation / executions options such as the number of shots. 55 | 56 | """ 57 | 58 | if isinstance(circuits, (QuantumCircuit, str)): 59 | circuits = [circuits] 60 | 61 | config = backend.configuration() 62 | provider = backend.provider() 63 | 64 | for circuit_idx, circuit in enumerate(circuits): 65 | if verbose: 66 | if isinstance(circuit, QuantumCircuit): 67 | print(f"======={circuit.name}=======") 68 | print("=======OpenQASM 3======") 69 | print(qasm3.Exporter(includes=[], basis_gates=config.basis_gates).dumps(circuit)) 70 | print("==================") 71 | if draw: 72 | print(circuit.draw()) 73 | print("==================") 74 | else: 75 | print("=======OpenQASM 3======") 76 | print(circuit) 77 | 78 | 79 | runtime_params = { 80 | 'circuits': circuits, 81 | "run_config": run_config, 82 | "merge_circuits": merge_circuits, 83 | "init_num_resets": init_num_resets, 84 | "init_delay": init_delay, 85 | "init_circuit": init_circuit, 86 | } 87 | options = { 88 | 'backend_name': backend.name(), 89 | } 90 | job = provider.runtime.run( 91 | program_id="qasm3-runner", 92 | options=options, 93 | inputs=runtime_params, 94 | image=runtime_image, 95 | result_decoder=RunnerResult, 96 | ) 97 | if verbose: 98 | print(f"Running: {job.job_id()}") 99 | 100 | if verbose: 101 | result = job.result() 102 | for circuit_idx, circuit in enumerate(circuits): 103 | counts = result.get_counts(circuit_idx) 104 | if isinstance(circuit, QuantumCircuit): 105 | print(f"======={circuit.name}=======") 106 | else: 107 | print(f"==============") 108 | print (counts) 109 | 110 | return job 111 | 112 | 113 | --------------------------------------------------------------------------------