Exemple #1
0
 def run(self, q_job):
     """Run circuits in q_job"""
     # Generating a string id for the job
     result_list = []
     qobj = q_job.qobj
     self._validate(qobj)
     self._sim = Simulator(gate_fusion=True)
     if 'seed' in qobj['config']:
         self._seed = qobj['config']['seed']
         self._sim._simulator = CppSim(self._seed)
     else:
         self._seed = random.getrandbits(32)
     self._shots = qobj['config']['shots']
     start = time.time()
     for circuit in qobj['circuits']:
         result_list.append(self.run_circuit(circuit))
     end = time.time()
     result = {
         'backend': self._configuration['name'],
         'id': qobj['id'],
         'result': result_list,
         'status': 'COMPLETED',
         'success': True,
         'time_taken': (end - start)
     }
     return Result(result, qobj)
Exemple #2
0
def sim(request):
    if request.param == "cpp_simulator":
        from projectq.backends._sim._cppsim import Simulator as CppSim
        sim = Simulator(gate_fusion=True)
        sim._simulator = CppSim(1)
        return sim
    if request.param == "py_simulator":
        from projectq.backends._sim._pysim import Simulator as PySim
        sim = Simulator()
        sim._simulator = PySim(1)
        return sim
Exemple #3
0
def sim(request):
    if request.param == "cpp_simulator":
        from projectq.backends._sim._cppsim import Simulator as CppSim
        sim = Simulator(gate_fusion=True)
        sim._simulator = CppSim(1)
        # If an ImportError occurs, the C++ simulator was either not installed
        # or compiled for a different Python version.
        return sim
    if request.param == "py_simulator":
        from projectq.backends._sim._pysim import Simulator as PySim
        sim = Simulator()
        sim._simulator = PySim(1)
        return sim
Exemple #4
0
def test_simulator_constant_math_emulation():
    if "cpp_simulator" not in get_available_simulators():
        pytest.skip("No C++ simulator")
        return

    results = [[[1, 1, 0, 0, 0]], [[0, 1, 0, 0, 0]], [[0, 1, 1, 1, 0]]]

    import projectq.backends._sim._simulator as _sim
    from projectq.backends._sim._pysim import Simulator as PySim
    from projectq.backends._sim._cppsim import Simulator as CppSim
    from projectq.libs.math import (AddConstant, AddConstantModN,
                                    MultiplyByConstantModN)

    def gate_filter(eng, cmd):
        g = cmd.gate
        if isinstance(g, BasicMathGate):
            return False
        return eng.next_engine.is_available(cmd)

    def run_simulation(sim):
        eng = MainEngine(sim, [])
        quint = eng.allocate_qureg(5)
        AddConstant(3) | quint
        All(Measure) | quint
        eng.flush()
        results[0].append([int(qb) for qb in quint])

        AddConstantModN(4, 5) | quint
        All(Measure) | quint
        eng.flush()
        results[1].append([int(qb) for qb in quint])

        MultiplyByConstantModN(15, 16) | quint
        All(Measure) | quint
        eng.flush()
        results[2].append([int(qb) for qb in quint])

    cppsim = Simulator(gate_fusion=False)
    cppsim._simulator = CppSim(1)
    run_simulation(cppsim)

    _sim.FALLBACK_TO_PYSIM = True
    pysim = Simulator()
    pysim._simulator = PySim(1)
    # run_simulation(pysim)

    for result in results:
        ref = result[0]
        for res in result[1:]:
            assert ref == res
Exemple #5
0
    def _run_job(self, job_id, qobj):
        """Run circuits in qobj and return the result

            Args:
                qobj (Qobj): Qobj structure
                job_id (str): A job id

            Returns:
                qiskit.Result: Result is a class including the information to be returned to users.
                    Specifically, result_list in the return contains the essential information,
                    which looks like this::

                        [{'data':
                        {
                          'counts': {'000': 40, '111': 60}
                        },
                        'status': 'DONE'
                        }]
        """

        result_list = []
        self._validate(qobj)
        self._sim = Simulator(gate_fusion=True)
        if hasattr(qobj.config, 'seed'):
            self._seed = qobj.config.seed
            self._sim._simulator = CppSim(self._seed)
        else:
            self._seed = random.getrandbits(32)
        self._shots = qobj.config.shots
        start = time.time()
        for circuit in qobj.experiments:
            result_list.append(self.run_circuit(circuit))
        end = time.time()
        job_id = str(uuid.uuid4())

        result = {
            'backend_name': self._configuration.backend_name,
            'backend_version': '0.1.0',
            'qobj_id': qobj.qobj_id,
            'job_id': job_id,
            'results': result_list,
            'status': 'COMPLETED',
            'success': True,
            'time_taken': (end - start)
        }
        return Result.from_dict(result)
 def run(self, q_job):
     """Run circuits in q_job"""
     # Generating a string id for the job
     job_id = str(uuid.uuid4())
     result_list = []
     qobj = q_job.qobj
     self._sim = Simulator(gate_fusion=True)
     if 'seed' in qobj['config']:
         self._seed = qobj['config']['seed']
         self._sim._simulator = CppSim(self._seed)
     else:
         self._seed = random.getrandbits(32)
     self._shots = qobj['config']['shots']
     for circuit in qobj['circuits']:
         result_list.append(self.run_circuit(circuit))
     return Result({'job_id': job_id, 'result': result_list,
                    'status': 'COMPLETED'},
                   qobj)
Exemple #7
0
    def run_circuit(self, circuit):
        """Run a circuit and return a single Result.

        Args:
            circuit (dict): JSON circuit from qobj circuits list

        Returns:
            dict: A dictionary of results which looks something like::

                {
                "data":
                    {  #### DATA CAN BE A DIFFERENT DICTIONARY FOR EACH BACKEND ####
                    "counts": {'00000': XXXX, '00001': XXXXX},
                    "time"  : xx.xxxxxxxx
                    },
                "status": --status (string)--
                }
        Raises:
            SimulatorError: if an error occurred.
        """
        # pylint: disable=expression-not-assigned,pointless-statement
        ccircuit = circuit['compiled_circuit']
        self._number_of_qubits = ccircuit['header']['number_of_qubits']
        self._number_of_clbits = ccircuit['header']['number_of_clbits']
        self._statevector = 0
        self._classical_state = 0
        cl_reg_index = []  # starting bit index of classical register
        cl_reg_nbits = []  # number of bits in classical register
        clbit_index = 0
        qobj_quregs = OrderedDict(
            _get_register_specs(ccircuit['header']['qubit_labels']))
        eng = MainEngine(backend=self._sim)
        for cl_reg in ccircuit['header']['clbit_labels']:
            cl_reg_nbits.append(cl_reg[1])
            cl_reg_index.append(clbit_index)
            clbit_index += cl_reg[1]
        # let circuit seed override qobj default
        if 'config' in circuit:
            if 'seed' in circuit['config']:
                if circuit['config']['seed'] is not None:
                    self._sim._simulator = CppSim(circuit['config']['seed'])
        outcomes = []
        start = time.time()
        for _ in range(self._shots):
            self._statevector = np.zeros(1 << self._number_of_qubits,
                                         dtype=complex)
            self._statevector[0] = 1
            # initialize starting state
            self._classical_state = 0
            unmeasured_qubits = list(range(self._number_of_qubits))
            projq_qureg_dict = OrderedDict(
                ((key, eng.allocate_qureg(size))
                 for key, size in qobj_quregs.items()))
            qureg = [
                qubit for sublist in projq_qureg_dict.values()
                for qubit in sublist
            ]
            # Do each operation in this shot
            for operation in ccircuit['operations']:
                if 'conditional' in operation:
                    mask = int(operation['conditional']['mask'], 16)
                    if mask > 0:
                        value = self._classical_state & mask
                        while (mask & 0x1) == 0:
                            mask >>= 1
                            value >>= 1
                        if value != int(operation['conditional']['val'], 16):
                            continue
                # Check if single  gate
                if operation['name'] in ['U', 'u3']:
                    params = operation['params']
                    qubit = qureg[operation['qubits'][0]]
                    Rz(params[2]) | qubit
                    Ry(params[0]) | qubit
                    Rz(params[1]) | qubit
                elif operation['name'] in ['u1']:
                    params = operation['params']
                    qubit = qureg[operation['qubits'][0]]
                    Rz(params[0]) | qubit
                elif operation['name'] in ['u2']:
                    params = operation['params']
                    qubit = qureg[operation['qubits'][0]]
                    Rz(params[1] - np.pi / 2) | qubit
                    Rx(np.pi / 2) | qubit
                    Rz(params[0] + np.pi / 2) | qubit
                elif operation['name'] == 't':
                    qubit = qureg[operation['qubits'][0]]
                    T | qubit
                elif operation['name'] == 'h':
                    qubit = qureg[operation['qubits'][0]]
                    H | qubit
                elif operation['name'] == 's':
                    qubit = qureg[operation['qubits'][0]]
                    S | qubit
                elif operation['name'] in ['CX', 'cx']:
                    qubit0 = qureg[operation['qubits'][0]]
                    qubit1 = qureg[operation['qubits'][1]]
                    CX | (qubit0, qubit1)
                elif operation['name'] in ['id', 'u0']:
                    pass
                # Check if measure
                elif operation['name'] == 'measure':
                    qubit_index = operation['qubits'][0]
                    qubit = qureg[qubit_index]
                    clbit = operation['clbits'][0]
                    Measure | qubit
                    bit = 1 << clbit
                    self._classical_state = (self._classical_state &
                                             (~bit)) | (int(qubit) << clbit)
                    # check whether we already measured this qubit
                    if operation['qubits'][0] in unmeasured_qubits:
                        unmeasured_qubits.remove(operation['qubits'][0])
                # Check if reset
                elif operation['name'] == 'reset':
                    qubit = operation['qubits'][0]
                    raise SimulatorError('Reset operation not yet implemented '
                                         'for ProjectQ C++ backend')
                elif operation['name'] == 'barrier':
                    pass
                else:
                    backend = self._configuration['name']
                    err_msg = '{0} encountered unrecognized operation "{1}"'
                    raise SimulatorError(
                        err_msg.format(backend, operation['name']))
            for ind in unmeasured_qubits:
                qubit = qureg[ind]
                Measure | qubit
            eng.flush()
            # Turn classical_state (int) into bit string
            state = format(self._classical_state, 'b')
            outcomes.append(state.zfill(self._number_of_clbits))
        # Return the results
        counts = dict(Counter(outcomes))
        data = {'counts': _format_result(counts, cl_reg_index, cl_reg_nbits)}
        if self._shots == 1:
            # TODO: deprecated -- remove in v0.6
            data['statevector'] = self._statevector
            data['quantum_state'] = self._statevector
            data['classical_state'] = self._classical_state
        end = time.time()
        return {
            'name': circuit['name'],
            'seed': self._seed,
            'shots': self._shots,
            'data': data,
            'status': 'DONE',
            'success': True,
            'time_taken': (end - start)
        }
Exemple #8
0
    def run_circuit(self, circuit):
        """Run a circuit and return a single Result.

        Args:
            circuit (QobjExperiment): Qobj experiment

        Returns:
            dict: A dictionary of results which looks something like:

                {
                "data":
                    {  #### DATA CAN BE A DIFFERENT DICTIONARY FOR EACH BACKEND ####
                    "counts": {'00000': XXXX, '00001': XXXXX},
                    "time"  : xx.xxxxxxxx
                    },
                "status": --status (string)--
                }
        Raises:
            ProjectQSimulatorError: if an error occurred.
        """
        # pylint: disable=expression-not-assigned,pointless-statement
        self._number_of_qubits = circuit.config.n_qubits
        self._number_of_clbits = circuit.config.memory_slots
        self._classical_state = 0
        cl_reg_index = []  # starting bit index of classical register
        cl_reg_nbits = []  # number of bits in classical register
        clbit_index = 0
        qobj_quregs = OrderedDict(
            _get_register_specs(circuit.header.qubit_labels))
        eng = MainEngine(backend=self._sim)
        for cl_reg in circuit.header.clbit_labels:
            cl_reg_nbits.append(cl_reg[1])
            cl_reg_index.append(clbit_index)
            clbit_index += cl_reg[1]
        # let circuit seed override qobj default
        if hasattr(circuit, 'config'):
            if hasattr(circuit.config, 'seed'):
                if circuit.config.seed is not None:
                    self._sim._simulator = CppSim(circuit.config.seed)
        outcomes = []
        snapshots = {}
        projq_qureg_dict = OrderedDict(((key, eng.allocate_qureg(size))
                                        for key, size in qobj_quregs.items()))

        if self._shots > 1:
            ground_state = np.zeros(1 << self._number_of_qubits, dtype=complex)
            ground_state[0] = 1

        start = time.time()
        for i in range(self._shots):
            # initialize starting state
            self._classical_state = 0

            qureg = [
                qubit for sublist in projq_qureg_dict.values()
                for qubit in sublist
            ]

            if i > 0:
                eng.flush()
                eng.backend.set_wavefunction(ground_state, qureg)

            # Do each operation in this shot
            for operation in circuit.instructions:
                if hasattr(operation, 'conditional'):
                    mask = int(operation.conditional.mask, 16)
                    if mask > 0:
                        value = self._classical_state & mask
                        while (mask & 0x1) == 0:
                            mask >>= 1
                            value >>= 1
                        if value != int(operation.conditional.val, 16):
                            continue
                # Check if single gate
                if operation.name in ['U', 'u3']:
                    params = operation.params
                    qubit = qureg[operation.qubits[0]]
                    Rz(params[2]) | qubit
                    Ry(params[0]) | qubit
                    Rz(params[1]) | qubit
                elif operation.name in ['u1']:
                    params = operation.params
                    qubit = qureg[operation.qubits[0]]
                    Rz(params[0]) | qubit
                elif operation.name in ['u2']:
                    params = operation.params
                    qubit = qureg[operation.qubits[0]]
                    Rz(params[1] - np.pi / 2) | qubit
                    Rx(np.pi / 2) | qubit
                    Rz(params[0] + np.pi / 2) | qubit
                elif operation.name == 't':
                    qubit = qureg[operation.qubits[0]]
                    T | qubit
                elif operation.name == 'h':
                    qubit = qureg[operation.qubits[0]]
                    H | qubit
                elif operation.name == 's':
                    qubit = qureg[operation.qubits[0]]
                    S | qubit
                elif operation.name in ['CX', 'cx']:
                    qubit0 = qureg[operation.qubits[0]]
                    qubit1 = qureg[operation.qubits[1]]
                    CX | (qubit0, qubit1)
                elif operation.name in ['id', 'u0']:
                    pass
                # Check if measure
                elif operation.name == 'measure':
                    qubit_index = operation.qubits[0]
                    qubit = qureg[qubit_index]
                    clbit = operation.memory[0]
                    Measure | qubit
                    bit = 1 << clbit
                    self._classical_state = (self._classical_state &
                                             (~bit)) | (int(qubit) << clbit)
                # Check if reset
                elif operation.name == 'reset':
                    qubit = operation.qubits[0]
                    raise ProjectQSimulatorError(
                        'Reset operation not yet implemented '
                        'for ProjectQ C++ backend')
                # Check if snapshot
                elif operation.name == 'snapshot':
                    eng.flush()
                    location = str(operation.params[0])
                    statevector = np.array(eng.backend.cheat()[1],
                                           dtype=complex)

                    formatted_state = [[x.real, x.imag] for x in statevector]
                    if location in snapshots:
                        snapshots[location]['statevector'].append(
                            formatted_state)
                    else:
                        snapshots[location] = {
                            'statevector': [formatted_state]
                        }
                elif operation.name == 'barrier':
                    pass
                else:
                    backend = self._configuration.backend_name
                    err_msg = '{0} encountered unrecognized operation "{1}"'
                    raise ProjectQSimulatorError(
                        err_msg.format(backend, operation.name))

            # Before the program terminates, all the qubits must be measured,
            # including those that have not been measured by the circuit.
            # Otherwise ProjectQ throws an exception about qubits in superposition.
            for ind in list(range(self._number_of_qubits)):
                qubit = qureg[ind]
                Measure | qubit
            eng.flush()
            # Turn classical_state (int) into bit string
            state = format(self._classical_state, 'b')
            outcomes.append(state.zfill(self._number_of_clbits))

        # Return the results
        counts = dict(Counter(outcomes))
        data = {'counts': _format_result(counts, cl_reg_nbits)}
        if snapshots != {}:
            data['snapshots'] = snapshots
        if self._shots == 1:
            data['classical_state'] = self._classical_state
        end = time.time()

        # Calculate creg_sizes
        pre_creg_sizes = {}
        for clbit_label in circuit.header.clbit_labels:
            if clbit_label[0] in pre_creg_sizes:
                pre_creg_sizes[clbit_label[0]] += 1
            else:
                pre_creg_sizes[clbit_label[0]] = 1
        creg_sizes = []
        for clbit_label in pre_creg_sizes:
            creg_sizes.append([clbit_label, pre_creg_sizes[clbit_label]])

        return {
            'header': {
                'name': circuit.header.name,
                'memory_slots': circuit.header.memory_slots,
                'creg_sizes': creg_sizes
            },
            'seed': self._seed,
            'shots': self._shots,
            'data': data,
            'status': 'DONE',
            'success': True,
            'time_taken': (end - start)
        }