def _validate(self, qobj):
        """Semantic validations of the qobj which cannot be done via schemas.
        Some of these may later move to backend schemas.

        1. No shots
        2. No measurements in the middle
        """
        self._set_shots_to_1(qobj, False)
        for circuit in qobj['circuits']:
            self._set_shots_to_1(circuit, True)
            for operator in circuit['compiled_circuit']['operations']:
                if operator['name'] in ['measure', 'reset']:
                    raise SimulatorError("In circuit {}: statevector simulator does "
                                         "not support measure or reset.".format(circuit['name']))
Ejemplo n.º 2
0
    def _validate(self, qobj):
        """Semantic validations of the qobj which cannot be done via schemas.
        Some of these may later move to backend schemas.

        1. No shots
        2. No measurements in the middle
        """
        if qobj.config.shots != 1:
            logger.info("statevector simulator only supports 1 shot. "
                        "Setting shots=1.")
            qobj.config.shots = 1
        for experiment in qobj.experiments:
            if getattr(experiment.config, 'shots', 1) != 1:
                logger.info("statevector simulator only supports 1 shot. "
                            "Setting shots=1 for circuit %s.", experiment.name)
                experiment.config.shots = 1
            for op in experiment.instructions:
                if op.name in ['measure', 'reset']:
                    raise SimulatorError(
                        "In circuit {}: statevector simulator does not support "
                        "measure or reset.".format(experiment.header.name))
Ejemplo n.º 3
0
    def _validate(self, qobj):
        """Semantic validations of the qobj which cannot be done via schemas.
        Some of these may later move to backend schemas.

        1. No shots
        2. No measurements in the middle
        """
        if qobj['config']['shots'] != 1:
            logger.info("statevector simulator only supports 1 shot. "
                        "Setting shots=1.")
            qobj['config']['shots'] = 1
        for circuit in qobj['circuits']:
            if 'shots' in circuit['config'] and circuit['config']['shots'] != 1:
                logger.info("statevector simulator only supports 1 shot. "
                            "Setting shots=1 for circuit %s.", circuit['name'])
                circuit['config']['shots'] = 1
            for op in circuit['compiled_circuit']['operations']:
                if op['name'] in ['measure', 'reset']:
                    raise SimulatorError("In circuit {}: statevector simulator does "
                                         "not support measure or reset.".format(circuit['name']))
        return
Ejemplo n.º 4
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)
        }
Ejemplo n.º 5
0
    def run_circuit(self, circuit):
        """Run a circuit and return object
        Args:
            circuit (dict): JSON that describes the circuit
        Returns:
            dict: A dictionary of results which looks something like::
                {
                "data":{
                        'classical_state': 0,
                        'counts': {'11': 1},
                        'quantum_state': array([sqrt(2)/2, 0, 0, sqrt(2)/2], dtype=object)},
                "status": --status (string)--
                }
        Raises:
            SimulatorError: if an error occurred.
        """
        ccircuit = circuit['compiled_circuit']
        self._number_of_qubits = ccircuit['header']['number_of_qubits']
        self._number_of_cbits = ccircuit['header']['number_of_clbits']
        self._quantum_state = 0
        self._classical_state = 0
        cl_reg_index = []  # starting bit index of classical register
        cl_reg_nbits = []  # number of bits in classical register
        cbit_index = 0
        for cl_reg in ccircuit['header']['clbit_labels']:
            cl_reg_nbits.append(cl_reg[1])
            cl_reg_index.append(cbit_index)
            cbit_index += cl_reg[1]
        if circuit['config']['seed'] is None:
            random.seed(random.getrandbits(32))
        else:
            random.seed(circuit['config']['seed'])

        actual_shots = self._shots
        self._quantum_state = Qubit(*tuple([0]*self._number_of_qubits))
        self._classical_state = 0
        # Do each operation in this shot
        for operation in ccircuit['operations']:
            if 'conditional' in operation:  # not related to sympy
                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
            if operation['name'] in ['U', 'u1', 'u2', 'u3']:
                qubit = operation['qubits'][0]
                opname = operation['name'].upper()
                opparas = operation['params']
                _sym_op = SympyQasmSimulator.get_sym_op(opname, tuple([qubit]), opparas)
                _applied_quantum_state = _sym_op * self._quantum_state
                self._quantum_state = qapply(_applied_quantum_state)
            # Check if CX gate
            elif operation['name'] in ['id']:
                logger.info('Identity gate is ignored by sympy-based qasm simulator.')
            elif operation['name'] in ['CX', 'cx']:
                qubit0 = operation['qubits'][0]
                qubit1 = operation['qubits'][1]
                opname = operation['name'].upper()
                if 'params' in operation:
                    opparas = operation['params']
                else:
                    opparas = None
                q0q1tuple = tuple([qubit0, qubit1])
                _sym_op = SympyQasmSimulator.get_sym_op(opname, q0q1tuple, opparas)
                self._quantum_state = qapply(_sym_op * self._quantum_state)
            # Check if measure
            elif operation['name'] == 'measure':
                logger.info('The statement measure is ignored by sympy-based qasm simulator.')
            elif operation['name'] == 'reset':
                logger.info('The statement reset is ignored by sympy-based qasm simulator.')
            elif operation['name'] == 'barrier':
                logger.info('The statement barrier is ignored by sympy-based qasm simulator.')
            else:
                backend = globals()['__configuration']['name']
                err_msg = '{0} encountered unrecognized operation "{1}"'
                raise SimulatorError(err_msg.format(backend, operation['name']))

        outcomes = []
        matrix_form = represent(self._quantum_state)
        shape_n = matrix_form.shape[0]
        list_form = [matrix_form[i, 0] for i in range(shape_n)]

        pdist = [SympyQasmSimulator._conjugate_square(matrix_form[i, 0]) for i in range(shape_n)]
        norm_pdist = [float(i)/sum(pdist) for i in pdist]

        for _ in range(actual_shots):
            _classical_state_observed = np.random.choice(np.arange(0, shape_n), p=norm_pdist)
            outcomes.append(bin(_classical_state_observed)[2:].zfill(
                self._number_of_cbits))

        # Return the results
        counts = dict(Counter(outcomes))
        # data['quantum_state']: consistent with other backends.
        data = {
            'counts': self._format_result(counts, cl_reg_index, cl_reg_nbits),
            'quantum_state': np.asarray(list_form),
            'classical_state': self._classical_state
        }

        return {'data': data, 'status': 'DONE'}
    def run_circuit(self, circuit):
        """Run a circuit and return object.

        Args:
            circuit (dict): JSON that describes the circuit
        Returns:
            dict: A dictionary of results which looks something like::

                {
                "data":{
                        'statevector': array([sqrt(2)/2, 0, 0, sqrt(2)/2], dtype=object)},
                "status": --status (string)--
                }

        Raises:
            SimulatorError: if an error occurred.
        """
        ccircuit = circuit['compiled_circuit']
        self._number_of_qubits = ccircuit['header']['number_of_qubits']
        self._statevector = 0

        self._statevector = Qubit(*tuple([0]*self._number_of_qubits))
        for operation in ccircuit['operations']:
            if 'conditional' in operation:
                raise SimulatorError('conditional operations not supported '
                                     'in statevector simulator')
            if operation['name'] == 'measure' or operation['name'] == 'reset':
                raise SimulatorError('operation {} not supported by '
                                     'sympy statevector simulator.'.format(operation['name']))
            if operation['name'] in ['U', 'u1', 'u2', 'u3']:
                qubit = operation['qubits'][0]
                opname = operation['name'].upper()
                opparas = operation['params']
                _sym_op = SympyStatevectorSimulator.get_sym_op(opname, tuple([qubit]), opparas)
                _applied_statevector = _sym_op * self._statevector
                self._statevector = qapply(_applied_statevector)
            elif operation['name'] in ['id']:
                logger.info('Identity gate is ignored by sympy-based statevector simulator.')
            elif operation['name'] in ['barrier']:
                logger.info('Barrier is ignored by sympy-based statevector simulator.')
            elif operation['name'] in ['CX', 'cx']:
                qubit0 = operation['qubits'][0]
                qubit1 = operation['qubits'][1]
                opname = operation['name'].upper()
                if 'params' in operation:
                    opparas = operation['params']
                else:
                    opparas = None
                q0q1tuple = tuple([qubit0, qubit1])
                _sym_op = SympyStatevectorSimulator.get_sym_op(opname, q0q1tuple, opparas)
                self._statevector = qapply(_sym_op * self._statevector)
            else:
                backend = globals()['__configuration']['name']
                err_msg = '{0} encountered unrecognized operation "{1}"'
                raise SimulatorError(err_msg.format(backend, operation['name']))

        matrix_form = represent(self._statevector)
        shape_n = matrix_form.shape[0]
        list_form = [matrix_form[i, 0] for i in range(shape_n)]

        # Return the results
        data = {
            'statevector': np.asarray(list_form),
        }

        return {'name': circuit['name'], 'data': data, 'status': 'DONE'}
Ejemplo n.º 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.
        """
        ccircuit = circuit['compiled_circuit']
        self._number_of_qubits = ccircuit['header']['number_of_qubits']
        self._number_of_cbits = ccircuit['header']['number_of_clbits']
        self._quantum_state = 0
        self._classical_state = 0
        cl_reg_index = []  # starting bit index of classical register
        cl_reg_nbits = []  # number of bits in classical register
        cbit_index = 0
        for cl_reg in ccircuit['header']['clbit_labels']:
            cl_reg_nbits.append(cl_reg[1])
            cl_reg_index.append(cbit_index)
            cbit_index += cl_reg[1]
        if circuit['config']['seed'] is None:
            self._local_random.seed(random.getrandbits(32))
        else:
            self._local_random.seed(circuit['config']['seed'])
        outcomes = []
        for _ in range(self._shots):
            self._quantum_state = np.zeros(1 << self._number_of_qubits,
                                           dtype=complex)
            self._quantum_state[0] = 1
            self._classical_state = 0
            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', 'u1', 'u2', 'u3']:
                    if 'params' in operation:
                        params = operation['params']
                    else:
                        params = None
                    qubit = operation['qubits'][0]
                    gate = single_gate_matrix(operation['name'], params)
                    self._add_qasm_single(gate, qubit)
                # Check if CX gate
                elif operation['name'] in ['id', 'u0']:
                    pass
                elif operation['name'] in ['CX', 'cx']:
                    qubit0 = operation['qubits'][0]
                    qubit1 = operation['qubits'][1]
                    self._add_qasm_cx(qubit0, qubit1)
                # Check if measure
                elif operation['name'] == 'measure':
                    qubit = operation['qubits'][0]
                    cbit = operation['clbits'][0]
                    self._add_qasm_measure(qubit, cbit)
                # Check if reset
                elif operation['name'] == 'reset':
                    qubit = operation['qubits'][0]
                    self._add_qasm_reset(qubit)
                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']))
            # Turn classical_state (int) into bit string
            outcomes.append(
                bin(self._classical_state)[2:].zfill(self._number_of_cbits))
        # Return the results
        counts = dict(Counter(outcomes))
        data = {
            'counts': self._format_result(counts, cl_reg_index, cl_reg_nbits)
        }
        if self._shots == 1:
            data['quantum_state'] = self._quantum_state
            data['classical_state'] = self._classical_state
        return {'data': data, 'status': 'DONE'}
Ejemplo n.º 8
0
    def run_circuit(self, circuit):
        """Run a circuit and return the results.
        Args:
            circuit (dict): JSON that describes the circuit

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

                {'data': {'unitary': array([[sqrt(2)/2, sqrt(2)/2, 0, 0],
                                            [0, 0, sqrt(2)/2, -sqrt(2)/2],
                                             [0, 0, sqrt(2)/2, sqrt(2)/2],
                                             [sqrt(2)/2, -sqrt(2)/2, 0, 0]], dtype=object)
                           },
                'status': 'DONE'}

        Raises:
            SimulatorError: if unsupported operations passed
        """
        ccircuit = circuit['compiled_circuit']
        self._number_of_qubits = ccircuit['header']['number_of_qubits']
        result = {}
        result['data'] = {}
        self._unitary_state = eye(2**self._number_of_qubits)
        for operation in ccircuit['operations']:
            if 'conditional' in operation:
                raise SimulatorError(
                    'conditional operations not supported in unitary simulator'
                )
            if operation['name'] == 'measure' or operation['name'] == 'reset':
                raise SimulatorError('operation {} not supported by '
                                     'sympy unitary simulator.'.format(
                                         operation['name']))
            if operation['name'] in ['U', 'u1', 'u2', 'u3']:
                if 'params' in operation:
                    params = operation['params']
                else:
                    params = None
                qubit = operation['qubits'][0]
                gate = SympyUnitarySimulator.compute_ugate_matrix_wrap(params)
                self._add_unitary_single(gate, qubit)
            elif operation['name'] in ['id']:
                logger.info(
                    'Identity gate is ignored by sympy-based unitary simulator.'
                )
            elif operation['name'] in ['barrier']:
                logger.info(
                    'Barrier is ignored by sympy-based unitary simulator.')
            elif operation['name'] in ['CX', 'cx']:
                qubit0 = operation['qubits'][0]
                qubit1 = operation['qubits'][1]
                gate = Matrix([[1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0],
                               [0, 1, 0, 0]])
                self._add_unitary_two(gate, qubit0, qubit1)
            else:
                result['status'] = 'ERROR'
                return result
        result['data']['unitary'] = np.array(self._unitary_state)
        result['status'] = 'DONE'
        result['name'] = circuit['name']

        return result