From 63708e290737a223dc801ad39ce823f9c16b8c3b Mon Sep 17 00:00:00 2001 From: rtvuser1 Date: Sat, 8 Jun 2024 14:02:26 -0700 Subject: [PATCH 1/7] Implement api-independent PE benchmark for qiskit and cudaq (partial) --- phase-estimation/cudaq/pe_kernel.py | 76 +++++++++ phase-estimation/pe_benchmark.py | 250 ++++++++++++++++++++++++++++ 2 files changed, 326 insertions(+) create mode 100644 phase-estimation/cudaq/pe_kernel.py create mode 100644 phase-estimation/pe_benchmark.py diff --git a/phase-estimation/cudaq/pe_kernel.py b/phase-estimation/cudaq/pe_kernel.py new file mode 100644 index 00000000..2ec6723a --- /dev/null +++ b/phase-estimation/cudaq/pe_kernel.py @@ -0,0 +1,76 @@ +''' +Phase Estimation Benchmark Program - CUDA Quantum Kernel +(C) Quantum Economic Development Consortium (QED-C) 2024. +''' + +import cudaq + +# saved circuits for display +QC_ = None +Uf_ = None + +############### BV Circuit Definition +''' +@cudaq.kernel +def oracle(register: cudaq.qview, auxillary_qubit: cudaq.qubit, + hidden_bits: List[int]): + input_size = len(hidden_bits) + for index, bit in enumerate(hidden_bits): + if bit == 1: + # apply a `cx` gate with the current qubit as + # the control and the auxillary qubit as the target. + x.ctrl(register[input_size - index - 1], auxillary_qubit) +''' +@cudaq.kernel +def pe_kernel (num_qubits: int, theta: float): + + # size of input is one less than available qubits + input_size = num_qubits - 1 + + # Allocate the specified number of qubits - this + # corresponds to the length of the hidden bitstring. + qubits = cudaq.qvector(input_size) + + # Allocate an extra auxillary qubit. + auxillary_qubit = cudaq.qubit() + + # Prepare the auxillary qubit. + h(auxillary_qubit) + z(auxillary_qubit) + + # Place the rest of the register in a superposition state. + h(qubits) + + # Query the oracle. + #oracle(qubits, auxillary_qubit, hidden_bits) + + # Apply another set of Hadamards to the register. + h(qubits) + + # DEVNOTE: compare to Qiskit version - do we need to flip the aux bit back? and measure all? + + # Apply measurement gates to just the `qubits` + # (excludes the auxillary qubit). + mz(qubits) + + +def PhaseEstimation (num_qubits: int, theta: float): + + qc = [pe_kernel, [num_qubits, theta]] + + global QC_ + if num_qubits <= 9: + QC_ = qc + + return qc + +############### BV Circuit Drawer + +# Draw the circuits of this benchmark program +def kernel_draw(): + print("Sample Circuit:"); + if QC_ != None: + print(cudaq.draw(QC_[0], *QC_[1])) + else: + print(" ... too large!") + \ No newline at end of file diff --git a/phase-estimation/pe_benchmark.py b/phase-estimation/pe_benchmark.py new file mode 100644 index 00000000..8c67fed3 --- /dev/null +++ b/phase-estimation/pe_benchmark.py @@ -0,0 +1,250 @@ +''' +Phase Estimation Benchmark Program +(C) Quantum Economic Development Consortium (QED-C) 2024. +''' + +import sys +import time +import numpy as np + +############### Configure API +# +# Configure the QED-C Benchmark package for use with the given API +def qedc_benchmarks_init(api: str = "qiskit"): + + if api == None: api = "qiskit" + + sys.path[1:1] = [ f"{api}" ] + sys.path[1:1] = [ "_common", f"_common/{api}" ] + sys.path[1:1] = [ "../_common", f"../_common/{api}" ] + + import execute as ex + globals()["ex"] = ex + + import metrics as metrics + globals()["metrics"] = metrics + + from pe_kernel import PhaseEstimation, kernel_draw + + return PhaseEstimation, kernel_draw + + +# Benchmark Name +benchmark_name = "Phase Estimation" + +np.random.seed(0) + +verbose = False + + +############### Analyze Result + +# Analyze and print measured results +# Expected result is always theta, so fidelity calc is simple +def analyze_and_print_result(qc, result, num_counting_qubits, theta, num_shots): + + # get results as measured counts + counts = result.get_counts(qc) + ''' + print(counts) + print(type(counts)) + print(counts.items()) + ''' + # calculate expected output histogram + correct_dist = theta_to_bitstring(theta, num_counting_qubits) + + # generate thermal_dist to be comparable to correct_dist + thermal_dist = metrics.uniform_dist(num_counting_qubits) + + # convert counts, expectation, and thermal_dist to app form for visibility + # app form of correct distribution is measuring theta correctly 100% of the time + app_counts = bitstring_to_theta(counts, num_counting_qubits) + app_correct_dist = {theta: 1.0} + app_thermal_dist = bitstring_to_theta(thermal_dist, num_counting_qubits) + + if verbose: + print(f"For theta {theta}, expected: {correct_dist} measured: {counts}") + print(f" ... For theta {theta} thermal_dist: {thermal_dist}") + print(f"For theta {theta}, app expected: {app_correct_dist} measured: {app_counts}") + print(f" ... For theta {theta} app_thermal_dist: {app_thermal_dist}") + + # use polarization fidelity with rescaling + fidelity = metrics.polarization_fidelity(counts, correct_dist, thermal_dist) + + # use polarization fidelity with rescaling + fidelity = metrics.polarization_fidelity(counts, correct_dist, thermal_dist) + #fidelity = metrics.polarization_fidelity(app_counts, app_correct_dist, app_thermal_dist) + + hf_fidelity = metrics.hellinger_fidelity_with_expected(counts, correct_dist) + + if verbose: print(f" ... fidelity: {fidelity} hf_fidelity: {hf_fidelity}") + + return counts, fidelity + +# Convert theta to a bitstring distribution +def theta_to_bitstring(theta, num_counting_qubits): + counts = {format( int(theta * (2**num_counting_qubits)), "0"+str(num_counting_qubits)+"b"): 1.0} + return counts + +# Convert bitstring to theta representation, useful for debugging +def bitstring_to_theta(counts, num_counting_qubits): + theta_counts = {} + #for key in counts.keys(): + for item in counts.items(): + key, r = item + #key = item[0] + #r = counts[key] + + #print(f"... key={key} r={r}") + + theta = int(key,2) / (2**num_counting_qubits) + if theta not in theta_counts.keys(): + theta_counts[theta] = 0 + theta_counts[theta] += r + return theta_counts + + +################ Benchmark Loop + +# Execute program with default parameters +def run(min_qubits=3, max_qubits=8, skip_qubits=1, max_circuits=3, num_shots=100, + theta=None, + backend_id=None, provider_backend=None, + hub="ibm-q", group="open", project="main", exec_options=None, + context=None, api=None): + + # configure the QED-C Benchmark package for use with the given API + PhaseEstimation, kernel_draw = qedc_benchmarks_init(api) + + print(f"{benchmark_name} Benchmark Program - Qiskit") + + num_state_qubits = 1 # default, not exposed to users, cannot be changed in current implementation + + # validate parameters (smallest circuit is 3 qubits) + num_state_qubits = max(1, num_state_qubits) + if max_qubits < num_state_qubits + 2: + print(f"ERROR: PE Benchmark needs at least {num_state_qubits + 2} qubits to run") + return + min_qubits = max(max(3, min_qubits), num_state_qubits + 2) + skip_qubits = max(1, skip_qubits) + #print(f"min, max, state = {min_qubits} {max_qubits} {num_state_qubits}") + + # create context identifier + if context is None: context = f"{benchmark_name} Benchmark" + + ########## + + # Initialize metrics module + metrics.init_metrics() + + # Define custom result handler + def execution_handler(qc, result, num_qubits, theta, num_shots): + + # determine fidelity of result set + num_counting_qubits = int(num_qubits) - 1 + counts, fidelity = analyze_and_print_result(qc, result, num_counting_qubits, float(theta), num_shots) + metrics.store_metric(num_qubits, theta, 'fidelity', fidelity) + + # Initialize execution module using the execution result handler above and specified backend_id + ex.init_execution(execution_handler) + ex.set_execution_target(backend_id, provider_backend=provider_backend, + hub=hub, group=group, project=project, exec_options=exec_options, + context=context) + + ########## + + # Execute Benchmark Program N times for multiple circuit sizes + # Accumulate metrics asynchronously as circuits complete + for num_qubits in range(min_qubits, max_qubits + 1, skip_qubits): + + # reset random seed + np.random.seed(0) + + # as circuit width grows, the number of counting qubits is increased + num_counting_qubits = num_qubits - num_state_qubits - 1 + + # determine number of circuits to execute for this group + num_circuits = min(2 ** (num_counting_qubits), max_circuits) + + print(f"************\nExecuting [{num_circuits}] circuits with num_qubits = {num_qubits}") + + # determine range of secret strings to loop over + if 2**(num_counting_qubits) <= max_circuits: + theta_range = [i/(2**(num_counting_qubits)) for i in list(range(num_circuits))] + else: + theta_range = [i/(2**(num_counting_qubits)) for i in np.random.choice(2**(num_counting_qubits), num_circuits, False)] + + # loop over limited # of random theta choices + for theta in theta_range: + theta = float(theta) + + # create the circuit for given qubit size and theta, store time metric + ts = time.time() + qc = PhaseEstimation(num_qubits, theta) + metrics.store_metric(num_qubits, theta, 'create_time', time.time() - ts) + + # submit circuit for execution on target (simulator, cloud simulator, or hardware) + ex.submit_circuit(qc, num_qubits, theta, num_shots) + + # Wait for some active circuits to complete; report metrics when groups complete + ex.throttle_execution(metrics.finalize_group) + + # Wait for all active circuits to complete; report metrics when groups complete + ex.finalize_execution(metrics.finalize_group) + + ########## + + # draw a sample circuit + kernel_draw() + + # Plot metrics for all circuit sizes + metrics.plot_metrics(f"Benchmark Results - {benchmark_name} - Qiskit") + + +####################### +# MAIN + +import argparse +def get_args(): + parser = argparse.ArgumentParser(description="Bernstei-Vazirani Benchmark") + parser.add_argument("--api", "-a", default=None, help="Programming API", type=str) + parser.add_argument("--target", "-t", default=None, help="Target Backend", type=str) + parser.add_argument("--backend_id", "-b", default=None, help="Backend Identifier", type=str) + parser.add_argument("--num_shots", "-s", default=100, help="Number of shots", type=int) + parser.add_argument("--num_qubits", "-n", default=0, help="Number of qubits", type=int) + parser.add_argument("--min_qubits", "-min", default=3, help="Minimum number of qubits", type=int) + parser.add_argument("--max_qubits", "-max", default=8, help="Maximum number of qubits", type=int) + parser.add_argument("--skip_qubits", "-k", default=1, help="Number of qubits to skip", type=int) + parser.add_argument("--max_circuits", "-c", default=3, help="Maximum circuit repetitions", type=int) + parser.add_argument("--method", "-m", default=1, help="Algorithm Method", type=int) + parser.add_argument("--theta", "-th", default=0.0, help="Input Theta Value", type=float) + parser.add_argument("--nonoise", "-non", action="store_true", help="Use Noiseless Simulator") + parser.add_argument("--verbose", "-v", action="store_true", help="Verbose") + return parser.parse_args() + +# if main, execute method +if __name__ == '__main__': + args = get_args() + + # configure the QED-C Benchmark package for use with the given API + # (done here so we can set verbose for now) + PhaseEstimation, kernel_draw = qedc_benchmarks_init(args.api) + + # special argument handling + ex.verbose = args.verbose + verbose = args.verbose + + if args.num_qubits > 0: args.min_qubits = args.max_qubits = args.num_qubits + + # execute benchmark program + run(min_qubits=args.min_qubits, max_qubits=args.max_qubits, + skip_qubits=args.skip_qubits, max_circuits=args.max_circuits, + num_shots=args.num_shots, + #method=args.method, + theta=args.theta, + backend_id=args.backend_id, + exec_options = {"noise_model" : None} if args.nonoise else {}, + api=args.api + ) + + From 4bbbb5026bc8ce7d5a0c3a0b78bdeb9eb48ecf1a Mon Sep 17 00:00:00 2001 From: rtvuser1 Date: Sun, 9 Jun 2024 13:45:37 -0700 Subject: [PATCH 2/7] Simplify QFT code in phase estimation benchmark, and add init_phase option --- phase-estimation/qiskit/pe_benchmark.py | 18 ++++++++++++++---- phase-estimation/qiskit/pe_kernel.py | 22 ++++++++++++++++++++-- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/phase-estimation/qiskit/pe_benchmark.py b/phase-estimation/qiskit/pe_benchmark.py index 8ba89798..73445b57 100644 --- a/phase-estimation/qiskit/pe_benchmark.py +++ b/phase-estimation/qiskit/pe_benchmark.py @@ -72,8 +72,8 @@ def theta_to_bitstring(theta, num_counting_qubits): # Convert bitstring to theta representation, useful for debugging def bitstring_to_theta(counts, num_counting_qubits): theta_counts = {} - for key in counts.keys(): - r = counts[key] + for item in counts.items(): + key, r = item theta = int(key,2) / (2**num_counting_qubits) if theta not in theta_counts.keys(): theta_counts[theta] = 0 @@ -85,6 +85,7 @@ def bitstring_to_theta(counts, num_counting_qubits): # Execute program with default parameters def run(min_qubits=3, max_qubits=8, skip_qubits=1, max_circuits=3, num_shots=100, + init_phase=None, backend_id=None, provider_backend=None, hub="ibm-q", group="open", project="main", exec_options=None, context=None): @@ -149,6 +150,11 @@ def execution_handler(qc, result, num_qubits, theta, num_shots): # loop over limited # of random theta choices for theta in theta_range: + theta = float(theta) + + # if initial phase passed in, use it instead of random values + if init_phase: + theta = init_phase # create the circuit for given qubit size and theta, store time metric ts = time.time() @@ -189,7 +195,8 @@ def get_args(): parser.add_argument("--skip_qubits", "-k", default=1, help="Number of qubits to skip", type=int) parser.add_argument("--max_circuits", "-c", default=3, help="Maximum circuit repetitions", type=int) parser.add_argument("--method", "-m", default=1, help="Algorithm Method", type=int) - parser.add_argument("--theta", default=0.0, help="Input Theta Value", type=float) + parser.add_argument("--init_phase", "-p", default=0.0, help="Input Phase Value", type=float) + parser.add_argument("--nonoise", "-non", action="store_true", help="Use Noiseless Simulator") parser.add_argument("--verbose", "-v", action="store_true", help="Verbose") return parser.parse_args() @@ -203,6 +210,8 @@ def get_args(): # special argument handling ex.verbose = args.verbose + verbose = args.verbose + if args.num_qubits > 0: args.min_qubits = args.max_qubits = args.num_qubits # execute benchmark program @@ -210,8 +219,9 @@ def get_args(): skip_qubits=args.skip_qubits, max_circuits=args.max_circuits, num_shots=args.num_shots, #method=args.method, - #theta=args.theta, + init_phase=args.init_phase, backend_id=args.backend_id, + exec_options = {"noise_model" : None} if args.nonoise else {}, #api=args.api ) diff --git a/phase-estimation/qiskit/pe_kernel.py b/phase-estimation/qiskit/pe_kernel.py index 098002d0..d543fa9e 100644 --- a/phase-estimation/qiskit/pe_kernel.py +++ b/phase-estimation/qiskit/pe_kernel.py @@ -82,10 +82,9 @@ def inv_qft_gate(input_size): #global QFTI_, num_gates, depth global QFTI_ qr = QuantumRegister(input_size); qc = QuantumCircuit(qr, name="inv_qft") - + ''' # Generate multiple groups of diminishing angle CRZs and H gate for i_qubit in reversed(range(0, input_size)): - # start laying out gates from highest order qubit (the hidx) hidx = input_size - i_qubit - 1 @@ -101,6 +100,25 @@ def inv_qft_gate(input_size): qc.barrier() + qc.barrier() + ''' + # Generate multiple groups of diminishing angle CRZs and H gate + for i_qubit in range(input_size): + + # precede with an H gate (applied to all qubits) + qc.h(qr[i_qubit]) + + # number of controlled Z rotations to perform at this level + num_crzs = input_size - i_qubit - 1 + + # if not the highest order qubit, add multiple controlled RZs of decreasing angle + if i_qubit < input_size - 1: + for j in range(0, num_crzs): + divisor = 2 ** (j + 1) + qc.crz( -math.pi / divisor , qr[i_qubit], qr[i_qubit + j + 1]) + + qc.barrier() + if QFTI_ == None or input_size <= 5: if input_size < 9: QFTI_= qc From 2fc8727083bf5520781c46f998db17b48a8b2777 Mon Sep 17 00:00:00 2001 From: rtvuser1 Date: Sun, 9 Jun 2024 14:35:16 -0700 Subject: [PATCH 3/7] A version of Phase Estimation that works on CUDA Quantum --- phase-estimation/cudaq/pe_kernel.py | 91 +++++++++++++++++++--------- phase-estimation/pe_benchmark.py | 16 +++-- phase-estimation/qiskit/pe_kernel.py | 21 +------ 3 files changed, 71 insertions(+), 57 deletions(-) diff --git a/phase-estimation/cudaq/pe_kernel.py b/phase-estimation/cudaq/pe_kernel.py index 2ec6723a..75483797 100644 --- a/phase-estimation/cudaq/pe_kernel.py +++ b/phase-estimation/cudaq/pe_kernel.py @@ -4,54 +4,89 @@ ''' import cudaq - + # saved circuits for display QC_ = None Uf_ = None -############### BV Circuit Definition -''' +############### Phase Esimation Circuit Definition + +# Inverse Quantum Fourier Transform @cudaq.kernel -def oracle(register: cudaq.qview, auxillary_qubit: cudaq.qubit, - hidden_bits: List[int]): - input_size = len(hidden_bits) - for index, bit in enumerate(hidden_bits): - if bit == 1: - # apply a `cx` gate with the current qubit as - # the control and the auxillary qubit as the target. - x.ctrl(register[input_size - index - 1], auxillary_qubit) -''' +def iqft(register: cudaq.qview): + M_PI = 3.1415926536 + + input_size = register.size() + + # use this as a barrier when drawing circuit; comment out otherwise + for i in range(input_size / 2): + swap(register[i], register[input_size - i - 1]) + swap(register[i], register[input_size - i - 1]) + + # Generate multiple groups of diminishing angle CRZs and H gate + for i_qubit in range(input_size): + ri_qubit = input_size - i_qubit - 1 # map to cudaq qubits + + # precede with an H gate (applied to all qubits) + h(register[ri_qubit]) + + # number of controlled Z rotations to perform at this level + num_crzs = input_size - i_qubit - 1 + + # if not the highest order qubit, add multiple controlled RZs of decreasing angle + if i_qubit < input_size - 1: + for j in range(0, num_crzs): + #divisor = 2 ** (j + 1) # DEVNOTE: #1663 This does not work on Quantum Cloud + + X = j + 1 # WORKAROUND + divisor = 1 + for i in range(X): + divisor *= 2 + + r1.ctrl( -M_PI / divisor , register[ri_qubit], register[ri_qubit - j - 1]) + @cudaq.kernel +#def pe_kernel (num_qubits: int, theta: float, do_uopt: bool): def pe_kernel (num_qubits: int, theta: float): + M_PI = 3.1415926536 + + init_phase = 2 * M_PI * theta + do_uopt = True # size of input is one less than available qubits input_size = num_qubits - 1 - # Allocate the specified number of qubits - this - # corresponds to the length of the hidden bitstring. - qubits = cudaq.qvector(input_size) + # Allocate on less than the specified number of qubits for phase register + counting_qubits = cudaq.qvector(input_size) - # Allocate an extra auxillary qubit. - auxillary_qubit = cudaq.qubit() + # Allocate an extra qubit for the state register (can expand this later) + state_register = cudaq.qubit() # Prepare the auxillary qubit. - h(auxillary_qubit) - z(auxillary_qubit) - - # Place the rest of the register in a superposition state. - h(qubits) + x(state_register) - # Query the oracle. - #oracle(qubits, auxillary_qubit, hidden_bits) + # Place the phase register in a superposition state. + h(counting_qubits) - # Apply another set of Hadamards to the register. - h(qubits) + # Perform `ctrl-U^j` (DEVNOTE: need to pass in as lambda later) + for i in range(input_size): + ii_qubit = input_size - i - 1 + i_qubit = i + + # optimize by collapsing all phase gates at one level to single gate + if do_uopt: + exp_phase = init_phase * (2 ** i_qubit) + r1.ctrl(exp_phase, counting_qubits[i_qubit], state_register); + else: + for j in range(2 ** i_qubit): + r1.ctrl(init_phase, counting_qubits[i_qubit], state_register); - # DEVNOTE: compare to Qiskit version - do we need to flip the aux bit back? and measure all? + # Apply inverse quantum Fourier transform + iqft(counting_qubits) # Apply measurement gates to just the `qubits` # (excludes the auxillary qubit). - mz(qubits) + mz(counting_qubits) def PhaseEstimation (num_qubits: int, theta: float): diff --git a/phase-estimation/pe_benchmark.py b/phase-estimation/pe_benchmark.py index 8c67fed3..6bdeceb8 100644 --- a/phase-estimation/pe_benchmark.py +++ b/phase-estimation/pe_benchmark.py @@ -89,14 +89,8 @@ def theta_to_bitstring(theta, num_counting_qubits): # Convert bitstring to theta representation, useful for debugging def bitstring_to_theta(counts, num_counting_qubits): theta_counts = {} - #for key in counts.keys(): for item in counts.items(): key, r = item - #key = item[0] - #r = counts[key] - - #print(f"... key={key} r={r}") - theta = int(key,2) / (2**num_counting_qubits) if theta not in theta_counts.keys(): theta_counts[theta] = 0 @@ -108,7 +102,7 @@ def bitstring_to_theta(counts, num_counting_qubits): # Execute program with default parameters def run(min_qubits=3, max_qubits=8, skip_qubits=1, max_circuits=3, num_shots=100, - theta=None, + init_phase=None, backend_id=None, provider_backend=None, hub="ibm-q", group="open", project="main", exec_options=None, context=None, api=None): @@ -177,6 +171,10 @@ def execution_handler(qc, result, num_qubits, theta, num_shots): # loop over limited # of random theta choices for theta in theta_range: theta = float(theta) + + # if initial phase passed in, use it instead of random values + if init_phase: + theta = init_phase # create the circuit for given qubit size and theta, store time metric ts = time.time() @@ -217,7 +215,7 @@ def get_args(): parser.add_argument("--skip_qubits", "-k", default=1, help="Number of qubits to skip", type=int) parser.add_argument("--max_circuits", "-c", default=3, help="Maximum circuit repetitions", type=int) parser.add_argument("--method", "-m", default=1, help="Algorithm Method", type=int) - parser.add_argument("--theta", "-th", default=0.0, help="Input Theta Value", type=float) + parser.add_argument("--init_phase", "-p", default=0.0, help="Input Phase Value", type=float) parser.add_argument("--nonoise", "-non", action="store_true", help="Use Noiseless Simulator") parser.add_argument("--verbose", "-v", action="store_true", help="Verbose") return parser.parse_args() @@ -241,7 +239,7 @@ def get_args(): skip_qubits=args.skip_qubits, max_circuits=args.max_circuits, num_shots=args.num_shots, #method=args.method, - theta=args.theta, + init_phase=args.init_phase, backend_id=args.backend_id, exec_options = {"noise_model" : None} if args.nonoise else {}, api=args.api diff --git a/phase-estimation/qiskit/pe_kernel.py b/phase-estimation/qiskit/pe_kernel.py index d543fa9e..c9ce3c9c 100644 --- a/phase-estimation/qiskit/pe_kernel.py +++ b/phase-estimation/qiskit/pe_kernel.py @@ -82,26 +82,7 @@ def inv_qft_gate(input_size): #global QFTI_, num_gates, depth global QFTI_ qr = QuantumRegister(input_size); qc = QuantumCircuit(qr, name="inv_qft") - ''' - # Generate multiple groups of diminishing angle CRZs and H gate - for i_qubit in reversed(range(0, input_size)): - # start laying out gates from highest order qubit (the hidx) - hidx = input_size - i_qubit - 1 - - # precede with an H gate (applied to all qubits) - qc.h(qr[hidx]) - - # if not the highest order qubit, add multiple controlled RZs of decreasing angle - if hidx < input_size - 1: - num_crzs = i_qubit - for j in reversed(range(0, num_crzs)): - divisor = 2 ** (num_crzs - j) - qc.crz( -math.pi / divisor , qr[hidx], qr[input_size - j - 1]) - - qc.barrier() - - qc.barrier() - ''' + # Generate multiple groups of diminishing angle CRZs and H gate for i_qubit in range(input_size): From 92575635e07fc50ed83ce1e9c4f519191f3da2b8 Mon Sep 17 00:00:00 2001 From: rtvuser1 Date: Sun, 9 Jun 2024 15:30:48 -0700 Subject: [PATCH 4/7] Improve the computation of choices of initial phase angles for performance --- phase-estimation/pe_benchmark.py | 20 ++++++++++---------- phase-estimation/qiskit/pe_benchmark.py | 14 +++++++++----- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/phase-estimation/pe_benchmark.py b/phase-estimation/pe_benchmark.py index 6bdeceb8..4d088712 100644 --- a/phase-estimation/pe_benchmark.py +++ b/phase-estimation/pe_benchmark.py @@ -45,11 +45,7 @@ def analyze_and_print_result(qc, result, num_counting_qubits, theta, num_shots): # get results as measured counts counts = result.get_counts(qc) - ''' - print(counts) - print(type(counts)) - print(counts.items()) - ''' + # calculate expected output histogram correct_dist = theta_to_bitstring(theta, num_counting_qubits) @@ -64,9 +60,9 @@ def analyze_and_print_result(qc, result, num_counting_qubits, theta, num_shots): if verbose: print(f"For theta {theta}, expected: {correct_dist} measured: {counts}") - print(f" ... For theta {theta} thermal_dist: {thermal_dist}") + #print(f" ... For theta {theta} thermal_dist: {thermal_dist}") print(f"For theta {theta}, app expected: {app_correct_dist} measured: {app_counts}") - print(f" ... For theta {theta} app_thermal_dist: {app_thermal_dist}") + #print(f" ... For theta {theta} app_thermal_dist: {app_thermal_dist}") # use polarization fidelity with rescaling fidelity = metrics.polarization_fidelity(counts, correct_dist, thermal_dist) @@ -155,7 +151,7 @@ def execution_handler(qc, result, num_qubits, theta, num_shots): np.random.seed(0) # as circuit width grows, the number of counting qubits is increased - num_counting_qubits = num_qubits - num_state_qubits - 1 + num_counting_qubits = num_qubits - num_state_qubits # determine number of circuits to execute for this group num_circuits = min(2 ** (num_counting_qubits), max_circuits) @@ -164,9 +160,13 @@ def execution_handler(qc, result, num_qubits, theta, num_shots): # determine range of secret strings to loop over if 2**(num_counting_qubits) <= max_circuits: - theta_range = [i/(2**(num_counting_qubits)) for i in list(range(num_circuits))] + theta_choices = list(range(num_circuits)) else: - theta_range = [i/(2**(num_counting_qubits)) for i in np.random.choice(2**(num_counting_qubits), num_circuits, False)] + theta_choices = np.random.randint(1, 2**(num_counting_qubits), num_circuits + 10) + theta_choices = list(set(theta_choices))[0:num_circuits] + + # scale choices to 1.0 + theta_range = [i/(2**(num_counting_qubits)) for i in theta_choices] # loop over limited # of random theta choices for theta in theta_range: diff --git a/phase-estimation/qiskit/pe_benchmark.py b/phase-estimation/qiskit/pe_benchmark.py index 73445b57..66cd1397 100644 --- a/phase-estimation/qiskit/pe_benchmark.py +++ b/phase-estimation/qiskit/pe_benchmark.py @@ -47,9 +47,9 @@ def analyze_and_print_result(qc, result, num_counting_qubits, theta, num_shots): if verbose: print(f"For theta {theta}, expected: {correct_dist} measured: {counts}") - print(f" ... For theta {theta} thermal_dist: {thermal_dist}") + #print(f" ... For theta {theta} thermal_dist: {thermal_dist}") print(f"For theta {theta}, app expected: {app_correct_dist} measured: {app_counts}") - print(f" ... For theta {theta} app_thermal_dist: {app_thermal_dist}") + #print(f" ... For theta {theta} app_thermal_dist: {app_thermal_dist}") # use polarization fidelity with rescaling fidelity = metrics.polarization_fidelity(counts, correct_dist, thermal_dist) @@ -135,7 +135,7 @@ def execution_handler(qc, result, num_qubits, theta, num_shots): np.random.seed(0) # as circuit width grows, the number of counting qubits is increased - num_counting_qubits = num_qubits - num_state_qubits - 1 + num_counting_qubits = num_qubits - num_state_qubits # determine number of circuits to execute for this group num_circuits = min(2 ** (num_counting_qubits), max_circuits) @@ -144,9 +144,13 @@ def execution_handler(qc, result, num_qubits, theta, num_shots): # determine range of secret strings to loop over if 2**(num_counting_qubits) <= max_circuits: - theta_range = [i/(2**(num_counting_qubits)) for i in list(range(num_circuits))] + theta_choices = list(range(num_circuits)) else: - theta_range = [i/(2**(num_counting_qubits)) for i in np.random.choice(2**(num_counting_qubits), num_circuits, False)] + theta_choices = np.random.randint(1, 2**(num_counting_qubits), num_circuits + 10) + theta_choices = list(set(theta_choices))[0:num_circuits] + + # scale choices to 1.0 + theta_range = [i/(2**(num_counting_qubits)) for i in theta_choices] # loop over limited # of random theta choices for theta in theta_range: From 2aa5b5447501f17f05d428563c2efaf3b9125bf8 Mon Sep 17 00:00:00 2001 From: rtvuser1 Date: Sun, 9 Jun 2024 16:37:31 -0700 Subject: [PATCH 5/7] Add --noise option to several of the benchmark mains --- bernstein-vazirani/bv_benchmark.py | 4 ++++ bernstein-vazirani/qiskit/bv_benchmark.py | 4 ++++ grovers/qiskit/grovers_benchmark.py | 4 ++++ hidden-shift/qiskit/hs_benchmark.py | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/bernstein-vazirani/bv_benchmark.py b/bernstein-vazirani/bv_benchmark.py index 7c48adc0..cbafc132 100644 --- a/bernstein-vazirani/bv_benchmark.py +++ b/bernstein-vazirani/bv_benchmark.py @@ -217,6 +217,7 @@ def get_args(): parser.add_argument("--max_circuits", "-c", default=3, help="Maximum circuit repetitions", type=int) parser.add_argument("--method", "-m", default=1, help="Algorithm Method", type=int) parser.add_argument("--input_value", "-i", default=None, help="Fixed Input Value", type=int) + parser.add_argument("--nonoise", "-non", action="store_true", help="Use Noiseless Simulator") parser.add_argument("--verbose", "-v", action="store_true", help="Verbose") return parser.parse_args() @@ -230,6 +231,8 @@ def get_args(): # special argument handling ex.verbose = args.verbose + verbose = args.verbose + if args.num_qubits > 0: args.min_qubits = args.max_qubits = args.num_qubits # execute benchmark program @@ -239,6 +242,7 @@ def get_args(): method=args.method, input_value=args.input_value, backend_id=args.backend_id, + exec_options = {"noise_model" : None} if args.nonoise else {}, api=args.api ) diff --git a/bernstein-vazirani/qiskit/bv_benchmark.py b/bernstein-vazirani/qiskit/bv_benchmark.py index 4c073457..0873cce1 100644 --- a/bernstein-vazirani/qiskit/bv_benchmark.py +++ b/bernstein-vazirani/qiskit/bv_benchmark.py @@ -200,6 +200,7 @@ def get_args(): parser.add_argument("--max_circuits", "-c", default=3, help="Maximum circuit repetitions", type=int) parser.add_argument("--method", "-m", default=1, help="Algorithm Method", type=int) parser.add_argument("--input_value", "-i", default=None, help="Fixed Input Value", type=int) + parser.add_argument("--nonoise", "-non", action="store_true", help="Use Noiseless Simulator") parser.add_argument("--verbose", "-v", action="store_true", help="Verbose") return parser.parse_args() @@ -213,6 +214,8 @@ def get_args(): # special argument handling ex.verbose = args.verbose + verbose = args.verbose + if args.num_qubits > 0: args.min_qubits = args.max_qubits = args.num_qubits # execute benchmark program @@ -222,6 +225,7 @@ def get_args(): method=args.method, input_value=args.input_value, backend_id=args.backend_id, + exec_options = {"noise_model" : None} if args.nonoise else {}, #api=args.api ) diff --git a/grovers/qiskit/grovers_benchmark.py b/grovers/qiskit/grovers_benchmark.py index 9b58fd3f..122687b9 100644 --- a/grovers/qiskit/grovers_benchmark.py +++ b/grovers/qiskit/grovers_benchmark.py @@ -173,6 +173,7 @@ def get_args(): parser.add_argument("--method", "-m", default=1, help="Algorithm Method", type=int) #parser.add_argument("--input_value", "-i", default=None, help="Fixed Input Value", type=int) parser.add_argument("--use_mcx_shim", action="store_true", help="Use MCX Shim") + parser.add_argument("--nonoise", "-non", action="store_true", help="Use Noiseless Simulator") parser.add_argument("--verbose", "-v", action="store_true", help="Verbose") return parser.parse_args() @@ -186,6 +187,8 @@ def get_args(): # special argument handling ex.verbose = args.verbose + verbose = args.verbose + if args.num_qubits > 0: args.min_qubits = args.max_qubits = args.num_qubits # execute benchmark program @@ -195,6 +198,7 @@ def get_args(): #method=args.method, # not used currently use_mcx_shim=args.use_mcx_shim, backend_id=args.backend_id, + exec_options = {"noise_model" : None} if args.nonoise else {}, #api=args.api ) diff --git a/hidden-shift/qiskit/hs_benchmark.py b/hidden-shift/qiskit/hs_benchmark.py index 35a3723d..0b6d318a 100644 --- a/hidden-shift/qiskit/hs_benchmark.py +++ b/hidden-shift/qiskit/hs_benchmark.py @@ -145,6 +145,7 @@ def get_args(): parser.add_argument("--max_circuits", "-c", default=3, help="Maximum circuit repetitions", type=int) parser.add_argument("--method", "-m", default=1, help="Algorithm Method", type=int) #parser.add_argument("--input_value", "-i", default=None, help="Fixed Input Value", type=int) + parser.add_argument("--nonoise", "-non", action="store_true", help="Use Noiseless Simulator") parser.add_argument("--verbose", "-v", action="store_true", help="Verbose") return parser.parse_args() @@ -158,6 +159,8 @@ def get_args(): # special argument handling ex.verbose = args.verbose + verbose = args.verbose + if args.num_qubits > 0: args.min_qubits = args.max_qubits = args.num_qubits # execute benchmark program @@ -167,6 +170,7 @@ def get_args(): #method=args.method, # not used currently #input_value=args.input_value, # not used currently backend_id=args.backend_id, + exec_options = {"noise_model" : None} if args.nonoise else {}, #api=args.api ) From 2ae69c7023f8be1cd211c88babe01921881e8430 Mon Sep 17 00:00:00 2001 From: rtvuser1 Date: Sun, 9 Jun 2024 23:11:48 -0700 Subject: [PATCH 6/7] Add main or Update main function with --nonoise arg and other minor cleanup --- amplitude-estimation/qiskit/ae_benchmark.py | 47 +++++++++++++- bernstein-vazirani/qiskit/bv_benchmark.py | 6 +- deutsch-jozsa/qiskit/dj_benchmark.py | 45 ++++++++++++- monte-carlo/qiskit/mc_benchmark.py | 47 +++++++++++++- .../qiskit/qft_benchmark.py | 64 +++++++++++++++++-- 5 files changed, 197 insertions(+), 12 deletions(-) diff --git a/amplitude-estimation/qiskit/ae_benchmark.py b/amplitude-estimation/qiskit/ae_benchmark.py index 84af65ce..46c06615 100644 --- a/amplitude-estimation/qiskit/ae_benchmark.py +++ b/amplitude-estimation/qiskit/ae_benchmark.py @@ -330,5 +330,50 @@ def execution_handler(qc, result, num_qubits, s_int, num_shots): metrics.plot_metrics(f"Benchmark Results - {benchmark_name} - Qiskit") +####################### +# MAIN + +import argparse +def get_args(): + parser = argparse.ArgumentParser(description="Bernstei-Vazirani Benchmark") + #parser.add_argument("--api", "-a", default=None, help="Programming API", type=str) + #parser.add_argument("--target", "-t", default=None, help="Target Backend", type=str) + parser.add_argument("--backend_id", "-b", default=None, help="Backend Identifier", type=str) + parser.add_argument("--num_shots", "-s", default=100, help="Number of shots", type=int) + parser.add_argument("--num_qubits", "-n", default=0, help="Number of qubits", type=int) + parser.add_argument("--min_qubits", "-min", default=3, help="Minimum number of qubits", type=int) + parser.add_argument("--max_qubits", "-max", default=8, help="Maximum number of qubits", type=int) + parser.add_argument("--skip_qubits", "-k", default=1, help="Number of qubits to skip", type=int) + parser.add_argument("--max_circuits", "-c", default=3, help="Maximum circuit repetitions", type=int) + parser.add_argument("--method", "-m", default=1, help="Algorithm Method", type=int) + parser.add_argument("--num_state_qubits", "-nsq", default=0.0, help="Number of State Qubits", type=int) + parser.add_argument("--nonoise", "-non", action="store_true", help="Use Noiseless Simulator") + parser.add_argument("--verbose", "-v", action="store_true", help="Verbose") + return parser.parse_args() + # if main, execute method -if __name__ == '__main__': run() +if __name__ == '__main__': + args = get_args() + + # configure the QED-C Benchmark package for use with the given API + # (done here so we can set verbose for now) + #AmplitudeEstimation, kernel_draw = qedc_benchmarks_init(args.api) + + # special argument handling + ex.verbose = args.verbose + verbose = args.verbose + + if args.num_qubits > 0: args.min_qubits = args.max_qubits = args.num_qubits + + # execute benchmark program + run(min_qubits=args.min_qubits, max_qubits=args.max_qubits, + skip_qubits=args.skip_qubits, max_circuits=args.max_circuits, + num_shots=args.num_shots, + #method=args.method, + num_state_qubits=args.num_state_qubits, + backend_id=args.backend_id, + exec_options = {"noise_model" : None} if args.nonoise else {}, + #api=args.api + ) + + diff --git a/bernstein-vazirani/qiskit/bv_benchmark.py b/bernstein-vazirani/qiskit/bv_benchmark.py index 0873cce1..4d00cf3f 100644 --- a/bernstein-vazirani/qiskit/bv_benchmark.py +++ b/bernstein-vazirani/qiskit/bv_benchmark.py @@ -139,8 +139,8 @@ def execution_handler (qc, result, num_qubits, s_int, num_shots): if 2**(input_size) <= max_circuits: s_range = list(range(num_circuits)) else: - # create selection larger than needed and remove duplicates (faster than random.choice()) - s_range = np.random.randint(1, 2**(input_size), num_circuits + 10) + # create selection larger than needed and remove duplicates + s_range = np.random.randint(1, 2**(input_size), num_circuits + 2) s_range = list(set(s_range))[0:max_circuits] # loop over limited # of secret strings for this @@ -148,7 +148,7 @@ def execution_handler (qc, result, num_qubits, s_int, num_shots): s_int = int(s_int) # if user specifies input_value, use it instead - # DEVNOTE: if max_circuits used, this will generate multiple bars per width + # DEVNOTE: if max_circuits used, this will generate separate bar for each num_circuits if input_value is not None: s_int = input_value diff --git a/deutsch-jozsa/qiskit/dj_benchmark.py b/deutsch-jozsa/qiskit/dj_benchmark.py index 7387ced9..93e6e74d 100644 --- a/deutsch-jozsa/qiskit/dj_benchmark.py +++ b/deutsch-jozsa/qiskit/dj_benchmark.py @@ -226,5 +226,48 @@ def execution_handler (qc, result, num_qubits, type, num_shots): # Plot metrics for all circuit sizes metrics.plot_metrics(f"Benchmark Results - {benchmark_name} - Qiskit") + +####################### +# MAIN + +import argparse +def get_args(): + parser = argparse.ArgumentParser(description="Bernstei-Vazirani Benchmark") + #parser.add_argument("--api", "-a", default=None, help="Programming API", type=str) + #parser.add_argument("--target", "-t", default=None, help="Target Backend", type=str) + parser.add_argument("--backend_id", "-b", default=None, help="Backend Identifier", type=str) + parser.add_argument("--num_shots", "-s", default=100, help="Number of shots", type=int) + parser.add_argument("--num_qubits", "-n", default=0, help="Number of qubits", type=int) + parser.add_argument("--min_qubits", "-min", default=3, help="Minimum number of qubits", type=int) + parser.add_argument("--max_qubits", "-max", default=8, help="Maximum number of qubits", type=int) + parser.add_argument("--skip_qubits", "-k", default=1, help="Number of qubits to skip", type=int) + parser.add_argument("--max_circuits", "-c", default=3, help="Maximum circuit repetitions", type=int) + #parser.add_argument("--method", "-m", default=1, help="Algorithm Method", type=int) + parser.add_argument("--nonoise", "-non", action="store_true", help="Use Noiseless Simulator") + parser.add_argument("--verbose", "-v", action="store_true", help="Verbose") + return parser.parse_args() + # if main, execute method -if __name__ == '__main__': run() +if __name__ == '__main__': + args = get_args() + + # configure the QED-C Benchmark package for use with the given API + # (done here so we can set verbose for now) + #BersteinVazirani, kernel_draw = qedc_benchmarks_init(args.api) + + # special argument handling + ex.verbose = args.verbose + verbose = args.verbose + + if args.num_qubits > 0: args.min_qubits = args.max_qubits = args.num_qubits + + # execute benchmark program + run(min_qubits=args.min_qubits, max_qubits=args.max_qubits, + skip_qubits=args.skip_qubits, max_circuits=args.max_circuits, + num_shots=args.num_shots, + #method=args.method, + backend_id=args.backend_id, + exec_options = {"noise_model" : None} if args.nonoise else {}, + #api=args.api + ) + diff --git a/monte-carlo/qiskit/mc_benchmark.py b/monte-carlo/qiskit/mc_benchmark.py index 8f8e39c3..c69a91dd 100644 --- a/monte-carlo/qiskit/mc_benchmark.py +++ b/monte-carlo/qiskit/mc_benchmark.py @@ -489,5 +489,50 @@ def execution_handler(qc, result, num_qubits, mu, num_shots): metrics.plot_metrics(f"Benchmark Results - {benchmark_name} ({method}) - Qiskit") +####################### +# MAIN + +import argparse +def get_args(): + parser = argparse.ArgumentParser(description="Bernstei-Vazirani Benchmark") + #parser.add_argument("--api", "-a", default=None, help="Programming API", type=str) + #parser.add_argument("--target", "-t", default=None, help="Target Backend", type=str) + parser.add_argument("--backend_id", "-b", default=None, help="Backend Identifier", type=str) + parser.add_argument("--num_shots", "-s", default=100, help="Number of shots", type=int) + parser.add_argument("--num_qubits", "-n", default=0, help="Number of qubits", type=int) + parser.add_argument("--min_qubits", "-min", default=3, help="Minimum number of qubits", type=int) + parser.add_argument("--max_qubits", "-max", default=8, help="Maximum number of qubits", type=int) + parser.add_argument("--skip_qubits", "-k", default=1, help="Number of qubits to skip", type=int) + parser.add_argument("--max_circuits", "-c", default=3, help="Maximum circuit repetitions", type=int) + parser.add_argument("--method", "-m", default=1, help="Algorithm Method", type=int) + parser.add_argument("--num_state_qubits", "-nsq", default=0.0, help="Number of State Qubits", type=int) + parser.add_argument("--nonoise", "-non", action="store_true", help="Use Noiseless Simulator") + parser.add_argument("--verbose", "-v", action="store_true", help="Verbose") + return parser.parse_args() + # if main, execute method -if __name__ == '__main__': run() +if __name__ == '__main__': + args = get_args() + + # configure the QED-C Benchmark package for use with the given API + # (done here so we can set verbose for now) + #MonteCarloSampling, kernel_draw = qedc_benchmarks_init(args.api) + + # special argument handling + ex.verbose = args.verbose + verbose = args.verbose + + if args.num_qubits > 0: args.min_qubits = args.max_qubits = args.num_qubits + + # execute benchmark program + run(min_qubits=args.min_qubits, max_qubits=args.max_qubits, + skip_qubits=args.skip_qubits, max_circuits=args.max_circuits, + num_shots=args.num_shots, + #method=args.method, + num_state_qubits=args.num_state_qubits, + backend_id=args.backend_id, + exec_options = {"noise_model" : None} if args.nonoise else {}, + #api=args.api + ) + + diff --git a/quantum-fourier-transform/qiskit/qft_benchmark.py b/quantum-fourier-transform/qiskit/qft_benchmark.py index 031ee641..71eaaae5 100644 --- a/quantum-fourier-transform/qiskit/qft_benchmark.py +++ b/quantum-fourier-transform/qiskit/qft_benchmark.py @@ -248,7 +248,7 @@ def analyze_and_print_result (qc, result, num_qubits, secret_int, num_shots, met # Execute program with default parameters def run (min_qubits = 2, max_qubits = 8, max_circuits = 3, skip_qubits=1, num_shots = 100, - method=1, + method=1, input_value=None, backend_id='qasm_simulator', provider_backend=None, hub="ibm-q", group="open", project="main", exec_options=None, context=None): @@ -302,7 +302,8 @@ def execution_handler (qc, result, input_size, s_int, num_shots): if 2**(input_size) <= max_circuits: s_range = list(range(num_circuits)) else: - s_range = np.random.choice(2**(input_size), num_circuits, False) + s_range = np.random.randint(0, 2**(input_size), num_circuits + 2) + s_range = list(set(s_range))[0:num_circuits] elif method == 3: num_circuits = min(input_size, max_circuits) @@ -310,15 +311,22 @@ def execution_handler (qc, result, input_size, s_int, num_shots): if input_size <= max_circuits: s_range = list(range(num_circuits)) else: - s_range = np.random.choice(range(input_size), num_circuits, False) + s_range = np.random.randint(0, 2**(input_size), num_circuits + 2) + s_range = list(set(s_range))[0:num_circuits] else: sys.exit("Invalid QFT method") - + print(f"************\nExecuting [{num_circuits}] circuits with num_qubits = {num_qubits}") # loop over limited # of secret strings for this for s_int in s_range: + s_int = int(s_int) + + # if user specifies input_value, use it instead + # DEVNOTE: if max_circuits used, this will generate separate bar for each num_circuits + if input_value is not None: + s_int = input_value # create the circuit for given qubit size and secret string, store time metric ts = time.time() @@ -351,5 +359,49 @@ def execution_handler (qc, result, input_size, s_int, num_shots): # Plot metrics for all circuit sizes metrics.plot_metrics(f"Benchmark Results - {benchmark_name} ({method}) - Qiskit") -# if main, execute method 1 -if __name__ == '__main__': run() +####################### +# MAIN + +import argparse +def get_args(): + parser = argparse.ArgumentParser(description="Bernstei-Vazirani Benchmark") + #parser.add_argument("--api", "-a", default=None, help="Programming API", type=str) + #parser.add_argument("--target", "-t", default=None, help="Target Backend", type=str) + parser.add_argument("--backend_id", "-b", default=None, help="Backend Identifier", type=str) + parser.add_argument("--num_shots", "-s", default=100, help="Number of shots", type=int) + parser.add_argument("--num_qubits", "-n", default=0, help="Number of qubits", type=int) + parser.add_argument("--min_qubits", "-min", default=3, help="Minimum number of qubits", type=int) + parser.add_argument("--max_qubits", "-max", default=8, help="Maximum number of qubits", type=int) + parser.add_argument("--skip_qubits", "-k", default=1, help="Number of qubits to skip", type=int) + parser.add_argument("--max_circuits", "-c", default=3, help="Maximum circuit repetitions", type=int) + parser.add_argument("--method", "-m", default=1, help="Algorithm Method", type=int) + parser.add_argument("--input_value", "-i", default=None, help="Fixed Input Value", type=int) + parser.add_argument("--nonoise", "-non", action="store_true", help="Use Noiseless Simulator") + parser.add_argument("--verbose", "-v", action="store_true", help="Verbose") + return parser.parse_args() + +# if main, execute method +if __name__ == '__main__': + args = get_args() + + # configure the QED-C Benchmark package for use with the given API + # (done here so we can set verbose for now) + #QuantumFourierTransform, kernel_draw = qedc_benchmarks_init(args.api) + + # special argument handling + ex.verbose = args.verbose + verbose = args.verbose + + if args.num_qubits > 0: args.min_qubits = args.max_qubits = args.num_qubits + + # execute benchmark program + run(min_qubits=args.min_qubits, max_qubits=args.max_qubits, + skip_qubits=args.skip_qubits, max_circuits=args.max_circuits, + num_shots=args.num_shots, + method=args.method, + input_value=args.input_value, # not implemented yet + backend_id=args.backend_id, + exec_options = {"noise_model" : None} if args.nonoise else {}, + #api=args.api + ) + From 192081eaf3f85d2ebf918f3673457adf307a9742 Mon Sep 17 00:00:00 2001 From: rtvuser1 Date: Sun, 9 Jun 2024 23:16:03 -0700 Subject: [PATCH 7/7] Fix random input_value gen for api-independent version --- bernstein-vazirani/bv_benchmark.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bernstein-vazirani/bv_benchmark.py b/bernstein-vazirani/bv_benchmark.py index cbafc132..355e5508 100644 --- a/bernstein-vazirani/bv_benchmark.py +++ b/bernstein-vazirani/bv_benchmark.py @@ -156,8 +156,8 @@ def execution_handler (qc, result, num_qubits, s_int, num_shots): if 2**(input_size) <= max_circuits: s_range = list(range(num_circuits)) else: - # create selection larger than needed and remove duplicates (faster than random.choice()) - s_range = np.random.randint(1, 2**(input_size), num_circuits + 10) + # create selection larger than needed and remove duplicates + s_range = np.random.randint(1, 2**(input_size), num_circuits + 2) s_range = list(set(s_range))[0:max_circuits] # loop over limited # of secret strings for this @@ -165,7 +165,7 @@ def execution_handler (qc, result, num_qubits, s_int, num_shots): s_int = int(s_int) # if user specifies input_value, use it instead - # DEVNOTE: if max_circuits used, this will generate multiple bars per width + # DEVNOTE: if max_circuits used, this will generate separate bar for each num_circuits if input_value is not None: s_int = input_value