def __init__(self, configuration=None): self._configuration = configuration if 'problems' not in configuration or len( configuration['problems']) <= 0: raise AlgorithmError( 'Algorithm Input missing or empty configuration problems') for problem in configuration['problems']: if problem not in AlgorithmInput._PROBLEM_SET: raise AlgorithmError( 'Problem {} not in known problem set {}'.format( problem, AlgorithmInput._PROBLEM_SET))
def init_params(self, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params (dict): parameters dictionary algo_input (EnergyInput): EnergyInput instance """ if algo_input is None: raise AlgorithmError("EnergyInput instance is required.") operator = algo_input.qubit_op qaoa_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) operator_mode = qaoa_params.get(QAOA.PROP_OPERATOR_MODE) p = qaoa_params.get(QAOA.PROP_P) initial_point = qaoa_params.get(QAOA.PROP_INIT_POINT) # Set up optimizer opt_params = params.get(QuantumAlgorithm.SECTION_KEY_OPTIMIZER) optimizer = get_optimizer_instance(opt_params['name']) optimizer.init_params(opt_params) if 'statevector' not in self._backend and operator_mode == 'matrix': logger.debug('Qasm simulation does not work on {} mode, changing \ the operator_mode to paulis'.format(operator_mode)) operator_mode = 'paulis' self.init_args(operator, operator_mode, p, optimizer, opt_init_point=initial_point, aux_operators=algo_input.aux_ops)
def init_params(self, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params: parameters dictionary algo_input: EnergyInput instance """ if algo_input is None: raise AlgorithmError("EnergyInput instance is required.") operator = algo_input.qubit_op iqpe_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) num_time_slices = iqpe_params.get(IQPE.PROP_NUM_TIME_SLICES) paulis_grouping = iqpe_params.get(IQPE.PROP_PAULIS_GROUPING) expansion_mode = iqpe_params.get(IQPE.PROP_EXPANSION_MODE) expansion_order = iqpe_params.get(IQPE.PROP_EXPANSION_ORDER) num_iterations = iqpe_params.get(IQPE.PROP_NUM_ITERATIONS) # Set up initial state, we need to add computed num qubits to params init_state_params = params.get( QuantumAlgorithm.SECTION_KEY_INITIAL_STATE) init_state_params['num_qubits'] = operator.num_qubits init_state = get_initial_state_instance(init_state_params['name']) init_state.init_params(init_state_params) self.init_args(operator, init_state, num_time_slices, num_iterations, paulis_grouping=paulis_grouping, expansion_mode=expansion_mode, expansion_order=expansion_order)
def set_default_properties_for_name(self,section_name): if self._parser is None: raise AlgorithmError('Input not initialized.') name = self._parser.get_section_property(section_name,InputParser.NAME) self._parser.delete_section_properties(section_name) value = self._parser.get_section_default_properties(section_name) if name is not None: self._parser.set_section_property(section_name,InputParser.NAME,name) if isinstance(value,dict): for property_name,property_value in value.items(): if property_name != InputParser.NAME: self._parser.set_section_property(section_name,property_name,property_value) else: if value is None: types = self._parser.get_section_types(section_name) if 'null' not in types: if 'string' in types: value = '' elif 'object' in types: value = {} elif 'array' in types: value = [] self._parser.set_section_data(section_name,value)
def set_section(self,section_name): if self._parser is None: raise AlgorithmError('Input not initialized.') self._parser.set_section(section_name) value = self._parser.get_section_default_properties(section_name) if isinstance(value,dict): for property_name,property_value in value.items(): self._parser.set_section_property(section_name,property_name,property_value) # do one more time in case schema was updated value = self._parser.get_section_default_properties(section_name) for property_name,property_value in value.items(): self._parser.set_section_property(section_name,property_name,property_value) else: if value is None: types = self._parser.get_section_types(section_name) if 'null' not in types: if 'string' in types: value = '' elif 'object' in types: value = {} elif 'array' in types: value = [] self._parser.set_section_data(section_name,value)
def init_params(self, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params: parameters dictionary algo_input: EnergyInput instance """ if algo_input is None: raise AlgorithmError("EnergyInput instance is required.") operator = algo_input.qubit_op evolution_fidelity_params = params.get( QuantumAlgorithm.SECTION_KEY_ALGORITHM) expansion_order = evolution_fidelity_params.get( EvolutionFidelity.PROP_EXPANSION_ORDER) # Set up initial state, we need to add computed num qubits to params initial_state_params = params.get( QuantumAlgorithm.SECTION_KEY_INITIAL_STATE) initial_state_params['num_qubits'] = operator.num_qubits initial_state = get_initial_state_instance( initial_state_params['name']) initial_state.init_params(initial_state_params) self.init_args(operator, initial_state, expansion_order)
def from_params(self, params): if EnergyInput.PROP_KEY_QUBITOP not in params: raise AlgorithmError("Qubit operator is required.") qparams = params[EnergyInput.PROP_KEY_QUBITOP] self._qubit_op = Operator.load_from_dict(qparams) if EnergyInput.PROP_KEY_AUXOPS in params: auxparams = params[EnergyInput.PROP_KEY_AUXOPS] self._aux_ops = [Operator.load_from_dict(auxparams[i]) for i in range(len(auxparams))]
def delete_section_property(self, section_name, property_name): if self._parser is None: raise AlgorithmError('Input not initialized.') self._parser.delete_section_property(section_name, property_name) if property_name == InputParser.NAME and \ (InputParser.is_pluggable_section(section_name) or section_name == InputParser.INPUT): self._parser.delete_section_properties(section_name)
def _register_pluggable(pluggable_type, cls, configuration=None): """ Registers a pluggable class Args: pluggable_type(str): The pluggable type cls (object): Pluggable class. configuration (object, optional): Pluggable configuration Returns: name: pluggable name Raises: AlgorithmError: if the class is already registered or could not be registered """ if pluggable_type not in _REGISTERED_PLUGGABLES: _REGISTERED_PLUGGABLES[pluggable_type] = {} # Verify that the pluggable is not already registered. registered_classes = _REGISTERED_PLUGGABLES[pluggable_type] if cls in [pluggable.cls for pluggable in registered_classes.values()]: raise AlgorithmError( 'Could not register class {} is already registered'.format(cls)) try: pluggable_instance = cls(configuration=configuration) except Exception as err: raise AlgorithmError( 'Could not register puggable:{} could not be instantiated: {}'. format(cls, str(err))) # Verify that it has a minimal valid configuration. try: pluggable_name = pluggable_instance.configuration['name'] except (LookupError, TypeError): raise AlgorithmError( 'Could not register pluggable: invalid configuration') if pluggable_name in _REGISTERED_PLUGGABLES[pluggable_type]: raise AlgorithmError( 'Could not register class {}. Name {} {} is already registered'. format(cls, pluggable_name, _REGISTERED_PLUGGABLES[pluggable_type][pluggable_name].cls)) # Append the pluggable to the `registered_classes` dict. _REGISTERED_PLUGGABLES[pluggable_type][ pluggable_name] = RegisteredPluggable(pluggable_name, cls, pluggable_instance.configuration) return pluggable_name
def init_params(self, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params: parameters dictionary algo_input: EnergyInput instance """ if algo_input is None: raise AlgorithmError("EnergyInput instance is required.") # For getting the extra operator, caller has to do something like: algo_input.add_aux_op(evo_op) operator = algo_input.qubit_op aux_ops = algo_input.aux_ops if aux_ops is None or len(aux_ops) != 1: raise AlgorithmError( "EnergyInput, a single aux op is required for evaluation.") evo_operator = aux_ops[0] if evo_operator is None: raise AlgorithmError("EnergyInput, invalid aux op.") dynamics_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) operator_mode = dynamics_params.get(Dynamics.PROP_OPERATOR_MODE) evo_time = dynamics_params.get(Dynamics.PROP_EVO_TIME) num_time_slices = dynamics_params.get(Dynamics.PROP_NUM_TIME_SLICES) paulis_grouping = dynamics_params.get(Dynamics.PROP_PAULIS_GROUPING) expansion_mode = dynamics_params.get(Dynamics.PROP_EXPANSION_MODE) expansion_order = dynamics_params.get(Dynamics.PROP_EXPANSION_ORDER) # Set up initial state, we need to add computed num qubits to params initial_state_params = params.get( QuantumAlgorithm.SECTION_KEY_INITIAL_STATE) initial_state_params['num_qubits'] = operator.num_qubits initial_state = get_initial_state_instance( initial_state_params['name']) initial_state.init_params(initial_state_params) self.init_args(operator, operator_mode, initial_state, evo_operator, evo_time, num_time_slices, paulis_grouping=paulis_grouping, expansion_mode=expansion_mode, expansion_order=expansion_order)
def deregister_pluggable(pluggable_type,pluggable_name): """ Deregisters a pluggable class Args: pluggable_type(str): The pluggable type pluggable_name (str): The pluggable name Raises: AlgorithmError: if the class is not registered """ _discover_on_demand() if pluggable_type not in _REGISTERED_PLUGGABLES: raise AlgorithmError('Could not deregister {} {} not registered'.format(pluggable_type,pluggable_name)) if pluggable_name not in _REGISTERED_PLUGGABLES[pluggable_type]: raise AlgorithmError('Could not deregister {} {} not registered'.format(pluggable_type,pluggable_name)) _REGISTERED_PLUGGABLES[pluggable_type].pop(pluggable_name)
def get_pluggable_instance(pluggable_type,pluggable_name): """ Instantiates a pluggable class Args: pluggable_type(str): The pluggable type pluggable_name (str): The pluggable name Returns: instance: pluggable instance """ _discover_on_demand() if pluggable_type not in _REGISTERED_PLUGGABLES: raise AlgorithmError('{} {} not registered'.format(pluggable_type,pluggable_name)) if pluggable_name not in _REGISTERED_PLUGGABLES[pluggable_type]: raise AlgorithmError('{} {} not registered'.format(pluggable_type,pluggable_name)) return _REGISTERED_PLUGGABLES[pluggable_type][pluggable_name].cls( configuration=_REGISTERED_PLUGGABLES[pluggable_type][pluggable_name].configuration)
def get_pluggable_configuration(pluggable_type,pluggable_name): """ Accesses pluggable configuration Args: pluggable_type(str): The pluggable type pluggable_name (str): The pluggable name Returns: configuration: pluggable configuration Raises: AlgorithmError: if the class is not registered """ _discover_on_demand() if pluggable_type not in _REGISTERED_PLUGGABLES: raise AlgorithmError('{} {} not registered'.format(pluggable_type,pluggable_name)) if pluggable_name not in _REGISTERED_PLUGGABLES[pluggable_type]: raise AlgorithmError('{} {} not registered'.format(pluggable_type,pluggable_name)) return _REGISTERED_PLUGGABLES[pluggable_type][pluggable_name].configuration
def init_params(self, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params: parameters dictionary algo_input: EnergyInput instance """ if algo_input is None: raise AlgorithmError("EnergyInput instance is required.") ee_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) k = ee_params.get(ExactEigensolver.PROP_K) self.init_args(algo_input.qubit_op, k, algo_input.aux_ops)
def register_input(cls, configuration=None): """ Registers an input class Args: cls (object): Input class. configuration (object, optional): Pluggable configuration Returns: name: input name Raises: AlgorithmError: if the class is already registered or could not be registered """ _discover_on_demand() # Verify that the pluggable is not already registered if cls in [input.cls for input in _REGISTERED_INPUTS.values()]: raise AlgorithmError( 'Could not register class {} is already registered'.format(cls)) try: input_instance = cls(configuration=configuration) except Exception as err: raise AlgorithmError( 'Could not register input:{} could not be instantiated: {}'.format( cls, str(err))) # Verify that it has a minimal valid configuration. try: input_name = input_instance.configuration['name'] except (LookupError, TypeError): raise AlgorithmError('Could not register input: invalid configuration') if input_name in _REGISTERED_INPUTS: raise AlgorithmError( 'Could not register class {}. Name {} {} is already registered'. format(cls, input_name, _REGISTERED_INPUTS[input_name].cls)) # Append the pluggable to the `registered_classes` dict. _REGISTERED_INPUTS[input_name] = RegisteredInput( input_name, cls, input_instance.configuration) return input_name
def set_section_property(self, section_name, property_name, value): if self._parser is None: raise AlgorithmError('Input not initialized.') self._parser.set_section_property(section_name,property_name,value) if property_name == InputParser.NAME and \ (InputParser.is_pluggable_section(section_name) or section_name == InputParser.INPUT): properties = self._parser.get_section_default_properties(section_name) if isinstance(properties,dict): properties[ InputParser.NAME] = value self._parser.delete_section_properties(section_name) for property_name,property_value in properties.items(): self._parser.set_section_property(section_name,property_name,property_value)
def init_params(self, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params: parameters dictionary algo_input: input instance """ if algo_input is not None: raise AlgorithmError("Unexpected Input instance.") oracle_params = params.get(QuantumAlgorithm.SECTION_KEY_ORACLE) oracle = get_oracle_instance(oracle_params['name']) oracle.init_params(oracle_params) self.init_args(oracle)
def local_pluggables(pluggable_type): """ Accesses pluggable names Args: pluggable_type(str): The pluggable type Returns: names: pluggable names Raises: AlgorithmError: if the tyoe is not registered """ _discover_on_demand() if pluggable_type not in _REGISTERED_PLUGGABLES: raise AlgorithmError('{} not registered'.format(pluggable_type)) return [pluggable.name for pluggable in _REGISTERED_PLUGGABLES[pluggable_type].values()]
def deregister_input(input_name): """ Deregisters am input class Args: input_name(str): The input name Raises: AlgorithmError: if the class is not registered """ _discover_on_demand() if input_name not in _REGISTERED_INPUTS: raise AlgorithmError( 'Could not deregister {} not registered'.format(input_name)) _REGISTERED_INPUTS.pop(input_name)
def init_params(self, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params (dict): parameters dictionary algo_input (EnergyInput): EnergyInput instance """ if algo_input is None: raise AlgorithmError("EnergyInput instance is required.") operator = algo_input.qubit_op vqe_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) operator_mode = vqe_params.get('operator_mode') initial_point = vqe_params.get('initial_point') # Set up initial state, we need to add computed num qubits to params init_state_params = params.get( QuantumAlgorithm.SECTION_KEY_INITIAL_STATE) init_state_params['num_qubits'] = operator.num_qubits init_state = get_initial_state_instance(init_state_params['name']) init_state.init_params(init_state_params) # Set up variational form, we need to add computed num qubits, and initial state to params var_form_params = params.get(QuantumAlgorithm.SECTION_KEY_VAR_FORM) var_form_params['num_qubits'] = operator.num_qubits var_form_params['initial_state'] = init_state var_form = get_variational_form_instance(var_form_params['name']) var_form.init_params(var_form_params) # Set up optimizer opt_params = params.get(QuantumAlgorithm.SECTION_KEY_OPTIMIZER) optimizer = get_optimizer_instance(opt_params['name']) optimizer.init_params(opt_params) if 'statevector' not in self._backend and operator_mode == 'matrix': logger.debug('Qasm simulation does not work on {} mode, changing \ the operator_mode to paulis'.format(operator_mode)) operator_mode = 'paulis' self.init_args(operator, operator_mode, var_form, optimizer, opt_init_point=initial_point, aux_operators=algo_input.aux_ops) logger.info(self.print_setting())
def get_input_configuration(input_name): """ Accesses input configuration Args: input_name (str): The input name Returns: configuration: input configuration Raises: AlgorithmError: if the class is not registered """ _discover_on_demand() if input_name not in _REGISTERED_INPUTS: raise AlgorithmError('{} not registered'.format(input_name)) return _REGISTERED_INPUTS[input_name].configuration
def init_params(self, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params: parameters dictionary algo_input: input instance """ if algo_input is not None: raise AlgorithmError("Unexpected Input instance.") grover_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) num_iterations = grover_params.get(Grover.PROP_NUM_ITERATIONS) oracle_params = params.get(QuantumAlgorithm.SECTION_KEY_ORACLE) oracle = get_oracle_instance(oracle_params['name']) oracle.init_params(oracle_params) self.init_args(oracle, num_iterations=num_iterations)
def get_input_instance(input_name): """ Instantiates an input class Args: input_name (str): The input name Returns: instance: input instance Raises: AlgorithmError: if the class is not registered """ _discover_on_demand() if input_name not in _REGISTERED_INPUTS: raise AlgorithmError('{} not registered'.format(input_name)) return _REGISTERED_INPUTS[input_name].cls( configuration=_REGISTERED_INPUTS[input_name].configuration)
def init_params(self, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params: parameters dictionary algo_input: EnergyInput instance """ if algo_input is None: raise AlgorithmError("EnergyInput instance is required.") operator = algo_input.qubit_op qpe_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) num_time_slices = qpe_params.get(QPE.PROP_NUM_TIME_SLICES) paulis_grouping = qpe_params.get(QPE.PROP_PAULIS_GROUPING) expansion_mode = qpe_params.get(QPE.PROP_EXPANSION_MODE) expansion_order = qpe_params.get(QPE.PROP_EXPANSION_ORDER) num_ancillae = qpe_params.get(QPE.PROP_NUM_ANCILLAE) use_basis_gates = qpe_params.get(QPE.PROP_USE_BASIS_GATES) # Set up initial state, we need to add computed num qubits to params init_state_params = params.get( QuantumAlgorithm.SECTION_KEY_INITIAL_STATE) init_state_params['num_qubits'] = operator.num_qubits init_state = get_initial_state_instance(init_state_params['name']) init_state.init_params(init_state_params) # Set up iqft, we need to add num qubits to params which is our num_ancillae bits here iqft_params = params.get(QuantumAlgorithm.SECTION_KEY_IQFT) iqft_params['num_qubits'] = num_ancillae iqft = get_iqft_instance(iqft_params['name']) iqft.init_params(iqft_params) self.init_args(operator, init_state, iqft, num_time_slices, num_ancillae, paulis_grouping=paulis_grouping, expansion_mode=expansion_mode, expansion_order=expansion_order, use_basis_gates=use_basis_gates)
def register_pluggable(cls, configuration=None): """ Registers a pluggable class Args: cls (object): Pluggable class. configuration (object, optional): Pluggable configuration Returns: name: pluggable name """ _discover_on_demand() pluggable_type = None for type,c in _PLUGGABLES.items(): if issubclass(cls, c): pluggable_type = type break if pluggable_type is None: raise AlgorithmError('Could not register class {} is not subclass of any known pluggable'.format(cls)) return _register_pluggable(pluggable_type,cls,configuration)
def save_to_file(self,filename): if self.is_empty(): raise AlgorithmError("Empty input data.") self._parser.save_to_file(filename)
def init_params(self, params, algo_input): if algo_input is None: raise AlgorithmError("EnergyInput instance is required.") self._ins.parse(algo_input.qubit_op.save_to_dict()['paulis']) self._params = params
def setup_quantum_backend(self, backend='local_statevector_simulator', shots=1024, skip_transpiler=False, timeout=None, wait=5, noise_params=None): """ Setup the quantum backend. Args: backend (str): name of selected backend shots (int): number of shots for the backend skip_transpiler (bool): flag of skipping gate mapping, be aware that only basis gates of the backend are executed others are skipped. timeout (float or None): seconds to wait for job. If None, wait indefinitely. wait (float): seconds between queries noise_params (dict): the noise setting for simulator Raises: AlgorithmError: set backend with invalid Qconfig """ operational_backends = self.register_and_get_operational_backends( self.qconfig) if self.EQUIVALENT_BACKENDS.get(backend, backend) not in operational_backends: raise AlgorithmError( "This backend '{}' is not operational for the quantum algorithm\ , please check your Qconfig.py, or select any one below: {}". format(backend, operational_backends)) self._backend = backend self._qjob_config = {'timeout': timeout, 'wait': wait} shots = 1 if 'statevector' in backend else shots noise_params = noise_params if 'simulator' in backend else None if backend.startswith('local'): self._qjob_config.pop('wait', None) my_backend = get_backend(backend) self._execute_config = { 'shots': shots, 'skip_transpiler': skip_transpiler, 'config': { "noise_params": noise_params }, 'basis_gates': my_backend.configuration['basis_gates'], 'coupling_map': my_backend.configuration['coupling_map'], 'initial_layout': None, 'max_credits': 10, 'seed': self._random_seed, 'qobj_id': None, 'hpc': None } info = "Algorithm: '{}' setup with backend '{}', with following setting:\n {}\n{}".format( self._configuration['name'], my_backend.configuration['name'], self._execute_config, self._qjob_config) logger.info('QISKit Core version {}'.format(qiskit_version)) logger.info(info)
def set_section_text(self, section_name, value): if self._parser is None: raise AlgorithmError('Input not initialized.') self._parser.set_section_data(section_name, value)
def delete_section_text(self, section_name): if self._parser is None: raise AlgorithmError('Input not initialized.') self._parser.delete_section_text(section_name)