Skip to content

Commit

Permalink
Merge pull request #634 from SRI-International/upgrade-to-qiskit-1.2
Browse files Browse the repository at this point in the history
Upgrade to qiskit 1.2, required changes
  • Loading branch information
rtvuser1 authored Oct 1, 2024
2 parents e9e3823 + be75eb6 commit 9b5feef
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 27 deletions.
64 changes: 40 additions & 24 deletions _common/qiskit/execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,12 @@ def __init__(self, qiskit_result):
self.metadata = qiskit_result.metadata

def get_counts(self, qc=0):
counts= self.qiskit_result.quasi_dists[0].binary_probabilities()
for key in counts.keys():
counts[key] = int(counts[key] * self.qiskit_result.metadata[0]['shots'])
# counts= self.qiskit_result.quasi_dists[0].binary_probabilities()
# for key in counts.keys():
# counts[key] = int(counts[key] * self.qiskit_result.metadata[0]['shots'])
qc_index = 0 # this should point to the index of the circuit in a pub
bitvals = next(iter(self.qiskit_result[qc_index].data.values()))
counts = bitvals.get_counts()
return counts

# Special Job object class to hold job information for custom executors
Expand Down Expand Up @@ -250,6 +253,7 @@ def set_execution_target(backend_id='qasm_simulator',
provider_name='Quantinuum')
"""
global backend
global sampler
global session
global use_sessions
global session_count
Expand Down Expand Up @@ -291,12 +295,16 @@ def set_execution_target(backend_id='qasm_simulator',
# handle Statevector simulator specially
elif backend_id == 'statevector_simulator':
backend = Aer.get_backend("statevector_simulator")


elif backend_id == "statevector_sampler":
from qiskit.primitives import StatevectorSampler
sampler = StatevectorSampler()

# handle 'fake' backends here
elif 'fake' in backend_id:
backend = getattr(
importlib.import_module(
f'qiskit.providers.fake_provider.backends.{backend_id.split("_")[-1]}.{backend_id}'
f'qiskit_ibm_runtime.fake_provider.backends.{backend_id.split("_")[-1]}.{backend_id}'
),
backend_id.title().replace('_', '')
)
Expand All @@ -306,7 +314,6 @@ def set_execution_target(backend_id='qasm_simulator',
# otherwise use the given providername or backend_id to find the backend
else:
global service
global sampler

# if provider_module name and provider_name are provided, obtain a custom provider
if provider_module_name and provider_name:
Expand Down Expand Up @@ -375,7 +382,7 @@ def set_execution_target(backend_id='qasm_simulator',

# if use sessions, setup runtime service, Session, and Sampler
if use_sessions:
from qiskit_ibm_runtime import QiskitRuntimeService, Sampler, Session, Options
from qiskit_ibm_runtime import QiskitRuntimeService, Session, Options, SamplerV2 as Sampler

service = QiskitRuntimeService()
session_count += 1
Expand All @@ -385,8 +392,8 @@ def set_execution_target(backend_id='qasm_simulator',

# get Sampler resilience level and transpiler optimization level from exec_options
options = Options()
options.resilience_level = exec_options.get("resilience_level", 1)
options.optimization_level = exec_options.get("optimization_level", 3)
# options.resilience_level = exec_options.get("resilience_level", 1)
# options.optimization_level = exec_options.get("optimization_level", 3)

# special handling for ibmq_qasm_simulator to set noise model
if backend_id == "ibmq_qasm_simulator":
Expand Down Expand Up @@ -423,14 +430,13 @@ def set_execution_target(backend_id='qasm_simulator',
###############################
# otherwise, assume the backend_id is given only and assume it is IBM Cloud device
else:
from qiskit_ibm_runtime import QiskitRuntimeService, Sampler, Session, Options
from qiskit_ibm_runtime import QiskitRuntimeService, Session, SamplerOptions as Options, SamplerV2 as Sampler

# create the Runtime Service object
service = QiskitRuntimeService()

# obtain a backend from the service
backend = service.backend(backend_id)

# DEVNOTE: here we assume if the sessions flag is set, we use Sampler
# however, we may want to add a use_sampler option so that we can separate these

Expand All @@ -449,8 +455,8 @@ def set_execution_target(backend_id='qasm_simulator',

# get Sampler resilience level and transpiler optimization level from exec_options
options = Options()
options.resilience_level = exec_options.get("resilience_level", 1)
options.optimization_level = exec_options.get("optimization_level", 3)
# options.resilience_level = exec_options.get("resilience_level", 1)
# options.optimization_level = exec_options.get("optimization_level", 3)

# special handling for ibmq_qasm_simulator to set noise model
if backend_id == "ibmq_qasm_simulator":
Expand Down Expand Up @@ -675,7 +681,7 @@ def execute_circuit(circuit):

#************************************************
# Initiate execution (with noise if specified and this is a simulator backend)
if this_noise is not None and not use_sessions and backend_name.endswith("qasm_simulator"):
if this_noise is not None and not sampler and backend_name.endswith("qasm_simulator"):
logger.info(f"Performing noisy simulation, shots = {shots}")

# if the noise model has associated QV value, copy it to metrics module for plotting
Expand Down Expand Up @@ -750,8 +756,9 @@ def execute_circuit(circuit):
logger.info(f'Running trans_qc, shots={shots}')
st = time.time()

if use_sessions:
job = sampler.run(trans_qc, shots=shots, **backend_exec_options_copy)
if sampler:
# turn input into pub-like
job = sampler.run([trans_qc], shots=shots)
else:
job = backend.run(trans_qc, shots=shots, **backend_exec_options_copy)

Expand Down Expand Up @@ -1106,7 +1113,7 @@ def job_complete(job):
# get job result (DEVNOTE: this might be different for diff targets)
result = None

if job.status() == JobStatus.DONE:
if job.status() == JobStatus.DONE or job.status() == 'DONE':
result = job.result()
# print("... result = ", str(result))

Expand All @@ -1128,13 +1135,18 @@ def job_complete(job):
# if we are using sessions, structure of result object is different;
# use a BenchmarkResult object to hold session result and provide a get_counts()
# that returns counts to the benchmarks in the same form as without sessions
if use_sessions:
if sampler:
result = BenchmarkResult(result)
#counts = result.get_counts()

actual_shots = result.metadata[0]['shots']
result_obj = result.metadata[0]
results_obj = result.metadata[0]
# actual_shots = result.metadata[0]['shots']
# get the name of the classical register
# TODO: need to rewrite to allow for submit multiple circuits in one job
# get DataBin associated with the classical register
bitvals = next(iter(result.qiskit_result[0].data.values()))
actual_shots = bitvals.num_shots
result_obj = result.metadata # not sure how to update to be V2 compatible
results_obj = result.metadata
else:
result_obj = result.to_dict()
results_obj = result.to_dict()['results'][0]
Expand Down Expand Up @@ -1169,6 +1181,10 @@ def job_complete(job):
elif "time_taken" in results_obj:
exec_time = results_obj["time_taken"]

elif 'execution' in result_obj:
# read execution time for the first circuit
exec_time = result_obj['execution']['execution_spans'][0].duration

# override the initial value with exec_time returned from successful execution
metrics.store_metric(active_circuit["group"], active_circuit["circuit"], 'exec_time', exec_time)

Expand Down Expand Up @@ -1273,7 +1289,7 @@ def process_step_times(job, result, active_circuit):

if verbose:
print(f"... job.metrics() = {job.metrics()}")
print(f"... job.result().metadata[0] = {result.metadata[0]}")
print(f"... job.result().metadata[0] = {result.metadata}")

# occasionally, these metrics come back as None, so try to use them
try:
Expand Down Expand Up @@ -1494,7 +1510,7 @@ def check_jobs(completion_handler=None):
if hasattr(job, "error_message"):
print(f" job = {job.job_id()} {job.error_message()}")

if status == JobStatus.DONE or status == JobStatus.CANCELLED or status == JobStatus.ERROR:
if status == JobStatus.DONE or status == JobStatus.CANCELLED or status == JobStatus.ERROR or status == 'DONE' or status =='CANCELLED' or status == 'ERROR':
#if verbose: print("Job status is ", job.status() )

active_circuit = active_circuits[job]
Expand Down
4 changes: 2 additions & 2 deletions monte-carlo/qiskit/mc_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def square_on_objective(qc, qr):
qc.cx(control, num_state_qubits)

def state_prep(qc, qr, target_dist, num_state_qubits):
"""
r"""
Use controlled Ry gates to construct the superposition Sum \sqrt{p_i} |i>
"""
r_probs = mc_utils.region_probs(target_dist, num_state_qubits)
Expand Down Expand Up @@ -505,7 +505,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("--num_state_qubits", "-nsq", default=0.0, help="Number of State Qubits", type=int)
parser.add_argument("--num_state_qubits", "-nsq", default=1, 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()
Expand Down
2 changes: 1 addition & 1 deletion shors/qiskit/shors_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ def analyze_and_print_result(qc, result, num_qubits, order, num_shots, method):

# Execute program with default parameters
def run (min_qubits=3, max_circuits=1, max_qubits=18, num_shots=100, method = 1,
verbose=verbose, backend_id='qasm_simulator', provider_backend=None,
verbose=verbose, backend_id='statevector_sampler', provider_backend=None,
hub="ibm-q", group="open", project="main", exec_options=None,
context=None):

Expand Down

0 comments on commit 9b5feef

Please sign in to comment.