def test_saving_and_loading(self): backend = BasicAer.get_backend('statevector_simulator') num_qubits = self.algo_input.qubit_op.num_qubits init_state = Zero(num_qubits) var_form = RY(num_qubits, 3, initial_state=init_state) optimizer = L_BFGS_B() algo = VQE(self.algo_input.qubit_op, var_form, optimizer, 'matrix') fd, cache_tmp_file = tempfile.mkstemp(suffix='.inp') os.close(fd) circuit_cache = CircuitCache(skip_qobj_deepcopy=True, cache_file=cache_tmp_file) quantum_instance_caching = QuantumInstance(backend, circuit_cache=circuit_cache, skip_qobj_validation=True) result_caching = algo.run(quantum_instance_caching) self.assertLessEqual(circuit_cache.misses, 0) is_file_exist = os.path.exists(cache_tmp_file) self.assertTrue(is_file_exist, "Does not store content successfully.") circuit_cache_new = CircuitCache(skip_qobj_deepcopy=True, cache_file=cache_tmp_file) self.assertEqual(circuit_cache.mappings, circuit_cache_new.mappings) self.assertLessEqual(circuit_cache_new.misses, 0) if is_file_exist: os.remove(cache_tmp_file)
def test_saving_and_loading_e2e(self): backend = BasicAer.get_backend('statevector_simulator') num_qubits = self.algo_input.qubit_op.num_qubits init_state = Zero(num_qubits) var_form = RY(num_qubits, 3, initial_state=init_state) optimizer = L_BFGS_B() algo = VQE(self.algo_input.qubit_op, var_form, optimizer, 'matrix') with tempfile.NamedTemporaryFile(suffix='.inp', delete=True) as cache_tmp_file: cache_tmp_file_name = cache_tmp_file.name quantum_instance_caching = QuantumInstance( backend, circuit_caching=True, cache_file=cache_tmp_file_name, skip_qobj_deepcopy=True, skip_qobj_validation=True) algo.run(quantum_instance_caching) self.assertLessEqual(quantum_instance_caching.circuit_cache.misses, 0) is_file_exist = os.path.exists(cache_tmp_file_name) self.assertTrue(is_file_exist, "Does not store content successfully.") circuit_cache_new = CircuitCache(skip_qobj_deepcopy=True, cache_file=cache_tmp_file_name) self.assertEqual(quantum_instance_caching.circuit_cache.mappings, circuit_cache_new.mappings) self.assertLessEqual(circuit_cache_new.misses, 0)
def test_vqe_caching_direct(self, batch_mode=True): backend = BasicAer.get_backend('statevector_simulator') num_qubits = self.algo_input.qubit_op.num_qubits init_state = Zero(num_qubits) var_form = RY(num_qubits, 3, initial_state=init_state) optimizer = L_BFGS_B() algo = VQE(self.algo_input.qubit_op, var_form, optimizer, 'matrix', batch_mode=batch_mode) circuit_cache = CircuitCache(skip_qobj_deepcopy=True) quantum_instance_caching = QuantumInstance(backend, circuit_cache=circuit_cache, skip_qobj_validation=True) result_caching = algo.run(quantum_instance_caching) self.assertLessEqual(circuit_cache.misses, 0) self.assertAlmostEqual(self.reference_vqe_result['statevector_simulator']['energy'], result_caching['energy']) speedup_check = 3 self.log.info(result_caching['eval_time'], self.reference_vqe_result['statevector_simulator']['eval_time']/speedup_check)
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 _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)