Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change expectation value metric to HOP for QV circuits #223

Merged
merged 36 commits into from
Feb 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
41495e2
add quantum volume
Misty-W Feb 11, 2025
c85ab74
Turn off the noise for ideal value
Misty-W Feb 11, 2025
b25db52
Merge branch 'plot-expectation-value' into match-observables-with-cir…
Misty-W Feb 11, 2025
0d0876e
reduce noise level on 1q gates
Misty-W Feb 11, 2025
d8b9396
set defaults for noisy density matrix simulation
Misty-W Feb 13, 2025
d0ee544
rename variables
Misty-W Feb 13, 2025
b9723f6
Bug fixes for save
Misty-W Feb 13, 2025
a0bb4fa
refactor expval benchmark to run single iteration
natestemen Jan 14, 2025
75958e2
Add filenames to expal run
jordandsullivan Jan 14, 2025
90c5d60
Fix filenames
jordandsullivan Jan 14, 2025
40a2ecc
first plot
natestemen Jan 15, 2025
7f7d3cc
more plots
natestemen Jan 15, 2025
081dd57
uncomment first commands to run
natestemen Jan 17, 2025
531b275
s/relative/absolute for errors
natestemen Jan 17, 2025
2c2c7fb
add new data and remove relative errors
natestemen Jan 17, 2025
36863cc
remove old plot
natestemen Jan 17, 2025
fd0bc7e
ensure noise is added to all target gates
natestemen Feb 9, 2025
db334ff
add quantum volume
Misty-W Feb 11, 2025
332a82d
Turn off the noise for ideal value
Misty-W Feb 11, 2025
9047094
use transpile as translate for consistency
natestemen Feb 11, 2025
024f3f7
ignore python compiled files
natestemen Feb 11, 2025
5458b22
remove pycache from repo
natestemen Feb 11, 2025
f4b0453
Merge branch 'main' into match-observables-with-circuits
Misty-W Feb 14, 2025
9f210a5
Clean up files
Misty-W Feb 15, 2025
887832d
Finish refactor of `expval_benchmark.py`
Misty-W Feb 15, 2025
87aeaf7
re-attempt ruff format
Misty-W Feb 15, 2025
ddea6bc
Update benchmark results [benchmark chore]
actions-user Feb 15, 2025
2f4f4b7
Update benchmark results [benchmark chore]
actions-user Feb 15, 2025
608c4e3
Add docstrings
Misty-W Feb 15, 2025
46fda7b
Resolve conflicts
Misty-W Feb 18, 2025
27a03cc
Delete common.cpython-312.pyc
Misty-W Feb 19, 2025
3a16139
set noise flag
Misty-W Feb 19, 2025
a807931
Apply suggestions from code review
Misty-W Feb 19, 2025
d083104
Add conflicting file back
Misty-W Feb 19, 2025
07c30cf
Fix ruff format
Misty-W Feb 19, 2025
52a2a54
remove result files
Misty-W Feb 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified benchmarks/avg_compiler_benchmarks_over_time.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified benchmarks/latest_compiler_benchmarks_by_circuit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified benchmarks/latest_expval_benchmark_by_compiler.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified benchmarks/scripts/__pycache__/common.cpython-312.pyc
Binary file not shown.
91 changes: 75 additions & 16 deletions benchmarks/scripts/expval_benchmark.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import sys
import math
import os.path
from typing import Any
from typing import Any, Set

import cirq
import pytket
Expand Down Expand Up @@ -158,35 +159,92 @@ def fetch_pre_post_compiled_circuits(
return uncompiled_qiskit_circuit, compiled_qiskit_circuit


def get_heavy_bitstrings(circuit: qiskit.QuantumCircuit) -> Set[str]:
""" "Determine the heavy bitstrings of the circuit."""
simulator = AerSimulator(method="statevector")
result = simulator.run(circuit, shots=1024).result()
counts = list(result.get_counts().items())
median = np.median([c for (_, c) in counts])
return set(bitstring for (bitstring, p) in counts if p > median)


def estimate_heavy_output_prob(
circuit: qiskit.QuantumCircuit, noisy: bool = True
) -> float:
"""Sample the heavy bitstrings on the backend and estimate the heavy output
probability from the counts of the heavy bitstrings.

Args:
circuit: The circuit for which to compute the heavy output metric.
qv_1q_err: The single qubit error rate for the backend noise model.
qv_2q_err: The two-qubit error rate for the backend noise model.

Returns:
The heavy output probability as a float.
"""
heavy_bitstrings = get_heavy_bitstrings(circuit)

if noisy:
qv_1q_err = 0.002
qv_2q_err = 0.02
else:
qv_1q_err = 0.0
qv_2q_err = 0.0
simulator = AerSimulator(
method="statevector",
noise_model=create_depolarizing_noise_model(
circuit, qv_1q_err, qv_2q_err
),
)
result = simulator.run(circuit).result()

heavy_counts = sum(
result.get_counts().get(bitstring, 0) for bitstring in heavy_bitstrings
)
nshots = 1024
hop = (
heavy_counts - 2 * math.sqrt(heavy_counts * (nshots - heavy_counts))
) / nshots
return hop


def simulate_expvals(
uncompiled_circuit: qiskit.QuantumCircuit,
compiled_circuit: qiskit.QuantumCircuit,
observable: str,
circuit_name: str,
) -> tuple[float, float]:
"""Simulates the expectation values of a given observable for
both uncompiled and compiled quantum circuits.

Args:
uncompiled_circuit: The original quantum circuit before compilation.
compiled_circuit: The quantum circuit after compilation.
observable: The observable for which the expectation value
is to be calculated, represented as a string.
circuit_name: The name of the quantum circuit in string format.

Returns:
A tuple containing the expectation values of the observable for the
uncompiled and compiled circuits, respectively.
"""
if circuit_name == "qv":
compiled_circuit.measure_all()
uncompiled_circuit.measure_all()
return (
estimate_heavy_output_prob(compiled_circuit, noisy=True),
estimate_heavy_output_prob(uncompiled_circuit, noisy=False),
"HOP",
)

density_matrix = simulate_density_matrix(compiled)

observable = Operator.from_label(observable)
else:
density_matrix = simulate_density_matrix(compiled_circuit)
obs_str = "Z" * compiled.num_qubits
observable = Operator.from_label(obs_str)

compiled_ev = np.real(density_matrix.expectation_value(observable))
compiled_ev = np.real(density_matrix.expectation_value(observable))

ideal_state = Statevector.from_instruction(uncompiled)
ideal_ev = np.real(ideal_state.expectation_value(observable))
ideal_state = Statevector.from_instruction(uncompiled_circuit)
ideal_ev = np.real(ideal_state.expectation_value(observable))

return ideal_ev, compiled_ev
return ideal_ev, compiled_ev, obs_str


if __name__ == "__main__":
Expand All @@ -195,15 +253,16 @@ def simulate_expvals(
uncompiled, compiled = fetch_pre_post_compiled_circuits(
qasm_path, compiler_alias, log_details=log
)

observable = "Z" * compiled.num_qubits
ideal_ev, compiled_ev = simulate_expvals(uncompiled, compiled, observable)
circuit_name = qasm_path.split("/")[-1].split("_N")[0]
ideal_ev, compiled_ev, obs_str = simulate_expvals(
uncompiled, compiled, circuit_name
)

results = [
{
"compiler": compiler_alias,
"circuit_name": qasm_path.split("/")[-1].split("_N")[0],
"observable": observable,
"circuit_name": circuit_name,
"observable": obs_str,
"expval": compiled_ev,
"absolute_error": abs(ideal_ev - compiled_ev),
"relative_error": abs(ideal_ev - compiled_ev) / abs(ideal_ev),
Expand Down