def test_two_qubit_pulse_optimal_none_no_raise(self): """Verify pulse optimal decomposition when pulse_optimize==None doesn't raise when pulse optimal decomposition unknown.""" # this assumes iswawp pulse optimal decomposition doesn't exist backend = FakeVigo() conf = backend.configuration() conf.basis_gates = [gate if gate != "cx" else "iswap" for gate in conf.basis_gates] qr = QuantumRegister(2) coupling_map = CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]]) triv_layout_pass = TrivialLayout(coupling_map) qc = QuantumCircuit(qr) qc.unitary(random_unitary(4, seed=12), [0, 1]) unisynth_pass = UnitarySynthesis( basis_gates=conf.basis_gates, coupling_map=coupling_map, backend_props=backend.properties(), pulse_optimize=None, natural_direction=True, ) pm = PassManager([triv_layout_pass, unisynth_pass]) try: qc_out = pm.run(qc) except QiskitError: self.fail("pulse_optimize=None raised exception unexpectedly") if isinstance(qc_out, QuantumCircuit): num_ops = qc_out.count_ops() else: num_ops = qc_out[0].count_ops() self.assertIn("sx", num_ops) self.assertLessEqual(num_ops["sx"], 14)
def test_two_qubit_synthesis_to_directional_cx_from_gate_errors(self): """Verify two qubit unitaries are synthesized to match basis gates.""" # TODO: should make check more explicit e.g. explicitly set gate # direction in test instead of using specific fake backend backend = FakeVigo() conf = backend.configuration() qr = QuantumRegister(2) coupling_map = CouplingMap(conf.coupling_map) triv_layout_pass = TrivialLayout(coupling_map) qc = QuantumCircuit(qr) qc.unitary(random_unitary(4, seed=12), [0, 1]) unisynth_pass = UnitarySynthesis( basis_gates=conf.basis_gates, coupling_map=None, backend_props=backend.properties(), pulse_optimize=True, natural_direction=False, ) pm = PassManager([triv_layout_pass, unisynth_pass]) qc_out = pm.run(qc) unisynth_pass_nat = UnitarySynthesis( basis_gates=conf.basis_gates, coupling_map=None, backend_props=backend.properties(), pulse_optimize=True, natural_direction=True, ) pm_nat = PassManager([triv_layout_pass, unisynth_pass_nat]) qc_out_nat = pm_nat.run(qc) self.assertEqual(Operator(qc), Operator(qc_out)) self.assertEqual(Operator(qc), Operator(qc_out_nat))
def test_two_qubit_natural_direction_true_duration_fallback(self): """Verify not attempting pulse optimal decomposition when pulse_optimize==False.""" # this assumes iswawp pulse optimal decomposition doesn't exist backend = FakeVigo() conf = backend.configuration() # conf.basis_gates = [gate if gate != "cx" else "iswap" for gate in conf.basis_gates] qr = QuantumRegister(2) coupling_map = CouplingMap([[0, 1], [1, 0], [1, 2], [1, 3], [3, 4]]) triv_layout_pass = TrivialLayout(coupling_map) qc = QuantumCircuit(qr) qc.unitary(random_unitary(4, seed=12), [0, 1]) unisynth_pass = UnitarySynthesis( basis_gates=conf.basis_gates, coupling_map=coupling_map, backend_props=backend.properties(), pulse_optimize=True, natural_direction=True, ) pm = PassManager([triv_layout_pass, unisynth_pass]) qc_out = pm.run(qc) self.assertTrue( all( # pylint: disable=no-member ([qr[0], qr[1]] == qlist for _, qlist, _ in qc_out.get_instructions("cx"))))
def test_two_qubit_pulse_optimal_none_optimal(self): """Verify pulse optimal decomposition when pulse_optimize==None.""" # this assumes iswawp pulse optimal decomposition doesn't exist backend = FakeVigo() conf = backend.configuration() qr = QuantumRegister(2) coupling_map = CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]]) triv_layout_pass = TrivialLayout(coupling_map) qc = QuantumCircuit(qr) qc.unitary(random_unitary(4, seed=12), [0, 1]) unisynth_pass = UnitarySynthesis( basis_gates=conf.basis_gates, coupling_map=coupling_map, backend_props=backend.properties(), pulse_optimize=None, natural_direction=True, ) pm = PassManager([triv_layout_pass, unisynth_pass]) qc_out = pm.run(qc) if isinstance(qc_out, QuantumCircuit): num_ops = qc_out.count_ops() # pylint: disable=no-member else: num_ops = qc_out[0].count_ops() self.assertIn("sx", num_ops) self.assertLessEqual(num_ops["sx"], 12)
class DatasetGenerator: def __init__(self, shots=1000): """ Initialize this class :param shots: number of times to measure each circuit """ self.shots = shots self.observations = [] self.features = [] self.labels = [] self.dataset = QuantumNoiseDataset() # Device Model self.device_backend = FakeVigo() self.coupling_map = self.device_backend.configuration().coupling_map self.simulator = Aer.get_backend('qasm simulator') def add_observation(self, circuit, noise_model): """ Add a new data point - (feature, label) -to the dataset. Blocking method (until counts are calculated) :param circuit: :param noise_model: :return: none """ feature = (circuit, noise_model) label = self.get_counts(circuit, noise_model) self.dataset.add_data_point(feature, label) def get_counts(self, circuit, noise_model): """ Simulate a circuit with a noise_model and return measurement counts :param circuit: :param noise_model: :return: measurement counts (dict) """ result = execute(circuit, self.simulator, noise_model=noise_model, coupling_map=self.coupling_map, basis_gates=noise_model.basis_gates, shots=self.shots).result() counts = result.get_counts() return counts def get_dataset(self): """ :return: the dataset (QuantumNoiseDataset) """ return self.dataset def __repr__(self): return "I am a dataset generator for quantum noise estimation" def mock_dataset(self): """ Generate a mock dataset :return: the dataset (QuantumNoiseDataset) """ raise NotImplementedError
def main(): # Parse all command line arguments args = parser.parse_args() shots = args.shots seed = args.seed basis = args.bell logfile = args.logfile verbose = args.verbose # Define the logger logger = logging.getLogger('task2') if logfile: logger.addHandler(logging.FileHandler(logfile)) if verbose: logger.addHandler(logging.StreamHandler()) logger.setLevel(logging.DEBUG) np.random.seed(seed=seed) # Get the noise model device_backend = FakeVigo() noise_model = NoiseModel.from_backend(device_backend) coupling_map = device_backend.configuration().coupling_map basis_gates = noise_model.basis_gates backend = Aer.get_backend('qasm_simulator') statevector_backend = Aer.get_backend('statevector_simulator') circuit = build_circuit(measure=basis) circuit_for_counts = build_circuit(measure='computational') unmeasured_circuit = build_circuit(measure=None) # qiskit's COBYLA can't take args to pass to the objective function, so we freeze them with functools.partial optimizer = COBYLA(maxiter=1000, tol=1e-8, disp=True) for nshots in shots: logger.debug('====================================================================================') logger.debug(f'\nShots per iteration: {nshots}') logger.debug(circuit) partial_objective_function = partial(objective_function, circuit=circuit, shots=nshots, backend=backend, bell_basis=(basis == 'bell'), noise_model=noise_model, coupling_map=coupling_map, basis_gates=basis_gates) ret = optimizer.optimize(num_vars=2, objective_function=partial_objective_function, initial_point=np.random.rand(len(circuit.parameters))*4*np.pi - 2*np.pi) params = ret[0] logger.debug(f'\nParameters:\n{params}') logger.debug(f'\nStatevector:\n{execute_circuit(unmeasured_circuit, params, statevector_backend).result().get_statevector()}') logger.debug(f'\nSimulated results:\n{execute_circuit(circuit_for_counts, params, backend, nshots, noise_model, coupling_map, basis_gates).result().get_counts()}') logger.debug('====================================================================================\n') sys.exit(ExitStatus.success)
def __init__(self): self.py = Parameter("θ_y") self.px = Parameter("θ_x") self.ansatz = self.make_ansatz() self.backend = Aer.get_backend("qasm_simulator") # Get noise model vigo_backend = FakeVigo() self.noise_model = NoiseModel.from_backend(vigo_backend) self.coupling_map = vigo_backend.configuration().coupling_map self.basis_gates = self.noise_model.basis_gates # Extra arrays for debugging self.cost_history = []
def test_two_qubit_synthesis_to_directional_cx_from_coupling_map_natural_false(self): """Verify natural cx direction is used when specified in coupling map when natural_direction is None.""" # TODO: should make check more explicit e.g. explicitly set gate # direction in test instead of using specific fake backend backend = FakeVigo() conf = backend.configuration() qr = QuantumRegister(2) coupling_map = CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]]) triv_layout_pass = TrivialLayout(coupling_map) qc = QuantumCircuit(qr) qc.unitary(random_unitary(4, seed=12), [0, 1]) unisynth_pass = UnitarySynthesis( basis_gates=conf.basis_gates, coupling_map=coupling_map, backend_props=backend.properties(), pulse_optimize=True, natural_direction=False, ) pm = PassManager([triv_layout_pass, unisynth_pass]) qc_out = pm.run(qc) unisynth_pass_nat = UnitarySynthesis( basis_gates=conf.basis_gates, coupling_map=coupling_map, backend_props=backend.properties(), pulse_optimize=True, natural_direction=False, ) pm_nat = PassManager([triv_layout_pass, unisynth_pass_nat]) qc_out_nat = pm_nat.run(qc) # the decomposer defaults to the [1, 0] direction but the coupling # map specifies a [0, 1] direction. Check that this is respected. self.assertTrue( all( # pylint: disable=no-member ([qr[1], qr[0]] == qlist for _, qlist, _ in qc_out.get_instructions("cx")) ) ) self.assertTrue( all( # pylint: disable=no-member ([qr[1], qr[0]] == qlist for _, qlist, _ in qc_out_nat.get_instructions("cx")) ) ) self.assertEqual(Operator(qc), Operator(qc_out)) self.assertEqual(Operator(qc), Operator(qc_out_nat))
def test_two_qubit_pulse_optimal_true_raises(self): """Verify raises if pulse optimal==True but cx is not in the backend basis.""" backend = FakeVigo() conf = backend.configuration() # this assumes iswawp pulse optimal decomposition doesn't exist conf.basis_gates = [gate if gate != "cx" else "iswap" for gate in conf.basis_gates] qr = QuantumRegister(2) coupling_map = CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]]) triv_layout_pass = TrivialLayout(coupling_map) qc = QuantumCircuit(qr) qc.unitary(random_unitary(4, seed=12), [0, 1]) unisynth_pass = UnitarySynthesis( basis_gates=conf.basis_gates, coupling_map=coupling_map, backend_props=backend.properties(), pulse_optimize=True, natural_direction=True, ) pm = PassManager([triv_layout_pass, unisynth_pass]) with self.assertRaises(QiskitError): pm.run(qc)
def test_two_qubit_natural_direction_true_gate_length_raises(self): """Verify not attempting pulse optimal decomposition when pulse_optimize==False.""" # this assumes iswawp pulse optimal decomposition doesn't exist backend = FakeVigo() conf = backend.configuration() for _, nduv in backend.properties()._gates["cx"].items(): nduv["gate_length"] = (4e-7, nduv["gate_length"][1]) nduv["gate_error"] = (7e-3, nduv["gate_error"][1]) qr = QuantumRegister(2) coupling_map = CouplingMap([[0, 1], [1, 0], [1, 2], [1, 3], [3, 4]]) triv_layout_pass = TrivialLayout(coupling_map) qc = QuantumCircuit(qr) qc.unitary(random_unitary(4, seed=12), [0, 1]) unisynth_pass = UnitarySynthesis( basis_gates=conf.basis_gates, backend_props=backend.properties(), pulse_optimize=True, natural_direction=True, ) pm = PassManager([triv_layout_pass, unisynth_pass]) with self.assertRaises(TranspilerError): pm.run(qc)
class DatasetGenerator: def __init__(self, shots=1000, L=3): """ Initialize a new DatasetGenerator. This object provides an interface to generate synthetic quantum-noisy datasets. The user must prescribe the circuits and noise models. Some presets are available. :param shots: number of times to measure each circuit, default: 1000 :param L: maximum circuit length """ # Simulator Variables self.device_backend = FakeVigo() self.coupling_map = self.device_backend.configuration().coupling_map self.simulator = Aer.get_backend('qasm_simulator') self.shots = shots self.L = L self.dataset = self.emptyDataset() """self.observations = [] self.features = [] self.labels = []""" def add_observation(self, circuit, noise_model): """ Add a new data point - (feature, label) - to the dataset. :param circuit: circuit, len(circuit) <= self.L :param noise_model: :return: none """ assert len(circuit) <= self.L feature = (circuit, noise_model) label = self.get_counts(circuit, noise_model) self.dataset.add_data_point(feature, label) def get_dataset(self): """ :return: the dataset (DataFrame) """ return self.dataset def get_counts(self, circuit, noise_model): """ Simulate a circuit with a noise_model and return measurement counts :param circuit: :param noise_model: :return: measurement counts (dict {'0':C0, '1':C1}) """ result = execute(circuit, self.simulator, noise_model=noise_model, coupling_map=self.coupling_map, basis_gates=noise_model.basis_gates, shots=self.shots).result() counts = result.get_counts() return counts def emptyDataset(self): """ Generate an empty Dataset. Column format: Gate_1 NM_1 ... ... Expected Value :return: df: DataFrame """ column_names = [] for i in range(self.L): column_names.append("Gate_{}_theta".format(i)) column_names.append("Gate_{}_phi".format(i)) column_names.append("Gate_{}_lambda".format(i)) column_names.append("NM_{}".format(i)) column_names.append("ExpectedValue") df = pd.DataFrame(dtype='float64', columns=column_names) df.loc[0] = pd.Series(dtype='float64') df.loc[1] = pd.Series(dtype='float64') df.loc[2] = pd.Series(dtype='float64') return df def __repr__(self): return "I am a dataset generator for quantum noise estimation"
c.rx(pi/2, qreg_q[1]) c.rx(pi/2, qreg_q[0]) c.ry(pi/2, qreg_q[1]) c.cx(qreg_q[0], qreg_q[1]) c.rx(pi/2, qreg_q[0]) c.ry(pi/2, qreg_q[1]) c.cx(qreg_q[0], qreg_q[1]) c.rx(pi/2, qreg_q[0]) c.ry(pi/2, qreg_q[1]) c.cx(qreg_q[0], qreg_q[1]) c.measure(qreg_q[0], creg_c[0]) c.measure(qreg_q[1], creg_c[1]) # Get the basis gates for the noise model device_backend = FakeVigo() coupling_map = device_backend.configuration().coupling_map # Get the basis gates for the noise model noise_model = NoiseModel.from_backend(device_backend) basis_gates = noise_model.basis_gates # Select the QasmSimulator from the Aer provider simulator = Aer.get_backend('qasm_simulator') ###NOTE: I attempted to pass a variable to the shot count, but it gave an error each attempt, so 1000 shots were set. # Execute noisy simulation and get counts result_noise = execute(c, simulator, noise_model=noise_model, coupling_map=coupling_map, basis_gates=basis_gates, shots=1000).result() counts_noise = result_noise.get_counts(c)
def main(): # Noise device_backend = FakeVigo() coupling_map = device_backend.configuration().coupling_map simulator = Aer.get_backend('qasm_simulator') noise_model = NoiseModel() basis_gates = noise_model.basis_gates error = amplitude_damping_error(0.5) # error = depolarizing_error(0.5, 1) noise_model.add_all_qubit_quantum_error(error, ['id', 'u1', 'u2', 'u3']) # Circuit circ = QuantumCircuit(1, 1) circ.h(0) circ.measure([0], [0]) print("*" * 25 + " Circuit " + "*" * 25) print(circ.draw()) model1 = {'name': 'noisy', 'model': noise_model} model2 = {'name': 'ideal', 'model': None} noise_models = [model1, model2] print() print("*" * 25 + " Noise Models " + "*" * 25) pprint(noise_models) # Execution Dataset = [(run_circuit(circ, simulator, nm['model'], coupling_map, basis_gates), nm) for nm in noise_models] # Data Prep for counts, nm in Dataset: counts.setdefault('0', 0) counts.setdefault('1', 0) X = [[x[1] for x in sorted(counts.items())] for counts, nm in Dataset] Y_raw = [nm['name'] for counts, nm in Dataset] zeros = [x[0] for x in X] le = preprocessing.LabelEncoder() le.fit(Y_raw) Y = le.transform(Y_raw) print() print("*" * 25 + " Dataset " + "*" * 25) print("Features: ", X) print("Labels: ", Y_raw) print("Encoded Labels: ", Y) # Training Classifier clf = RandomForestClassifier(random_state=0) clf.fit(X, Y) print() print("*" * 25 + " Predictions " + "*" * 25) # Predict labels on original data print("Prediction on training set: ", list(le.inverse_transform(clf.predict(X)))) # Predict labels on new data Xtest = [] Ytest = [] for i in range(max(0, min(zeros) - 50), min(max(zeros) + 51, 1001)): feature = [[i, 1000 - i]] prediction = list(le.inverse_transform(clf.predict(feature))) # print("Prediction on {}: {}".format(feature, prediction)) Xtest.append(i) Ytest.append(prediction[0]) # Plot Diagrams fig = plt.figure() plt.scatter(Xtest, Ytest, label="test set") plt.scatter(zeros, Y_raw, label="training set") plt.xlabel("Feature = Count of '0' measurements") plt.ylabel("Predicted Label") plt.legend() # fig.axes.append(circ.draw(output='mpl').axes[0]) plt.show()