qiskit-extensions / circuit-knitting-toolbox Goto Github PK
View Code? Open in Web Editor NEWTools for knitting quantum circuits with Qiskit
Home Page: https://qiskit-extensions.github.io/circuit-knitting-toolbox/
License: Apache License 2.0
Tools for knitting quantum circuits with Qiskit
Home Page: https://qiskit-extensions.github.io/circuit-knitting-toolbox/
License: Apache License 2.0
All docstrings should follow the same pattern and have consistent styling.
We may want to follow up on this and begin to create a style guide for this repo.
Create a TestRuntimeService class, so we can execute the lines of code associated with runtime in the unit tests.
EntanglementForgingResult.eigenstate
returns the minimum eigenvalue found during the forging routine, but it does not include the energy shift that must be applied to find the estimated ground state energy.
Add a node to the EF tutorials showing how to find the shifted ground state energy, and explain what the energy shift is.
Link to Qiskit by default. Add non-conflicting w Qiskit (more strict) styles.
Note: We may have to wait for Quantum Serverless to accept Qiskit Nature 0.6.0 before we migrate
Migrate to Qiskit Nature 0.6.0. Resolution of this issue should result in zero deprecation warnings from Qiskit Nature during unit testing.
Resolution of this issue should include a function which generates all the experiments needed to conduct a quasiprobability simulation. Its inputs, at minimum, should include the circuit containing QPD gates and the observables of interest.
Ensure all new circuit cutting documentation, including any tutorials and how-tos, is complete and consistent.
QPD can be used to cut a circuit and reconstruct a simulated expectation value. To do this, we need to evaluate an exponential number of experiments on the backend for each observable we are interested in.
Resolution of this issue will include:
Options
object
We should support both cases:
The two-body integrals in EF are decomposed into a ListOp
of single body integrals.
ListOp
is deprecated and should be replaced with something outside of opflow, potentially PauliList
#97 introduces an instruction which can be decomposed into its defined quasiprobability basis.
Although these instructions could be decomposed automatically using QuantumCircuit.decompose
, users should be able to use this library to decompose only their QPD instructions without having to do conversions both to and from DAGCircuit
, which is how QuantumCircuit.decompose
is implemented.
Resolution of this issue should include a function which decomposes all QPD instructions in a quantum circuit without doing conversions to and from DAGCircuit representation.
Determine whether this triple for loop is as inefficient as it looks as number of cuts grows.
If it is slowing down drastically as number of cuts grows, find a way to make it more efficient and expand this bottleneck in the workflow.
The name of the tool/algorithm should be at the top level of the directory
pyproject.toml
to make cplex and DOcplex optional dependenciesQiskit Nature 0.5.0 brings an overhaul to the structure of the package, so migrating will be non-trivial.
Due to the wide-reaching affects of the Nature refactor, and the pre-beta status of circuit-knitting-toolbox
, we will not offer a deprecation period for handling the Qiskit Nature < 0.5.0 inputs. What this generally means for users is that they should prepare their input ElectronicStructureProblem
in the more modern way, by building up a hamiltonian using the ElectronicEnergy
. Entanglement forging will no longer accept the legacy inputs, such as qiskit_nature.problems.second_quantization.ElectronicStructureProblem
.
Resolution of this issue should also include updates to the tutorials and how-tos, showing how to build up the new objects offered in Nature >= 0.5.0.
This package is noisy with warnings and is no longer worth it. We can use np.ndarray
as the type for all of these instances
At some point, we will likely want to change the installation instructions to suggest that users install the latest stable version via pip install
from pypi rather than the latest development version (main
branch) via git clone
.
A few open questions, though:
pip install
command.)Dockerfile
, too, so that it installs the latest released version?#96 will introduce a data structure for defining one decomposition.
Resolution of this issue should include a Qiskit Instruction
object which wraps one of the decompositions defined by the introduction of #96. This instruction should work automatically with the Qiskit decomposition process and should decompose into its defined random quasiprobabilistic basis instructions.
The freezing orbital how-to should show how to use the EFGroundStateSolver
to freeze orbitals, as this is the way we intend users to do it.
Resolution of this issue should include a function which reconstructs the results of the quasiprobability simulation experiments into an expectation value for the full, uncut circuit. This function will need information generated throughout the workflow.
Generally, users should:
Create a how-to for freezing orbitals
Create a how-to for specifying different bitstrings for each subsystem.
Waiting on Qiskit/qiskit-serverless#413
Changed as part of #230:
Once the serverless issue is resolved:
notebook
environment in tox.ini
test the forging + serverless notebook once againdocker.yml
workflow test the forging + serverless notebook once again (changed in #328)There are some gates which have known optimal decompositions. Implement an interface for creating a quasiprobability decomposition, given a Qiskit Instruction with a known optimal decomposition.
# This code is a Qiskit project.
#
# (C) Copyright IBM 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright # updated to say "This code is a Qiskit project." if possible
keep version table, but copy/paste the text generated by %qiskit_copyright in place of modifying that util
LICENSE.txt
Support both cases:
The tests in this file are really about cutting, so we should move the file (and possibly rename it).
To support a circuit cutting workflow, a function is needed which takes a quantum circuit and partitions it according to some boundary inputs.
Resolution of this issue should include a function which automatically replaces instructions which lie across a specified qubit boundary with their optimal decompositions.
In general, a circuit could contain many different elements which could be quasiprobabilistically simulated in one experiment.
Resolution of this issue will include a function which allows for easy sampling of many different QPD bases' joint probability distribution.
This isn't a general enough util to justify being at that level. It should be moved within EF.
Currently, entanglement forging only accepts strings for backends. It should accept both strings and Backends
The typing package has deprecated List
and Tuple
in favor of the base types. Ensure no deprecated types are being used.
Test comparisons should be formatted like (tested_value, expected_value)
Resolution of this issue includes adjusting all comparisons in all tests to adhere to this custom
Hello,
I am trying to run the freeze orbitals code found here https://qiskit-extensions.github.io/circuit-knitting-toolbox/how-tos/entanglement_forging/freeze-orbitals.html
However I run into the following problem, as if the reduction was not properly applied:
ValueError: The number of qubits of the 0-th circuit (5) does not match the number of qubits of the 0-th observable (7).
from matplotlib import pyplot as plt
import numpy as np
from qiskit.circuit import QuantumCircuit, Parameter
from qiskit.circuit.library import TwoLocal
from qiskit.algorithms.optimizers import COBYLA
from qiskit_nature.drivers import Molecule
from qiskit_nature.drivers.second_quantization import PySCFDriver
from qiskit_nature.problems.second_quantization import ElectronicStructureProblem
from qiskit_nature.mappers.second_quantization import JordanWignerMapper
from qiskit_nature.converters.second_quantization import QubitConverter
from qiskit_nature.algorithms.ground_state_solvers import (
GroundStateEigensolver,
NumPyMinimumEigensolverFactory,
)
from circuit_knitting_toolbox.entanglement_forging import (
EntanglementForgingAnsatz,
EntanglementForgingGroundStateSolver,
)
from circuit_knitting_toolbox.utils import reduce_bitstrings
from qiskit_ibm_runtime import QiskitRuntimeService, Options
from circuit_knitting_toolbox.entanglement_forging import (
EntanglementForgingGroundStateSolver,
)
radius_1 = 0.958 # position for the first H atom
radius_2 = 0.958 # position for the second H atom
thetas_in_deg = 104.478 # bond angles.
H1_x = radius_1
H2_x = radius_2 * np.cos(np.pi / 180 * thetas_in_deg)
H2_y = radius_2 * np.sin(np.pi / 180 * thetas_in_deg)
molecule = Molecule(
geometry=[
["O", [0.0, 0.0, 0.0]],
["H", [H1_x, 0.0, 0.0]],
["H", [H2_x, H2_y, 0.0]],
],
charge=0,
multiplicity=1,
)
driver = PySCFDriver.from_molecule(molecule=molecule, basis="sto6g")
problem = ElectronicStructureProblem(driver)
converter = QubitConverter(JordanWignerMapper())
theta = Parameter("θ")
hop_gate = QuantumCircuit(2, name="Hop gate")
hop_gate.h(0)
hop_gate.cx(1, 0)
hop_gate.cx(0, 1)
hop_gate.ry(-theta, 0)
hop_gate.ry(-theta, 1)
hop_gate.cx(0, 1)
hop_gate.h(0)
theta_1, theta_2, theta_3, theta_4 = (
Parameter("θ1"),
Parameter("θ2"),
Parameter("θ3"),
Parameter("θ4"),
)
circuit_u = QuantumCircuit(5)
circuit_u.append(hop_gate.to_gate({theta: theta_1}), [0, 1])
circuit_u.append(hop_gate.to_gate({theta: theta_2}), [3, 4])
circuit_u.append(hop_gate.to_gate({theta: 0}), [1, 4])
circuit_u.append(hop_gate.to_gate({theta: theta_3}), [0, 2])
circuit_u.append(hop_gate.to_gate({theta: theta_4}), [3, 4])
orbitals_to_reduce = [0, 3]
bitstrings_u = [(1, 1, 1, 1, 1, 0, 0), (1, 0, 1, 1, 1, 0, 1), (1, 0, 1, 1, 1, 1, 0)]
reduced_bitstrings = reduce_bitstrings(bitstrings_u, orbitals_to_reduce)
ansatz = EntanglementForgingAnsatz(circuit_u=circuit_u, bitstrings_u=reduced_bitstrings)
service = None
backend_names = ["ibmq_qasm_simulator"] * 2
options = [Options(execution={"shots": 1000}), Options(execution={"shots": 2000})]
optimizer = COBYLA(maxiter=100)
solver = EntanglementForgingGroundStateSolver(
ansatz=ansatz,
optimizer=optimizer,
service=service,
backend_names=backend_names,
options=options,
# initial_point=[0.0, np.pi / 2, 0.0, 0.0],
)
results = solver.solve(problem)
Currently, the exact simulator ignores classical condition bits. It will need to support them, eventually, if we are going to implement LOCC cutting.
I would not be opposed to explicitly ignoring coverage on wire cutting and EF modules and requiring 100% of everything else implicitly. I feel that much of wire cutting will be replaced by a qpd-based approach soon, and EF was never designed for unit testing anyway. EF is tested with a variety of molecules of different complexities and tested against their known ground state energies. We know the coverage is 85% and barring a large refactor of EF, that is likely where it will always remain.
After cloning the repo and installing it with pip, I've been trying to run the automatic circuit-cutting tutorial. It's spitting out an error.
I'll include the full traceback below:
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
Cell In[48], line 13
4 circuit = EfficientSU2(
5 num_qubits=num_qubits,
6 reps=2,
7 entanglement="linear",
8 su2_gates=["ry"],
9 )
11 circuit = circuit.decompose()
---> 13 cuts = cut_circuit_wires(
14 circuit=circuit,
15 method="automatic",
16 max_subcircuit_width=5,
17 max_cuts=2,
18 num_subcircuits=[2],
19 )
File ~/circuit-knitting-toolbox/circuit_knitting_toolbox/circuit_cutting/wire_cutting/wire_cutting.py:69, in cut_circuit_wires(circuit, method, subcircuit_vertices, max_subcircuit_width, max_subcircuit_cuts, max_subcircuit_size, max_cuts, num_subcircuits, verbose)
65 if max_subcircuit_width is None:
66 raise ValueError(
67 "The max_subcircuit_width argument must be set if using automatic cut finding."
68 )
---> 69 cuts = find_wire_cuts(
70 circuit=circuit,
71 max_subcircuit_width=max_subcircuit_width,
72 max_cuts=max_cuts,
73 num_subcircuits=num_subcircuits,
74 max_subcircuit_cuts=max_subcircuit_cuts,
75 max_subcircuit_size=max_subcircuit_size,
76 verbose=verbose,
77 )
78 elif method == "manual":
79 if subcircuit_vertices is None:
File ~/circuit-knitting-toolbox/circuit_knitting_toolbox/circuit_cutting/wire_cutting/wire_cutting.py:368, in find_wire_cuts(circuit, max_subcircuit_width, max_cuts, num_subcircuits, max_subcircuit_cuts, max_subcircuit_size, verbose)
354 kwargs = dict(
355 n_vertices=n_vertices,
356 edges=edges,
(...)
364 max_cuts=max_cuts,
365 )
367 mip_model = MIPModel(**kwargs)
--> 368 feasible = mip_model.solve(min_postprocessing_cost=min_cost)
369 if not feasible:
370 if verbose:
File ~/circuit-knitting-toolbox/circuit_knitting_toolbox/circuit_cutting/wire_cutting/mip_model.py:496, in MIPModel.solve(self, min_postprocessing_cost)
488 # print('solving for %d subcircuits'%self.num_subcircuit)
489 # print('model has %d variables, %d linear constraints,%d quadratic constraints, %d general constraints'
490 # % (self.model.NumVars,self.model.NumConstrs, self.model.NumQConstrs, self.model.NumGenConstrs))
491 print(
492 "Exporting as a LP file to let you check the model that will be solved : ",
493 min_postprocessing_cost,
494 str(type(min_postprocessing_cost)),
495 )
--> 496 self.model.export_as_lp(path="./docplex_cutter.lp")
497 try:
498 self.model.set_time_limit(300)
File /opt/homebrew/Caskroom/miniforge/base/envs/qiskit-env/lib/python3.9/site-packages/docplex/mp/model.py:5491, in Model.export_as_lp(self, path, basename, hide_user_names)
5442 def export_as_lp(self, path=None, basename=None, hide_user_names=False):
5443 """ Exports a model in LP format.
5444
5445 Args:
(...)
5489 will write file ``e:/home/docplex/docplex_mymodel.lp``.
5490 """
-> 5491 return self.export(path, basename, hide_user_names=hide_user_names, format_spec='lp')
File /opt/homebrew/Caskroom/miniforge/base/envs/qiskit-env/lib/python3.9/site-packages/docplex/mp/model.py:5590, in Model.export(self, path, basename, hide_user_names, format_spec)
5587 def export(self, path=None, basename=None,
5588 hide_user_names=False, format_spec="lp"):
5589 # INTERNAL
-> 5590 return self._export(path, basename,
5591 use_engine=False,
5592 hide_user_names=hide_user_names,
5593 format_spec=format_spec)
File /opt/homebrew/Caskroom/miniforge/base/envs/qiskit-env/lib/python3.9/site-packages/docplex/mp/model.py:5610, in Model._export(self, path, basename, use_engine, hide_user_names, format_spec)
5608 # combination of path/directory and basename resolution are done in resolve_path
5609 path = self._resolve_path(path, basename, extension)
-> 5610 ret = self._export_to_path(path, hide_user_names, use_engine, _format)
5611 if ret:
5612 self.trace("model file: {0} overwritten", path)
File /opt/homebrew/Caskroom/miniforge/base/envs/qiskit-env/lib/python3.9/site-packages/docplex/mp/model.py:5630, in Model._export_to_path(self, path, hide_user_names, use_engine, format_spec)
5627 return None
5628 else:
5629 # a path is not a stream but anyway it will work
-> 5630 self._export_to_stream(stream=path, hide_user_names=hide_user_names, format_spec=format_)
5631 return path
5633 except IOError:
File /opt/homebrew/Caskroom/miniforge/base/envs/qiskit-env/lib/python3.9/site-packages/docplex/mp/model.py:5642, in Model._export_to_stream(self, stream, hide_user_names, format_spec)
5640 if printer:
5641 printer.set_mangle_names(hide_user_names)
-> 5642 printer.printModel(self, stream)
5643 else:
5644 self.__engine.export(stream, format_spec)
File /opt/homebrew/Caskroom/miniforge/base/envs/qiskit-env/lib/python3.9/site-packages/docplex/mp/mprinter.py:44, in ModelPrinter.printModel(self, mdl, out)
38 def printModel(self, mdl, out=None):
39 """ Generic method.
40 If passed with a string, uses it as a file name
41 if None is passed, uses standard output.
42 else assume a stream is passed and try it
43 """
---> 44 mdl._resolve_pwls()
45 if out is None:
46 # prints on standard output
47 self.print_model_to_stream(sys.stdout, mdl)
File /opt/homebrew/Caskroom/miniforge/base/envs/qiskit-env/lib/python3.9/site-packages/docplex/mp/model.py:7030, in Model._resolve_pwls(self)
7028 no_pwl_scopes = [self._linct_scope, self._logical_scope, self._quadct_scope]
7029 for sc in no_pwl_scopes:
-> 7030 for x in sc.iter_objects():
7031 x.resolve()
7032 # this call updates the dict so we must iterate on something else.
7033 #pwls = [pw for pw in self._pwl_scope.iter_objects()]
RuntimeError: dictionary changed size during iteration
Unsure of what could be causing this. I've tried with other circuits as well but have had no success.
Quasiprobabilistic sampling for quantum circuits was first introduced as a technique for error mitigation and has since been used to design techniques for cutting quantum circuits in both the space (gate cuts) and time (wire cuts).
Resolution of this issue should include a class or data structure defining one decomposition with a given circuit (i.e. one gate cut or one wire cut).
Nature 0.6.0 will remove the need for JordanWignerMapper, we should be able to use QubitMapper directly in Entanglement Forging
Outstanding/unresolved item from #145:
Currently, Terra's
group_commuting
will put each observable into at most a single set. However, a given observable might actually be mutually commuting with more than one set. Taking advantage of this will allow us to collect more statistics for the observable without doing any additional quantum experiments. To be specific, we should handle the particular special case of this where multiplegeneral_observables
actually contain the observable. This covers what is probably the most important case, evaluating the "expectation value" of the identity of the current subsystem (which really just involves keeping track of QPD measurements only).
This will be accomplished by taking a second pass over the commuting_groups
where there is a TODO in the code.
Qiskit Aer is used in ckt in one place: cutqc verification. We should change Aer to be an optional dependency instead. If Aer is not installed, the simulator introduced in #145 should suffice.
Of course, running the tests or notebooks will still require that Aer is installed.
Wire cutting evaluation currently takes only strings for backends. It should accept both strings and Backends.
Optional[Union[QiskitRuntimeService, Dict[str, Any]]]
# noqa
tags whenever possible. Only leave in extenuating circumstances.tox.ini
instead)A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.