Giter VIP home page Giter VIP logo

qiskit-extensions / circuit-knitting-toolbox Goto Github PK

View Code? Open in Web Editor NEW
73.0 5.0 25.0 68.92 MB

Tools for knitting quantum circuits with Qiskit

Home Page: https://qiskit-extensions.github.io/circuit-knitting-toolbox/

License: Apache License 2.0

Python 99.62% Dockerfile 0.15% OpenQASM 0.22%
python qiskit quantum-computing quantum-circuit quantum-circuit-cutting circuit-cutting circuit-knitting

circuit-knitting-toolbox's People

Contributors

caleb-johnson avatar dependabot[bot] avatar dharmash avatar eric-arellano avatar garrison avatar hitomitak avatar ibrahim-shehzad avatar jenglick avatar kevinsung avatar lockwo avatar pemmaras avatar psschwei avatar saashajoshi avatar seetharamiseelam avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

circuit-knitting-toolbox's Issues

Google style docstrings throughout CKT

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.

Show use of energy_shift in entanglement forging tutorials

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.

Migrate to Qiskit Nature 0.6.0

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.

Finalize cutting documentation

Ensure all new circuit cutting documentation, including any tutorials and how-tos, is complete and consistent.

  • Update README
  • Update cutting explanatory
  • Improve comments in cutting tutorials and how-tos
  • QA Sphinx docs for circuit cutting

Create a package for handling observables in the context of circuit cutting

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:

  • some functionality for splitting observables across a qubit boundary to prepare the subobservables for cutting
  • some functionality for grouping observables, as each excessive observable we evaluate costs us an exponential number of experiments
  • some functionality for appending observables to circuits, adding measurements, etc in support of creation of the experiments

Take primitive/backend options as input into EFGSSolver


As of now, a few hand-picked options (resilience_level, optimization_level, shots) are hard-coded in the EF source code. These should be passed in through a dict or Options object

We should support both cases:

  • Users pass in one set of options to be used on all backends
  • Users pass in a list of options, 1 for each backend, to be used

Replace ListOp in EntForging

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

Create a function which decomposes only quasiprobability instructions in a quantum circuit

#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.

Make cplex and DOcplex dependencies be truly optional

  • Make it so circuit cutting can be imported without cplex or DOCplex present: #73
  • Modify pyproject.toml to make cplex and DOcplex optional dependencies
  • Update tests to skip certain ones that require cplex if it is not present. (This might not be easily possible for the notebook tests, but we can try.)
  • Update install instructions to encourage installing cplex if automatic cut finding is desired; also, users who don't need it may not need to use Docker.
  • Attempt tests under Python 3.11; add it to test matrix.
  • Add a release note

Migrate to Qiskit Nature 0.5.0

Qiskit 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.

Remove nptyping as a dependency

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

Change installation instructions to suggest installing from pypi instead of `git clone`

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:

  1. When is the timing best for making this change?
  2. How do we anticipate the user will obtain the correct tutorial notebooks? (They won't be provided by any pip install command.)
  3. Do we want to update the Dockerfile, too, so that it installs the latest released version?
  4. Should we, concurrently with this change, make it so the latest stable version's documentation is hosted on the web?

Improve freezing orbital how-to

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.

Create functions which facilitate circuit cutting (decompose, evaluate, reconstruct) at the highest level

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:

  • Decompose their problem into subexperiments #103
  • Run their subexperiments on a backend
  • Reconstruct the results of the quasiprobability simulation experiments into expectation values -- one for each observable of interest

Add Forging/Serverless tutorial back on development CI workflow when serialization of ElectronicStructureProblem is addressed

Waiting on Qiskit/qiskit-serverless#413

Changed as part of #230:

  • unpin qiskit-nature<0.6.0 in notebook-dependencies
  • Revert #120

Once the serverless issue is resolved:

  • Remove warning text in forging w/ serverless notebook
  • Make notebook environment in tox.ini test the forging + serverless notebook once again
  • Make the docker.yml workflow test the forging + serverless notebook once again (changed in #328)

Publish to Zenodo

  • Add mention/include of CITATION.bib to the Sphinx build (#165)
  • Review author list, update CITATION.bib (#181)
  • Obtain doi upon next release (0.2.0)
  • Add Zenodo/doi badge to README (#224)
  • Make sure all authors are correctly listed by Zenodo

Add copyright and license header to files

  • All python files should include this header:
# 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.
  • All ipynb should include footer with package versions, copyright, license, etc info
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

  • Repo should include a LICENSE.txt

Remove deprecated types

The typing package has deprecated List and Tuple in favor of the base types. Ensure no deprecated types are being used.

Standardize comparisons in all tests

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

Error on frozen orbitals example code

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)

Adapt coverage testing to require 100% of all new code.

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.

Error on automatic circuit cutting tutorial.

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.

Remove use of JordanWignerMapper

Nature 0.6.0 will remove the need for JordanWignerMapper, we should be able to use QubitMapper directly in Entanglement Forging

In `ObservableCollection`, allow an observable to be part of multiple mutually-commuting groups

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 multiple general_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.

Make Aer an optional dependency

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.

Clean up source code documentation based on Sphinx output

  • Remove any hidden fields from docstrings
  • Remove underscores from attributes in docstrings
  • WireCutter should accept a service or the service args directly Optional[Union[QiskitRuntimeService, Dict[str, Any]]]
  • Remove the # noqa tags whenever possible. Only leave in extenuating circumstances.
  • Ensure all functions/methods are private/public with a purpose. We want API to be lean but we want to expose users to functionality
  • Add sphinx to pyproject.toml? (marked as done because it's in tox.ini instead)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.