Esempio n. 1
0
 def test_get_qasms_noname(self):
     """Test the get_qasms from a qprogram without names.
     """
     q_program = QuantumProgram()
     qr = q_program.create_quantum_register(size=3)
     cr = q_program.create_classical_register(size=3)
     qc1 = q_program.create_circuit(qregisters=[qr], cregisters=[cr])
     qc2 = q_program.create_circuit(qregisters=[qr], cregisters=[cr])
     qc1.h(qr[0])
     qc1.cx(qr[0], qr[1])
     qc1.cx(qr[1], qr[2])
     qc1.measure(qr[0], cr[0])
     qc1.measure(qr[1], cr[1])
     qc1.measure(qr[2], cr[2])
     qc2.h(qr)
     qc2.measure(qr[0], cr[0])
     qc2.measure(qr[1], cr[1])
     qc2.measure(qr[2], cr[2])
     results = dict(
         zip(q_program.get_circuit_names(), q_program.get_qasms()))
     qr_name_len = len(qr.name)
     cr_name_len = len(cr.name)
     self.assertEqual(len(results[qc1.name]),
                      qr_name_len * 9 + cr_name_len * 4 + 147)
     self.assertEqual(len(results[qc2.name]),
                      qr_name_len * 7 + cr_name_len * 4 + 137)
Esempio n. 2
0
 def test_get_register_and_circuit_names_nonames(self):
     """Get the names of the circuits and registers after create them without a name
     """
     q_program = QuantumProgram()
     qr1 = q_program.create_quantum_register(size=3)
     cr1 = q_program.create_classical_register(size=3)
     qr2 = q_program.create_quantum_register(size=3)
     cr2 = q_program.create_classical_register(size=3)
     q_program.create_circuit(qregisters=[qr1], cregisters=[cr1])
     q_program.create_circuit(qregisters=[qr2], cregisters=[cr2])
     q_program.create_circuit(qregisters=[qr1, qr2], cregisters=[cr1, cr2])
     qrn = q_program.get_quantum_register_names()
     crn = q_program.get_classical_register_names()
     qcn = q_program.get_circuit_names()
     self.assertEqual(len(qrn), 2)
     self.assertEqual(len(crn), 2)
     self.assertEqual(len(qcn), 3)
 def test_get_register_and_circuit_names_nonames(self):
     """Get the names of the circuits and registers after create them without a name
     """
     q_program = QuantumProgram()
     qr1 = q_program.create_quantum_register(size=3)
     cr1 = q_program.create_classical_register(size=3)
     qr2 = q_program.create_quantum_register(size=3)
     cr2 = q_program.create_classical_register(size=3)
     q_program.create_circuit(qregisters=[qr1], cregisters=[cr1])
     q_program.create_circuit(qregisters=[qr2], cregisters=[cr2])
     q_program.create_circuit(qregisters=[qr1, qr2], cregisters=[cr1, cr2])
     qrn = q_program.get_quantum_register_names()
     crn = q_program.get_classical_register_names()
     qcn = q_program.get_circuit_names()
     self.assertEqual(len(qrn), 2)
     self.assertEqual(len(crn), 2)
     self.assertEqual(len(qcn), 3)
    def test_get_register_and_circuit_names(self):
        """Get the names of the circuits and registers.

        If all is correct we should get the arrays of the names

        Previusly:
            Libraries:
                from qiskit import QuantumProgram
        """
        QP_program = QuantumProgram()
        qr1 = QP_program.create_quantum_register("qr1", 3, verbose=False)
        cr1 = QP_program.create_classical_register("cr1", 3, verbose=False)
        qr2 = QP_program.create_quantum_register("qr2", 3, verbose=False)
        cr2 = QP_program.create_classical_register("cr2", 3, verbose=False)
        QP_program.create_circuit("qc1", [qr1], [cr1])
        QP_program.create_circuit("qc2", [qr2], [cr2])
        QP_program.create_circuit("qc2", [qr1, qr2], [cr1, cr2])
        qrn = QP_program.get_quantum_register_names()
        crn = QP_program.get_classical_register_names()
        qcn = QP_program.get_circuit_names()
        self.assertEqual(qrn, ['qr1', 'qr2'])
        self.assertEqual(crn, ['cr1', 'cr2'])
        self.assertEqual(qcn, ['qc1', 'qc2'])
 def test_get_qasms_noname(self):
     """Test the get_qasms from a qprogram without names.
     """
     q_program = QuantumProgram()
     qr = q_program.create_quantum_register(size=3)
     cr = q_program.create_classical_register(size=3)
     qc1 = q_program.create_circuit(qregisters=[qr], cregisters=[cr])
     qc2 = q_program.create_circuit(qregisters=[qr], cregisters=[cr])
     qc1.h(qr[0])
     qc1.cx(qr[0], qr[1])
     qc1.cx(qr[1], qr[2])
     qc1.measure(qr[0], cr[0])
     qc1.measure(qr[1], cr[1])
     qc1.measure(qr[2], cr[2])
     qc2.h(qr)
     qc2.measure(qr[0], cr[0])
     qc2.measure(qr[1], cr[1])
     qc2.measure(qr[2], cr[2])
     results = dict(zip(q_program.get_circuit_names(), q_program.get_qasms()))
     qr_name_len = len(qr.name)
     cr_name_len = len(cr.name)
     self.assertEqual(len(results[qc1.name]), qr_name_len * 9 + cr_name_len * 4 + 147)
     self.assertEqual(len(results[qc2.name]), qr_name_len * 7 + cr_name_len * 4 + 137)
    def test_get_register_and_circuit_names(self):
        """Get the names of the circuits and registers.

        If all is correct we should get the arrays of the names

        Previusly:
            Libraries:
                from qiskit import QuantumProgram
        """
        QP_program = QuantumProgram()
        qr1 = QP_program.create_quantum_register("qr1", 3, verbose=False)
        cr1 = QP_program.create_classical_register("cr1", 3, verbose=False)
        qr2 = QP_program.create_quantum_register("qr2", 3, verbose=False)
        cr2 = QP_program.create_classical_register("cr2", 3, verbose=False)
        QP_program.create_circuit("qc1", [qr1], [cr1])
        QP_program.create_circuit("qc2", [qr2], [cr2])
        QP_program.create_circuit("qc2", [qr1, qr2], [cr1, cr2])
        qrn = QP_program.get_quantum_register_names()
        crn = QP_program.get_classical_register_names()
        qcn = QP_program.get_circuit_names()
        self.assertEqual(qrn, {'qr1', 'qr2'})
        self.assertEqual(crn, {'cr1', 'cr2'})
        self.assertEqual(qcn, {'qc1', 'qc2'})
class LocalQasmSimulatorTest(unittest.TestCase):
    """Test local qasm simulator."""

    @classmethod
    def setUpClass(cls):
        cls.moduleName = os.path.splitext(__file__)[0]
        cls.pdf = PdfPages(cls.moduleName + '.pdf')
        cls.log = logging.getLogger(__name__)
        cls.log.setLevel(logging.INFO)
        logFileName = cls.moduleName + '.log'
        handler = logging.FileHandler(logFileName)
        handler.setLevel(logging.INFO)
        log_fmt = ('{}.%(funcName)s:%(levelname)s:%(asctime)s:'
                   ' %(message)s'.format(cls.__name__))
        formatter = logging.Formatter(log_fmt)
        handler.setFormatter(formatter)
        cls.log.addHandler(handler)

    @classmethod
    def tearDownClass(cls):
        cls.pdf.close()

    def setUp(self):
        self.seed = 88
        self.qasmFileName = os.path.join(qiskit.__path__[0],
                                         '../test/python/qasm/example.qasm')
        self.qp = QuantumProgram()

    def tearDown(self):
        pass

    def test_qasm_simulator_single_shot(self):
        """Test single shot run."""
        shots = 1
        self.qp.load_qasm_file(self.qasmFileName, name='example')
        basis_gates = []  # unroll to base gates
        unroller = unroll.Unroller(
            qasm.Qasm(data=self.qp.get_qasm("example")).parse(),
                      unroll.JsonBackend(basis_gates))
        circuit = unroller.execute()
        config = {'shots': shots, 'seed': self.seed}
        job = {'compiled_circuit': circuit, 'config': config}
        result = QasmSimulator(job).run()
        self.assertEqual(result['status'], 'DONE')

    def test_qasm_simulator(self):
        """Test data counts output for single circuit run against reference."""
        shots = 1024
        self.qp.load_qasm_file(self.qasmFileName, name='example')
        basis_gates = []  # unroll to base gates
        unroller = unroll.Unroller(
            qasm.Qasm(data=self.qp.get_qasm("example")).parse(),
                      unroll.JsonBackend(basis_gates))
        circuit = unroller.execute()
        config = {'shots': shots, 'seed': self.seed}
        job = {'compiled_circuit': circuit, 'config': config}
        result = QasmSimulator(job).run()
        expected = {'100 100': 137, '011 011': 131, '101 101': 117, '111 111': 127,
                    '000 000': 131, '010 010': 141, '110 110': 116, '001 001': 124}
        self.assertEqual(result['data']['counts'], expected)

    def test_if_statement(self):
        self.log.info('test_if_statement_x')
        shots = 100
        max_qubits = 3
        qp = QuantumProgram()
        qr = qp.create_quantum_register('qr', max_qubits)
        cr = qp.create_classical_register('cr', max_qubits)
        circuit = qp.create_circuit('test_if', [qr], [cr])
        circuit.x(qr[0])
        circuit.x(qr[1])
        circuit.measure(qr[0], cr[0])
        circuit.measure(qr[1], cr[1])
        circuit.x(qr[2]).c_if(cr, 0x3)
        circuit.measure(qr[0], cr[0])
        circuit.measure(qr[1], cr[1])
        circuit.measure(qr[2], cr[2])
        circuit2 = qp.create_circuit('test_if_case_2', [qr], [cr])
        circuit2.x(qr[0])
        circuit2.measure(qr[0], cr[0])
        circuit2.measure(qr[1], cr[1])
        circuit2.x(qr[2]).c_if(cr, 0x3)
        circuit2.measure(qr[0], cr[0])
        circuit2.measure(qr[1], cr[1])
        circuit2.measure(qr[2], cr[2])
        basis_gates = []  # unroll to base gates
        unroller = unroll.Unroller(
            qasm.Qasm(data=qp.get_qasm('test_if')).parse(),
            unroll.JsonBackend(basis_gates))
        ucircuit = unroller.execute()
        unroller = unroll.Unroller(
            qasm.Qasm(data=qp.get_qasm('test_if_case_2')).parse(),
            unroll.JsonBackend(basis_gates))
        ucircuit2 = unroller.execute()
        config = {'shots': shots, 'seed': self.seed}
        job = {'compiled_circuit': ucircuit, 'config': config}
        result_if_true = QasmSimulator(job).run()
        job = {'compiled_circuit': ucircuit2, 'config': config}
        result_if_false = QasmSimulator(job).run()

        self.log.info('result_if_true circuit:')
        self.log.info(circuit.qasm())
        self.log.info('result_if_true={0}'.format(result_if_true))

        del circuit.data[1]
        self.log.info('result_if_false circuit:')
        self.log.info(circuit.qasm())
        self.log.info('result_if_false={0}'.format(result_if_false))
        self.assertTrue(result_if_true['data']['counts']['111'] == 100)
        self.assertTrue(result_if_false['data']['counts']['001'] == 100)

    def test_teleport(self):
        """test teleportation as in tutorials"""

        self.log.info('test_teleport')
        pi = np.pi
        shots = 1000
        qp = QuantumProgram()
        qr = qp.create_quantum_register('qr', 3)
        cr0 = qp.create_classical_register('cr0', 1)
        cr1 = qp.create_classical_register('cr1', 1)
        cr2 = qp.create_classical_register('cr2', 1)
        circuit = qp.create_circuit('teleport', [qr],
                                    [cr0, cr1, cr2])
        circuit.h(qr[1])
        circuit.cx(qr[1], qr[2])
        circuit.ry(pi/4, qr[0])
        circuit.cx(qr[0], qr[1])
        circuit.h(qr[0])
        circuit.barrier(qr)
        circuit.measure(qr[0], cr0[0])
        circuit.measure(qr[1], cr1[0])
        circuit.z(qr[2]).c_if(cr0, 1)
        circuit.x(qr[2]).c_if(cr1, 1)
        circuit.measure(qr[2], cr2[0])
        backend = 'local_qasm_simulator'
        qobj = qp.compile('teleport', backend=backend, shots=shots,
                   seed=self.seed)
        results = qp.run(qobj)
        data = results.get_counts('teleport')
        alice = {}
        bob = {}
        alice['00'] = data['0 0 0'] + data['1 0 0']
        alice['01'] = data['0 1 0'] + data['1 1 0']
        alice['10'] = data['0 0 1'] + data['1 0 1']
        alice['11'] = data['0 1 1'] + data['1 1 1']
        bob['0'] = data['0 0 0'] + data['0 1 0'] +  data['0 0 1'] + data['0 1 1']
        bob['1'] = data['1 0 0'] + data['1 1 0'] +  data['1 0 1'] + data['1 1 1']
        self.log.info('test_telport: circuit:')
        self.log.info( circuit.qasm() )
        self.log.info('test_teleport: data {0}'.format(data))
        self.log.info('test_teleport: alice {0}'.format(alice))
        self.log.info('test_teleport: bob {0}'.format(bob))
        alice_ratio = 1/np.tan(pi/8)**2
        bob_ratio = bob['0']/float(bob['1'])
        error = abs(alice_ratio - bob_ratio) / alice_ratio
        self.log.info('test_teleport: relative error = {0:.4f}'.format(error))
        self.assertLess(error, 0.05)

    def profile_qasm_simulator(self):
        """Profile randomly generated circuits.

        Writes profile results to <this_module>.prof as well as recording
        to the log file.

        number of circuits = 100.
        number of operations/circuit in [1, 40]
        number of qubits in [1, 5]
        """
        seed = 88
        shots = 1024
        nCircuits = 100
        minDepth = 1
        maxDepth = 40
        minQubits = 1
        maxQubits = 5
        pr = cProfile.Profile()
        randomCircuits = RandomQasmGenerator(seed,
                                             minQubits=minQubits,
                                             maxQubits=maxQubits,
                                             minDepth=minDepth,
                                             maxDepth=maxDepth)
        randomCircuits.add_circuits(nCircuits)
        self.qp = randomCircuits.getProgram()
        pr.enable()
        self.qp.execute(self.qp.get_circuit_names(),
                        backend='local_qasm_simulator',
                        shots=shots)
        pr.disable()
        sout = io.StringIO()
        ps = pstats.Stats(pr, stream=sout).sort_stats('cumulative')
        self.log.info('------- start profiling QasmSimulator -----------')
        ps.print_stats()
        self.log.info(sout.getvalue())
        self.log.info('------- stop profiling QasmSimulator -----------')
        sout.close()
        pr.dump_stats(self.moduleName + '.prof')

    def profile_nqubit_speed_grow_depth(self):
        """simulation time vs the number of qubits

        where the circuit depth is 10x the number of simulated
        qubits. Also creates a pdf file with this module name showing a
        plot of the results. Compilation is not included in speed.
        """
        import matplotlib.pyplot as plt
        from matplotlib.ticker import MaxNLocator
        qubitRangeMax = 15
        nQubitList = range(1,qubitRangeMax + 1)
        nCircuits = 10
        shots = 1024
        seed = 88
        maxTime = 30 # seconds; timing stops when simulation time exceeds this number
        fmtStr1 = 'profile_nqubit_speed::nqubits:{0}, backend:{1}, elapsed_time:{2:.2f}'
        fmtStr2 = 'backend:{0}, circuit:{1}, numOps:{2}, result:{3}'
        fmtStr3 = 'minDepth={minDepth}, maxDepth={maxDepth}, num circuits={nCircuits}, shots={shots}'
        backendList = ['local_qasm_simulator', 'local_unitary_simulator']
        if shutil.which('qasm_simulator'):
            backendList.append('local_qasm_cpp_simulator')
        else:
            self.log.info('profile_nqubit_speed::\"qasm_simulator\" executable not in path...skipping')
        fig = plt.figure(0)
        plt.clf()
        ax = fig.add_axes((0.1, 0.25, 0.8, 0.6))
        for i, backend in enumerate(backendList):
            elapsedTime = np.zeros(len(nQubitList))
            if backend is 'local_unitary_simulator':
                doMeasure = False
            else:
                doMeasure = True
            j, timedOut = 0, False
            while j < qubitRangeMax and not timedOut:
                nQubits = nQubitList[j]
                randomCircuits = RandomQasmGenerator(seed,
                                                     minQubits=nQubits,
                                                     maxQubits=nQubits,
                                                     minDepth=nQubits*10,
                                                     maxDepth=nQubits*10)
                randomCircuits.add_circuits(nCircuits, doMeasure=doMeasure)
                qp = randomCircuits.getProgram()
                cnames = qp.get_circuit_names()
                qobj = qp.compile(cnames, backend=backend, shots=shots,
                                  seed=seed)
                start = time.perf_counter()
                results = qp.run(qobj)
                stop = time.perf_counter()
                elapsedTime[j] = stop - start
                if elapsedTime[j] > maxTime:
                    timedOut = True
                self.log.info(fmtStr1.format(nQubits, backend, elapsedTime[j]))
                if backend is not 'local_unitary_simulator':
                    for name in cnames:
                        self.log.info(fmtStr2.format(
                            backend, name, len(qp.get_circuit(name)),
                            results.get_data(name)))
                j += 1
            ax.xaxis.set_major_locator(MaxNLocator(integer=True))
            if backend is 'local_unitary_simulator':
                ax.plot(nQubitList[:j], elapsedTime[:j], label=backend, marker='o')
            else:
                ax.plot(nQubitList[:j], elapsedTime[:j]/shots, label=backend,
                        marker='o')
            ax.set_yscale('log', basey=10)
            ax.set_xlabel('number of qubits')
            ax.set_ylabel('process time/shot')
            ax.set_title('profile_nqubit_speed_grow_depth')
            fig.text(0.1, 0.05,
                     fmtStr3.format(minDepth='10*nQubits', maxDepth='10*nQubits',
                                    nCircuits=nCircuits, shots=shots))
            ax.legend()
        self.pdf.savefig(fig)

    def profile_nqubit_speed_constant_depth(self):
        """simulation time vs the number of qubits

        where the circuit depth is fixed at 40. Also creates a pdf file
        with this module name showing a plot of the results. Compilation
        is not included in speed.
        """
        import matplotlib.pyplot as plt
        from matplotlib.ticker import MaxNLocator
        qubitRangeMax = 15
        nQubitList = range(1,qubitRangeMax + 1)
        maxDepth = 40
        minDepth = 40
        nCircuits = 10
        shots = 1024
        seed = 88
        maxTime = 30 # seconds; timing stops when simulation time exceeds this number
        fmtStr1 = 'profile_nqubit_speed::nqubits:{0}, backend:{1}, elapsed_time:{2:.2f}'
        fmtStr2 = 'backend:{0}, circuit:{1}, numOps:{2}, result:{3}'
        fmtStr3 = 'minDepth={minDepth}, maxDepth={maxDepth}, num circuits={nCircuits}, shots={shots}'
        backendList = ['local_qasm_simulator', 'local_unitary_simulator']
        if shutil.which('qasm_simulator'):
            backendList.append('local_qasm_cpp_simulator')
        else:
            self.log.info('profile_nqubit_speed::\"qasm_simulator\" executable not in path...skipping')
        fig = plt.figure(0)
        plt.clf()
        ax = fig.add_axes((0.1, 0.2, 0.8, 0.6))
        for i, backend in enumerate(backendList):
            elapsedTime = np.zeros(len(nQubitList))
            if backend is 'local_unitary_simulator':
                doMeasure = False
            else:
                doMeasure = True
            j, timedOut = 0, False
            while j < qubitRangeMax and not timedOut:
                nQubits = nQubitList[j]
                randomCircuits = RandomQasmGenerator(seed,
                                                     minQubits=nQubits,
                                                     maxQubits=nQubits,
                                                     minDepth=minDepth,
                                                     maxDepth=maxDepth)
                randomCircuits.add_circuits(nCircuits, doMeasure=doMeasure)
                qp = randomCircuits.getProgram()
                cnames = qp.get_circuit_names()
                qobj = qp.compile(cnames, backend=backend, shots=shots, seed=seed)
                start = time.perf_counter()
                results = qp.run(qobj)
                stop = time.perf_counter()
                elapsedTime[j] = stop - start
                if elapsedTime[j] > maxTime:
                    timedOut = True
                self.log.info(fmtStr1.format(nQubits, backend, elapsedTime[j]))
                if backend is not 'local_unitary_simulator':
                    for name in cnames:
                        self.log.info(fmtStr2.format(
                            backend, name, len(qp.get_circuit(name)),
                            results.get_data(name)))
                j += 1
            ax.xaxis.set_major_locator(MaxNLocator(integer=True))
            if backend is 'local_unitary_simulator':
                ax.plot(nQubitList[:j], elapsedTime[:j], label=backend, marker='o')
            else:
                ax.plot(nQubitList[:j], elapsedTime[:j]/shots, label=backend,
                        marker='o')
            ax.set_yscale('log', basey=10)
            ax.set_xlabel('number of qubits')
            ax.set_ylabel('process time/shot')
            ax.set_title('profile_nqubit_speed_constant_depth')
            fig.text(0.1, 0.05,
                     fmtStr3.format(minDepth=minDepth, maxDepth=maxDepth,
                                    nCircuits=nCircuits, shots=shots))
            ax.legend()
        self.pdf.savefig(fig)
Esempio n. 8
0
class TestLocalQasmSimulatorPy(QiskitTestCase):
    """Test local_qasm_simulator_py."""
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        if do_profiling:
            cls.pdf = PdfPages(cls.moduleName + '.pdf')

    @classmethod
    def tearDownClass(cls):
        if do_profiling:
            cls.pdf.close()

    def setUp(self):
        self.seed = 88
        self.qasm_filename = self._get_resource_path('qasm/example.qasm')
        self.qp = QuantumProgram()
        self.qp.load_qasm_file(self.qasm_filename, name='example')
        basis_gates = []  # unroll to base gates
        unroller = unroll.Unroller(
            qasm.Qasm(data=self.qp.get_qasm('example')).parse(),
            unroll.JsonBackend(basis_gates))
        circuit = unroller.execute()
        circuit_config = {
            'coupling_map': None,
            'basis_gates': 'u1,u2,u3,cx,id',
            'layout': None,
            'seed': self.seed
        }
        resources = {'max_credits': 3}
        self.qobj = {
            'id':
            'test_sim_single_shot',
            'config': {
                'max_credits': resources['max_credits'],
                'shots': 1024,
                'backend_name': 'local_qasm_simulator_py',
            },
            'circuits': [{
                'name': 'test',
                'compiled_circuit': circuit,
                'compiled_circuit_qasm': None,
                'config': circuit_config
            }]
        }
        self.q_job = QuantumJob(self.qobj,
                                backend=QasmSimulatorPy(),
                                circuit_config=circuit_config,
                                seed=self.seed,
                                resources=resources,
                                preformatted=True)

    def tearDown(self):
        pass

    def test_qasm_simulator_single_shot(self):
        """Test single shot run."""
        shots = 1
        self.qobj['config']['shots'] = shots
        result = QasmSimulatorPy().run(self.q_job).result()
        self.assertEqual(result.get_status(), 'COMPLETED')

    def test_qasm_simulator(self):
        """Test data counts output for single circuit run against reference."""
        result = QasmSimulatorPy().run(self.q_job).result()
        shots = 1024
        threshold = 0.04 * shots
        counts = result.get_counts('test')
        target = {
            '100 100': shots / 8,
            '011 011': shots / 8,
            '101 101': shots / 8,
            '111 111': shots / 8,
            '000 000': shots / 8,
            '010 010': shots / 8,
            '110 110': shots / 8,
            '001 001': shots / 8
        }
        self.assertDictAlmostEqual(counts, target, threshold)

    def test_if_statement(self):
        self.log.info('test_if_statement_x')
        shots = 100
        max_qubits = 3
        qp = QuantumProgram()
        qr = qp.create_quantum_register('qr', max_qubits)
        cr = qp.create_classical_register('cr', max_qubits)
        circuit_if_true = qp.create_circuit('test_if_true', [qr], [cr])
        circuit_if_true.x(qr[0])
        circuit_if_true.x(qr[1])
        circuit_if_true.measure(qr[0], cr[0])
        circuit_if_true.measure(qr[1], cr[1])
        circuit_if_true.x(qr[2]).c_if(cr, 0x3)
        circuit_if_true.measure(qr[0], cr[0])
        circuit_if_true.measure(qr[1], cr[1])
        circuit_if_true.measure(qr[2], cr[2])
        circuit_if_false = qp.create_circuit('test_if_false', [qr], [cr])
        circuit_if_false.x(qr[0])
        circuit_if_false.measure(qr[0], cr[0])
        circuit_if_false.measure(qr[1], cr[1])
        circuit_if_false.x(qr[2]).c_if(cr, 0x3)
        circuit_if_false.measure(qr[0], cr[0])
        circuit_if_false.measure(qr[1], cr[1])
        circuit_if_false.measure(qr[2], cr[2])
        basis_gates = []  # unroll to base gates
        unroller = unroll.Unroller(
            qasm.Qasm(data=qp.get_qasm('test_if_true')).parse(),
            unroll.JsonBackend(basis_gates))
        ucircuit_true = unroller.execute()
        unroller = unroll.Unroller(
            qasm.Qasm(data=qp.get_qasm('test_if_false')).parse(),
            unroll.JsonBackend(basis_gates))
        ucircuit_false = unroller.execute()
        qobj = {
            'id':
            'test_if_qobj',
            'config': {
                'max_credits': 3,
                'shots': shots,
                'backend_name': 'local_qasm_simulator_py',
            },
            'circuits': [{
                'name': 'test_if_true',
                'compiled_circuit': ucircuit_true,
                'compiled_circuit_qasm': None,
                'config': {
                    'coupling_map': None,
                    'basis_gates': 'u1,u2,u3,cx,id',
                    'layout': None,
                    'seed': None
                }
            }, {
                'name': 'test_if_false',
                'compiled_circuit': ucircuit_false,
                'compiled_circuit_qasm': None,
                'config': {
                    'coupling_map': None,
                    'basis_gates': 'u1,u2,u3,cx,id',
                    'layout': None,
                    'seed': None
                }
            }]
        }
        q_job = QuantumJob(qobj, backend=QasmSimulatorPy(), preformatted=True)
        result = QasmSimulatorPy().run(q_job).result()
        result_if_true = result.get_data('test_if_true')
        self.log.info('result_if_true circuit:')
        self.log.info(circuit_if_true.qasm())
        self.log.info('result_if_true=%s', result_if_true)

        result_if_false = result.get_data('test_if_false')
        self.log.info('result_if_false circuit:')
        self.log.info(circuit_if_false.qasm())
        self.log.info('result_if_false=%s', result_if_false)
        self.assertTrue(result_if_true['counts']['111'] == 100)
        self.assertTrue(result_if_false['counts']['001'] == 100)

    @unittest.skipIf(version_info.minor == 5,
                     "Due to gate ordering issues with Python 3.5 \
                                         we have to disable this test until fixed"
                     )
    def test_teleport(self):
        """test teleportation as in tutorials"""

        self.log.info('test_teleport')
        pi = np.pi
        shots = 1000
        qp = QuantumProgram()
        qr = qp.create_quantum_register('qr', 3)
        cr0 = qp.create_classical_register('cr0', 1)
        cr1 = qp.create_classical_register('cr1', 1)
        cr2 = qp.create_classical_register('cr2', 1)
        circuit = qp.create_circuit('teleport', [qr], [cr0, cr1, cr2])
        circuit.h(qr[1])
        circuit.cx(qr[1], qr[2])
        circuit.ry(pi / 4, qr[0])
        circuit.cx(qr[0], qr[1])
        circuit.h(qr[0])
        circuit.barrier(qr)
        circuit.measure(qr[0], cr0[0])
        circuit.measure(qr[1], cr1[0])
        circuit.z(qr[2]).c_if(cr0, 1)
        circuit.x(qr[2]).c_if(cr1, 1)
        circuit.measure(qr[2], cr2[0])
        backend = 'local_qasm_simulator_py'
        qobj = qp.compile('teleport',
                          backend=backend,
                          shots=shots,
                          seed=self.seed)
        results = qp.run(qobj)
        data = results.get_counts('teleport')
        alice = {}
        bob = {}
        alice['00'] = data['0 0 0'] + data['1 0 0']
        alice['01'] = data['0 1 0'] + data['1 1 0']
        alice['10'] = data['0 0 1'] + data['1 0 1']
        alice['11'] = data['0 1 1'] + data['1 1 1']
        bob['0'] = data['0 0 0'] + data['0 1 0'] + data['0 0 1'] + data['0 1 1']
        bob['1'] = data['1 0 0'] + data['1 1 0'] + data['1 0 1'] + data['1 1 1']
        self.log.info('test_telport: circuit:')
        self.log.info(circuit.qasm())
        self.log.info('test_teleport: data %s', data)
        self.log.info('test_teleport: alice %s', alice)
        self.log.info('test_teleport: bob %s', bob)
        alice_ratio = 1 / np.tan(pi / 8)**2
        bob_ratio = bob['0'] / float(bob['1'])
        error = abs(alice_ratio - bob_ratio) / alice_ratio
        self.log.info('test_teleport: relative error = %s', error)
        self.assertLess(error, 0.05)

    @unittest.skipIf(not do_profiling, "skipping simulator profiling.")
    def profile_qasm_simulator(self):
        """Profile randomly generated circuits.

        Writes profile results to <this_module>.prof as well as recording
        to the log file.

        number of circuits = 100.
        number of operations/circuit in [1, 40]
        number of qubits in [1, 5]
        """
        seed = 88
        shots = 1024
        n_circuits = 100
        min_depth = 1
        max_depth = 40
        min_qubits = 1
        max_qubits = 5
        pr = cProfile.Profile()
        random_circuits = RandomQasmGenerator(seed,
                                              min_qubits=min_qubits,
                                              max_qubits=max_qubits,
                                              min_depth=min_depth,
                                              max_depth=max_depth)
        random_circuits.add_circuits(n_circuits)
        self.qp = random_circuits.get_program()
        pr.enable()
        self.qp.execute(self.qp.get_circuit_names(),
                        backend='local_qasm_simulator_py',
                        shots=shots)
        pr.disable()
        sout = io.StringIO()
        ps = pstats.Stats(pr, stream=sout).sort_stats('cumulative')
        self.log.info('------- start profiling QasmSimulatorPy -----------')
        ps.print_stats()
        self.log.info(sout.getvalue())
        self.log.info('------- stop profiling QasmSimulatorPy -----------')
        sout.close()
        pr.dump_stats(self.moduleName + '.prof')

    @unittest.skipIf(not do_profiling, "skipping simulator profiling.")
    def profile_nqubit_speed_grow_depth(self):
        """simulation time vs the number of qubits

        where the circuit depth is 10x the number of simulated
        qubits. Also creates a pdf file with this module name showing a
        plot of the results. Compilation is not included in speed.
        """
        import matplotlib.pyplot as plt
        from matplotlib.ticker import MaxNLocator
        qubit_range_max = 15
        n_qubit_list = range(1, qubit_range_max + 1)
        n_circuits = 10
        shots = 1024
        seed = 88
        max_time = 30  # seconds; timing stops when simulation time exceeds this number
        fmt_str1 = 'profile_nqubit_speed::nqubits:{0}, backend:{1}, elapsed_time:{2:.2f}'
        fmt_str2 = 'backend:{0}, circuit:{1}, numOps:{2}, result:{3}'
        fmt_str3 = 'minDepth={minDepth}, maxDepth={maxDepth}, num circuits={nCircuits},' \
                   'shots={shots}'
        backend_list = [
            'local_qasm_simulator_py', 'local_unitary_simulator_py'
        ]
        if shutil.which('qasm_simulator'):
            backend_list.append('local_qasm_simulator_cpp')
        else:
            self.log.info('profile_nqubit_speed::\"qasm_simulator\" executable'
                          'not in path...skipping')
        fig = plt.figure(0)
        plt.clf()
        ax = fig.add_axes((0.1, 0.25, 0.8, 0.6))
        for _, backend in enumerate(backend_list):
            elapsed_time = np.zeros(len(n_qubit_list))
            if backend == 'local_unitary_simulator_py':
                do_measure = False
            else:
                do_measure = True
            j, timed_out = 0, False
            while j < qubit_range_max and not timed_out:
                n_qubits = n_qubit_list[j]
                random_circuits = RandomQasmGenerator(seed,
                                                      min_qubits=n_qubits,
                                                      max_qubits=n_qubits,
                                                      min_depth=n_qubits * 10,
                                                      max_depth=n_qubits * 10)
                random_circuits.add_circuits(n_circuits, do_measure=do_measure)
                qp = random_circuits.get_program()
                c_names = qp.get_circuit_names()
                qobj = qp.compile(c_names,
                                  backend=backend,
                                  shots=shots,
                                  seed=seed)
                start = time.perf_counter()
                results = qp.run(qobj)
                stop = time.perf_counter()
                elapsed_time[j] = stop - start
                if elapsed_time[j] > max_time:
                    timed_out = True
                self.log.info(
                    fmt_str1.format(n_qubits, backend, elapsed_time[j]))
                if backend != 'local_unitary_simulator_py':
                    for name in c_names:
                        log_str = fmt_str2.format(backend, name,
                                                  len(qp.get_circuit(name)),
                                                  results.get_data(name))
                        self.log.info(log_str)
                j += 1
            ax.xaxis.set_major_locator(MaxNLocator(integer=True))
            if backend == 'local_unitary_simulator_py':
                ax.plot(n_qubit_list[:j],
                        elapsed_time[:j],
                        label=backend,
                        marker='o')
            else:
                ax.plot(n_qubit_list[:j],
                        elapsed_time[:j] / shots,
                        label=backend,
                        marker='o')
            ax.set_yscale('log', basey=10)
            ax.set_xlabel('number of qubits')
            ax.set_ylabel('process time/shot')
            ax.set_title('profile_nqubit_speed_grow_depth')
            fig.text(
                0.1, 0.05,
                fmt_str3.format(minDepth='10*nQubits',
                                maxDepth='10*nQubits',
                                nCircuits=n_circuits,
                                shots=shots))
            ax.legend()
        self.pdf.savefig(fig)

    @unittest.skipIf(not do_profiling, "skipping simulator profiling.")
    def profile_nqubit_speed_constant_depth(self):
        """simulation time vs the number of qubits

        where the circuit depth is fixed at 40. Also creates a pdf file
        with this module name showing a plot of the results. Compilation
        is not included in speed.
        """
        import matplotlib.pyplot as plt
        from matplotlib.ticker import MaxNLocator
        qubit_range_max = 15
        n_qubit_list = range(1, qubit_range_max + 1)
        max_depth = 40
        min_depth = 40
        n_circuits = 10
        shots = 1024
        seed = 88
        max_time = 30  # seconds; timing stops when simulation time exceeds this number
        fmt_str1 = 'profile_nqubit_speed::nqubits:{0}, backend:{1},' \
                   'elapsed_time:{2:.2f}'
        fmt_str2 = 'backend:{0}, circuit:{1}, numOps:{2}, result:{3}'
        fmt_str3 = 'minDepth={minDepth}, maxDepth={maxDepth},' \
                   'num circuits={nCircuits}, shots={shots}'
        backend_list = [
            'local_qasm_simulator_py', 'local_unitary_simulator_py'
        ]
        if shutil.which('qasm_simulator'):
            backend_list.append('local_qasm_simulator_cpp')
        else:
            self.log.info('profile_nqubit_speed::\"qasm_simulator\" executable'
                          'not in path...skipping')
        fig = plt.figure(0)
        plt.clf()
        ax = fig.add_axes((0.1, 0.2, 0.8, 0.6))
        for _, backend in enumerate(backend_list):
            elapsedTime = np.zeros(len(n_qubit_list))
            if backend == 'local_unitary_simulator_py':
                doMeasure = False
            else:
                doMeasure = True
            j, timedOut = 0, False
            while j < qubit_range_max and not timedOut:
                nQubits = n_qubit_list[j]
                randomCircuits = RandomQasmGenerator(seed,
                                                     min_qubits=nQubits,
                                                     max_qubits=nQubits,
                                                     min_depth=min_depth,
                                                     max_depth=max_depth)
                randomCircuits.add_circuits(n_circuits, do_measure=doMeasure)
                qp = randomCircuits.get_program()
                cnames = qp.get_circuit_names()
                qobj = qp.compile(cnames,
                                  backend=backend,
                                  shots=shots,
                                  seed=seed)
                start = time.perf_counter()
                results = qp.run(qobj)
                stop = time.perf_counter()
                elapsedTime[j] = stop - start
                if elapsedTime[j] > max_time:
                    timedOut = True
                self.log.info(fmt_str1.format(nQubits, backend,
                                              elapsedTime[j]))
                if backend != 'local_unitary_simulator_py':
                    for name in cnames:
                        log_str = fmt_str2.format(backend, name,
                                                  len(qp.get_circuit(name)),
                                                  results.get_data(name))
                        self.log.info(log_str)
                j += 1
            ax.xaxis.set_major_locator(MaxNLocator(integer=True))
            if backend == 'local_unitary_simulator_py':
                ax.plot(n_qubit_list[:j],
                        elapsedTime[:j],
                        label=backend,
                        marker='o')
            else:
                ax.plot(n_qubit_list[:j],
                        elapsedTime[:j] / shots,
                        label=backend,
                        marker='o')
            ax.set_yscale('log', basey=10)
            ax.set_xlabel('number of qubits')
            ax.set_ylabel('process time/shot')
            ax.set_title('profile_nqubit_speed_constant_depth')
            fig.text(
                0.1, 0.05,
                fmt_str3.format(minDepth=min_depth,
                                maxDepth=max_depth,
                                nCircuits=n_circuits,
                                shots=shots))
            ax.legend()
        self.pdf.savefig(fig)
class LocalUnitarySimulatorTest(unittest.TestCase):
    """Test local unitary simulator."""

    def setUp(self):
        self.seed = 88
        self.qasmFileName = os.path.join(qiskit.__path__[0],
                                         '../test/python/qasm/example.qasm')
        self.qp = QuantumProgram()
        self.moduleName = os.path.splitext(__file__)[0]
        self.modulePath = os.path.dirname(__file__)
        logFileName = self.moduleName + '.log'
        logging.basicConfig(filename=logFileName, level=logging.INFO)

    def tearDown(self):
        pass

    def test_unitary_simulator(self):
        """test generation of circuit unitary"""
        shots = 1024
        self.qp.load_qasm_file(self.qasmFileName, name='example')
        basis_gates = []  # unroll to base gates
        unroller = unroll.Unroller(
            qasm.Qasm(data=self.qp.get_qasm("example")).parse(),
                      unroll.JsonBackend(basis_gates))
        circuit = unroller.execute()
	# if we want to manipulate the circuit, we have to convert it to a dict
        circuit = json.loads(circuit.decode())
        #strip measurements from circuit to avoid warnings
        circuit['operations'] = [op for op in circuit['operations']
                                 if op['name'] != 'measure']
	# the simulator is expecting a JSON format, so we need to convert it back to JSON
        job = {'compiled_circuit': json.dumps(circuit).encode()}
        # numpy savetxt is currently prints complex numbers in a way
        # loadtxt can't read. To save file do,
        # fmtstr=['% .4g%+.4gj' for i in range(numCols)]
        # np.savetxt('example_unitary_matrix.dat', numpyMatrix, fmt=fmtstr, delimiter=',')
        expected = np.loadtxt(os.path.join(self.modulePath,
                                           'example_unitary_matrix.dat'),
                              dtype='complex', delimiter=',')
        result = UnitarySimulator(job).run()
        self.assertTrue(np.allclose(result['data']['unitary'], expected,
                                    rtol=1e-3))

    def profile_unitary_simulator(self):
        """Profile randomly generated circuits.

        Writes profile results to <this_module>.prof as well as recording
        to the log file.

        number of circuits = 100.
        number of operations/circuit in [1, 40]
        number of qubits in [1, 5]
        """
        nCircuits = 100
        maxDepth = 40
        maxQubits = 5
        pr = cProfile.Profile()
        randomCircuits = RandomQasmGenerator(seed=self.seed,
                                             maxDepth=maxDepth,
                                             maxQubits=maxQubits)
        randomCircuits.add_circuits(nCircuits, doMeasure=False)
        self.qp = randomCircuits.getProgram()
        pr.enable()
        self.qp.execute(self.qp.get_circuit_names(),
                        backend='local_unitary_simulator')
        pr.disable()
        sout = io.StringIO()
        ps = pstats.Stats(pr, stream=sout).sort_stats('cumulative')
        logging.info('------- start profiling UnitarySimulator -----------')
        ps.print_stats()
        logging.info(sout.getvalue())
        logging.info('------- stop profiling UnitarySimulator -----------')
        sout.close()
        pr.dump_stats(self.moduleName + '.prof')
Esempio n. 10
0
# second eight (qu)bits have superposition of
# '8' = 00111000
# ';' = 00111011
# these differ only on the rightmost two bits

circuit.h(quantum_r[9])
circuit.cx(quantum_r[9], quantum_r[8])
circuit.x(quantum_r[11])
circuit.x(quantum_r[12])
circuit.x(quantum_r[13])

# measure
for j in range(16):
    circuit.measure(quantum_r[j], classical_r[j])

qp.get_circuit_names()

QASM_source = qp.get_qasm('Circuit')

print(QASM_source)
import os
import shutil
from qiskit.tools.visualization import latex_drawer
import pdf2image


def circuitImage(circuit, basis="u1,u2,u3,cx"):
    """Obtain the circuit in image format
    Note: Requires pdflatex installed (to compile Latex)
    Note: Required pdf2image Python package (to display pdf as image)
    """
Esempio n. 11
0
class QC():
    '''
    class QC
    '''
    # pylint: disable=too-many-instance-attributes
    def __init__(self, backend='local_qasm_simulator', remote=False, qubits=3):
        # private member
        # __qp
        self.__qp = None

        # calc phase
        self.phase = [
            ['0', 'initialized.']
            ]
        # config
        self.backend = backend
        self.remote = remote
        self.qubits = qubits
        # circuits variable
        self.shots = 2
        # async
        self.wait = False
        self.last = ['init', 'None']

        self.load()

    def load(self, api_info=True):
        '''
        load
        '''
        self.__qp = QuantumProgram()
        if self.remote:
            try:
                import Qconfig
                self.__qp.set_api(Qconfig.APItoken, Qconfig.config["url"],
                                  hub=Qconfig.config["hub"],
                                  group=Qconfig.config["group"],
                                  project=Qconfig.config["project"])

            except ImportError as ex:
                msg = 'Error in loading Qconfig.py!. Error = {}\n'.format(ex)
                sys.stdout.write(msg)
                sys.stdout.flush()
                return False

            if api_info is True:
                api = self.__qp.get_api()
                sys.stdout.write('<IBM Quantum Experience API information>\n')
                sys.stdout.flush()
                sys.stdout.write('Version: {0}\n'.format(api.api_version()))
                sys.stdout.write('User jobs (last 5):\n')
                jobs = api.get_jobs(limit=500)

                def format_date(job_item):
                    '''
                    format
                    '''
                    return datetime.strptime(job_item['creationDate'],
                                             '%Y-%m-%dT%H:%M:%S.%fZ')
                sortedjobs = sorted(jobs,
                                    key=format_date)
                sys.stdout.write('  {0:<32} {1:<24} {2:<9} {3}\n'
                                 .format('id',
                                         'creationDate',
                                         'status',
                                         'backend'))
                sys.stdout.write('{:-^94}\n'.format(""))
                for job in sortedjobs[-5:]:
                    sys.stdout.write('  {0:<32} {1:<24} {2:<9} {3}\n'
                                     .format(job['id'],
                                             job['creationDate'],
                                             job['status'],
                                             job['backend']['name']))
                sys.stdout.write('There are {0} jobs on the server\n'
                                 .format(len(jobs)))
                sys.stdout.write('Credits: {0}\n'
                                 .format(api.get_my_credits()))
                sys.stdout.flush()

        self.backends = self.__qp.available_backends()
        status = self.__qp.get_backend_status(self.backend)

        if 'available' in status:
            if status['available'] is False:
                return False
        return True

    def set_config(self, config=None):
        '''
        set config
        '''
        if config is None:
            config = {}

        if 'backend' in config:
            self.backend = str(config['backend'])
            if 'local_' in self.backend:
                self.remote = False
            else:
                self.remote = True

        if 'remote' in config:
            self.remote = config['remote']

        if 'qubits' in config:
            self.qubits = int(config['qubits'])

        return True

    def _progress(self, phasename, text):
        self.phase.append([str(phasename), str(text)])
        text = "Phase {0}: {1}".format(phasename, text)
        sys.stdout.write("{}\n".format(text))
        sys.stdout.flush()

    def _init_circuit(self):
        self._progress('1', 'Initialize quantum registers and circuit')
        qubits = self.qubits

        quantum_registers = [
            {"name": "cin", "size": 1},
            {"name": "qa", "size": qubits},
            {"name": "qb", "size": qubits},
            {"name": "cout", "size": 1}
            ]

        classical_registers = [
            {"name": "ans", "size": qubits + 1}
            ]

        if 'cin' in self.__qp.get_quantum_register_names():
            self.__qp.destroy_quantum_registers(quantum_registers)
            self.__qp.destroy_classical_registers(classical_registers)

        q_r = self.__qp.create_quantum_registers(quantum_registers)
        c_r = self.__qp.create_classical_registers(classical_registers)

        self.__qp.create_circuit("qcirc", q_r, c_r)

    def _create_circuit_qadd(self):
        # quantum ripple-carry adder from Cuccaro et al, quant-ph/0410184
        def majority(circuit, q_a, q_b, q_c):
            '''
            majority
            '''
            circuit.cx(q_c, q_b)
            circuit.cx(q_c, q_a)
            circuit.ccx(q_a, q_b, q_c)

        def unmaj(circuit, q_a, q_b, q_c):
            '''
            unmajority
            '''
            circuit.ccx(q_a, q_b, q_c)
            circuit.cx(q_c, q_a)
            circuit.cx(q_a, q_b)

        def adder(circuit, c_in, q_a, q_b, c_out, qubits):
            '''
            adder
            '''
            # pylint: disable=too-many-arguments
            majority(circuit, c_in[0], q_b[0], q_a[0])
            for i in range(qubits - 1):
                majority(circuit, q_a[i], q_b[i + 1], q_a[i + 1])

            circuit.cx(q_a[qubits - 1], c_out[0])

            for i in range(qubits - 1)[::-1]:
                unmaj(circuit, q_a[i], q_b[i + 1], q_a[i + 1])
            unmaj(circuit, c_in[0], q_b[0], q_a[0])

        if 'add' not in self.__qp.get_circuit_names():
            [c_in, q_a, q_b, c_out] = map(self.__qp.get_quantum_register,
                                          ["cin", "qa", "qb", "cout"])
            ans = self.__qp.get_classical_register('ans')
            qadder = self.__qp.create_circuit("qadd",
                                              [c_in, q_a, q_b, c_out],
                                              [ans])
            adder(qadder, c_in, q_a, q_b, c_out, self.qubits)

        return 'add' in self.__qp.get_circuit_names()

    def _create_circuit_qsub(self):
        circuit_names = self.__qp.get_circuit_names()
        if 'qsub' not in circuit_names:
            if 'qadd' not in circuit_names:
                self._create_circuit_qadd()

            # subtractor circuit
            self.__qp.add_circuit('qsub', self.__qp.get_circuit('qadd'))
            qsubtractor = self.__qp.get_circuit('qsub')
            qsubtractor.reverse()
        return 'qsub' in self.__qp.get_circuit_names()

    def _qadd(self, input_a, input_b=None, subtract=False, observe=False):
        # pylint: disable=too-many-locals

        def measure(circuit, q_b, c_out, ans):
            '''
            measure
            '''
            circuit.barrier()
            for i in range(self.qubits):
                circuit.measure(q_b[i], ans[i])
            circuit.measure(c_out[0], ans[self.qubits])

        def char2q(circuit, cbit, qbit):
            '''
            char2q
            '''
            if cbit == '1':
                circuit.x(qbit)
            elif cbit == 'H':
                circuit.h(qbit)
                self.shots = 5 * (2**self.qubits)

        def input_state(circuit, input_a, input_b=None):
            '''
            input state
            '''
            input_a = input_a[::-1]
            for i in range(self.qubits):
                char2q(circuit, input_a[i], q_a[i])

            if input_b is not None:
                input_b = input_b[::-1]
                for i in range(self.qubits):
                    char2q(circuit, input_b[i], q_b[i])

        def reset_input(circuit, c_in, q_a, c_out):
            '''
            reset input
            '''
            circuit.reset(c_in)
            circuit.reset(c_out)
            for i in range(self.qubits):
                circuit.reset(q_a[i])

        # get registers
        [c_in, q_a, q_b, c_out] = map(self.__qp.get_quantum_register,
                                      ["cin", "qa", "qb", "cout"])
        ans = self.__qp.get_classical_register('ans')
        qcirc = self.__qp.get_circuit('qcirc')

        self._progress('2',
                       'Define input state ({})'
                       .format('QADD' if subtract is False else 'QSUB'))
        if input_b is not None:
            if subtract is True:
                # subtract
                input_state(qcirc, input_b, input_a)
            else:
                # add
                input_state(qcirc, input_a, input_b)
        else:
            reset_input(qcirc, c_in, q_a, c_out)
            input_state(qcirc, input_a)

        self._progress('3',
                       'Define quantum circuit ({})'
                       .format('QADD' if subtract is False else 'QSUB'))
        if subtract is True:
            self._create_circuit_qsub()
            qcirc.extend(self.__qp.get_circuit('qsub'))
        else:
            self._create_circuit_qadd()
            qcirc.extend(self.__qp.get_circuit('qadd'))

        if observe is True:
            measure(qcirc, q_b, c_out, ans)

    def _qsub(self, input_a, input_b=None, observe=False):
        self._qadd(input_a, input_b, subtract=True, observe=observe)

    def _qope(self, input_a, operator, input_b=None, observe=False):
        if operator == '+':
            return self._qadd(input_a, input_b, observe=observe)
        elif operator == '-':
            return self._qsub(input_a, input_b, observe=observe)
        return None

    def _compile(self, name, cross_backend=None, print_qasm=False):
        self._progress('4', 'Compile quantum circuit')

        coupling_map = None
        if cross_backend is not None:
            backend_conf = self.__qp.get_backend_configuration(cross_backend)
            coupling_map = backend_conf.get('coupling_map', None)
            if coupling_map is None:
                sys.stdout.write('backend: {} coupling_map not found'
                                 .format(cross_backend))

        qobj = self.__qp.compile([name],
                                 backend=self.backend,
                                 shots=self.shots,
                                 seed=1,
                                 coupling_map=coupling_map)

        if print_qasm is True:
            sys.stdout.write(self.__qp.get_compiled_qasm(qobj, 'qcirc'))
            sys.stdout.flush()
        return qobj

    def _run(self, qobj):
        self._progress('5', 'Run quantum circuit (wait for answer)')
        result = self.__qp.run(qobj, wait=5, timeout=100000)
        return result

    def _run_async(self, qobj):
        '''
        _run_async
        '''
        self._progress('5', 'Run quantum circuit')
        self.wait = True

        def async_result(result):
            '''
            async call back
            '''
            self.wait = False
            self.last = self.result_parse(result)

        self.__qp.run_async(qobj,
                            wait=5, timeout=100000, callback=async_result)

    def _is_regular_number(self, numstring, base):
        '''
        returns input binary format string or None.
        '''
        if base == 'bin':
            binstring = numstring
        elif base == 'dec':
            if numstring == 'H':
                binstring = 'H'*self.qubits
            else:
                binstring = format(int(numstring), "0{}b".format(self.qubits))

        if len(binstring) != self.qubits:
            return None

        return binstring

    def get_seq(self, text, base='dec'):
        '''
        convert seq and check it
        if text is invalid, return the list of length 0.
        '''
        operators = u'(\\+|\\-)'
        seq = re.split(operators, text)

        # length check
        if len(seq) % 2 == 0 or len(seq) == 1:
            return []

        # regex
        if base == 'bin':
            regex = re.compile(r'[01H]+')
        else:
            regex = re.compile(r'(^(?!.H)[0-9]+|H)')

        for i in range(0, len(seq), 2):
            match = regex.match(seq[i])
            if match is None:
                return []
            num = match.group(0)
            seq[i] = self._is_regular_number(num, base)

            if seq[i] is None:
                return []

        return seq

    def result_parse(self, result):
        '''
        result_parse
        '''
        data = result.get_data("qcirc")
        sys.stdout.write("job id: {0}\n".format(result.get_job_id()))
        sys.stdout.write("raw result: {0}\n".format(data))
        sys.stdout.write("{:=^40}\n".format("answer"))

        counts = data['counts']
        sortedcounts = sorted(counts.items(),
                              key=lambda x: -x[1])

        sortedans = []
        for count in sortedcounts:
            if count[0][0] == '1':
                ans = 'OR'
            else:
                ans = str(int(count[0][-self.qubits:], 2))
            sortedans.append(ans)
            sys.stdout.write('Dec: {0:>2} Bin: {1} Count: {2} \n'
                             .format(ans, str(count[0]), str(count[1])))

        sys.stdout.write('{0:d} answer{1}\n'
                         .format(len(sortedans),
                                 '' if len(sortedans) == 1 else 's'))
        sys.stdout.write("{:=^40}\n".format(""))
        if 'time' in data:
            sys.stdout.write("time: {0:<3} sec\n".format(data['time']))
        sys.stdout.write("All process done.\n")
        sys.stdout.flush()

        uniqanswer = sorted(set(sortedans), key=sortedans.index)

        ans = ",".join(uniqanswer)

        return [str(result), ans]

    def exec_calc(self, text, base='dec', wait_result=False):
        '''
        exec_calc
        '''
        seq = self.get_seq(text, base)
        print('QC seq:', seq)
        if seq == []:
            return ["Syntax error", None]

        # fail message
        fail_msg = None

        try:
            self._init_circuit()
            numbers = seq[0::2]     # slice even index
            i = 1
            observe = False
            for oper in seq[1::2]:  # slice odd index
                if i == len(numbers) - 1:
                    observe = True
                if i == 1:
                    self._qope(numbers[0], oper, numbers[1], observe=observe)
                else:
                    self._qope(numbers[i], oper, observe=observe)
                i = i + 1

            qobj = self._compile('qcirc')

            if wait_result is True:
                [status, ans] = self.result_parse(self._run(qobj))
            else:
                self._run_async(qobj)
                [status, ans] = [
                    'Wait. Calculating on {0}'.format(self.backend),
                    '...'
                    ]

        except QISKitError as ex:
            fail_msg = ('There was an error in the circuit!. Error = {}\n'
                        .format(ex))
        except RegisterSizeError as ex:
            fail_msg = ('Error in the number of registers!. Error = {}\n'
                        .format(ex))

        if fail_msg is not None:
            sys.stdout.write(fail_msg)
            sys.stdout.flush()
            return ["FAIL", None]

        return [status, ans]
class LocalUnitarySimulatorTest(unittest.TestCase):
    """Test local unitary simulator."""
    @classmethod
    def setUpClass(cls):
        cls.moduleName = os.path.splitext(__file__)[0]
        cls.log = logging.getLogger(__name__)
        cls.log.setLevel(logging.INFO)
        logFileName = cls.moduleName + '.log'
        handler = logging.FileHandler(logFileName)
        handler.setLevel(logging.INFO)
        log_fmt = ('{}.%(funcName)s:%(levelname)s:%(asctime)s:'
                   ' %(message)s'.format(cls.__name__))
        formatter = logging.Formatter(log_fmt)
        handler.setFormatter(formatter)
        cls.log.addHandler(handler)

    def setUp(self):
        self.seed = 88
        self.qasmFileName = os.path.join(qiskit.__path__[0],
                                         '../test/python/qasm/example.qasm')
        self.modulePath = os.path.dirname(__file__)
        self.qp = QuantumProgram()

    def tearDown(self):
        pass

    def test_unitary_simulator(self):
        """test generation of circuit unitary"""
        shots = 1024
        self.qp.load_qasm_file(self.qasmFileName, name='example')
        basis_gates = []  # unroll to base gates
        unroller = unroll.Unroller(
            qasm.Qasm(data=self.qp.get_qasm("example")).parse(),
            unroll.JsonBackend(basis_gates))
        circuit = unroller.execute()
        # if we want to manipulate the circuit, we have to convert it to a dict
        circuit = json.loads(circuit.decode())
        #strip measurements from circuit to avoid warnings
        circuit['operations'] = [
            op for op in circuit['operations'] if op['name'] != 'measure'
        ]
        # the simulator is expecting a JSON format, so we need to convert it back to JSON
        job = {'compiled_circuit': json.dumps(circuit).encode()}
        # numpy savetxt is currently prints complex numbers in a way
        # loadtxt can't read. To save file do,
        # fmtstr=['% .4g%+.4gj' for i in range(numCols)]
        # np.savetxt('example_unitary_matrix.dat', numpyMatrix, fmt=fmtstr, delimiter=',')
        expected = np.loadtxt(os.path.join(self.modulePath,
                                           'example_unitary_matrix.dat'),
                              dtype='complex',
                              delimiter=',')
        result = UnitarySimulator(job).run()
        self.assertTrue(
            np.allclose(result['data']['unitary'], expected, rtol=1e-3))

    def profile_unitary_simulator(self):
        """Profile randomly generated circuits.

        Writes profile results to <this_module>.prof as well as recording
        to the log file.

        number of circuits = 100.
        number of operations/circuit in [1, 40]
        number of qubits in [1, 5]
        """
        nCircuits = 100
        maxDepth = 40
        maxQubits = 5
        pr = cProfile.Profile()
        randomCircuits = RandomQasmGenerator(seed=self.seed,
                                             maxDepth=maxDepth,
                                             maxQubits=maxQubits)
        randomCircuits.add_circuits(nCircuits, doMeasure=False)
        self.qp = randomCircuits.getProgram()
        pr.enable()
        self.qp.execute(self.qp.get_circuit_names(),
                        backend='local_unitary_simulator')
        pr.disable()
        sout = io.StringIO()
        ps = pstats.Stats(pr, stream=sout).sort_stats('cumulative')
        self.log.info('------- start profiling UnitarySimulator -----------')
        ps.print_stats()
        self.log.info(sout.getvalue())
        self.log.info('------- stop profiling UnitarySimulator -----------')
        sout.close()
        pr.dump_stats(self.moduleName + '.prof')
class LocalUnitarySimulatorTest(QiskitTestCase):
    """Test local unitary simulator."""

    def setUp(self):
        self.seed = 88
        self.qasm_filename = self._get_resource_path('qasm/example.qasm')
        self.qp = QuantumProgram()

    def tearDown(self):
        pass

    def test_unitary_simulator(self):
        """test generation of circuit unitary"""
        self.qp.load_qasm_file(self.qasm_filename, name='example')
        basis_gates = []  # unroll to base gates
        unroller = unroll.Unroller(
            qasm.Qasm(data=self.qp.get_qasm('example')).parse(),
            unroll.JsonBackend(basis_gates))
        circuit = unroller.execute()
        # strip measurements from circuit to avoid warnings
        circuit['operations'] = [op for op in circuit['operations']
                                 if op['name'] != 'measure']
        # the simulator is expecting a JSON format, so we need to convert it
        # back to JSON
        qobj = {
            'id': 'unitary',
            'config': {
                'max_credits': None,
                'shots': 1,
                'backend_name': 'local_unitary_simulator_py'
            },
            'circuits': [
                {
                    'name': 'test',
                    'compiled_circuit': circuit,
                    'compiled_circuit_qasm': self.qp.get_qasm('example'),
                    'config': {
                        'coupling_map': None,
                        'basis_gates': None,
                        'layout': None,
                        'seed': None
                    }
                }
            ]
        }
        # numpy.savetxt currently prints complex numbers in a way
        # loadtxt can't read. To save file do,
        # fmtstr=['% .4g%+.4gj' for i in range(numCols)]
        # np.savetxt('example_unitary_matrix.dat', numpyMatrix, fmt=fmtstr,
        # delimiter=',')
        expected = np.loadtxt(self._get_resource_path('example_unitary_matrix.dat'),
                              dtype='complex', delimiter=',')
        q_job = QuantumJob(qobj,
                           backend=UnitarySimulatorPy(),
                           preformatted=True)

        result = UnitarySimulatorPy().run(q_job).result()
        self.assertTrue(np.allclose(result.get_unitary('test'),
                                    expected,
                                    rtol=1e-3))

    def test_two_unitary_simulator(self):
        """test running two circuits

        This test is similar to one in test_quantumprogram but doesn't use
        multiprocessing.
        """
        qr = QuantumRegister(2)
        cr = ClassicalRegister(1)
        qc1 = QuantumCircuit(qr, cr)
        qc2 = QuantumCircuit(qr, cr)
        qc1.h(qr)
        qc2.cx(qr[0], qr[1])
        backend = UnitarySimulatorPy()
        qobj = compile([qc1, qc2], backend=backend)
        job = backend.run(QuantumJob(qobj, backend=backend, preformatted=True))
        unitary1 = job.result().get_unitary(qc1)
        unitary2 = job.result().get_unitary(qc2)
        unitaryreal1 = np.array([[0.5, 0.5, 0.5, 0.5], [0.5, -0.5, 0.5, -0.5],
                                 [0.5, 0.5, -0.5, -0.5],
                                 [0.5, -0.5, -0.5, 0.5]])
        unitaryreal2 = np.array([[1, 0, 0, 0], [0, 0, 0, 1],
                                 [0., 0, 1, 0], [0, 1, 0, 0]])
        norm1 = np.trace(np.dot(np.transpose(np.conj(unitaryreal1)), unitary1))
        norm2 = np.trace(np.dot(np.transpose(np.conj(unitaryreal2)), unitary2))
        self.assertAlmostEqual(norm1, 4)
        self.assertAlmostEqual(norm2, 4)

    def profile_unitary_simulator(self):
        """Profile randomly generated circuits.

        Writes profile results to <this_module>.prof as well as recording
        to the log file.

        number of circuits = 100.
        number of operations/circuit in [1, 40]
        number of qubits in [1, 5]
        """
        n_circuits = 100
        max_depth = 40
        max_qubits = 5
        pr = cProfile.Profile()
        random_circuits = RandomQasmGenerator(seed=self.seed,
                                              max_depth=max_depth,
                                              max_qubits=max_qubits)
        random_circuits.add_circuits(n_circuits, do_measure=False)
        self.qp = random_circuits.get_program()
        pr.enable()
        self.qp.execute(self.qp.get_circuit_names(),
                        backend=UnitarySimulatorPy())
        pr.disable()
        sout = io.StringIO()
        ps = pstats.Stats(pr, stream=sout).sort_stats('cumulative')
        self.log.info('------- start profiling UnitarySimulatorPy -----------')
        ps.print_stats()
        self.log.info(sout.getvalue())
        self.log.info('------- stop profiling UnitarySimulatorPy -----------')
        sout.close()
        pr.dump_stats(self.moduleName + '.prof')
Esempio n. 14
0
class LocalQasmSimulatorTest(unittest.TestCase):
    """Test local qasm simulator."""
    @classmethod
    def setUpClass(cls):
        cls.moduleName = os.path.splitext(__file__)[0]
        cls.pdf = PdfPages(cls.moduleName + '.pdf')
        cls.log = logging.getLogger(__name__)
        cls.log.setLevel(logging.INFO)
        logFileName = cls.moduleName + '.log'
        handler = logging.FileHandler(logFileName)
        handler.setLevel(logging.INFO)
        log_fmt = ('{}.%(funcName)s:%(levelname)s:%(asctime)s:'
                   ' %(message)s'.format(cls.__name__))
        formatter = logging.Formatter(log_fmt)
        handler.setFormatter(formatter)
        cls.log.addHandler(handler)

    @classmethod
    def tearDownClass(cls):
        cls.pdf.close()

    def setUp(self):
        self.seed = 88
        self.qasmFileName = os.path.join(qiskit.__path__[0],
                                         '../test/python/qasm/example.qasm')
        self.qp = QuantumProgram()

    def tearDown(self):
        pass

    def test_qasm_simulator_single_shot(self):
        """Test single shot run."""
        shots = 1
        self.qp.load_qasm_file(self.qasmFileName, name='example')
        basis_gates = []  # unroll to base gates
        unroller = unroll.Unroller(
            qasm.Qasm(data=self.qp.get_qasm("example")).parse(),
            unroll.JsonBackend(basis_gates))
        circuit = unroller.execute()
        config = {'shots': shots, 'seed': self.seed}
        job = {'compiled_circuit': circuit, 'config': config}
        result = QasmSimulator(job).run()
        self.assertEqual(result['status'], 'DONE')

    def test_qasm_simulator(self):
        """Test data counts output for single circuit run against reference."""
        shots = 1024
        self.qp.load_qasm_file(self.qasmFileName, name='example')
        basis_gates = []  # unroll to base gates
        unroller = unroll.Unroller(
            qasm.Qasm(data=self.qp.get_qasm("example")).parse(),
            unroll.JsonBackend(basis_gates))
        circuit = unroller.execute()
        config = {'shots': shots, 'seed': self.seed}
        job = {'compiled_circuit': circuit, 'config': config}
        result = QasmSimulator(job).run()
        expected = {
            '100 100': 137,
            '011 011': 131,
            '101 101': 117,
            '111 111': 127,
            '000 000': 131,
            '010 010': 141,
            '110 110': 116,
            '001 001': 124
        }
        self.assertEqual(result['data']['counts'], expected)

    def test_if_statement(self):
        self.log.info('test_if_statement_x')
        shots = 100
        max_qubits = 3
        qp = QuantumProgram()
        qr = qp.create_quantum_register('qr', max_qubits)
        cr = qp.create_classical_register('cr', max_qubits)
        circuit = qp.create_circuit('test_if', [qr], [cr])
        circuit.x(qr[0])
        circuit.x(qr[1])
        circuit.measure(qr[0], cr[0])
        circuit.measure(qr[1], cr[1])
        circuit.x(qr[2]).c_if(cr, 0x3)
        circuit.measure(qr[0], cr[0])
        circuit.measure(qr[1], cr[1])
        circuit.measure(qr[2], cr[2])
        circuit2 = qp.create_circuit('test_if_case_2', [qr], [cr])
        circuit2.x(qr[0])
        circuit2.measure(qr[0], cr[0])
        circuit2.measure(qr[1], cr[1])
        circuit2.x(qr[2]).c_if(cr, 0x3)
        circuit2.measure(qr[0], cr[0])
        circuit2.measure(qr[1], cr[1])
        circuit2.measure(qr[2], cr[2])
        basis_gates = []  # unroll to base gates
        unroller = unroll.Unroller(
            qasm.Qasm(data=qp.get_qasm('test_if')).parse(),
            unroll.JsonBackend(basis_gates))
        ucircuit = unroller.execute()
        unroller = unroll.Unroller(
            qasm.Qasm(data=qp.get_qasm('test_if_case_2')).parse(),
            unroll.JsonBackend(basis_gates))
        ucircuit2 = unroller.execute()
        config = {'shots': shots, 'seed': self.seed}
        job = {'compiled_circuit': ucircuit, 'config': config}
        result_if_true = QasmSimulator(job).run()
        job = {'compiled_circuit': ucircuit2, 'config': config}
        result_if_false = QasmSimulator(job).run()

        self.log.info('result_if_true circuit:')
        self.log.info(circuit.qasm())
        self.log.info('result_if_true={0}'.format(result_if_true))

        del circuit.data[1]
        self.log.info('result_if_false circuit:')
        self.log.info(circuit.qasm())
        self.log.info('result_if_false={0}'.format(result_if_false))
        self.assertTrue(result_if_true['data']['counts']['111'] == 100)
        self.assertTrue(result_if_false['data']['counts']['001'] == 100)

    def test_teleport(self):
        """test teleportation as in tutorials"""

        self.log.info('test_teleport')
        pi = np.pi
        shots = 1000
        qp = QuantumProgram()
        qr = qp.create_quantum_register('qr', 3)
        cr0 = qp.create_classical_register('cr0', 1)
        cr1 = qp.create_classical_register('cr1', 1)
        cr2 = qp.create_classical_register('cr2', 1)
        circuit = qp.create_circuit('teleport', [qr], [cr0, cr1, cr2])
        circuit.h(qr[1])
        circuit.cx(qr[1], qr[2])
        circuit.ry(pi / 4, qr[0])
        circuit.cx(qr[0], qr[1])
        circuit.h(qr[0])
        circuit.barrier(qr)
        circuit.measure(qr[0], cr0[0])
        circuit.measure(qr[1], cr1[0])
        circuit.z(qr[2]).c_if(cr0, 1)
        circuit.x(qr[2]).c_if(cr1, 1)
        circuit.measure(qr[2], cr2[0])
        backend = 'local_qasm_simulator'
        qobj = qp.compile('teleport',
                          backend=backend,
                          shots=shots,
                          seed=self.seed)
        results = qp.run(qobj)
        data = results.get_counts('teleport')
        alice = {}
        bob = {}
        alice['00'] = data['0 0 0'] + data['1 0 0']
        alice['01'] = data['0 1 0'] + data['1 1 0']
        alice['10'] = data['0 0 1'] + data['1 0 1']
        alice['11'] = data['0 1 1'] + data['1 1 1']
        bob['0'] = data['0 0 0'] + data['0 1 0'] + data['0 0 1'] + data['0 1 1']
        bob['1'] = data['1 0 0'] + data['1 1 0'] + data['1 0 1'] + data['1 1 1']
        self.log.info('test_telport: circuit:')
        self.log.info(circuit.qasm())
        self.log.info('test_teleport: data {0}'.format(data))
        self.log.info('test_teleport: alice {0}'.format(alice))
        self.log.info('test_teleport: bob {0}'.format(bob))
        alice_ratio = 1 / np.tan(pi / 8)**2
        bob_ratio = bob['0'] / float(bob['1'])
        error = abs(alice_ratio - bob_ratio) / alice_ratio
        self.log.info('test_teleport: relative error = {0:.4f}'.format(error))
        self.assertLess(error, 0.05)

    def profile_qasm_simulator(self):
        """Profile randomly generated circuits.

        Writes profile results to <this_module>.prof as well as recording
        to the log file.

        number of circuits = 100.
        number of operations/circuit in [1, 40]
        number of qubits in [1, 5]
        """
        seed = 88
        shots = 1024
        nCircuits = 100
        minDepth = 1
        maxDepth = 40
        minQubits = 1
        maxQubits = 5
        pr = cProfile.Profile()
        randomCircuits = RandomQasmGenerator(seed,
                                             minQubits=minQubits,
                                             maxQubits=maxQubits,
                                             minDepth=minDepth,
                                             maxDepth=maxDepth)
        randomCircuits.add_circuits(nCircuits)
        self.qp = randomCircuits.getProgram()
        pr.enable()
        self.qp.execute(self.qp.get_circuit_names(),
                        backend='local_qasm_simulator',
                        shots=shots)
        pr.disable()
        sout = io.StringIO()
        ps = pstats.Stats(pr, stream=sout).sort_stats('cumulative')
        self.log.info('------- start profiling QasmSimulator -----------')
        ps.print_stats()
        self.log.info(sout.getvalue())
        self.log.info('------- stop profiling QasmSimulator -----------')
        sout.close()
        pr.dump_stats(self.moduleName + '.prof')

    def profile_nqubit_speed_grow_depth(self):
        """simulation time vs the number of qubits

        where the circuit depth is 10x the number of simulated
        qubits. Also creates a pdf file with this module name showing a
        plot of the results. Compilation is not included in speed.
        """
        import matplotlib.pyplot as plt
        from matplotlib.ticker import MaxNLocator
        qubitRangeMax = 15
        nQubitList = range(1, qubitRangeMax + 1)
        nCircuits = 10
        shots = 1024
        seed = 88
        maxTime = 30  # seconds; timing stops when simulation time exceeds this number
        fmtStr1 = 'profile_nqubit_speed::nqubits:{0}, backend:{1}, elapsed_time:{2:.2f}'
        fmtStr2 = 'backend:{0}, circuit:{1}, numOps:{2}, result:{3}'
        fmtStr3 = 'minDepth={minDepth}, maxDepth={maxDepth}, num circuits={nCircuits}, shots={shots}'
        backendList = ['local_qasm_simulator', 'local_unitary_simulator']
        if shutil.which('qasm_simulator'):
            backendList.append('local_qasm_cpp_simulator')
        else:
            self.log.info(
                'profile_nqubit_speed::\"qasm_simulator\" executable not in path...skipping'
            )
        fig = plt.figure(0)
        plt.clf()
        ax = fig.add_axes((0.1, 0.25, 0.8, 0.6))
        for i, backend in enumerate(backendList):
            elapsedTime = np.zeros(len(nQubitList))
            if backend is 'local_unitary_simulator':
                doMeasure = False
            else:
                doMeasure = True
            j, timedOut = 0, False
            while j < qubitRangeMax and not timedOut:
                nQubits = nQubitList[j]
                randomCircuits = RandomQasmGenerator(seed,
                                                     minQubits=nQubits,
                                                     maxQubits=nQubits,
                                                     minDepth=nQubits * 10,
                                                     maxDepth=nQubits * 10)
                randomCircuits.add_circuits(nCircuits, doMeasure=doMeasure)
                qp = randomCircuits.getProgram()
                cnames = qp.get_circuit_names()
                qobj = qp.compile(cnames,
                                  backend=backend,
                                  shots=shots,
                                  seed=seed)
                start = time.perf_counter()
                results = qp.run(qobj)
                stop = time.perf_counter()
                elapsedTime[j] = stop - start
                if elapsedTime[j] > maxTime:
                    timedOut = True
                self.log.info(fmtStr1.format(nQubits, backend, elapsedTime[j]))
                if backend is not 'local_unitary_simulator':
                    for name in cnames:
                        self.log.info(
                            fmtStr2.format(backend, name,
                                           len(qp.get_circuit(name)),
                                           results.get_data(name)))
                j += 1
            ax.xaxis.set_major_locator(MaxNLocator(integer=True))
            if backend is 'local_unitary_simulator':
                ax.plot(nQubitList[:j],
                        elapsedTime[:j],
                        label=backend,
                        marker='o')
            else:
                ax.plot(nQubitList[:j],
                        elapsedTime[:j] / shots,
                        label=backend,
                        marker='o')
            ax.set_yscale('log', basey=10)
            ax.set_xlabel('number of qubits')
            ax.set_ylabel('process time/shot')
            ax.set_title('profile_nqubit_speed_grow_depth')
            fig.text(
                0.1, 0.05,
                fmtStr3.format(minDepth='10*nQubits',
                               maxDepth='10*nQubits',
                               nCircuits=nCircuits,
                               shots=shots))
            ax.legend()
        self.pdf.savefig(fig)

    def profile_nqubit_speed_constant_depth(self):
        """simulation time vs the number of qubits

        where the circuit depth is fixed at 40. Also creates a pdf file
        with this module name showing a plot of the results. Compilation
        is not included in speed.
        """
        import matplotlib.pyplot as plt
        from matplotlib.ticker import MaxNLocator
        qubitRangeMax = 15
        nQubitList = range(1, qubitRangeMax + 1)
        maxDepth = 40
        minDepth = 40
        nCircuits = 10
        shots = 1024
        seed = 88
        maxTime = 30  # seconds; timing stops when simulation time exceeds this number
        fmtStr1 = 'profile_nqubit_speed::nqubits:{0}, backend:{1}, elapsed_time:{2:.2f}'
        fmtStr2 = 'backend:{0}, circuit:{1}, numOps:{2}, result:{3}'
        fmtStr3 = 'minDepth={minDepth}, maxDepth={maxDepth}, num circuits={nCircuits}, shots={shots}'
        backendList = ['local_qasm_simulator', 'local_unitary_simulator']
        if shutil.which('qasm_simulator'):
            backendList.append('local_qasm_cpp_simulator')
        else:
            self.log.info(
                'profile_nqubit_speed::\"qasm_simulator\" executable not in path...skipping'
            )
        fig = plt.figure(0)
        plt.clf()
        ax = fig.add_axes((0.1, 0.2, 0.8, 0.6))
        for i, backend in enumerate(backendList):
            elapsedTime = np.zeros(len(nQubitList))
            if backend is 'local_unitary_simulator':
                doMeasure = False
            else:
                doMeasure = True
            j, timedOut = 0, False
            while j < qubitRangeMax and not timedOut:
                nQubits = nQubitList[j]
                randomCircuits = RandomQasmGenerator(seed,
                                                     minQubits=nQubits,
                                                     maxQubits=nQubits,
                                                     minDepth=minDepth,
                                                     maxDepth=maxDepth)
                randomCircuits.add_circuits(nCircuits, doMeasure=doMeasure)
                qp = randomCircuits.getProgram()
                cnames = qp.get_circuit_names()
                qobj = qp.compile(cnames,
                                  backend=backend,
                                  shots=shots,
                                  seed=seed)
                start = time.perf_counter()
                results = qp.run(qobj)
                stop = time.perf_counter()
                elapsedTime[j] = stop - start
                if elapsedTime[j] > maxTime:
                    timedOut = True
                self.log.info(fmtStr1.format(nQubits, backend, elapsedTime[j]))
                if backend is not 'local_unitary_simulator':
                    for name in cnames:
                        self.log.info(
                            fmtStr2.format(backend, name,
                                           len(qp.get_circuit(name)),
                                           results.get_data(name)))
                j += 1
            ax.xaxis.set_major_locator(MaxNLocator(integer=True))
            if backend is 'local_unitary_simulator':
                ax.plot(nQubitList[:j],
                        elapsedTime[:j],
                        label=backend,
                        marker='o')
            else:
                ax.plot(nQubitList[:j],
                        elapsedTime[:j] / shots,
                        label=backend,
                        marker='o')
            ax.set_yscale('log', basey=10)
            ax.set_xlabel('number of qubits')
            ax.set_ylabel('process time/shot')
            ax.set_title('profile_nqubit_speed_constant_depth')
            fig.text(
                0.1, 0.05,
                fmtStr3.format(minDepth=minDepth,
                               maxDepth=maxDepth,
                               nCircuits=nCircuits,
                               shots=shots))
            ax.legend()
        self.pdf.savefig(fig)
class TestLocalQasmSimulatorPy(QiskitTestCase):
    """Test local_qasm_simulator_py."""

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        if do_profiling:
            cls.pdf = PdfPages(cls.moduleName + '.pdf')

    @classmethod
    def tearDownClass(cls):
        if do_profiling:
            cls.pdf.close()

    def setUp(self):
        self.seed = 88
        self.qasm_filename = self._get_resource_path('qasm/example.qasm')
        self.qp = QuantumProgram()
        self.qp.load_qasm_file(self.qasm_filename, name='example')
        basis_gates = []  # unroll to base gates
        unroller = unroll.Unroller(
            qasm.Qasm(data=self.qp.get_qasm('example')).parse(),
            unroll.JsonBackend(basis_gates))
        circuit = unroller.execute()
        circuit_config = {'coupling_map': None,
                          'basis_gates': 'u1,u2,u3,cx,id',
                          'layout': None,
                          'seed': self.seed}
        resources = {'max_credits': 3}
        self.qobj = {'id': 'test_sim_single_shot',
                     'config': {
                         'max_credits': resources['max_credits'],
                         'shots': 1024,
                         'backend_name': 'local_qasm_simulator_py',
                     },
                     'circuits': [
                         {
                             'name': 'test',
                             'compiled_circuit': circuit,
                             'compiled_circuit_qasm': None,
                             'config': circuit_config
                         }
                     ]}
        self.q_job = QuantumJob(self.qobj,
                                backend=QasmSimulatorPy(),
                                circuit_config=circuit_config,
                                seed=self.seed,
                                resources=resources,
                                preformatted=True)

    def tearDown(self):
        pass

    def test_qasm_simulator_single_shot(self):
        """Test single shot run."""
        shots = 1
        self.qobj['config']['shots'] = shots
        result = QasmSimulatorPy().run(self.q_job).result()
        self.assertEqual(result.get_status(), 'COMPLETED')

    def test_qasm_simulator(self):
        """Test data counts output for single circuit run against reference."""
        result = QasmSimulatorPy().run(self.q_job).result()
        shots = 1024
        threshold = 0.04 * shots
        counts = result.get_counts('test')
        target = {'100 100': shots / 8, '011 011': shots / 8,
                  '101 101': shots / 8, '111 111': shots / 8,
                  '000 000': shots / 8, '010 010': shots / 8,
                  '110 110': shots / 8, '001 001': shots / 8}
        self.assertDictAlmostEqual(counts, target, threshold)

    def test_if_statement(self):
        self.log.info('test_if_statement_x')
        shots = 100
        max_qubits = 3
        qp = QuantumProgram()
        qr = qp.create_quantum_register('qr', max_qubits)
        cr = qp.create_classical_register('cr', max_qubits)
        circuit_if_true = qp.create_circuit('test_if_true', [qr], [cr])
        circuit_if_true.x(qr[0])
        circuit_if_true.x(qr[1])
        circuit_if_true.measure(qr[0], cr[0])
        circuit_if_true.measure(qr[1], cr[1])
        circuit_if_true.x(qr[2]).c_if(cr, 0x3)
        circuit_if_true.measure(qr[0], cr[0])
        circuit_if_true.measure(qr[1], cr[1])
        circuit_if_true.measure(qr[2], cr[2])
        circuit_if_false = qp.create_circuit('test_if_false', [qr], [cr])
        circuit_if_false.x(qr[0])
        circuit_if_false.measure(qr[0], cr[0])
        circuit_if_false.measure(qr[1], cr[1])
        circuit_if_false.x(qr[2]).c_if(cr, 0x3)
        circuit_if_false.measure(qr[0], cr[0])
        circuit_if_false.measure(qr[1], cr[1])
        circuit_if_false.measure(qr[2], cr[2])
        basis_gates = []  # unroll to base gates
        unroller = unroll.Unroller(
            qasm.Qasm(data=qp.get_qasm('test_if_true')).parse(),
            unroll.JsonBackend(basis_gates))
        ucircuit_true = unroller.execute()
        unroller = unroll.Unroller(
            qasm.Qasm(data=qp.get_qasm('test_if_false')).parse(),
            unroll.JsonBackend(basis_gates))
        ucircuit_false = unroller.execute()
        qobj = {
            'id': 'test_if_qobj',
            'config': {
                'max_credits': 3,
                'shots': shots,
                'backend_name': 'local_qasm_simulator_py',
            },
            'circuits': [
                {
                    'name': 'test_if_true',
                    'compiled_circuit': ucircuit_true,
                    'compiled_circuit_qasm': None,
                    'config': {
                        'coupling_map': None,
                        'basis_gates': 'u1,u2,u3,cx,id',
                        'layout': None,
                        'seed': None
                    }
                },
                {
                    'name': 'test_if_false',
                    'compiled_circuit': ucircuit_false,
                    'compiled_circuit_qasm': None,
                    'config': {
                        'coupling_map': None,
                        'basis_gates': 'u1,u2,u3,cx,id',
                        'layout': None,
                        'seed': None
                    }
                }
            ]
        }
        q_job = QuantumJob(qobj, backend=QasmSimulatorPy(), preformatted=True)
        result = QasmSimulatorPy().run(q_job).result()
        result_if_true = result.get_data('test_if_true')
        self.log.info('result_if_true circuit:')
        self.log.info(circuit_if_true.qasm())
        self.log.info('result_if_true=%s', result_if_true)

        result_if_false = result.get_data('test_if_false')
        self.log.info('result_if_false circuit:')
        self.log.info(circuit_if_false.qasm())
        self.log.info('result_if_false=%s', result_if_false)
        self.assertTrue(result_if_true['counts']['111'] == 100)
        self.assertTrue(result_if_false['counts']['001'] == 100)

    @unittest.skipIf(version_info.minor == 5, "Due to gate ordering issues with Python 3.5 \
                                         we have to disable this test until fixed")
    def test_teleport(self):
        """test teleportation as in tutorials"""

        self.log.info('test_teleport')
        pi = np.pi
        shots = 1000
        qp = QuantumProgram()
        qr = qp.create_quantum_register('qr', 3)
        cr0 = qp.create_classical_register('cr0', 1)
        cr1 = qp.create_classical_register('cr1', 1)
        cr2 = qp.create_classical_register('cr2', 1)
        circuit = qp.create_circuit('teleport', [qr],
                                    [cr0, cr1, cr2])
        circuit.h(qr[1])
        circuit.cx(qr[1], qr[2])
        circuit.ry(pi/4, qr[0])
        circuit.cx(qr[0], qr[1])
        circuit.h(qr[0])
        circuit.barrier(qr)
        circuit.measure(qr[0], cr0[0])
        circuit.measure(qr[1], cr1[0])
        circuit.z(qr[2]).c_if(cr0, 1)
        circuit.x(qr[2]).c_if(cr1, 1)
        circuit.measure(qr[2], cr2[0])
        backend = 'local_qasm_simulator_py'
        qobj = qp.compile('teleport', backend=backend, shots=shots,
                          seed=self.seed)
        results = qp.run(qobj)
        data = results.get_counts('teleport')
        alice = {}
        bob = {}
        alice['00'] = data['0 0 0'] + data['1 0 0']
        alice['01'] = data['0 1 0'] + data['1 1 0']
        alice['10'] = data['0 0 1'] + data['1 0 1']
        alice['11'] = data['0 1 1'] + data['1 1 1']
        bob['0'] = data['0 0 0'] + data['0 1 0'] + data['0 0 1'] + data['0 1 1']
        bob['1'] = data['1 0 0'] + data['1 1 0'] + data['1 0 1'] + data['1 1 1']
        self.log.info('test_telport: circuit:')
        self.log.info(circuit.qasm())
        self.log.info('test_teleport: data %s', data)
        self.log.info('test_teleport: alice %s', alice)
        self.log.info('test_teleport: bob %s', bob)
        alice_ratio = 1/np.tan(pi/8)**2
        bob_ratio = bob['0']/float(bob['1'])
        error = abs(alice_ratio - bob_ratio) / alice_ratio
        self.log.info('test_teleport: relative error = %s', error)
        self.assertLess(error, 0.05)

    @unittest.skipIf(not do_profiling, "skipping simulator profiling.")
    def profile_qasm_simulator(self):
        """Profile randomly generated circuits.

        Writes profile results to <this_module>.prof as well as recording
        to the log file.

        number of circuits = 100.
        number of operations/circuit in [1, 40]
        number of qubits in [1, 5]
        """
        seed = 88
        shots = 1024
        n_circuits = 100
        min_depth = 1
        max_depth = 40
        min_qubits = 1
        max_qubits = 5
        pr = cProfile.Profile()
        random_circuits = RandomQasmGenerator(seed,
                                              min_qubits=min_qubits,
                                              max_qubits=max_qubits,
                                              min_depth=min_depth,
                                              max_depth=max_depth)
        random_circuits.add_circuits(n_circuits)
        self.qp = random_circuits.get_program()
        pr.enable()
        self.qp.execute(self.qp.get_circuit_names(),
                        backend='local_qasm_simulator_py',
                        shots=shots)
        pr.disable()
        sout = io.StringIO()
        ps = pstats.Stats(pr, stream=sout).sort_stats('cumulative')
        self.log.info('------- start profiling QasmSimulatorPy -----------')
        ps.print_stats()
        self.log.info(sout.getvalue())
        self.log.info('------- stop profiling QasmSimulatorPy -----------')
        sout.close()
        pr.dump_stats(self.moduleName + '.prof')

    @unittest.skipIf(not do_profiling, "skipping simulator profiling.")
    def profile_nqubit_speed_grow_depth(self):
        """simulation time vs the number of qubits

        where the circuit depth is 10x the number of simulated
        qubits. Also creates a pdf file with this module name showing a
        plot of the results. Compilation is not included in speed.
        """
        import matplotlib.pyplot as plt
        from matplotlib.ticker import MaxNLocator
        qubit_range_max = 15
        n_qubit_list = range(1, qubit_range_max + 1)
        n_circuits = 10
        shots = 1024
        seed = 88
        max_time = 30  # seconds; timing stops when simulation time exceeds this number
        fmt_str1 = 'profile_nqubit_speed::nqubits:{0}, backend:{1}, elapsed_time:{2:.2f}'
        fmt_str2 = 'backend:{0}, circuit:{1}, numOps:{2}, result:{3}'
        fmt_str3 = 'minDepth={minDepth}, maxDepth={maxDepth}, num circuits={nCircuits},' \
                   'shots={shots}'
        backend_list = ['local_qasm_simulator_py', 'local_unitary_simulator_py']
        if shutil.which('qasm_simulator'):
            backend_list.append('local_qasm_simulator_cpp')
        else:
            self.log.info('profile_nqubit_speed::\"qasm_simulator\" executable'
                          'not in path...skipping')
        fig = plt.figure(0)
        plt.clf()
        ax = fig.add_axes((0.1, 0.25, 0.8, 0.6))
        for _, backend in enumerate(backend_list):
            elapsed_time = np.zeros(len(n_qubit_list))
            if backend == 'local_unitary_simulator_py':
                do_measure = False
            else:
                do_measure = True
            j, timed_out = 0, False
            while j < qubit_range_max and not timed_out:
                n_qubits = n_qubit_list[j]
                random_circuits = RandomQasmGenerator(seed,
                                                      min_qubits=n_qubits,
                                                      max_qubits=n_qubits,
                                                      min_depth=n_qubits * 10,
                                                      max_depth=n_qubits * 10)
                random_circuits.add_circuits(n_circuits, do_measure=do_measure)
                qp = random_circuits.get_program()
                c_names = qp.get_circuit_names()
                qobj = qp.compile(c_names, backend=backend, shots=shots,
                                  seed=seed)
                start = time.perf_counter()
                results = qp.run(qobj)
                stop = time.perf_counter()
                elapsed_time[j] = stop - start
                if elapsed_time[j] > max_time:
                    timed_out = True
                self.log.info(fmt_str1.format(n_qubits, backend, elapsed_time[j]))
                if backend != 'local_unitary_simulator_py':
                    for name in c_names:
                        log_str = fmt_str2.format(
                            backend, name, len(qp.get_circuit(name)),
                            results.get_data(name))
                        self.log.info(log_str)
                j += 1
            ax.xaxis.set_major_locator(MaxNLocator(integer=True))
            if backend == 'local_unitary_simulator_py':
                ax.plot(n_qubit_list[:j], elapsed_time[:j], label=backend, marker='o')
            else:
                ax.plot(n_qubit_list[:j], elapsed_time[:j]/shots, label=backend,
                        marker='o')
            ax.set_yscale('log', basey=10)
            ax.set_xlabel('number of qubits')
            ax.set_ylabel('process time/shot')
            ax.set_title('profile_nqubit_speed_grow_depth')
            fig.text(0.1, 0.05,
                     fmt_str3.format(minDepth='10*nQubits', maxDepth='10*nQubits',
                                     nCircuits=n_circuits, shots=shots))
            ax.legend()
        self.pdf.savefig(fig)

    @unittest.skipIf(not do_profiling, "skipping simulator profiling.")
    def profile_nqubit_speed_constant_depth(self):
        """simulation time vs the number of qubits

        where the circuit depth is fixed at 40. Also creates a pdf file
        with this module name showing a plot of the results. Compilation
        is not included in speed.
        """
        import matplotlib.pyplot as plt
        from matplotlib.ticker import MaxNLocator
        qubit_range_max = 15
        n_qubit_list = range(1, qubit_range_max + 1)
        max_depth = 40
        min_depth = 40
        n_circuits = 10
        shots = 1024
        seed = 88
        max_time = 30  # seconds; timing stops when simulation time exceeds this number
        fmt_str1 = 'profile_nqubit_speed::nqubits:{0}, backend:{1},' \
                   'elapsed_time:{2:.2f}'
        fmt_str2 = 'backend:{0}, circuit:{1}, numOps:{2}, result:{3}'
        fmt_str3 = 'minDepth={minDepth}, maxDepth={maxDepth},' \
                   'num circuits={nCircuits}, shots={shots}'
        backend_list = ['local_qasm_simulator_py', 'local_unitary_simulator_py']
        if shutil.which('qasm_simulator'):
            backend_list.append('local_qasm_simulator_cpp')
        else:
            self.log.info('profile_nqubit_speed::\"qasm_simulator\" executable'
                          'not in path...skipping')
        fig = plt.figure(0)
        plt.clf()
        ax = fig.add_axes((0.1, 0.2, 0.8, 0.6))
        for _, backend in enumerate(backend_list):
            elapsedTime = np.zeros(len(n_qubit_list))
            if backend == 'local_unitary_simulator_py':
                doMeasure = False
            else:
                doMeasure = True
            j, timedOut = 0, False
            while j < qubit_range_max and not timedOut:
                nQubits = n_qubit_list[j]
                randomCircuits = RandomQasmGenerator(seed,
                                                     min_qubits=nQubits,
                                                     max_qubits=nQubits,
                                                     min_depth=min_depth,
                                                     max_depth=max_depth)
                randomCircuits.add_circuits(n_circuits, do_measure=doMeasure)
                qp = randomCircuits.get_program()
                cnames = qp.get_circuit_names()
                qobj = qp.compile(cnames, backend=backend, shots=shots, seed=seed)
                start = time.perf_counter()
                results = qp.run(qobj)
                stop = time.perf_counter()
                elapsedTime[j] = stop - start
                if elapsedTime[j] > max_time:
                    timedOut = True
                self.log.info(fmt_str1.format(nQubits, backend, elapsedTime[j]))
                if backend != 'local_unitary_simulator_py':
                    for name in cnames:
                        log_str = fmt_str2.format(
                            backend, name, len(qp.get_circuit(name)),
                            results.get_data(name))
                        self.log.info(log_str)
                j += 1
            ax.xaxis.set_major_locator(MaxNLocator(integer=True))
            if backend == 'local_unitary_simulator_py':
                ax.plot(n_qubit_list[:j], elapsedTime[:j], label=backend, marker='o')
            else:
                ax.plot(n_qubit_list[:j], elapsedTime[:j]/shots, label=backend,
                        marker='o')
            ax.set_yscale('log', basey=10)
            ax.set_xlabel('number of qubits')
            ax.set_ylabel('process time/shot')
            ax.set_title('profile_nqubit_speed_constant_depth')
            fig.text(0.1, 0.05,
                     fmt_str3.format(minDepth=min_depth, maxDepth=max_depth,
                                     nCircuits=n_circuits, shots=shots))
            ax.legend()
        self.pdf.savefig(fig)
Esempio n. 16
0
class LocalUnitarySimulatorTest(QiskitTestCase):
    """Test local unitary simulator."""
    def setUp(self):
        self.seed = 88
        self.qasm_filename = self._get_resource_path('qasm/example.qasm')
        self.qp = QuantumProgram()

    def tearDown(self):
        pass

    def test_unitary_simulator(self):
        """test generation of circuit unitary"""
        self.qp.load_qasm_file(self.qasm_filename, name='example')
        basis_gates = []  # unroll to base gates
        unroller = unroll.Unroller(
            qasm.Qasm(data=self.qp.get_qasm('example')).parse(),
            unroll.JsonBackend(basis_gates))
        circuit = unroller.execute()
        # strip measurements from circuit to avoid warnings
        circuit['operations'] = [
            op for op in circuit['operations'] if op['name'] != 'measure'
        ]
        # the simulator is expecting a JSON format, so we need to convert it
        # back to JSON
        qobj = {
            'id':
            'unitary',
            'config': {
                'max_credits': None,
                'shots': 1,
                'backend_name': 'local_unitary_simulator_py'
            },
            'circuits': [{
                'name': 'test',
                'compiled_circuit': circuit,
                'compiled_circuit_qasm': self.qp.get_qasm('example'),
                'config': {
                    'coupling_map': None,
                    'basis_gates': None,
                    'layout': None,
                    'seed': None
                }
            }]
        }
        # numpy.savetxt currently prints complex numbers in a way
        # loadtxt can't read. To save file do,
        # fmtstr=['% .4g%+.4gj' for i in range(numCols)]
        # np.savetxt('example_unitary_matrix.dat', numpyMatrix, fmt=fmtstr,
        # delimiter=',')
        expected = np.loadtxt(
            self._get_resource_path('example_unitary_matrix.dat'),
            dtype='complex',
            delimiter=',')
        q_job = QuantumJob(qobj,
                           backend=UnitarySimulatorPy(),
                           preformatted=True)

        result = UnitarySimulatorPy().run(q_job).result()
        self.assertTrue(
            np.allclose(result.get_unitary('test'), expected, rtol=1e-3))

    def test_two_unitary_simulator(self):
        """test running two circuits

        This test is similar to one in test_quantumprogram but doesn't use
        multiprocessing.
        """
        qr = QuantumRegister(2)
        cr = ClassicalRegister(1)
        qc1 = QuantumCircuit(qr, cr)
        qc2 = QuantumCircuit(qr, cr)
        qc1.h(qr)
        qc2.cx(qr[0], qr[1])
        backend = UnitarySimulatorPy()
        qobj = compile([qc1, qc2], backend=backend)
        job = backend.run(QuantumJob(qobj, backend=backend, preformatted=True))
        unitary1 = job.result().get_unitary(qc1)
        unitary2 = job.result().get_unitary(qc2)
        unitaryreal1 = np.array([[0.5, 0.5, 0.5, 0.5], [0.5, -0.5, 0.5, -0.5],
                                 [0.5, 0.5, -0.5, -0.5],
                                 [0.5, -0.5, -0.5, 0.5]])
        unitaryreal2 = np.array([[1, 0, 0, 0], [0, 0, 0, 1], [0., 0, 1, 0],
                                 [0, 1, 0, 0]])
        norm1 = np.trace(np.dot(np.transpose(np.conj(unitaryreal1)), unitary1))
        norm2 = np.trace(np.dot(np.transpose(np.conj(unitaryreal2)), unitary2))
        self.assertAlmostEqual(norm1, 4)
        self.assertAlmostEqual(norm2, 4)

    def profile_unitary_simulator(self):
        """Profile randomly generated circuits.

        Writes profile results to <this_module>.prof as well as recording
        to the log file.

        number of circuits = 100.
        number of operations/circuit in [1, 40]
        number of qubits in [1, 5]
        """
        n_circuits = 100
        max_depth = 40
        max_qubits = 5
        pr = cProfile.Profile()
        random_circuits = RandomQasmGenerator(seed=self.seed,
                                              max_depth=max_depth,
                                              max_qubits=max_qubits)
        random_circuits.add_circuits(n_circuits, do_measure=False)
        self.qp = random_circuits.get_program()
        pr.enable()
        self.qp.execute(self.qp.get_circuit_names(),
                        backend=UnitarySimulatorPy())
        pr.disable()
        sout = io.StringIO()
        ps = pstats.Stats(pr, stream=sout).sort_stats('cumulative')
        self.log.info('------- start profiling UnitarySimulatorPy -----------')
        ps.print_stats()
        self.log.info(sout.getvalue())
        self.log.info('------- stop profiling UnitarySimulatorPy -----------')
        sout.close()
        pr.dump_stats(self.moduleName + '.prof')
Esempio n. 17
0
class LocalUnitarySimulatorTest(QiskitTestCase):
    """Test local unitary simulator."""
    def setUp(self):
        self.seed = 88
        self.qasmFileName = self._get_resource_path('qasm/example.qasm')
        self.qp = QuantumProgram()

    def tearDown(self):
        pass

    def test_unitary_simulator(self):
        """test generation of circuit unitary"""
        shots = 1024
        self.qp.load_qasm_file(self.qasmFileName, name='example')
        basis_gates = []  # unroll to base gates
        unroller = unroll.Unroller(
            qasm.Qasm(data=self.qp.get_qasm('example')).parse(),
            unroll.JsonBackend(basis_gates))
        circuit = unroller.execute()
        #strip measurements from circuit to avoid warnings
        circuit['operations'] = [
            op for op in circuit['operations'] if op['name'] != 'measure'
        ]
        # the simulator is expecting a JSON format, so we need to convert it back to JSON
        qobj = {
            'id':
            'unitary',
            'config': {
                'max_credits': None,
                'shots': 1,
                'backend': 'local_unitary_simulator'
            },
            'circuits': [{
                'name': 'test',
                'compiled_circuit': circuit,
                'compiled_circuit_qasm': self.qp.get_qasm('example'),
                'config': {
                    'coupling_map': None,
                    'basis_gates': None,
                    'layout': None,
                    'seed': None
                }
            }]
        }
        # numpy.savetxt currently prints complex numbers in a way
        # loadtxt can't read. To save file do,
        # fmtstr=['% .4g%+.4gj' for i in range(numCols)]
        # np.savetxt('example_unitary_matrix.dat', numpyMatrix, fmt=fmtstr, delimiter=',')
        expected = np.loadtxt(
            self._get_resource_path('example_unitary_matrix.dat'),
            dtype='complex',
            delimiter=',')
        result = UnitarySimulator(qobj).run()
        self.assertTrue(
            np.allclose(result.get_data('test')['unitary'],
                        expected,
                        rtol=1e-3))

    def profile_unitary_simulator(self):
        """Profile randomly generated circuits.

        Writes profile results to <this_module>.prof as well as recording
        to the log file.

        number of circuits = 100.
        number of operations/circuit in [1, 40]
        number of qubits in [1, 5]
        """
        nCircuits = 100
        maxDepth = 40
        maxQubits = 5
        pr = cProfile.Profile()
        randomCircuits = RandomQasmGenerator(seed=self.seed,
                                             maxDepth=maxDepth,
                                             maxQubits=maxQubits)
        randomCircuits.add_circuits(nCircuits, doMeasure=False)
        self.qp = randomCircuits.getProgram()
        pr.enable()
        self.qp.execute(self.qp.get_circuit_names(),
                        backend='local_unitary_simulator')
        pr.disable()
        sout = io.StringIO()
        ps = pstats.Stats(pr, stream=sout).sort_stats('cumulative')
        self.log.info('------- start profiling UnitarySimulator -----------')
        ps.print_stats()
        self.log.info(sout.getvalue())
        self.log.info('------- stop profiling UnitarySimulator -----------')
        sout.close()
        pr.dump_stats(self.moduleName + '.prof')