def build_algorithm_from_dict(params, algo_input=None, backend=None): """ Construct algorithm as named in params, using params and algo_input as input data and returning a QuantumAlgorithm and QuantumInstance instance Args: params (dict): Dictionary of params for algo and dependent objects algo_input (AlgorithmInput): Main input data for algorithm. Optional, an algo may run entirely from params backend (BaseBackend): Backend object to be used in place of backend name Returns: Ready-to-run QuantumAlgorithm and QuantumInstance as specified in input parameters. Note that no QuantumInstance will be returned if none is specified - None will be returned instead. """ _discover_on_demand() inputparser = InputParser(params) inputparser.parse() # before merging defaults attempts to find a provider for the backend in case no # provider was passed if backend is None and inputparser.get_section_property( JSONSchema.BACKEND, JSONSchema.PROVIDER) is None: backend_name = inputparser.get_section_property( JSONSchema.BACKEND, JSONSchema.NAME) if backend_name is not None: inputparser.set_section_property( JSONSchema.BACKEND, JSONSchema.PROVIDER, get_provider_from_backend(backend_name)) inputparser.validate_merge_defaults() logger.debug('Algorithm Input: {}'.format( json.dumps(inputparser.get_sections(), sort_keys=True, indent=4))) algo_name = inputparser.get_section_property(PluggableType.ALGORITHM.value, JSONSchema.NAME) if algo_name is None: raise AquaError('Missing algorithm name') if algo_name not in local_pluggables(PluggableType.ALGORITHM): raise AquaError( 'Algorithm "{0}" missing in local algorithms'.format(algo_name)) if algo_input is None: input_name = inputparser.get_section_property('input', JSONSchema.NAME) if input_name is not None: input_params = copy.deepcopy( inputparser.get_section_properties('input')) del input_params[JSONSchema.NAME] convert_json_to_dict(input_params) algo_input = get_pluggable_class( PluggableType.INPUT, input_name).from_params(input_params) algo_params = copy.deepcopy(inputparser.get_sections()) algorithm = get_pluggable_class(PluggableType.ALGORITHM, algo_name).init_params( algo_params, algo_input) random_seed = inputparser.get_section_property(JSONSchema.PROBLEM, 'random_seed') algorithm.random_seed = random_seed quantum_instance = None # setup backend backend_provider = inputparser.get_section_property( JSONSchema.BACKEND, JSONSchema.PROVIDER) backend_name = inputparser.get_section_property(JSONSchema.BACKEND, JSONSchema.NAME) if backend_provider is not None and backend_name is not None: # quantum algorithm backend_cfg = { k: v for k, v in inputparser.get_section(JSONSchema.BACKEND).items() if k not in [JSONSchema.PROVIDER, JSONSchema.NAME] } # TODO, how to build the noise model from a dictionary? backend_cfg['seed_mapper'] = random_seed pass_manager = PassManager() if backend_cfg.pop( 'skip_transpiler', False) else None if pass_manager is not None: backend_cfg['pass_manager'] = pass_manager if backend is None or not isinstance(backend, BaseBackend): backend = get_backend_from_provider(backend_provider, backend_name) backend_cfg['backend'] = backend # overwrite the basis_gates and coupling_map basis_gates = backend_cfg.pop('basis_gates', None) coupling_map = backend_cfg.pop('coupling_map', None) if backend.configuration().simulator: if basis_gates is not None: backend.configuration().basis_gates = basis_gates if coupling_map is not None: backend.configuration().coupling_map = coupling_map else: logger.warning( "Change basis_gates and coupling_map on a real device is disallowed." ) shots = backend_cfg.pop('shots', 1024) seed = random_seed max_credits = backend_cfg.pop('max_credits', 10) memory = backend_cfg.pop('memory', False) run_config = RunConfig(shots=shots, max_credits=max_credits, memory=memory) if seed is not None: run_config.seed = seed backend_cfg['run_config'] = run_config backend_cfg['skip_qobj_validation'] = inputparser.get_section_property( JSONSchema.PROBLEM, 'skip_qobj_validation') use_caching = inputparser.get_section_property(JSONSchema.PROBLEM, 'circuit_caching') if use_caching: deepcopy_qobj = inputparser.get_section_property( JSONSchema.PROBLEM, 'skip_qobj_deepcopy') cache_file = inputparser.get_section_property( JSONSchema.PROBLEM, 'circuit_cache_file') backend_cfg['circuit_cache'] = CircuitCache( skip_qobj_deepcopy=deepcopy_qobj, cache_file=cache_file) quantum_instance = QuantumInstance(**backend_cfg) # Note that quantum_instance can be None if none is specified return algorithm, quantum_instance
def __init__(self, backend, shots=1024, seed=None, max_credits=10, basis_gates=None, coupling_map=None, initial_layout=None, pass_manager=None, seed_mapper=None, backend_options=None, noise_model=None, timeout=None, wait=5, circuit_cache=None, skip_qobj_validation=False): """Constructor. Args: backend (BaseBackend): instance of selected backend shots (int, optional): number of repetitions of each circuit, for sampling seed (int, optional): random seed for simulators max_credits (int, optional): maximum credits to use basis_gates (list[str], optional): list of basis gate names supported by the target. Default: ['u1','u2','u3','cx','id'] coupling_map (list[list]): coupling map (perhaps custom) to target in mapping initial_layout (dict, optional): initial layout of qubits in mapping pass_manager (PassManager, optional): pass manager to handle how to compile the circuits seed_mapper (int, optional): the random seed for circuit mapper backend_options (dict, optional): all running options for backend, please refer to the provider. noise_model (qiskit.provider.aer.noise.noise_model.NoiseModel, optional): noise model for simulator timeout (float, optional): seconds to wait for job. If None, wait indefinitely. wait (float, optional): seconds between queries to result circuit_cache (CircuitCache, optional): A CircuitCache to use when calling compile_and_run_circuits skip_qobj_validation (bool, optional): Bypass Qobj validation to decrease submission time """ self._backend = backend # setup run config run_config = RunConfig(shots=shots, max_credits=max_credits) if seed: run_config.seed = seed if getattr(run_config, 'shots', None) is not None: if self.is_statevector and run_config.shots != 1: logger.info( "statevector backend only works with shot=1, change " "shots from {} to 1.".format(run_config.shots)) run_config.shots = 1 self._run_config = run_config # setup backend config basis_gates = basis_gates or backend.configuration().basis_gates coupling_map = coupling_map or getattr(backend.configuration(), 'coupling_map', None) self._backend_config = { 'basis_gates': basis_gates, 'coupling_map': coupling_map } # setup noise config noise_config = None if noise_model is not None: if is_aer_provider(self._backend): if not self.is_statevector: noise_config = noise_model else: logger.info( "The noise model can be only used with Aer qasm simulator. " "Change it to None.") else: logger.info( "The noise model can be only used with Qiskit Aer. " "Please install it.") self._noise_config = {} if noise_config is None else { 'noise_model': noise_config } # setup compile config if initial_layout is not None and not isinstance( initial_layout, Layout): initial_layout = Layout(initial_layout) self._compile_config = { 'pass_manager': pass_manager, 'initial_layout': initial_layout, 'seed_mapper': seed_mapper } # setup job config self._qjob_config = {'timeout': timeout} if self.is_local \ else {'timeout': timeout, 'wait': wait} # setup backend options for run self._backend_options = {} if is_ibmq_provider(self._backend): logger.info( "backend_options can not used with the backends in IBMQ provider." ) else: self._backend_options = {} if backend_options is None \ else {'backend_options': backend_options} self._shared_circuits = False self._circuit_summary = False self._circuit_cache = circuit_cache self._skip_qobj_validation = skip_qobj_validation logger.info(self)
def compile(circuits, backend, config=None, basis_gates=None, coupling_map=None, initial_layout=None, shots=1024, max_credits=10, seed=None, qobj_id=None, seed_mapper=None, pass_manager=None, memory=False): """Compile a list of circuits into a qobj. Args: circuits (QuantumCircuit or list[QuantumCircuit]): circuits to compile backend (BaseBackend): a backend to compile for config (dict): dictionary of parameters (e.g. noise) used by runner basis_gates (str): comma-separated basis gate set to compile to coupling_map (list): coupling map (perhaps custom) to target in mapping initial_layout (list): initial layout of qubits in mapping shots (int): number of repetitions of each circuit, for sampling max_credits (int): maximum credits to use seed (int): random seed for simulators seed_mapper (int): random seed for swapper mapper qobj_id (int): identifier for the generated qobj pass_manager (PassManager): a pass manger for the transpiler pipeline memory (bool): if True, per-shot measurement bitstrings are returned as well Returns: Qobj: the qobj to be run on the backends Raises: QiskitError: if the desired options are not supported by backend """ if config: warnings.warn( 'The `config` argument is deprecated and ' 'does not do anything', DeprecationWarning) circuits = transpiler.transpile(circuits, backend, basis_gates, coupling_map, initial_layout, seed_mapper, pass_manager) # step 4: Making a qobj run_config = RunConfig() if seed: run_config.seed = seed if shots: run_config.shots = shots if max_credits: run_config.max_credits = max_credits if memory: run_config.memory = memory qobj = circuits_to_qobj(circuits, user_qobj_header=QobjHeader(), run_config=run_config, qobj_id=qobj_id) return qobj
def _build_algorithm_from_dict(self, quantum_instance): _discover_on_demand() self._parser = InputParser(self._params) self._parser.parse() # before merging defaults attempts to find a provider for the backend in case no # provider was passed if quantum_instance is None and self._parser.get_section_property( JSONSchema.BACKEND, JSONSchema.PROVIDER) is None: backend_name = self._parser.get_section_property( JSONSchema.BACKEND, JSONSchema.NAME) if backend_name is not None: self._parser.set_section_property( JSONSchema.BACKEND, JSONSchema.PROVIDER, get_provider_from_backend(backend_name)) self._parser.validate_merge_defaults() logger.debug('Algorithm Input: {}'.format( json.dumps(self._parser.get_sections(), sort_keys=True, indent=4))) algo_name = self._parser.get_section_property( PluggableType.ALGORITHM.value, JSONSchema.NAME) if algo_name is None: raise AquaError('Missing algorithm name') if algo_name not in local_pluggables(PluggableType.ALGORITHM): raise AquaError( 'Algorithm "{0}" missing in local algorithms'.format( algo_name)) if self._algorithm_input is None: input_name = self._parser.get_section_property( 'input', JSONSchema.NAME) if input_name is not None: input_params = copy.deepcopy( self._parser.get_section_properties('input')) del input_params[JSONSchema.NAME] convert_json_to_dict(input_params) self._algorithm_input = get_pluggable_class( PluggableType.INPUT, input_name).from_params(input_params) algo_params = copy.deepcopy(self._parser.get_sections()) self._quantum_algorithm = get_pluggable_class( PluggableType.ALGORITHM, algo_name).init_params(algo_params, self._algorithm_input) random_seed = self._parser.get_section_property( JSONSchema.PROBLEM, 'random_seed') self._quantum_algorithm.random_seed = random_seed if isinstance(quantum_instance, QuantumInstance): self._quantum_instance = quantum_instance return backend = None if isinstance(quantum_instance, BaseBackend): backend = quantum_instance elif quantum_instance is not None: raise AquaError( 'Invalid QuantumInstance or BaseBackend parameter {}.'.format( quantum_instance)) # setup backend backend_provider = self._parser.get_section_property( JSONSchema.BACKEND, JSONSchema.PROVIDER) backend_name = self._parser.get_section_property( JSONSchema.BACKEND, JSONSchema.NAME) if backend_provider is not None and backend_name is not None: # quantum algorithm backend_cfg = { k: v for k, v in self._parser.get_section( JSONSchema.BACKEND).items() if k not in [JSONSchema.PROVIDER, JSONSchema.NAME] } # TODO, how to build the noise model from a dictionary? backend_cfg['seed_mapper'] = random_seed pass_manager = PassManager() if backend_cfg.pop( 'skip_transpiler', False) else None if pass_manager is not None: backend_cfg['pass_manager'] = pass_manager if backend is None: backend = get_backend_from_provider(backend_provider, backend_name) backend_cfg['backend'] = backend # overwrite the basis_gates and coupling_map basis_gates = backend_cfg.pop('basis_gates', None) if isinstance(basis_gates, str): basis_gates = basis_gates.split(',') coupling_map = backend_cfg.pop('coupling_map', None) if backend.configuration().simulator: if basis_gates is not None: backend.configuration().basis_gates = basis_gates if coupling_map is not None: backend.configuration().coupling_map = coupling_map else: logger.warning( "Change basis_gates and coupling_map on a real device is disallowed." ) shots = backend_cfg.pop('shots', 1024) seed = random_seed max_credits = backend_cfg.pop('max_credits', 10) memory = backend_cfg.pop('memory', False) run_config = RunConfig(shots=shots, max_credits=max_credits, memory=memory) if seed is not None: run_config.seed = seed backend_cfg['run_config'] = run_config backend_cfg[ 'skip_qobj_validation'] = self._parser.get_section_property( JSONSchema.PROBLEM, 'skip_qobj_validation') use_caching = self._parser.get_section_property( JSONSchema.PROBLEM, 'circuit_caching') if use_caching: deepcopy_qobj = self._parser.get_section_property( JSONSchema.PROBLEM, 'skip_qobj_deepcopy') cache_file = self._parser.get_section_property( JSONSchema.PROBLEM, 'circuit_cache_file') backend_cfg['circuit_cache'] = CircuitCache( skip_qobj_deepcopy=deepcopy_qobj, cache_file=cache_file) self._quantum_instance = QuantumInstance(**backend_cfg)