-
Notifications
You must be signed in to change notification settings - Fork 15
Added sweeps for number of qubits #47
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -4,7 +4,6 @@ | |||||||
# ------------------------------------------------------------------------------ | ||||||||
|
||||||||
"""Benchmark Bernstein Vazirani circuits.""" | ||||||||
|
||||||||
import os | ||||||||
|
||||||||
import pytest | ||||||||
|
@@ -13,9 +12,30 @@ | |||||||
|
||||||||
from red_queen.games.applications import backends, run_qiskit_circuit | ||||||||
|
||||||||
import random | ||||||||
|
||||||||
import requests | ||||||||
|
||||||||
import numpy as np | ||||||||
|
||||||||
QASM_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "qasm") | ||||||||
SECRET_STRING = "110011" | ||||||||
|
||||||||
|
||||||||
@pytest.fixture | ||||||||
def get_num_qubits(request): | ||||||||
user_params = request.config.getoption("--num_qubits") | ||||||||
user_params = user_params.split(":") | ||||||||
if user_params[0] == "linear": | ||||||||
sweep = np.linspace(int(user_params[1]), int(user_params[2]), int(user_params[3])) | ||||||||
sweep = [int(i) for i in sweep] | ||||||||
Comment on lines
+29
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can simplify this by specifying the dtype directly:
Suggested change
This will return a numpy array with an integer datatype |
||||||||
if user_params[0] == "log": | ||||||||
sweep = np.logspace(int(user_params[1]), int(user_params[2]), int(user_params[3])) | ||||||||
sweep = [int(i) for i in sweep] | ||||||||
return sweep | ||||||||
|
||||||||
|
||||||||
sweep_list = list(requests.get(get_num_qubits)) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this might need to be updated to call the function directly without requests. |
||||||||
default_secret_string = "110011" | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I expect this will fail pylint because it likes constants to be all caps, but you can check with |
||||||||
|
||||||||
|
||||||||
def build_bv_circuit(secret_string, mid_circuit_measure=False): | ||||||||
|
@@ -58,19 +78,22 @@ def build_bv_circuit(secret_string, mid_circuit_measure=False): | |||||||
@pytest.mark.parametrize("optimization_level", [0, 1, 2, 3]) | ||||||||
@pytest.mark.parametrize("backend", backends) | ||||||||
@pytest.mark.parametrize("method", ["normal", "mid-circuit measurement"]) | ||||||||
def bench_qiskit_bv(benchmark, optimization_level, backend, method): | ||||||||
@pytest.mark.parametrize("num_qubits", sweep_list) | ||||||||
def bench_qiskit_bv(benchmark, optimization_level, backend, method, num_qubits): | ||||||||
shots = 65536 | ||||||||
SECRET_STRING = str(bin(random.getrandbits(num_qubits - 1))[2:].zfill(num_qubits-1)) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The use of random here is potentially problematic from a reproducibility perspective. Since we're expecting to run these benchmarks for comparison purposes the selected secret string will potentially be different between runs for a fixed input parameter set. Using an random number generator to pick the exact secret string is fine but we should set it with a fixed seed: https://docs.python.org/3/library/random.html#random.seed to ensure the values are consistent/reproducible between runs. |
||||||||
expected_counts = {SECRET_STRING: shots} | ||||||||
|
||||||||
if method == "normal": | ||||||||
benchmark.name = "Bernstein Vazirani" | ||||||||
circ = QuantumCircuit.from_qasm_file(os.path.join(QASM_DIR, "bv.qasm")) | ||||||||
circ = build_bv_circuit(SECRET_STRING) | ||||||||
else: | ||||||||
benchmark.name = "Bernstein Vazirani (mid-circuit measurement)" | ||||||||
circ = QuantumCircuit.from_qasm_file(os.path.join(QASM_DIR, "bv_mcm.qasm")) | ||||||||
circ = build_bv_circuit(SECRET_STRING, True) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should check that the number of circuit qubits is <= the number of backend qubits. If not this will cause a runtime error and it'd be better to handle that gracefully. |
||||||||
benchmark.algorithm = f"Optimization level: {optimization_level} on {backend.name()}" | ||||||||
run_qiskit_circuit(benchmark, circ, backend, optimization_level, shots, expected_counts) | ||||||||
|
||||||||
|
||||||||
if __name__ == "__main__": | ||||||||
build_bv_circuit(SECRET_STRING).qasm(filename=os.path.join(QASM_DIR, "bv.qasm")) | ||||||||
build_bv_circuit(SECRET_STRING, True).qasm(filename=os.path.join(QASM_DIR, "bv_mcm.qasm")) | ||||||||
build_bv_circuit(default_secret_string).qasm(filename=os.path.join(QASM_DIR, "bv.qasm")) | ||||||||
build_bv_circuit(default_secret_string, True).qasm(filename=os.path.join(QASM_DIR, "bv_mcm.qasm")) | ||||||||
Comment on lines
97
to
+99
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we're changing the execution model of these benchmarks to no longer depend on hard coded qasm files we can delete this block of code now as we don't need to regenerate qasm files. Similarly we can remove the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we discussed offline, I don't think this import is needed and is likely the cause of the errors on import since requests is an external python library for HTTP: https://pypi.org/project/requests/ and it's not being part of red queens requirements.