def __init__(self, molecule, rz_index): """See class fields for parameter definitions. """ super() self.molecule = molecule self.rz_index = rz_index # Get circuit, cqp and slice_index. pickle_file_name = "{}_circuits.pickle".format(molecule.lower()) pickle_file_path = os.path.join(HPO_DATA_PATH, pickle_file_name) with open(pickle_file_path, "rb") as f: rz_indices, circuit_list = pickle.load(f) slice_index = rz_indices[self.rz_index] circuit, connected_qubit_pairs = circuit_list[slice_index] self.slice_index = slice_index self.circuit = circuit self.connected_qubit_pairs = connected_qubit_pairs self.unitary = get_unitary(circuit) self.file_name = "s{}".format(slice_index) datadir_name = "uccsd_{}".format(molecule.lower()) self.data_path = os.path.join(TIME_DATA_PATH, datadir_name) # TODO: We assume TIME_DATA_PATH exists. if not os.path.exists(self.data_path): os.mkdir(self.data_path) # Get grape config. # Set grape parameters. num_qubits = self.circuit.width() H0 = np.zeros((NUM_STATES ** num_qubits, NUM_STATES ** num_qubits)) Hops, Hnames = get_Hops_and_Hnames(num_qubits, NUM_STATES, self.connected_qubit_pairs) states_concerned_list = get_full_states_concerned_list(num_qubits, NUM_STATES) maxA = get_maxA(num_qubits, NUM_STATES, self.connected_qubit_pairs) reg_coeffs = {} self.grape_config = { "H0": H0, "Hops": Hops, "Hnames": Hnames, "states_concerned_list": states_concerned_list, "reg_coeffs": reg_coeffs, "maxA": maxA, } self.grape_config.update(GRAPE_TASK_CONFIG) # Get hyperparameters by choosing the configuration with the lowest loss. best_data = {"loss": 1} hpo_file_name = "{}.json".format(self.file_name) hpo_file_path = os.path.join(HPO_DATA_PATH, datadir_name, hpo_file_name) with open(hpo_file_path) as f: line = f.readline() while line: data = json.loads(line) if data["loss"] < best_data["loss"]: best_data = data line = f.readline() #ENDWITH self.lr = best_data["lr"] self.decay = best_data["decay"]
def __init__(self, molecule, slice_index, circuit, connected_qubit_pairs): """See corresponding class field declarations above for other arguments. """ super() self.molecule = molecule self.slice_index = slice_index self.circuit = circuit self.connected_qubit_pairs = connected_qubit_pairs self.unitary = get_unitary(self.circuit) if self.circuit.depth() > REDUCED_CIRCUIT_DEPTH_CUTOFF: self.pulse_time = get_max_pulse_time( self.circuit) * PULSE_TIME_MULTIPLIER else: self.pulse_time = get_max_pulse_time( self.circuit) * REDUCED_PULSE_TIME_MULTIPLIER self.file_name = "s{}".format(self.slice_index) self.data_path = os.path.join(BASE_DATA_PATH, "uccsd_{}".format(molecule.lower())) # TODO: We assume BASE_DATA_PATH exists. if not os.path.exists(self.data_path): os.mkdir(self.data_path) # Set grape parameters. num_qubits = self.circuit.width() H0 = np.zeros((NUM_STATES**num_qubits, NUM_STATES**num_qubits)) Hops, Hnames = get_Hops_and_Hnames(num_qubits, NUM_STATES, self.connected_qubit_pairs) states_concerned_list = get_full_states_concerned_list( num_qubits, NUM_STATES) maxA = get_maxA(num_qubits, NUM_STATES, self.connected_qubit_pairs) reg_coeffs = {} self.grape_config = { "H0": H0, "Hops": Hops, "Hnames": Hnames, "states_concerned_list": states_concerned_list, "reg_coeffs": reg_coeffs, "maxA": maxA, } self.grape_config.update(GRAPE_TASK_CONFIG)
NPS = 1 / SPN ### GATE DATA ### # fqc/experiments/Gate_Times.ipynb GATE_TIMES = {'h': 1.4, 'cx': 3.8, 'rz': 0.4, 'rx': 2.5, 'x': 2.5, 'swap': 7.4} _RZ = GATE_TIMES['rz'] ### GRAPE CONSTANTS ### REG_COEFFS = {} QUBIT2_CQP = get_nearest_neighbor_coupling_list(1, 2, directed=False) QUBIT2_H0 = np.zeros((NUM_STATES**2, NUM_STATES**2)) QUBIT2_HOPS, QUBIT2_HNAMES = get_Hops_and_Hnames(2, NUM_STATES, QUBIT2_CQP) QUBIT2_SCL = get_full_states_concerned_list(2, NUM_STATES) QUBIT2_MPA = get_maxA(2, NUM_STATES, QUBIT2_CQP) GRAPE_QUBIT2_CONFIG = { "H0": QUBIT2_H0, "Hops": QUBIT2_HOPS, "Hnames": QUBIT2_HNAMES, "states_concerned_list": QUBIT2_SCL, "reg_coeffs": REG_COEFFS, "maxA": QUBIT2_MPA, } QUBIT4_CQP = get_nearest_neighbor_coupling_list(2, 2, directed=False) QUBIT4_H0 = np.zeros((NUM_STATES**4, NUM_STATES**4)) QUBIT4_HOPS, QUBIT4_HNAMES = get_Hops_and_Hnames(4, NUM_STATES, QUBIT4_CQP) QUBIT4_SCL = get_full_states_concerned_list(4, NUM_STATES) QUBIT4_MPA = get_maxA(4, NUM_STATES, QUBIT4_CQP)
from quantum_optimal_control.core import hamiltonian d = 2 # this is the number of energy levels to consider (i.e. d-level qudits) max_iterations = 6000 decay = max_iterations / 2 convergence = {'rate':0.01, 'max_iterations': max_iterations, 'conv_target':1e-3, 'learning_rate_decay':decay, 'min_grad': 1e-12, 'update_step': 20} reg_coeffs = {} N = 4 connected_qubit_pairs = util.get_nearest_neighbor_coupling_list(2, 2, directed=False) H0 = np.zeros((d ** N, d ** N)) Hops, Hnames = hamiltonian.get_Hops_and_Hnames(N, d, connected_qubit_pairs) states_concerned_list = hamiltonian.get_full_states_concerned_list(N, d) maxA = hamiltonian.get_maxA(N, d, connected_qubit_pairs) circuit = uccsd.get_uccsd_circuit('LiH') slices = uccsd.get_uccsd_slices(circuit, granularity=1) slices = [slice for slice in slices if not slice.parameterized] def binary_search_for_shortest_pulse_time(min_time, max_time, tolerance=1): """Search between [min_time, max_time] up to 1ns tolerance. Assumes 20 steps per ns.""" min_steps, max_steps = min_time * 20, max_time * 20 while min_steps + 20 * tolerance < max_steps: # just estimate to +- 1ns
# Time backoff for binary search. BACKOFF = 1.2 # Binary search nanosecond granularity. BNS_GRANULARITY = 10 # Grape args. DATA_PATH = "" # Define hardware specific parameters. num_qubits = 4 num_states = 2 connected_qubit_pairs = get_nearest_neighbor_coupling_list(2, 2, directed=False) H0 = np.zeros((num_states ** num_qubits, num_states ** num_qubits)) Hops, Hnames = get_Hops_and_Hnames(num_qubits, num_states, connected_qubit_pairs) states_concerned_list = get_full_states_concerned_list(num_qubits, num_states) maxA = get_maxA(num_qubits, num_states, connected_qubit_pairs) # Define convergence parameters and penalties. convergence = {'rate': 2e-2, 'conv_target': 1e-3, 'max_iterations': 1e3, 'learning_rate_decay': 1e3} reg_coeffs = {} use_gpu = False sparse_H = False show_plots = False method = 'ADAM' # Steps per nanosecond and nanoseconds per step spn = 20.0 nps = 1 / spn # Get slices to perform qoc on. The initial angle of each RZ
ANGLE_CONSTANT = 180 TIME_MULTIPLIERS = [0.25, 0.5, 0.75] TIME_MULTIPLIER_CONSTANT = 0.5 JOBS_PER_SLICE = 5 BROADWELL_CORE_COUNT = 14 # Grape constants. NUM_QUBITS = 4 NUM_STATES = 2 CONNECTED_QUBIT_PAIRS = get_nearest_neighbor_coupling_list(2, 2, directed=False) H0 = np.zeros((NUM_STATES**NUM_QUBITS, NUM_STATES**NUM_QUBITS)) Hops, Hnames = get_Hops_and_Hnames(NUM_QUBITS, NUM_STATES, CONNECTED_QUBIT_PAIRS) STATES_CONCERNED_LIST = get_full_states_concerned_list(NUM_QUBITS, NUM_STATES) MAX_AMPLITUDE = get_maxA(NUM_QUBITS, NUM_STATES, CONNECTED_QUBIT_PAIRS) METHOD = 'ADAM' MAX_GRAPE_ITERATIONS = 1e3 DECAY = 1e3 REG_COEFFS = {} USE_GPU = False SPARSE_H = False SHOW_PLOTS = False # Wave steps per nanosecond of pulse time. SPN = 20 # Get slices and information. SLICE_GRANULARITY = 2 UCCSD_LIH_FULL_CIRCUIT = optimize_circuit( get_uccsd_circuit('LiH', UCCSD_LIH_THETA), CONNECTED_QUBIT_PAIRS)