Source code for qnetti.script_utils

from time import time


from .file_utilities import tmp_dir, mkdir, write_json, datetime_now_string
from .covariance_matrices import *
from .characteristic_matrices import *
from .qnodes import qubit_probs_qnode_fn


[docs]def infer_ibm_network_shot_dependence( provider, prep_node, ibm_device_name="ibmq_qasm_simulator", shots_list=[10, 100, 1000, 10000], meas_wires=None, prep_node_name="", num_cov_steps=0, num_vn_steps=0, num_mi_steps=0, num_mmi_steps=0, mi_step_size=0.1, mmi_step_size=0.25, cov_step_size=0.1, vn_step_size=0.1, cov_init_json={}, vn_init_json={}, mi_init_json={}, mmi_init_json={}, init_data_json={}, warm_start_step=0, ): """ Performs network inference on an IBMQ machine over a range of shot numbers. The prepared state is specified as the ``prep_node`` and the number of shots are passed as the ``shots_list`` parameter. The connection to the IBM hardware requires an IBMQ account. The IBM provider can be constructed using the private ``token`` as: .. code-block:: python token = "XYZ" # secret IBMQ API token for your account IBMQ.save_account(token=token, hub="ibm-q", group="open", project="main", overwrite=True) provider = IBMQ.load_account() :param provide: An IBM provider (see above). :type provider: IBMQ.provide :param prep_node: A qNetVO ``PrepareNode`` class describing the state to infer. :type prep_node: qnetvo.PrepareNode """ num_qubits = len(meas_wires) if meas_wires else len(prep_node.wires) dev_kwargs = ( { "name": "qiskit.ibmq", "backend": ibm_device_name, "provider": provider, } if ibm_device_name != "default.qubit" else {"name": "default.qubit"} ) qnode_kwargs = {"diff_method": "parameter-shift"} filepath = mkdir("./data/", "ibm_inference_" + prep_node_name + "_shot_dependence/") data_jsons = [] for shots_id, shots in enumerate(shots_list): shots_filepath = mkdir(filepath, "shots_" + str(shots) + "/") tmp_filepath = tmp_dir(shots_filepath) if num_cov_steps: shots_cov_filepath = mkdir(shots_filepath, "cov_opts/") if num_vn_steps: shots_vn_filepath = mkdir(shots_filepath, "vn_opts/") if num_mi_steps: shots_mi_filepath = mkdir(shots_filepath, "mi_opts/") if num_mmi_steps: shots_mmi_filepath = mkdir(shots_filepath, "mmi_opts/") dev_kwargs["shots"] = shots # helper functions to obtain per qubit cost data cov_mat_fn = qubit_covariance_matrix_fn( prep_node, meas_wires=meas_wires, dev_kwargs=dev_kwargs, qnode_kwargs=qnode_kwargs ) probs_qnode, dev = qubit_probs_qnode_fn( prep_node, meas_wires=meas_wires, dev_kwargs=dev_kwargs, qnode_kwargs=qnode_kwargs ) qubit_mmis = qubit_measured_mutual_infos_fn( prep_node, meas_wires=meas_wires, dev_kwargs=dev_kwargs, qnode_kwargs=qnode_kwargs ) meta_opt_kwargs = { "ibm_device": ibm_device_name, "shots": shots, "prep_node_name": prep_node_name, "num_qubits": num_qubits, "step_only": True, } cov_opt_dict = cov_init_json if shots_id == 0 else {} vn_opt_dict = vn_init_json if shots_id == 0 else {} mi_opt_dict = mi_init_json if shots_id == 0 else {} mmi_opt_dict = mmi_init_json if shots_id == 0 else {} curr_step = warm_start_step if shots_id == 0 else 0 num_steps = max(num_cov_steps, num_vn_steps, num_mi_steps, num_mmi_steps) file_name = ibm_device_name + "_" + datetime_now_string() cov_err = False vn_err = False mi_err = False mmi_err = False for step in range(curr_step, num_steps): print("num shots : ", shots, ", step : ", step, " / ", num_steps - 1) step_start_time = time() if step < num_cov_steps and not (cov_err): cov_opt_kwargs = { "num_steps": len(cov_opt_dict["settings_list"]) if cov_opt_dict else 1, "step_size": cov_step_size, "init_opt_dict": cov_opt_dict, "filepath": shots_cov_filepath, "filename": file_name, **meta_opt_kwargs, } cov_mat, cov_opt_dict = optimize_covariance_matrix( prep_node, meas_wires=meas_wires, dev_kwargs=dev_kwargs, qnode_kwargs=qnode_kwargs, **cov_opt_kwargs, ) if cov_opt_dict["error"]: cov_err = True print("cov opt error") else: if "cov_mats" in cov_opt_dict: cov_opt_dict["cov_mats"] += [cov_mat.tolist()] else: # add inital cov mat and cov mat after first optimization step cov_opt_dict["cov_mats"] = [ cov_mat_fn(cov_opt_dict["settings_list"][0]).tolist(), cov_mat.tolist(), ] tmp_path = tmp_dir(shots_cov_filepath) write_json(cov_opt_dict, tmp_path + file_name) print("cov opt step time : ", cov_opt_dict["opt_step_times"][-1]) if step < num_vn_steps and not (vn_err): vn_opt_kwargs = { "num_steps": len(vn_opt_dict["settings_list"]) if vn_opt_dict else 1, "step_size": vn_step_size, "init_opt_dict": vn_opt_dict, "filepath": shots_vn_filepath, "filename": file_name, **meta_opt_kwargs, } vn_opt_dict = optimize_vn_entropy( prep_node, meas_wires=meas_wires, dev_kwargs=dev_kwargs, qnode_kwargs=qnode_kwargs, **vn_opt_kwargs, ) if vn_opt_dict["error"]: vn_err = True print("vn opt error") else: vn_entropies = qubit_shannon_entropies( probs_qnode(vn_opt_dict["settings_list"][-1]) ) if "vn_entropies" in vn_opt_dict: vn_opt_dict["vn_entropies"] += [vn_entropies] else: vn_opt_dict["vn_entropies"] = [ qubit_shannon_entropies(probs_qnode(vn_opt_dict["settings_list"][0])), vn_entropies, ] tmp_path = tmp_dir(shots_vn_filepath) write_json(vn_opt_dict, tmp_path + file_name) print("vn opt step time : ", vn_opt_dict["opt_step_times"][-1]) if step < num_mi_steps and not (mi_err): mi_opt_kwargs = { "num_steps": len(mi_opt_dict["settings_list"]) if mi_opt_dict else 1, "step_size": mi_step_size, "init_opt_dict": mi_opt_dict, "filepath": shots_mi_filepath, "filename": file_name, **meta_opt_kwargs, } mi_opt_dict = optimize_mutual_info( prep_node, meas_wires=meas_wires, dev_kwargs=dev_kwargs, qnode_kwargs=qnode_kwargs, **mi_opt_kwargs, ) if mi_opt_dict["error"]: mi_err = True print("mi opt error") else: mutual_infos = qubit_mutual_infos(probs_qnode(mi_opt_dict["settings_list"][-1])) if "mutual_infos" in mi_opt_dict: mi_opt_dict["mutual_infos"] += [mutual_infos] else: mi_opt_dict["mutual_infos"] = [ qubit_mutual_infos(probs_qnode(mi_opt_dict["settings_list"][0])), mutual_infos, ] tmp_path = tmp_dir(shots_mi_filepath) write_json(mi_opt_dict, tmp_path + file_name) print("mi opt step time : ", mi_opt_dict["opt_step_times"][-1]) if step < num_mmi_steps and not (mmi_err): mmi_opt_kwargs = { "num_steps": len(mmi_opt_dict["settings_list"]) if mmi_opt_dict else 1, "step_size": mmi_step_size, "init_opt_dict": mmi_opt_dict, "filepath": shots_mmi_filepath, "filename": file_name, **meta_opt_kwargs, } mmi_opt_dict = optimize_measured_mutual_info( prep_node, meas_wires=meas_wires, dev_kwargs=dev_kwargs, qnode_kwargs=qnode_kwargs, **mmi_opt_kwargs, ) if mmi_opt_dict["error"]: mmi_err = True print("mmi opt error") else: measured_mutual_infos = qubit_mmis(mmi_opt_dict["settings_list"][-1]) if "measured_mutual_infos" in mmi_opt_dict: mmi_opt_dict["measured_mutual_infos"] += [measured_mutual_infos] else: mmi_opt_dict["measured_mutual_infos"] = [ qubit_mmis(mmi_opt_dict["settings_list"][0]), measured_mutual_infos, ] tmp_path = tmp_dir(shots_mmi_filepath) write_json(mmi_opt_dict, tmp_path + file_name) print("mmi opt step time : ", mmi_opt_dict["opt_step_times"][-1]) print("Iteration time : ", time() - step_start_time) # write data after complete optimizataion if num_cov_steps and not (cov_err): write_json( cov_opt_dict, shots_cov_filepath + file_name, ) if num_vn_steps and not (vn_err): write_json( vn_opt_dict, shots_vn_filepath + file_name, ) if num_mi_steps and not (mi_err): write_json( mi_opt_dict, shots_mi_filepath + file_name, ) if num_mmi_steps and not (mmi_err): write_json( mmi_opt_dict, shots_mmi_filepath + file_name, )