diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 63264533..a56a4bbe 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,22 +1,16 @@ repos: - repo: https://github.com/ambv/black - rev: 21.5b1 + rev: 21.12b0 hooks: - id: black language_version: python3 - repo: https://github.com/pycqa/flake8 - rev: 3.9.2 + rev: 4.0.1 hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: 'v0.812' + rev: 'v0.930' hooks: - id: mypy args: [--no-strict-optional, --ignore-missing-imports] - additional_dependencies: [cma==3.0.3, - numpy==1.19.5, - scipy==1.5.2, - tensorflow==2.4.2, - tensorflow-probability==0.12.1, - tensorflow-estimator==2.4.0 - ] + \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 1499cf87..4ca53cc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,12 @@ This Changelog tracks all past changes to this project as well as details about - `fixed` for any bug fixes. - `security` in case of vulnerabilities. +## Upcoming Version + +### Details + +- `added` proper physics simulation of circuits using qiskit interface #165 + ## Version `1.4` - 23 Dec 2021 ### Summary diff --git a/c3/experiment.py b/c3/experiment.py index f2c926a0..65189bb9 100755 --- a/c3/experiment.py +++ b/c3/experiment.py @@ -152,7 +152,7 @@ def quick_setup(self, cfg) -> None: qubit_1 = model.subsystems[props["qubit_1"]] qubit_2 = model.subsystems[props["qubit_2"]] instr = Instruction( - name=gate_name, + name=props["name"], targets=[ model.names.index(props["qubit_1"]), model.names.index(props["qubit_2"]), diff --git a/c3/libraries/propagation.py b/c3/libraries/propagation.py index b753b61f..ee4b0c92 100644 --- a/c3/libraries/propagation.py +++ b/c3/libraries/propagation.py @@ -165,7 +165,7 @@ def _get_hs_of_t_ts( ts = tf.constant(tf.math.reduce_mean(ts_list, axis=0)) if not np.all(tf.math.reduce_variance(ts_list, axis=0) < 1e-5 * (ts[1] - ts[0])): raise Exception("C3Error:Something with the times happend.") - if not np.all(tf.math.reduce_variance(ts[1:] - ts[:-1]) < 1e-5 * (ts[1] - ts[0])): + if not np.all(tf.math.reduce_variance(ts[1:] - ts[:-1]) < 1e-5 * (ts[1] - ts[0])): # type: ignore raise Exception("C3Error:Something with the times happend.") dt = tf.constant(ts[1 * prop_res].numpy() - ts[0].numpy(), dtype=tf.complex128) @@ -263,7 +263,7 @@ def pwc(model: Model, gen: Generator, instr: Instruction) -> Dict: ): raise Exception("C3Error:Something with the times happend.") if not np.all( - tf.math.reduce_variance(ts[1:] - ts[:-1]) < 1e-5 * (ts[1] - ts[0]) + tf.math.reduce_variance(ts[1:] - ts[:-1]) < 1e-5 * (ts[1] - ts[0]) # type: ignore ): raise Exception("C3Error:Something with the times happend.") diff --git a/c3/qiskit/c3_backend.py b/c3/qiskit/c3_backend.py index ce2f40c2..40d22431 100644 --- a/c3/qiskit/c3_backend.py +++ b/c3/qiskit/c3_backend.py @@ -375,8 +375,8 @@ def run_experiment(self, experiment: QasmQobjExperiment) -> Dict[str, Any]: # initialise parameters self._number_of_qubits = len(pmap.model.subsystems) - if self._number_of_qubits != experiment.config.n_qubits: - raise C3QiskitError("Number of qubits in Circuit & Device don't match") + if self._number_of_qubits < experiment.config.n_qubits: + raise C3QiskitError("Not enough qubits on device to run circuit") shots = self._shots @@ -453,7 +453,6 @@ def run_experiment(self, experiment: QasmQobjExperiment) -> Dict[str, Any]: class C3QasmPhysicsSimulator(C3QasmSimulator): - # TODO Boilerplate code. This simulator is not yet implemented. """A C3-based perfect gates simulator for Qiskit Parameters @@ -474,9 +473,12 @@ class C3QasmPhysicsSimulator(C3QasmSimulator): "open_pulse": False, "memory": False, "max_shots": 65536, - "coupling_map": None, + "coupling_map": None, # TODO Coupling map from config file "description": "A physics based c3 simulator for qasm experiments", - "basis_gates": [], # TODO add basis gates + "basis_gates": [ # TODO Basis gates from config file + "cx", + "x", + ], "gates": [], } @@ -544,14 +546,15 @@ def run_experiment(self, experiment: QasmQobjExperiment) -> Dict[str, Any]: # setup C3 Experiment exp = Experiment() - exp.quick_setup(self._device_config) + exp.load_quick_setup(self._device_config) + exp.enable_qasm() + exp.compute_propagators() # TODO only simulate qubits used in circuit pmap = exp.pmap - model = pmap.model # noqa # initialise parameters self._number_of_qubits = len(pmap.model.subsystems) - if self._number_of_qubits != experiment.config.n_qubits: - raise C3QiskitError("Number of qubits in Circuit & Device dont match") + if self._number_of_qubits < experiment.config.n_qubits: + raise C3QiskitError("Not enough qubits on device to run circuit") shots = self._shots # noqa @@ -564,24 +567,22 @@ def run_experiment(self, experiment: QasmQobjExperiment) -> Dict[str, Any]: # TODO set simulator seed, check qiskit python qasm simulator # qiskit-terra/qiskit/providers/basicaer/qasm_simulator.py seed_simulator = 2441129 + instructions_list = [ + instruction.to_dict() for instruction in experiment.instructions + ] - # convert qasm instruction set to c3 sequence - sequence = get_sequence(experiment.instructions) # noqa - - # TODO get_init_ground_state(), compute_propagators(), evaluate(), process() - - # generate shots style readout with no SPAM - # TODO a sophisticated readout/measurement routine - - # TODO generate state labels using get_labels() + pops = exp.evaluate([instructions_list]) + pop1s, _ = exp.process(pops) - # TODO create results dict and remove empty states - counts = {} # type: ignore + # TODO generate shots style readout ref Perfect Simulator + # TODO a sophisticated readout/measurement routine (w/ SPAM) + # C3 stores labels in exp.pmap.model.state_labels + counts = dict(zip(self.get_labels(), pop1s[0].numpy().tolist())) # flipping state labels to match qiskit style qubit indexing convention # default is to flip labels to qiskit style, use disable_flip_labels() - if self._flip_labels: - counts = flip_labels(counts) + # if self._flip_labels: + # counts = flip_labels(counts) end = time.time() diff --git a/examples/c3_qiskit.ipynb b/examples/c3_qiskit.ipynb index 5d057840..2040015f 100644 --- a/examples/c3_qiskit.ipynb +++ b/examples/c3_qiskit.ipynb @@ -43,6 +43,7 @@ }, "outputs": [], "source": [ + "from pprint import pprint\n", "import numpy as np\n", "from c3.qiskit import C3Provider\n", "from qiskit import transpile, execute, QuantumCircuit, Aer\n", @@ -69,21 +70,20 @@ }, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ - "" + "" ] }, + "execution_count": 3, "metadata": {}, - "execution_count": 3 + "output_type": "execute_result" } ], "source": [ - "qc = QuantumCircuit(6, 6)\n", - "qc.rx(np.pi/2, 0)\n", - "qc.rx(np.pi/2, 1)\n", - "qc.measure([0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5])" + "qc = QuantumCircuit(3, 3)\n", + "qc.x(0)\n", + "qc.cx(0, 1)" ] }, { @@ -99,29 +99,33 @@ }, "outputs": [ { - "output_type": "execute_result", "data": { - "text/plain": [ - " ┌─────────┐ ┌─┐ \n", - "q_0: ┤ RX(π/2) ├─────────┤M├───\n", - " ├─────────┤ └╥┘┌─┐\n", - "q_1: ┤ RX(π/2) ├──────────╫─┤M├\n", - " └───┬─┬───┘ ║ └╥┘\n", - "q_2: ────┤M├──────────────╫──╫─\n", - " └╥┘ ┌─┐ ║ ║ \n", - "q_3: ─────╫─────┤M├───────╫──╫─\n", - " ║ └╥┘┌─┐ ║ ║ \n", - "q_4: ─────╫──────╫─┤M├────╫──╫─\n", - " ║ ║ └╥┘┌─┐ ║ ║ \n", - "q_5: ─────╫──────╫──╫─┤M├─╫──╫─\n", - " ║ ║ ║ └╥┘ ║ ║ \n", - "c: 6/═════╩══════╩══╩══╩══╩══╩═\n", - " 2 3 4 5 0 1 " + "text/html": [ + "
     ┌───┐     \n",
+       "q_0: ┤ X ├──■──\n",
+       "     └───┘┌─┴─┐\n",
+       "q_1: ─────┤ X ├\n",
+       "          └───┘\n",
+       "q_2: ──────────\n",
+       "               \n",
+       "c: 3/══════════\n",
+       "               
" ], - "text/html": "
     ┌─────────┐         ┌─┐   \nq_0: ┤ RX(π/2) ├─────────┤M├───\n     ├─────────┤         └╥┘┌─┐\nq_1: ┤ RX(π/2) ├──────────╫─┤M├\n     └───┬─┬───┘          ║ └╥┘\nq_2: ────┤M├──────────────╫──╫─\n         └╥┘    ┌─┐       ║  ║ \nq_3: ─────╫─────┤M├───────╫──╫─\n          ║     └╥┘┌─┐    ║  ║ \nq_4: ─────╫──────╫─┤M├────╫──╫─\n          ║      ║ └╥┘┌─┐ ║  ║ \nq_5: ─────╫──────╫──╫─┤M├─╫──╫─\n          ║      ║  ║ └╥┘ ║  ║ \nc: 6/═════╩══════╩══╩══╩══╩══╩═\n          2      3  4  5  0  1 
" + "text/plain": [ + " ┌───┐ \n", + "q_0: ┤ X ├──■──\n", + " └───┘┌─┴─┐\n", + "q_1: ─────┤ X ├\n", + " └───┘\n", + "q_2: ──────────\n", + " \n", + "c: 3/══════════\n", + " " + ] }, + "execution_count": 4, "metadata": {}, - "execution_count": 4 + "output_type": "execute_result" } ], "source": [ @@ -149,7 +153,7 @@ "outputs": [], "source": [ "c3_provider = C3Provider()\n", - "c3_backend = c3_provider.get_backend(\"c3_qasm_perfect_simulator\")" + "c3_backend = c3_provider.get_backend(\"c3_qasm_physics_simulator\")" ] }, { @@ -165,10 +169,14 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "Name: c3_qasm_perfect_simulator\nVersion: 0.1\nMax Qubits: 20\nOpenPulse Support: False\nBasis Gates: ['cx', 'cz', 'iSwap', 'id', 'x', 'y', 'z', 'rx', 'ry', 'rz', 'rzx']\n" + "Name: c3_qasm_physics_simulator\n", + "Version: 0.1\n", + "Max Qubits: 10\n", + "OpenPulse Support: False\n", + "Basis Gates: ['cx', 'x']\n" ] } ], @@ -186,77 +194,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Let's view how the Qiskit Transpiler will convert the circuit" + "## Run a physical device simulation using C3" ] }, { "cell_type": "code", "execution_count": 7, - "metadata": { - "execution": { - "iopub.execute_input": "2021-01-27T04:59:44.819589Z", - "iopub.status.busy": "2021-01-27T04:59:44.818757Z", - "iopub.status.idle": "2021-01-27T04:59:44.952572Z", - "shell.execute_reply": "2021-01-27T04:59:44.951896Z" - } - }, - "outputs": [], - "source": [ - "trans_qc = transpile(qc, c3_backend)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "execution": { - "iopub.execute_input": "2021-01-27T04:59:44.961075Z", - "iopub.status.busy": "2021-01-27T04:59:44.960455Z", - "iopub.status.idle": "2021-01-27T04:59:44.965846Z", - "shell.execute_reply": "2021-01-27T04:59:44.966359Z" - } - }, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - " ┌─────────┐ ┌─┐ \n", - "q_0: ┤ RX(π/2) ├─────────┤M├───\n", - " ├─────────┤ └╥┘┌─┐\n", - "q_1: ┤ RX(π/2) ├──────────╫─┤M├\n", - " └───┬─┬───┘ ║ └╥┘\n", - "q_2: ────┤M├──────────────╫──╫─\n", - " └╥┘ ┌─┐ ║ ║ \n", - "q_3: ─────╫─────┤M├───────╫──╫─\n", - " ║ └╥┘┌─┐ ║ ║ \n", - "q_4: ─────╫──────╫─┤M├────╫──╫─\n", - " ║ ║ └╥┘┌─┐ ║ ║ \n", - "q_5: ─────╫──────╫──╫─┤M├─╫──╫─\n", - " ║ ║ ║ └╥┘ ║ ║ \n", - "c: 6/═════╩══════╩══╩══╩══╩══╩═\n", - " 2 3 4 5 0 1 " - ], - "text/html": "
     ┌─────────┐         ┌─┐   \nq_0: ┤ RX(π/2) ├─────────┤M├───\n     ├─────────┤         └╥┘┌─┐\nq_1: ┤ RX(π/2) ├──────────╫─┤M├\n     └───┬─┬───┘          ║ └╥┘\nq_2: ────┤M├──────────────╫──╫─\n         └╥┘    ┌─┐       ║  ║ \nq_3: ─────╫─────┤M├───────╫──╫─\n          ║     └╥┘┌─┐    ║  ║ \nq_4: ─────╫──────╫─┤M├────╫──╫─\n          ║      ║ └╥┘┌─┐ ║  ║ \nq_5: ─────╫──────╫──╫─┤M├─╫──╫─\n          ║      ║  ║ └╥┘ ║  ║ \nc: 6/═════╩══════╩══╩══╩══╩══╩═\n          2      3  4  5  0  1 
" - }, - "metadata": {}, - "execution_count": 8 - } - ], - "source": [ - "trans_qc.draw()" - ] - }, - { - "source": [ - "## Run an ideal device simulation using C3" - ], - "cell_type": "markdown", - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2021-01-27T04:59:44.975298Z", @@ -265,17 +208,26 @@ "shell.execute_reply": "2021-01-27T05:00:47.448767Z" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "No measurements in circuit \"circuit-0\", classical register will remain all zeros.\n", + "2021-12-29 11:55:17.185809: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:185] None of the MLIR Optimization Passes are enabled (registered 2)\n", + "2021-12-29 11:55:17.187947: W tensorflow/core/platform/profile_utils/cpu_utils.cc:128] Failed to get CPU frequency: 0 Hz\n" + ] + } + ], "source": [ - "c3_backend.set_device_config(\"quickstart.hjson\")\n", - "c3_backend.disable_flip_labels()\n", - "c3_job = execute(qc, c3_backend, shots=1000)\n", + "c3_backend.set_device_config(\"qiskit.cfg\")\n", + "c3_job = execute(qc, c3_backend)\n", "result = c3_job.result()" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2021-01-27T05:00:47.453142Z", @@ -286,21 +238,28 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "{'000000': 250, '010000': 250, '100000': 250, '110000': 250}\n" + "{'000': 0.005977052024699964,\n", + " '001': 3.309772803976941e-29,\n", + " '010': 0.5026307720154571,\n", + " '011': 5.253849204112465e-32,\n", + " '100': 0.08234031004302313,\n", + " '101': 1.185950334554713e-33,\n", + " '110': 0.40905186591686277,\n", + " '111': 6.79320316560621e-36}\n" ] } ], "source": [ - "res_counts = result.get_counts(qc)\n", - "print(res_counts)" + "res_counts = result.get_counts()\n", + "pprint(res_counts)" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2021-01-27T05:00:47.462110Z", @@ -311,49 +270,74 @@ }, "outputs": [ { - "output_type": "execute_result", "data": { + "image/png": "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\n", "text/plain": [ "
" - ], - "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-11T16:04:47.494981\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", - "image/png": "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\n" + ] }, + "execution_count": 9, "metadata": {}, - "execution_count": 11 + "output_type": "execute_result" } ], "source": [ - "plot_histogram(res_counts, title='C3 Perfect Devices simulation')" + "plot_histogram(res_counts, title='C3 Physical Device simulation')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As we can see above, the c3 simulator correctly calculates the populations taking into physical device coupling and unoptimized gate pulses." ] }, { + "cell_type": "markdown", + "metadata": {}, "source": [ "## Run Simulation and verify results on Qiskit simulator" - ], + ] + }, + { "cell_type": "markdown", - "metadata": {} + "metadata": {}, + "source": [ + "Qiskit uses little-endian bit ordering while most Quantum Computing literature uses big-endian. This is reflected in the reversed ordering of qubit labels here.\n", + "\n", + "Ref: [Basis Vector Ordering in Qiskit](https://qiskit.org/documentation/tutorials/circuits/3_summary_of_quantum_operations.html#Basis-vector-ordering-in-Qiskit)" + ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 10, "metadata": {}, "outputs": [ { - "output_type": "execute_result", + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/homebrew/Caskroom/miniforge/base/envs/c3-dev/lib/python3.8/site-packages/numpy/linalg/linalg.py:2158: RuntimeWarning: divide by zero encountered in det\n", + " r = _umath_linalg.det(a, signature=signature)\n", + "/opt/homebrew/Caskroom/miniforge/base/envs/c3-dev/lib/python3.8/site-packages/numpy/linalg/linalg.py:2158: RuntimeWarning: invalid value encountered in det\n", + " r = _umath_linalg.det(a, signature=signature)\n" + ] + }, + { "data": { + "image/png": "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\n", "text/plain": [ "
" - ], - "image/svg+xml": "\n\n\n\n \n \n \n \n 2021-03-11T16:04:47.768872\n image/svg+xml\n \n \n Matplotlib v3.3.4, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", - "image/png": "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hmHDhu3Q5t///jeXXnopY8eOZc8999zh2PXr1/Ppp58C8Oabb+4wgOjFF1/k1FNPpWXLltn5MiJSb1Q0RYCmTZvy0EMPceKJJ3LggQdy1lln0bt3b26++WbGjh0LwPDhw9m0aRNnnnkm/fr1qyyqTZo04e677+a4447joIMOwt25+OKLK889ZswYdc2KNBLm7rmOIWeKi4u9pKQk12GIiEiCmNk0dy+ubp+uNEVERGJS0RQRkbTUZfWsJk2aVK6SlTpuwN258cYb2X///TnwwAN54IEHsvJd0qUVgUREJLa6rp7VqlUr3n333S+cd/To0XzyySe8//77FBQUsGrVqmx9pbToSlNERGKry+pZtXn44Ye5+eabK5egTB2hniQqmiIiEltdVs8C2Lp1K8XFxQwcOJA//elPlds/+ugjnn/+eYqLizn55JOZP39+vcRfV+qeFRGRelGxetb48eMrty1evJguXbqwYMECjj32WA466CD23XdfSktLadmyJSUlJfzhD3/gwgsv3OGBB0mhK00REYmtLqtnVRwP0KNHD44++mj+/e9/A+GK9fTTTwfgm9/8JjNnzqzPr7HLVDRFRCS2uqyetW7dOkpLS4GwvORbb71VOYDotNNO45///CcA48ePZ//998/SN0qPumdFRCS21NWzysvLufDCCytXzyouLmbYsGE7rJ4F0K1bN8aOHcvcuXO59NJLKSgoYPv27dxwww2VRfOGG27g3HPP5d5776WwsJDf/e53ufyaNdKKQFoRSEREUmhFoASqy+RgCA81Lioq4sorr6zctm3bNi655BL2339/DjjgAF566aV6/x4iIvlERTMHKiYHv/LKK8yZM4fnnnuOOXPm7NCmYnLwzJkzOeOMM7j++ut32P+zn/2MwYMH77BtxIgR7LnnnsybN485c+YwZMiQev8uIiL5RPc0cyB1cjBQOTk4dUWNY445pvL1wIEDefrppyvfT5s2jZUrV3LSSSeR2r382GOP8f777wNQUFBAhw4d6vurJNbF9+U6gswZdU2uIxCRCrrSzIG6TA7evn071157LXffffcObdavXw+EK9ABAwZw5plnsnLlyswHLyKSx1Q0E65icvDw4cMBGDlyJKeccgpFRUU7tCsrK2PJkiUcccQRTJ8+ncMPP5zrrrsuFyGLiDRa6p7NgXQnB48fP75ycvDkyZOZ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\n" + ] }, + "execution_count": 10, "metadata": {}, - "execution_count": 12 + "output_type": "execute_result" } ], "source": [ "qiskit_simulator = Aer.get_backend('qasm_simulator')\n", + "qc.measure([0, 1, 2], [0, 1, 2])\n", "qiskit_result = execute(qc, qiskit_simulator, shots=1000).result()\n", "counts = qiskit_result.get_counts(qc)\n", "plot_histogram(counts, title='Qiskit simulation')" @@ -362,13 +346,9 @@ ], "metadata": { "kernelspec": { - "name": "python3", - "display_name": "Python 3.8.5 64-bit", - "metadata": { - "interpreter": { - "hash": "5a55665ade3e65c3d9088c5eff5fc5091af84ead5e61e59beae6d6d9de42aec4" - } - } + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -380,9 +360,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.5-final" + "version": "3.8.12" } }, "nbformat": 4, "nbformat_minor": 4 -} \ No newline at end of file +} diff --git a/examples/generator.cfg b/examples/generator.cfg index 4ade5e88..66312b47 100644 --- a/examples/generator.cfg +++ b/examples/generator.cfg @@ -47,21 +47,21 @@ } }, "Chains": { - "d1": { - "LO": [], - "AWG": [], - "DigitalToAnalog": ["AWG"], - "Response": ["DigitalToAnalog"], - "Mixer": ["LO", "Response"], - "VoltsToHertz": ["Mixer"] - }, - "d2": { - "LO": [], - "AWG": [], - "DigitalToAnalog": ["AWG"], - "Response": ["DigitalToAnalog"], - "Mixer": ["LO", "Response"], - "VoltsToHertz": ["Mixer"] - }, + "d1": { + "LO": [], + "AWG": [], + "DigitalToAnalog": ["AWG"], + "Response": ["DigitalToAnalog"], + "Mixer": ["LO", "Response"], + "VoltsToHertz": ["Mixer"] + }, + "d2": { + "LO": [], + "AWG": [], + "DigitalToAnalog": ["AWG"], + "Response": ["DigitalToAnalog"], + "Mixer": ["LO", "Response"], + "VoltsToHertz": ["Mixer"] + }, } } diff --git a/examples/qiskit.cfg b/examples/qiskit.cfg new file mode 100644 index 00000000..349374ad --- /dev/null +++ b/examples/qiskit.cfg @@ -0,0 +1,29 @@ +{ + "optim_type": "C1", + "run_name" : "qiskit", + "include_model" : true, + "model" : "test_model.cfg", + "generator": "generator.cfg", + "v2hz": 1e9 + "sideband": 50e6 + "single_qubit_gate_time" : 20e-9 + "single_qubit_gates": + { + "rx90pQ1": {name: "x", "qubits": "Q1"}, + "rx90pQ2": {name: "x", "qubits": "Q2"}, + } + "two_qubit_gates": + { + "cx01": + { + name: "cx" + qubit_1: Q1 + qubit_2: Q2 + gate_time: 50e-9 + }, + } + "dir_path" : "/tmp", + "algorithm" : lbfgs, + "fid_func" : average_infid_set, + "fid_subspace" : ["Q1", "Q2"], +} diff --git a/examples/test_model.cfg b/examples/test_model.cfg index b68e949e..36d7733d 100644 --- a/examples/test_model.cfg +++ b/examples/test_model.cfg @@ -39,45 +39,6 @@ }, "hilbert_dim" : 2 }, - "Q4" : { - "c3type": "Qubit", - "desc" : "Qubit 2", - "params": { - "freq" : { - "value" : 5.2e9, - "unit" : "Hz 2pi", - "min_val" : 4.5e9, - "max_val" : 5.5e9 - } - }, - "hilbert_dim" : 2 - }, - "Q5" : { - "c3type": "Qubit", - "desc" : "Qubit 1", - "params": { - "freq" : { - "value" : 5.1e9, - "unit" : "Hz 2pi", - "min_val" : 4.5e9, - "max_val" : 5.5e9 - } - }, - "hilbert_dim" : 2 - }, - "Q6" : { - "c3type": "Qubit", - "desc" : "Qubit 2", - "params": { - "freq" : { - "value" : 4.6e9, - "unit" : "Hz 2pi", - "min_val" : 4.5e9, - "max_val" : 5.5e9 - } - }, - "hilbert_dim" : 2 - } }, "Couplings" : { "Q1-Q2" : { @@ -94,20 +55,6 @@ "hamiltonian_func" : "int_XX", "connected" : ["Q1", "Q2"] }, - "Q4-Q6" : { - "c3type": "Coupling", - "desc" : "Coupling qubit 1 and 2", - "params": { - "strength" : { - "value" : 20e6, - "unit" : "Hz 2pi", - "min_val" : -1e6, - "max_val" : 50e6 - } - }, - "hamiltonian_func" : "int_XX", - "connected" : ["Q4", "Q6"] - }, "d1" : { "c3type": "Drive", "desc" : "Drive on qubit 1", diff --git a/test/conftest.py b/test/conftest.py index d6481010..c6582fe7 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -90,19 +90,29 @@ def get_bad_circuit() -> QuantumCircuit: @pytest.fixture() -def get_6_qubit_circuit() -> QuantumCircuit: - """fixture for 6 qubit Quantum Circuit +def get_3_qubit_circuit() -> QuantumCircuit: + """fixture for 3 qubit Quantum Circuit Returns ------- QuantumCircuit - A circuit with an X on qubit 1 """ - qc = QuantumCircuit(6, 6) + qc = QuantumCircuit(3, 3) qc.rx(np.pi / 2, 0) qc.rx(np.pi / 2, 1) - qc.measure([0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]) + qc.measure( + [ + 0, + 1, + 2, + ], + [ + 0, + 1, + 2, + ], + ) return qc @@ -132,7 +142,7 @@ def get_result_qiskit() -> Dict[str, Dict[str, Any]]: """ # Result of physics based sim for applying X on qubit 0 in 6 qubits - perfect_counts = {"000000": 250, "010000": 250, "100000": 250, "110000": 250} + perfect_counts = {"000": 250, "010": 250, "100": 250, "110": 250} counts_dict = { "c3_qasm_perfect_simulator": perfect_counts, diff --git a/test/qiskit.cfg b/test/qiskit.cfg new file mode 100644 index 00000000..22bc1a43 --- /dev/null +++ b/test/qiskit.cfg @@ -0,0 +1,29 @@ +{ + "optim_type": "C1", + "run_name" : "qiskit", + "include_model" : true, + "model" : "test/test_model.cfg", + "generator": "test/generator.cfg", + "v2hz": 1e9 + "sideband": 50e6 + "single_qubit_gate_time" : 20e-9 + "single_qubit_gates": + { + "rx90pQ1": {name: "x", "qubits": "Q1"}, + "rx90pQ2": {name: "x", "qubits": "Q2"}, + } + "two_qubit_gates": + { + "cx01": + { + name: "cx" + qubit_1: Q1 + qubit_2: Q2 + gate_time: 50e-9 + }, + } + "dir_path" : "/tmp", + "algorithm" : lbfgs, + "fid_func" : average_infid_set, + "fid_subspace" : ["Q1", "Q2"], +} diff --git a/test/test_model.cfg b/test/test_model.cfg index b68e949e..36d7733d 100644 --- a/test/test_model.cfg +++ b/test/test_model.cfg @@ -39,45 +39,6 @@ }, "hilbert_dim" : 2 }, - "Q4" : { - "c3type": "Qubit", - "desc" : "Qubit 2", - "params": { - "freq" : { - "value" : 5.2e9, - "unit" : "Hz 2pi", - "min_val" : 4.5e9, - "max_val" : 5.5e9 - } - }, - "hilbert_dim" : 2 - }, - "Q5" : { - "c3type": "Qubit", - "desc" : "Qubit 1", - "params": { - "freq" : { - "value" : 5.1e9, - "unit" : "Hz 2pi", - "min_val" : 4.5e9, - "max_val" : 5.5e9 - } - }, - "hilbert_dim" : 2 - }, - "Q6" : { - "c3type": "Qubit", - "desc" : "Qubit 2", - "params": { - "freq" : { - "value" : 4.6e9, - "unit" : "Hz 2pi", - "min_val" : 4.5e9, - "max_val" : 5.5e9 - } - }, - "hilbert_dim" : 2 - } }, "Couplings" : { "Q1-Q2" : { @@ -94,20 +55,6 @@ "hamiltonian_func" : "int_XX", "connected" : ["Q1", "Q2"] }, - "Q4-Q6" : { - "c3type": "Coupling", - "desc" : "Coupling qubit 1 and 2", - "params": { - "strength" : { - "value" : 20e6, - "unit" : "Hz 2pi", - "min_val" : -1e6, - "max_val" : 50e6 - } - }, - "hamiltonian_func" : "int_XX", - "connected" : ["Q4", "Q6"] - }, "d1" : { "c3type": "Drive", "desc" : "Drive on qubit 1", diff --git a/test/test_parsers.py b/test/test_parsers.py index 57f8baf6..e4b006cc 100644 --- a/test/test_parsers.py +++ b/test/test_parsers.py @@ -26,12 +26,16 @@ def test_name_collision() -> None: @pytest.mark.unit def test_subsystems() -> None: - assert list(model.subsystems.keys()) == ["Q1", "Q2", "Q3", "Q4", "Q5", "Q6"] + assert list(model.subsystems.keys()) == [ + "Q1", + "Q2", + "Q3", + ] @pytest.mark.unit def test_couplings() -> None: - assert list(model.couplings.keys()) == ["Q1-Q2", "Q4-Q6", "d1", "d2"] + assert list(model.couplings.keys()) == ["Q1-Q2", "d1", "d2"] @pytest.mark.unit @@ -45,8 +49,8 @@ def test_tasks() -> None: @pytest.mark.unit -def test_q6_freq() -> None: - assert str(model.subsystems["Q6"].params["freq"]) == "4.600 GHz 2pi " +def test_q3_freq() -> None: + assert str(model.subsystems["Q3"].params["freq"]) == "5.000 GHz 2pi " @pytest.mark.unit diff --git a/test/test_qiskit.py b/test/test_qiskit.py index 222dc827..f33837dd 100644 --- a/test/test_qiskit.py +++ b/test/test_qiskit.py @@ -7,7 +7,7 @@ from qiskit.quantum_info import Statevector from qiskit import transpile from qiskit.providers import BackendV1 as Backend -from qiskit import execute +from qiskit import execute, QuantumCircuit import pytest @@ -22,7 +22,9 @@ def test_backends(): @pytest.mark.unit @pytest.mark.qiskit -@pytest.mark.parametrize("backend", ["c3_qasm_perfect_simulator"]) +@pytest.mark.parametrize( + "backend", ["c3_qasm_perfect_simulator", "c3_qasm_physics_simulator"] +) def test_get_backend(backend): """Test get_backend() which returns the backend with matching name @@ -62,13 +64,13 @@ def test_transpile(get_test_circuit, backend): # noqa @pytest.mark.qiskit @pytest.mark.slow @pytest.mark.parametrize("backend", ["c3_qasm_perfect_simulator"]) -def test_get_result(get_6_qubit_circuit, backend, get_result_qiskit): # noqa - """Test the counts from running a 6 qubit Circuit +def test_get_result(get_3_qubit_circuit, backend, get_result_qiskit): # noqa + """Test the counts from running a 3 qubit Circuit Parameters ---------- - get_6_qubit_circuit : callable - pytest fixture for a 6 qubit circuit + get_3_qubit_circuit : callable + pytest fixture for a 3 qubit circuit backend : str name of the backend which is to be tested simulation_type: str @@ -80,7 +82,7 @@ def test_get_result(get_6_qubit_circuit, backend, get_result_qiskit): # noqa received_backend = c3_qiskit.get_backend(backend) received_backend.set_device_config("test/quickstart.hjson") received_backend.disable_flip_labels() - qc = get_6_qubit_circuit + qc = get_3_qubit_circuit job_sim = execute(qc, received_backend, shots=1000) result_sim = job_sim.result() @@ -121,3 +123,39 @@ def test_get_exception(get_bad_circuit, backend): # noqa with pytest.raises(C3QiskitError): execute(qc, received_backend, shots=1000) + + +def test_qiskit_physics(): + """API test for qiskit physics simulation""" + c3_qiskit = C3Provider() + physics_backend = c3_qiskit.get_backend("c3_qasm_physics_simulator") + physics_backend.set_device_config("test/qiskit.cfg") + qc = QuantumCircuit(3, 3) + qc.x(0) + qc.cx(0, 1) + job_sim = execute(qc, physics_backend) + print(job_sim.result().get_counts()) + + +@pytest.mark.parametrize( + "backend", + [ + ("c3_qasm_perfect_simulator", "test/quickstart.hjson"), + ("c3_qasm_physics_simulator", "test/qiskit.cfg"), + ], +) +def test_too_many_qubits(backend): + """Check that error is raised when circuit has more qubits than device + + Parameters + ---------- + backend : tuple + name and device config of the backend to be tested + """ + c3_qiskit = C3Provider() + received_backend = c3_qiskit.get_backend(backend[0]) + received_backend.set_device_config(backend[1]) + qc = QuantumCircuit(4, 4) + qc.x(1) + with pytest.raises(C3QiskitError): + execute(qc, received_backend, shots=1000)