Giter Club home page Giter Club logo

qokit's People

Contributors

1ucian0 avatar alex124585 avatar danlkv avatar haoty avatar rajgane07 avatar rsln-s avatar t3rrym avatar zichanghe 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qokit's Issues

Add (local) tests for MPI simulator

It has been reported that the MPI simulators are broken. This issue is to document the issues with the MPI simulators and to add local tests for them.

Windows Install Errors

I'm using Windows 10. When installing qokit using a conda environment with Python 3.11, pytest fails with 12 errors. When installing qokit using a conda environment with Python 3.9, pytest passes 99 tests and fails 1 test:

tests/test_labs.py::test_gate_optimized_terms_greedy - ValueError: high is out of bounds for int32

Note: I am running 64 bit python in both scenarios.

Objective function of a general QUBO problem

In you example "Simulation of QAOA applied to a general problem", you gave an example specified by 'terms' below:

N = 4
np.random.seed(10)
terms = [(np.random.normal(), spin_pair) for spin_pair in combinations(range(N), r=2)]

I wonder how to get the objective function in order to optimize this general Hamiltonian. Many thanks.

Avoid precomputing energies outside of the simulator

In certain conditions, when precomputed_costs is not provided by the user, qokit would calculate it with CPU-version functions outside of the simulator. This is intractable when the number of qubits is high. Instead, precomputed_costs should be either user-provided or calculated in fur with the user-specified backend, whenever possible. The explicit retrieving precomputed_costs from the simulator and re-passing-in when calling the simulator objective functions should also be avoided, which, when the backend is GPU, can eliminate an unnecessary copy of the large energy vector in the CPU memory and reduce communication time.

#34 needs to be addressed to correctly implement this. Constraint-related values (e.g. portfolio optimization overlap) will be tricky for the simulator to calculate and have to be done outside of the simulator for now.

Unify `precomputed_diagonal_hamiltonian` and `precomputed_costs`

Currently, there are two arguments related to precomputed energies in get_qaoa_objective(). precomputed_diagonal_hamiltonian is passed into the simulator but not used for get-objective functions after the simulation, except when precomputed_costs is None. However, judging from problem-specific get-objective functions, this exception is never the case, and even if so, it would produce incorrect results. Having two similar arguments leads to ambiguity and the duplication of the energy vector, whose size is exponential in the number of qubits.

Unsure if the QOKit MaxCut examples are working -- `brute_force` method.

I have been trying to use the QOKit simulator for larger instances but before that I wanted to verify it works for some trivial small ones.

I'd love some insight into if I'm doing something wrong -- thank you in advance ๐Ÿ˜

I have created a basic 2-regular or ring graph
image

The solution for the two subsets are trivial:

  • Subset 0: Node 0, Node 2, Node 4
  • Subset 1: Node 1, Node 3, Node 5

However; when I run the code (see below) -- brute-force output is incorrect.

Pls let me know if I'm implementing this wrong?

from qokit.utils import brute_force
from qokit.qaoa_objective_maxcut import get_qaoa_maxcut_objective
from qokit.qaoa_circuit_maxcut import get_parameterized_qaoa_circuit

import gurobipy as gp
from gurobipy import GRB

# Define # of Layers
N_LAYERS = 20
# Generate a random 2-regular graph
N = 6
d = 2
seed = 1
G = nx.random_regular_graph(d,N,seed=seed)

# Build QC Circuit
qc = get_parameterized_qaoa_circuit(G, N_LAYERS)
qaoa_obj = get_qaoa_maxcut_objective(N, N_LAYERS, G)

brute_force_sol = brute_force(qaoa_obj, N, minimize=True)
print(brute_force_sol)

>>> (-1.091045519270739, array([1, 1, 0, 1, 1, 0]))

Here is a plot:

image

I also validated with Gurobi and it can produce the correct solution:

import gurobipy as gp
from gurobipy import GRB

for (u, v) in G.edges():
    G.edges[u, v]['weight'] = 1   # Set to 1 or some other weight if needed

# Create a new model
m = gp.Model("max_cut")
x = m.addVars(G.nodes(), vtype=GRB.BINARY, name="x")
m.setObjective(gp.quicksum(G[u][v]['weight'] * (x[u] + x[v] - 2 * x[u] * x[v]) for u, v in G.edges()), GRB.MAXIMIZE)

m.optimize()


if m.status == GRB.OPTIMAL:
    solution = m.getAttr('x', x)
    print("Solution:")
    for v in solution:
        print(f"Vertex {v}: {int(solution[v])}")
else:
    print("No optimal solution found.")

image

Badge is not rendering

"tests passing" badge does not render in public version as it points to the wrong repo

`sys.maxsize()` should not be used for seed generation

The problem is caused by line 502 in labs.py.

Replacing line 502 with seed = seed if seed else np.random.randint(np.iinfo(np.int32).max) fixes the issue.

@alex124585, would you mind submitting a PR with the above change?

Thank you!

See error below.

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[2], line 4
      2 p = 1
      3 gamma, beta = parameter_utils.get_best_known_parameters_for_LABS_wrt_overlap_for_p(N, p)
----> 4 terms = get_gate_optimized_terms_greedy(N) # indices of Pauli Zs

File ~\Dropbox\ANL\qaoaPortfolioOptimization\test\QOKit\qokit\labs.py:502, in get_gate_optimized_terms_greedy(N, number_of_gate_zones, seed)
    498         two_body.append((i, i + 2 * k))
    500 circuit = []
--> 502 seed = seed if seed else np.random.randint(sys.maxsize)
    503 print(f"seed: {seed}")
    504 rng = np.random.default_rng(seed)

File mtrand.pyx:746, in numpy.random.mtrand.RandomState.randint()

File _bounded_integers.pyx:1336, in numpy.random._bounded_integers._rand_int32()

ValueError: high is out of bounds for int32

pip install git+ causes error in asset-dependent parameter utils

Minimal reproducible example:

pip install git+https://github.com/jpmorganchase/QOKit
from qokit.parameter_utils import get_fixed_gamma_beta
get_fixed_gamma_beta(3, 1)

causes

  File "<stdin>", line 1, in <module>
  File "/home/hao/.pyenv/versions/test/lib/python3.10/site-packages/qokit/parameter_utils.py", line 234, in get_fixed_gamma_beta
    df = pd.read_json(str(files("qokit.assets.maxcut_datasets").joinpath("fixed_angles_for_regular_graphs.json")), orient="index")
  File "/home/hao/.pyenv/versions/test/lib/python3.10/site-packages/importlib_resources/_common.py", line 46, in wrapper
    return func(anchor)
  File "/home/hao/.pyenv/versions/test/lib/python3.10/site-packages/importlib_resources/_common.py", line 56, in files
    return from_package(resolve(anchor))
  File "/home/hao/.pyenv/versions/3.10.4/lib/python3.10/functools.py", line 889, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
  File "/home/hao/.pyenv/versions/test/lib/python3.10/site-packages/importlib_resources/_common.py", line 82, in _
    return importlib.import_module(cand)
  File "/home/hao/.pyenv/versions/3.10.4/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1004, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'qokit.assets.maxcut_datasets'

Installing by manually cloning to local does not have this issue.

LABS using circuit?

Is there an example where QOKit evaluates the LABS circuit instead of the statevector simulation?

In the qaoa_objective_labs file:

from .qaoa_circuit_labs import get_parameterized_qaoa_circuit

I see that the circuit is imported, but I don't see where it is ever used/evaluated? Isn't this necessary for large N?

(I see QOKit has this implemented for portfolio optimization though.)

@mmenickelly

Communication inside the MPI simulator may cause overflow error when the message is large

This happens, for example, when calling MPI simulator's get_probabilities() which does self._comm.allgather(result.copy_to_host()). If the vector is too large (e.g. 32 qubits), the following is raised:

  File "mpi4py/MPI/Comm.pyx", line 1595, in mpi4py.MPI.Comm.allgather
  File "mpi4py/MPI/msgpickle.pxi", line 862, in mpi4py.MPI.PyMPI_allgather
  File "mpi4py/MPI/msgpickle.pxi", line 147, in mpi4py.MPI.pickle_dump
  File "mpi4py/MPI/msgbuffer.pxi", line 50, in mpi4py.MPI.downcast
OverflowError: integer 34359738509 does not fit in 'int'

which is due to a legacy issue of mpi4py/pickle (see mpi4py/mpi4py#119) that is solved by mpi4py.util.pkl5. It seems the switch to pkl5 can be realized by simply changing the current self._comm = MPI.COMM_WORLD to pkl5.Intracomm(MPI.COMM_WORLD).

Fix parameterization of LABS tests and parameterize MaxCut tests

Currently, a very nice parameterization is used to test that QAOA objective for LABS is computed the same way for all simulators (see tests/test_objectives.py).

However, for MaxCut there are two separate files that manually test only a small number of simulators (I believe, only "auto" and "qiskit"): tests/test_qaoa_objective_maxcut.py and tests/test_maxcut.py.

At the same time, parameterization for LABS is missing "qiskit" simulator. I suspect this lack of test coverage is what caused #28.

The request is to add parameterization to MaxCut tests along the lines of how LABS tests are parameterized in tests/test_objectives.py and to add "qiskit" simulator to the tests for LABS objective.

I would also suggest the following minor refactoring:

  • tests/test_objectives.py -> tests/test_qaoa_objective_labs.py
  • Move all functions except test_maxcut_obj from tests/test_maxcut.py to tests/test_qaoa_objective_maxcut.py

Issues introduced in #31 and #24

  • GPU simulation is completely broken as sign change is implemented incorrectly on GPU (np.assaray is invalid for Nvidia datatypes)
  • Debugging prints have not been removed

Higher level considerations:

  • It is unnatural to define optimization_type inside fur. It should be defined at a higher level

Default behavior for overlap objective is incorrect

When overlap objective is requested from get_qaoa_maxcut_objective, the default behavior is to return an incorrect number (1).

Specifically, the following code:

import networkx as nx
import numpy as np
from functools import partial

from qokit.maxcut import maxcut_obj, get_adjacency_matrix
from qokit.utils import precompute_energies

from qokit.parameter_utils import get_fixed_gamma_beta
from qokit.qaoa_objective_maxcut import get_qaoa_maxcut_objective

N = 8
d = 3
seed = 1

G = nx.random_regular_graph(d,N,seed=seed)
obj = partial(maxcut_obj, w=get_adjacency_matrix(G))
precomputed_energies = precompute_energies(obj, N)

for p in range(1, 12):
    gamma, beta = get_fixed_gamma_beta(d, p)
    f = get_qaoa_maxcut_objective(
        N, p, precomputed_cuts=precomputed_energies, parameterization='gamma beta', objective='expectation and overlap'
    )
    e,o = f(gamma, beta)

    print(f"Energy: {e:.2f}, Overlap: {o:.2f}")

Returns

Energy: 7.98, Overlap: 1.00
Energy: 8.74, Overlap: 1.00
Energy: 9.24, Overlap: 1.00
Energy: 9.55, Overlap: 1.00
Energy: 9.76, Overlap: 1.00
Energy: 9.85, Overlap: 1.00
Energy: 9.87, Overlap: 1.00
Energy: 9.87, Overlap: 1.00
Energy: 9.85, Overlap: 1.00
Energy: 9.86, Overlap: 1.00
Energy: 9.90, Overlap: 1.00

Note that the energy is computed correctly, but the overlap is not.

Desired behavior

get_qaoa_objective should use the information in precomputed_energies to populate bitstring_loc (https://github.com/jpmorganchase/QOKit/blob/0281555bdf4c8ca0a645f010e26adb78ae7d6197/qokit/qaoa_objective.py#L189C25-L189C25) object by noticing that the optimal bitstrings are those that correspond to maximum entries in precomputed_energies, i.e.

optimal_energy = np.max(precomputed_energies)
optimal_bitstrings_location = np.isclose(precomputed_energies, optimal_energy).astype(int)

Note that a bit more work is needed since optimal_bitstrings_location does not actually give you the correct format for bitstring_loc (I think?..).

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.