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']))
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))
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
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) }
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'}
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'}
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