def test_is_modified(self): json_dict = self.parser.get_sections() p = InputParser(json_dict) p.parse() p.set_section_property('optimizer', 'maxfun', 1002) self.assertTrue(p.is_modified()) self.assertEqual(p.get_section_property('optimizer', 'maxfun'), 1002)
def test_load_from_dict(self): json_dict = self.parser.get_sections() p = InputParser(json_dict) p.parse() dict1 = json.loads(json.dumps(self.parser.to_dictionary())) dict2 = json.loads(json.dumps(p.to_dictionary())) self.assertEqual(dict1, dict2)
def test_save(self): save_path = self._get_resource_path('output.txt') self.parser.save_to_file(save_path) p = InputParser(save_path) p.parse() os.remove(save_path) dict1 = json.loads(json.dumps(self.parser.to_dictionary())) dict2 = json.loads(json.dumps(p.to_dictionary())) self.assertEqual(dict1, dict2)
class TestInputParser(QiskitChemistryTestCase): """InputParser tests.""" def setUp(self): super().setUp() filepath = self._get_resource_path('test_input_parser.txt') self.parser = InputParser(filepath) self.parser.parse() def test_save(self): """ save test """ save_path = self._get_resource_path('output.txt') self.parser.save_to_file(save_path) parse = InputParser(save_path) parse.parse() os.remove(save_path) dict1 = json.loads(json.dumps(self.parser.to_dictionary())) dict2 = json.loads(json.dumps(parse.to_dictionary())) self.assertEqual(dict1, dict2) def test_load_from_dict(self): """ load from dict test """ json_dict = self.parser.get_sections() parse = InputParser(json_dict) parse.parse() dict1 = json.loads(json.dumps(self.parser.to_dictionary())) dict2 = json.loads(json.dumps(parse.to_dictionary())) self.assertEqual(dict1, dict2) def test_is_modified(self): """ is modified test """ json_dict = self.parser.get_sections() parse = InputParser(json_dict) parse.parse() parse.set_section_property('optimizer', 'maxfun', 1002) self.assertTrue(parse.is_modified()) self.assertEqual(parse.get_section_property('optimizer', 'maxfun'), 1002) def test_validate(self): """ validate test """ json_dict = self.parser.get_sections() parse = InputParser(json_dict) parse.parse() try: parse.validate_merge_defaults() except Exception as ex: # pylint: disable=broad-except self.fail(str(ex)) with self.assertRaises(AquaError): parse.set_section_property('backend', 'max_credits', -1)
def test_validate(self): json_dict = self.parser.get_sections() p = InputParser(json_dict) p.parse() try: p.validate_merge_defaults() except Exception as e: self.fail(str(e)) p.set_section_property('optimizer', 'dummy', 1002) self.assertRaises(AquaError, p.validate_merge_defaults)
def test_validate(self): json_dict = self.parser.get_sections() p = InputParser(json_dict) p.parse() try: p.validate_merge_defaults() except Exception as e: self.fail(str(e)) with self.assertRaises(AquaError): p.set_section_property('backend', 'max_credits', -1)
def test_validate(self): """ validate test """ json_dict = self.parser.get_sections() parse = InputParser(json_dict) parse.parse() try: parse.validate_merge_defaults() except Exception as ex: # pylint: disable=broad-except self.fail(str(ex)) with self.assertRaises(AquaError): parse.set_section_property('backend', 'max_credits', -1)
class TestInputParser(QiskitAquaChemistryTestCase): """InputParser tests.""" def setUp(self): filepath = self._get_resource_path('test_input_parser.txt') self.parser = InputParser(filepath) self.parser.parse() def test_save(self): save_path = self._get_resource_path('output.txt') self.parser.save_to_file(save_path) p = InputParser(save_path) p.parse() os.remove(save_path) dict1 = json.loads(json.dumps(self.parser.to_dictionary())) dict2 = json.loads(json.dumps(p.to_dictionary())) self.assertEqual(dict1, dict2) def test_load_from_dict(self): json_dict = self.parser.get_sections() p = InputParser(json_dict) p.parse() dict1 = json.loads(json.dumps(self.parser.to_dictionary())) dict2 = json.loads(json.dumps(p.to_dictionary())) self.assertEqual(dict1, dict2) def test_is_modified(self): json_dict = self.parser.get_sections() p = InputParser(json_dict) p.parse() p.set_section_property('optimizer', 'maxfun', 1002) self.assertTrue(p.is_modified()) self.assertEqual(p.get_section_property('optimizer', 'maxfun'), 1002) def test_validate(self): json_dict = self.parser.get_sections() p = InputParser(json_dict) p.parse() try: p.validate_merge_defaults() except Exception as e: self.fail(str(e)) p.set_section_property('optimizer', 'dummy', 1002) self.assertRaises(AquaError, p.validate_merge_defaults)
class QiskitChemistry: """Main Chemistry class.""" def __init__(self): """Create an QiskitChemistry object.""" self._parser = None self._operator = None self._qiskit_aqua = None self._hdf5_file = None self._chemistry_result = None @property def qiskit_aqua(self): """Returns Qiskit Aqua object.""" return self._qiskit_aqua @property def hdf5_file(self): """Returns Chemistry hdf5 path with chemistry results, if used.""" return self._hdf5_file @property def operator(self): """Returns Chemistry Operator.""" return self._operator @property def chemistry_result(self): """Returns Chemistry result.""" return self._chemistry_result @property def parser(self): """Returns Chemistry parser.""" return self._parser def run(self, params, output=None, backend=None): """ Runs the Qiskit Chemistry experiment Args: params (Union(dictionary, filename)): Chemistry input data output (filename): Output data backend (QuantumInstance or BaseBackend): the experimental settings to be used in place of backend name Returns: dict: result dictionary Raises: QiskitChemistryError: Missing Input, QiskitAqua object not created, result should be dictionary """ if params is None: raise QiskitChemistryError("Missing input.") self.run_driver(params, backend) if self.hdf5_file: logger.info('No further process.') self._chemistry_result = { 'printable': ["HDF5 file saved '{}'".format(self.hdf5_file)] } return self.chemistry_result if self.qiskit_aqua is None: raise QiskitChemistryError("QiskitAqua object not created.") data = self.qiskit_aqua.run() if not isinstance(data, dict): raise QiskitChemistryError( "Algorithm run result should be a dictionary") if logger.isEnabledFor(logging.DEBUG): logger.debug('Algorithm returned: %s', pprint.pformat(data, indent=4)) lines, self._chemistry_result = self.operator.process_algorithm_result( data) logger.info('Processing complete. Final result available') self._chemistry_result['printable'] = lines if output is not None: with open(output, 'w') as file: for line in self.chemistry_result['printable']: print(line, file=file) return self.chemistry_result def run_driver(self, params, backend=None): """ Runs the Qiskit Chemistry driver Args: params (Union(dictionary, filename)): Chemistry input data backend (QuantumInstance or BaseBackend): the experimental settings to be used in place of backend name Raises: QiskitChemistryError: Missing Input """ if params is None: raise QiskitChemistryError("Missing input.") self._operator = None self._chemistry_result = None self._qiskit_aqua = None self._hdf5_file = None self._parser = InputParser(params) self._parser.parse() # before merging defaults attempts to find a provider for the backend in case no # provider was passed if backend 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)) # set provider and name in input file for proper backend schema dictionary build if isinstance(backend, BaseBackend): self._parser.backend = backend self._parser.add_section_properties( JSONSchema.BACKEND, { JSONSchema.PROVIDER: get_provider_from_backend(backend), JSONSchema.NAME: backend.name(), }) self._parser.validate_merge_defaults() experiment_name = "-- no &NAME section found --" if JSONSchema.NAME in self._parser.get_section_names(): name_sect = self._parser.get_section(JSONSchema.NAME) if name_sect is not None: experiment_name = str(name_sect) logger.info('Running chemistry problem from input file: %s', self._parser.get_filename()) logger.info('Experiment description: %s', experiment_name.rstrip()) driver_name = self._parser.get_section_property( InputParser.DRIVER, JSONSchema.NAME) if driver_name is None: raise QiskitChemistryError( 'Property "{0}" missing in section "{1}"'.format( JSONSchema.NAME, InputParser.DRIVER)) self._hdf5_file = \ self._parser.get_section_property(InputParser.DRIVER, InputParser.HDF5_OUTPUT) if driver_name not in local_drivers(): raise QiskitChemistryError( 'Driver "{0}" missing in local drivers'.format(driver_name)) work_path = None input_file = self._parser.get_filename() if input_file is not None: work_path = os.path.dirname(os.path.realpath(input_file)) section = self._parser.get_section(driver_name) driver = get_driver_class(driver_name).init_from_input(section) driver.work_path = work_path molecule = driver.run() if work_path is not None and \ self._hdf5_file is not None and not os.path.isabs(self._hdf5_file): self._hdf5_file = os.path.abspath( os.path.join(work_path, self._hdf5_file)) molecule.log() if self._hdf5_file is not None: molecule.save(self._hdf5_file) logger.info("HDF5 file saved '%s'", self._hdf5_file) # Run the Hamiltonian to process the QMolecule and get an input for algorithms clazz = get_chemistry_operator_class( self._parser.get_section_property(InputParser.OPERATOR, JSONSchema.NAME)) self._operator = clazz.init_params( self._parser.get_section_properties(InputParser.OPERATOR)) qubit_op, aux_ops = self.operator.run(molecule) input_object = EnergyInput(qubit_op, aux_ops) logger.debug('Core computed substitution variables %s', self.operator.molecule_info) result = self._parser.process_substitutions( self.operator.molecule_info) logger.debug('Substitutions %s', result) aqua_params = {} for section_name, section in self._parser.get_sections().items(): if section_name == JSONSchema.NAME or \ section_name == InputParser.DRIVER or \ section_name == driver_name.lower() or \ section_name == InputParser.OPERATOR or \ not isinstance(section, dict): continue aqua_params[section_name] = copy.deepcopy(section) if JSONSchema.PROBLEM == section_name and \ InputParser.AUTO_SUBSTITUTIONS in aqua_params[section_name]: del aqua_params[section_name][InputParser.AUTO_SUBSTITUTIONS] self._qiskit_aqua = QiskitAqua(aqua_params, input_object, backend)
class QiskitChemistry(object): """Main entry point.""" KEY_HDF5_OUTPUT = 'hdf5_output' _DRIVER_RUN_TO_HDF5 = 1 _DRIVER_RUN_TO_ALGO_INPUT = 2 def __init__(self): """Create an QiskitChemistry object.""" self._parser = None self._core = None def run(self, input, output=None, backend=None): """ Runs the Aqua Chemistry experiment Args: input (dictionary/filename): Input data output (filename): Output data backend (BaseBackend): backend object Returns: result dictionary """ if input is None: raise QiskitChemistryError("Missing input.") self._parser = InputParser(input) self._parser.parse() driver_return = self._run_driver_from_parser(self._parser, False) if driver_return[0] == QiskitChemistry._DRIVER_RUN_TO_HDF5: logger.info('No further process.') return {'printable': [driver_return[1]]} data = run_algorithm(driver_return[1], driver_return[2], True, backend) if not isinstance(data, dict): raise QiskitChemistryError( "Algorithm run result should be a dictionary") convert_json_to_dict(data) if logger.isEnabledFor(logging.DEBUG): logger.debug('Algorithm returned: {}'.format( pprint.pformat(data, indent=4))) lines, result = self._format_result(data) logger.info('Processing complete. Final result available') result['printable'] = lines if output is not None: with open(output, 'w') as f: for line in lines: print(line, file=f) return result def save_input(self, input_file): """ Save the input of a run to a file. Params: input_file (string): file path """ if self._parser is None: raise QiskitChemistryError("Missing input information.") self._parser.save_to_file(input_file) def run_drive_to_jsonfile(self, input, jsonfile): if jsonfile is None: raise QiskitChemistryError("Missing json file") data = self._run_drive(input, True) if data is None: logger.info('No data to save. No further process.') return with open(jsonfile, 'w') as fp: json.dump(data, fp, sort_keys=True, indent=4) print("Algorithm input file saved: '{}'".format(jsonfile)) def run_algorithm_from_jsonfile(self, jsonfile, output=None, backend=None): """ Runs the Aqua Chemistry experiment from json file Args: jsonfile (filename): Input data output (filename): Output data backend (BaseBackend): backend object Returns: result dictionary """ with open(jsonfile) as json_file: return self.run_algorithm_from_json(json.load(json_file), output, backend) def run_algorithm_from_json(self, params, output=None, backend=None): """ Runs the Aqua Chemistry experiment from json dictionary Args: params (dictionary): Input data output (filename): Output data backend (BaseBackend): backend object Returns: result dictionary """ ret = run_algorithm(params, None, True, backend) if not isinstance(ret, dict): raise QiskitChemistryError( "Algorithm run result should be a dictionary") convert_json_to_dict(ret) if logger.isEnabledFor(logging.DEBUG): logger.debug('Algorithm returned: {}'.format( pprint.pformat(ret, indent=4))) print('Output:') if isinstance(ret, dict): for k, v in ret.items(): print("'{}': {}".format(k, v)) else: print(ret) return ret def _format_result(self, data): lines, result = self._core.process_algorithm_result(data) return lines, result def run_drive(self, input): return self._run_drive(input, False) def _run_drive(self, input, save_json_algo_file): if input is None: raise QiskitChemistryError("Missing input.") self._parser = InputParser(input) self._parser.parse() driver_return = self._run_driver_from_parser(self._parser, save_json_algo_file) driver_return[1]['input'] = driver_return[2].to_params() driver_return[1]['input']['name'] = driver_return[2].configuration[ 'name'] return driver_return[1] def _run_driver_from_parser(self, p, save_json_algo_file): if p is None: raise QiskitChemistryError("Missing parser") # before merging defaults attempts to find a provider for the backend in case no # provider was passed if p.get_section_property(JSONSchema.BACKEND, JSONSchema.PROVIDER) is None: backend_name = p.get_section_property(JSONSchema.BACKEND, JSONSchema.NAME) if backend_name is not None: p.set_section_property(JSONSchema.BACKEND, JSONSchema.PROVIDER, get_provider_from_backend(backend_name)) p.validate_merge_defaults() # logger.debug('ALgorithm Input Schema: {}'.format(json.dumps(p..get_sections(), sort_keys=True, indent=4))) experiment_name = "-- no &NAME section found --" if JSONSchema.NAME in p.get_section_names(): name_sect = p.get_section(JSONSchema.NAME) if name_sect is not None: experiment_name = str(name_sect) logger.info('Running chemistry problem from input file: {}'.format( p.get_filename())) logger.info('Experiment description: {}'.format( experiment_name.rstrip())) driver_name = p.get_section_property(InputParser.DRIVER, JSONSchema.NAME) if driver_name is None: raise QiskitChemistryError( 'Property "{0}" missing in section "{1}"'.format( JSONSchema.NAME, InputParser.DRIVER)) hdf5_file = p.get_section_property(InputParser.DRIVER, QiskitChemistry.KEY_HDF5_OUTPUT) if driver_name not in local_drivers(): raise QiskitChemistryError( 'Driver "{0}" missing in local drivers'.format(driver_name)) work_path = None input_file = p.get_filename() if input_file is not None: work_path = os.path.dirname(os.path.realpath(input_file)) section = p.get_section(driver_name) driver = get_driver_class(driver_name).init_from_input(section) driver.work_path = work_path molecule = driver.run() if work_path is not None and hdf5_file is not None and not os.path.isabs( hdf5_file): hdf5_file = os.path.abspath(os.path.join(work_path, hdf5_file)) molecule.log() if hdf5_file is not None: molecule._origin_driver_name = driver_name molecule._origin_driver_config = section if isinstance( section, str) else json.dumps( section, sort_keys=True, indent=4) molecule.save(hdf5_file) text = "HDF5 file saved '{}'".format(hdf5_file) logger.info(text) if not save_json_algo_file: logger.info('Run ended with hdf5 file saved.') return QiskitChemistry._DRIVER_RUN_TO_HDF5, text # Run the Hamiltonian to process the QMolecule and get an input for algorithms cls = get_chemistry_operator_class( p.get_section_property(InputParser.OPERATOR, JSONSchema.NAME)) self._core = cls.init_params( p.get_section_properties(InputParser.OPERATOR)) input_object = self._core.run(molecule) logger.debug('Core computed substitution variables {}'.format( self._core.molecule_info)) result = p.process_substitutions(self._core.molecule_info) logger.debug('Substitutions {}'.format(result)) params = {} for section_name, section in p.get_sections().items(): if section_name == JSONSchema.NAME or \ section_name == InputParser.DRIVER or \ section_name == driver_name.lower() or \ section_name == InputParser.OPERATOR or \ not isinstance(section, dict): continue params[section_name] = copy.deepcopy(section) if JSONSchema.PROBLEM == section_name and InputParser.AUTO_SUBSTITUTIONS in params[ section_name]: del params[section_name][InputParser.AUTO_SUBSTITUTIONS] return QiskitChemistry._DRIVER_RUN_TO_ALGO_INPUT, params, input_object