Skip to content

Commit

Permalink
Added Challenge 2024
Browse files Browse the repository at this point in the history
  • Loading branch information
MonitSharma committed Jun 23, 2024
1 parent 5765597 commit b46a78a
Show file tree
Hide file tree
Showing 17 changed files with 12,488 additions and 22 deletions.
11 changes: 11 additions & 0 deletions IBM Quantum Challenge 2024/birds_dataset.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
names,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19,c20,c21,c22,c23,c24,c25,c26,c27,c28,c29,c30,c31
Falcon,0.7071067811865476,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.7071067811865476
Hummingbird,0.0,0.7071067811865476,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.7071067811865476,0.0
Eagle,0.0,0.0,0.7071067811865476,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.7071067811865476,0.0,0.0
Osprey,0.0,0.0,0.0,0.7071067811865476,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.7071067811865476,0.0,0.0,0.0
Heron,0.0,0.0,0.0,0.0,0.7071067811865476,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.7071067811865476,0.0,0.0,0.0,0.0
Peacock,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
Parrot,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
Swan,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
Toucan,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
Cardinal,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
930 changes: 930 additions & 0 deletions IBM Quantum Challenge 2024/bonus-lab-solutions.ipynb

Large diffs are not rendered by default.

1,325 changes: 1,325 additions & 0 deletions IBM Quantum Challenge 2024/lab-0.ipynb

Large diffs are not rendered by default.

1,427 changes: 1,427 additions & 0 deletions IBM Quantum Challenge 2024/lab-1.ipynb

Large diffs are not rendered by default.

2,962 changes: 2,962 additions & 0 deletions IBM Quantum Challenge 2024/lab-2.ipynb

Large diffs are not rendered by default.

528 changes: 528 additions & 0 deletions IBM Quantum Challenge 2024/lab-3-ai-transpiler-solution.ipynb

Large diffs are not rendered by default.

1,511 changes: 1,511 additions & 0 deletions IBM Quantum Challenge 2024/lab-3-circuit-knitting(1).ipynb

Large diffs are not rendered by default.

428 changes: 428 additions & 0 deletions IBM Quantum Challenge 2024/lab-3-code-assistant.ipynb

Large diffs are not rendered by default.

1,234 changes: 1,234 additions & 0 deletions IBM Quantum Challenge 2024/lab-3-serverless-solution.ipynb

Large diffs are not rendered by default.

1,720 changes: 1,720 additions & 0 deletions IBM Quantum Challenge 2024/lab-4-solutions.ipynb

Large diffs are not rendered by default.

Binary file not shown.
Binary file added IBM Quantum Challenge 2024/params_0_list.npy
Binary file not shown.
68 changes: 68 additions & 0 deletions IBM Quantum Challenge 2024/transpile_parallel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# transpile_parallel.py

from qiskit import QuantumCircuit
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_transpiler_service.transpiler_service import TranspilerService
from qiskit_serverless import get_arguments, save_result, distribute_task, get
from qiskit_ibm_runtime import QiskitRuntimeService
from timeit import default_timer as timer

@distribute_task(target={"cpu": 2})
def transpile_parallel(circuit: QuantumCircuit, config):
"""Distributed transpilation for an abstract circuit into an ISA circuit for a given backend."""
transpiled_circuit = config.run(circuit)
return transpiled_circuit


# Get program arguments
arguments = get_arguments()
circuits = arguments.get("circuits")
backend_name = arguments.get("backend_name")

# Get backend
service = QiskitRuntimeService(channel="ibm_quantum")
backend = service.get_backend(backend_name)

# Define Configs
optimization_levels = [1, 2, 3]
pass_managers = [{'pass_manager': generate_preset_pass_manager(optimization_level=level, backend=backend), 'optimization_level': level} for level in optimization_levels]

transpiler_services = [
{'service': TranspilerService(
backend_name="ibm_sherbrooke",
ai=False,
optimization_level=3,
)},
{'service': TranspilerService(
backend_name="ibm_sherbrooke",
ai=True,
optimization_level=3,
) }
]
configs = pass_managers + transpiler_services

# Start process
print("Starting timer")
start = timer()

# run distributed tasks as async function
# we get task references as a return type
sample_task_references = []
for circuit in circuits:
sample_task_references.append([transpile_parallel(circuit, config) for config in configs])


# now we need to collect results from task references
results = get([task for subtasks in sample_task_references for task in subtasks])

end = timer()

# Record execution time
execution_time_serverless = end-start
print("Execution time: ", execution_time_serverless)

save_result({
"transpiled_circuits": results,
"execution_time" : execution_time_serverless

})
81 changes: 81 additions & 0 deletions IBM Quantum Challenge 2024/util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import numpy as np
from qiskit import transpile, QuantumCircuit

def version_check():
import qiskit
if qiskit.version.VERSION == '1.0.2':
return print("You have the right version! Enjoy the challenge!")
else:
return print("please install right version by copy/paste and execute - !pip install 'qiskit[visualization]' == 1.0.2'")

def transpile_scoring(circ, layout, backend):

"""
A custom cost function that includes T1 and T2 computed during idle periods
Parameters:
circ (QuantumCircuit): circuit of interest
layouts (list of lists): List of specified layouts
backend (IBMQBackend): An IBM Quantum backend instance
Returns:
float: Fidelity of circ
"""

fid = 1

touched = set()
dt = backend.dt
num_qubits = backend.num_qubits

error=0

t1s = [backend.qubit_properties(qq).t1 for qq in range(num_qubits)]
t2s = [backend.qubit_properties(qq).t2 for qq in range(num_qubits)]


for item in circ._data:
for gate in backend.operation_names:
if item[0].name == gate:
if (item[0].name == 'cz') or (item[0].name == 'ecr'):
q0 = circ.find_bit(item[1][0]).index
q1 = circ.find_bit(item[1][1]).index
fid *= 1 - backend.target[item[0].name][(q0, q1)].error
touched.add(q0)
touched.add(q1)
elif item[0].name == 'measure':
q0 = circ.find_bit(item[1][0]).index
fid *= 1 - backend.target[item[0].name][(q0, )].error
touched.add(q0)

elif item[0].name == 'delay':
q0 = circ.find_bit(item[1][0]).index
# Ignore delays that occur before gates
# This assumes you are in ground state and errors
# do not occur.
if q0 in touched:
time = item[0].duration * dt
fid *= 1-qubit_error(time, t1s[q0], t2s[q0])
else:
q0 = circ.find_bit(item[1][0]).index
fid *= 1 - backend.target[item[0].name][(q0, )].error
touched.add(q0)

return fid


def qubit_error(time, t1, t2):
"""Compute the approx. idle error from T1 and T2
Parameters:
time (float): Delay time in sec
t1 (float): T1 time in sec
t2 (float): T2 time in sec
Returns:
float: Idle error
"""
t2 = min(t1, t2)
rate1 = 1/t1
rate2 = 1/t2
p_reset = 1-np.exp(-time*rate1)
p_z = (1-p_reset)*(1-np.exp(-time*(rate2-rate1)))/2
return p_z + p_reset
106 changes: 106 additions & 0 deletions IBM Quantum Challenge 2024/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@

def plot_execution_times(execution_time_serverless, execution_time_local):
"""
Plots a comparison of execution times between serverless and local executions.
Parameters:
execution_time_serverless (int): Execution time for serverless execution.
execution_time_local (int): Execution time for local execution.
"""
# Create labels for the x-axis
labels = ['Serverless', 'Local']

# Execution times
execution_times = [execution_time_serverless, execution_time_local]

# Plotting
plt.figure(figsize=(8, 6))
bars = plt.bar(labels, execution_times, color=['skyblue', 'orange'])

# Add annotations to display the execution times on the bars
for bar in bars:
plt.text(bar.get_x() + bar.get_width() / 2, bar.get_height() - 1, f'{bar.get_height()}',
ha='center', va='bottom', color='black')

# Adding labels and title
plt.xlabel('Execution Type')
plt.ylabel('Execution Time (seconds)')
plt.title('Comparison of Execution Times: Serverless vs Local')
plt.tight_layout()
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()

import matplotlib.pyplot as plt

def process_transpiled_circuits(configs, result):
"""
Processes transpiled circuits, plots the depths for each configuration chunk, and stores the best circuits.
Parameters:
configs (list): List of configuration dictionaries.
result (dict): Dictionary containing transpiled circuits.
Returns:
best_circuits (list): List of best transpiled circuits.
best_depths (list): List of depths of the best transpiled circuits.
best_methods (list): List of methods used to obtain the best depths.
"""
# Helper function to create configuration names
def get_config_name(config):
if 'service' in config:
return f"TranspilerService(ai={config['ai']}, optimization_level={config['optimization_level']})"
else:
return f"PassManager(optimization_level={config['optimization_level']})"

# Generate the full list of configurations to match the number of transpiled circuits
full_configs = configs * (len(result) // len(configs))

# Number of results to process in each chunk
chunk_size = 5

# Lists to store the best circuits, depths, and methods
best_circuits = []
best_depths = []
best_methods = []

# Process each chunk of results
for chunk_start in range(0, len(result), chunk_size):
chunk_end = chunk_start + chunk_size
current_chunk = result[chunk_start:chunk_end]
current_configs = full_configs[chunk_start:chunk_end]

depths = [transpiled_circuit.depth() for transpiled_circuit in current_chunk]
config_names = [get_config_name(config) for config in current_configs]

# Find the index of the minimum depth
min_depth_index = depths.index(min(depths))

# Store the best circuit, depth, and method
best_circuit = current_chunk[min_depth_index]
best_depth = depths[min_depth_index]
best_method = config_names[min_depth_index]
best_circuits.append(best_circuit)
best_depths.append(best_depth)
best_methods.append(best_method)

# Plotting
plt.figure(figsize=(12, 8))
bars = plt.bar(range(len(depths)), depths, tick_label=config_names, color='skyblue')

# Highlight the bar with the minimum depth
bars[min_depth_index].set_color('green')

# Add annotations to highlight the minimum depth
for i, bar in enumerate(bars):
plt.text(bar.get_x() + bar.get_width() / 2, bar.get_height() - 1, f'{bar.get_height()}',
ha='center', va='bottom', color='black')

plt.xlabel('Configuration')
plt.ylabel('Transpiled Circuit Depth')
plt.title(f'Transpiled result for circuit {chunk_start // chunk_size}')
plt.xticks(rotation=45, ha='right')
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.tight_layout()
plt.show()

return best_circuits, best_depths, best_methods
Loading

0 comments on commit b46a78a

Please sign in to comment.