diff --git a/.pylintdict b/.pylintdict index bb40a9e097..e5d023e2dc 100644 --- a/.pylintdict +++ b/.pylintdict @@ -6,7 +6,6 @@ aerjob aij al algo -algorithminput amongst amsgrad anc @@ -335,7 +334,6 @@ ph piecewise plesset pluggable -PluggableType pluggables polynomially postoracle diff --git a/qiskit/aqua/__init__.py b/qiskit/aqua/__init__.py index fbdec6eba1..9c0986be3a 100644 --- a/qiskit/aqua/__init__.py +++ b/qiskit/aqua/__init__.py @@ -73,29 +73,9 @@ from .version import __version__ from .aqua_error import AquaError from .aqua_globals import aqua_globals -from .preferences import Preferences -from ._discover import (PLUGGABLES_ENTRY_POINT, - PluggableType, - refresh_pluggables, - local_pluggables_types, - local_pluggables, - get_pluggable_class, - get_pluggable_configuration, - register_pluggable, - deregister_pluggable) -from .utils.backend_utils import (get_aer_backend, - get_backends_from_provider, - get_backend_from_provider, - get_local_providers, - register_ibmq_and_get_known_providers, - get_provider_from_backend) from .pluggable import Pluggable from .quantum_instance import QuantumInstance from .algorithms import QuantumAlgorithm -from .qiskit_aqua import (QiskitAqua, - execute_algorithm, - run_algorithm, - run_algorithm_to_json) from ._logging import (get_logging_level, build_logging_config, set_logging_config, @@ -104,30 +84,10 @@ __all__ = ['__version__', 'AquaError', - 'Preferences', 'Pluggable', 'QuantumAlgorithm', - 'PLUGGABLES_ENTRY_POINT', - 'PluggableType', - 'refresh_pluggables', 'QuantumInstance', - 'get_aer_backend', - 'get_backends_from_provider', - 'get_backend_from_provider', - 'get_local_providers', - 'register_ibmq_and_get_known_providers', - 'get_provider_from_backend', - 'local_pluggables_types', - 'local_pluggables', - 'get_pluggable_class', - 'get_pluggable_configuration', - 'register_pluggable', - 'deregister_pluggable', 'aqua_globals', - 'QiskitAqua', - 'execute_algorithm', - 'run_algorithm', - 'run_algorithm_to_json', 'get_logging_level', 'build_logging_config', 'set_logging_config', diff --git a/qiskit/aqua/_discover.py b/qiskit/aqua/_discover.py deleted file mode 100644 index 01b7f50039..0000000000 --- a/qiskit/aqua/_discover.py +++ /dev/null @@ -1,485 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" -Methods for pluggable objects discovery, registration, information -""" - -import logging -import os -import pkgutil -import importlib -import inspect -import copy -from collections import namedtuple -from enum import Enum -import pkg_resources -from qiskit.aqua import AquaError - -logger = logging.getLogger(__name__) - -PLUGGABLES_ENTRY_POINT = 'qiskit.aqua.pluggables' - - -class PluggableType(Enum): - """ Pluggable Types """ - ALGORITHM = 'algorithm' - OPTIMIZER = 'optimizer' - VARIATIONAL_FORM = 'variational_form' - INITIAL_STATE = 'initial_state' - IQFT = 'iqft' - QFT = 'qft' - ORACLE = 'oracle' - FEATURE_MAP = 'feature_map' - MULTICLASS_EXTENSION = 'multiclass_extension' - UNCERTAINTY_PROBLEM = 'uncertainty_problem' - UNIVARIATE_DISTRIBUTION = 'univariate_distribution' - MULTIVARIATE_DISTRIBUTION = 'multivariate_distribution' - INPUT = 'input' - EIGENVALUES = 'eigs' - RECIPROCAL = 'reciprocal' - GENERATIVE_NETWORK = 'generative_network' - DISCRIMINATIVE_NETWORK = 'discriminative_network' - - -def _get_pluggables_types_dict(): - """ - Gets all the pluggables types - Any new pluggable type should be added here - """ - # pylint: disable=import-outside-toplevel - from qiskit.aqua.components.uncertainty_problems import UncertaintyProblem - from qiskit.aqua.components.uncertainty_models import UnivariateDistribution - from qiskit.aqua.components.uncertainty_models import MultivariateDistribution - from qiskit.aqua.components.optimizers import Optimizer - from qiskit.aqua.algorithms.quantum_algorithm import QuantumAlgorithm - from qiskit.aqua.components.variational_forms import VariationalForm - from qiskit.aqua.components.initial_states import InitialState - from qiskit.aqua.components.iqfts import IQFT - from qiskit.aqua.components.qfts import QFT - from qiskit.aqua.components.oracles import Oracle - from qiskit.aqua.components.feature_maps import FeatureMap - from qiskit.aqua.components.multiclass_extensions import MulticlassExtension - from qiskit.aqua.input import AlgorithmInput - from qiskit.aqua.components.eigs import Eigenvalues - from qiskit.aqua.components.reciprocals import Reciprocal - from qiskit.aqua.components.neural_networks.discriminative_network import \ - DiscriminativeNetwork - from qiskit.aqua.components.neural_networks.generative_network import GenerativeNetwork - - return { - PluggableType.ALGORITHM: QuantumAlgorithm, - PluggableType.OPTIMIZER: Optimizer, - PluggableType.VARIATIONAL_FORM: VariationalForm, - PluggableType.INITIAL_STATE: InitialState, - PluggableType.IQFT: IQFT, - PluggableType.QFT: QFT, - PluggableType.ORACLE: Oracle, - PluggableType.FEATURE_MAP: FeatureMap, - PluggableType.MULTICLASS_EXTENSION: MulticlassExtension, - PluggableType.UNCERTAINTY_PROBLEM: UncertaintyProblem, - PluggableType.UNIVARIATE_DISTRIBUTION: UnivariateDistribution, - PluggableType.MULTIVARIATE_DISTRIBUTION: MultivariateDistribution, - PluggableType.INPUT: AlgorithmInput, - PluggableType.EIGENVALUES: Eigenvalues, - PluggableType.RECIPROCAL: Reciprocal, - PluggableType.DISCRIMINATIVE_NETWORK: DiscriminativeNetwork, - PluggableType.GENERATIVE_NETWORK: GenerativeNetwork - } - - -_NAMES_TO_EXCLUDE = [os.path.basename(__file__)] - -_FOLDERS_TO_EXCLUDE = ['__pycache__', 'gauopen'] - - -class DiscoverRegistry: - """Contains Discovered Classes Info.""" - - REGISTERED_INFO = namedtuple( - 'REGISTERED_INFO', ['name', 'cls', 'configuration']) - - def __init__(self) -> None: - self._discovered = False - self._registry = {} - - @property - def discovered(self): - """ Returns discovered flag """ - return self._discovered - - def set_discovered(self): - """ Set registry as discovered """ - self._discovered = True - - @property - def registry(self): - """ Return registry dictionary """ - return self._registry - - def reset(self): - """ reset registry data """ - self._discovered = False - self._registry = {} - - -# Registry Global Instance -_REGISTRY_PLUGGABLE = DiscoverRegistry() - - -def refresh_pluggables(): - """ - Attempts to rediscover all pluggable modules - """ - _REGISTRY_PLUGGABLE.reset() - _REGISTRY_PLUGGABLE.set_discovered() - directory = os.path.dirname(__file__) - _discover_local_pluggables(directory) - _discover_local_pluggables(os.path.abspath(os.path.join(directory, '..', 'ml')), - 'qiskit.ml') - _discover_local_pluggables(os.path.abspath(os.path.join(directory, '..', 'chemistry')), - 'qiskit.chemistry') - _discover_local_pluggables(os.path.abspath(os.path.join(directory, '..', 'finance')), - 'qiskit.finance') - _discover_local_pluggables(os.path.abspath(os.path.join(directory, '..', 'optimization')), - 'qiskit.optimization') - _discover_entry_pt_pluggables() - if logger.isEnabledFor(logging.DEBUG): - for ptype in local_pluggables_types(): - logger.debug("Found: '%s' has pluggables %s ", ptype.value, local_pluggables(ptype)) - - -def _discover_on_demand(): - """ - Attempts to discover pluggable modules, if not already discovered - """ - if not _REGISTRY_PLUGGABLE.discovered: - _REGISTRY_PLUGGABLE.reset() - _REGISTRY_PLUGGABLE.set_discovered() - directory = os.path.dirname(__file__) - _discover_local_pluggables(directory) - _discover_local_pluggables(os.path.abspath(os.path.join(directory, '..', 'ml')), - 'qiskit.ml') - _discover_local_pluggables(os.path.abspath(os.path.join(directory, '..', 'chemistry')), - 'qiskit.chemistry') - _discover_local_pluggables(os.path.abspath(os.path.join(directory, '..', 'finance')), - 'qiskit.finance') - _discover_local_pluggables(os.path.abspath(os.path.join(directory, '..', 'optimization')), - 'qiskit.optimization') - _discover_entry_pt_pluggables() - if logger.isEnabledFor(logging.DEBUG): - for ptype in local_pluggables_types(): - logger.debug("Found: '%s' has pluggables %s ", ptype.value, local_pluggables(ptype)) - - -def _discover_entry_pt_pluggables(): - """ - Discovers the pluggable modules defined by entry_points in setup - and attempts to register them. Pluggable modules should subclass Pluggable Base classes. - """ - for entry_point in pkg_resources.iter_entry_points(PLUGGABLES_ENTRY_POINT): - # first calls require and log any errors returned due to dependencies mismatches - try: - entry_point.require() - except Exception as ex: # pylint: disable=broad-except - logger.warning("Entry point '%s' requirements issue: %s", entry_point, str(ex)) - - # now call resolve and try to load entry point - try: - e_p = entry_point.resolve() - _registered = False - for pluggable_type, c in _get_pluggables_types_dict().items(): - if not inspect.isabstract(e_p) and issubclass(e_p, c): - _register_pluggable(pluggable_type, e_p) - _registered = True - logger.debug( - "Registered entry point pluggable type '%s' '%s' class '%s'", - pluggable_type.value, entry_point, e_p) - break - - if not _registered: - # print("Unknown entry point pluggable '{}' class '{}'".format(entry_point, e_p)) - logger.debug("Unknown entry point pluggable '%s' class '%s'", entry_point, e_p) - except Exception as ex: # pylint: disable=broad-except - # Ignore entry point that could not be initialized. - # print("Failed to load entry point '{}' error {}".format(entry_point, str(e))) - logger.debug("Failed to load entry point '%s' error %s", entry_point, str(ex)) - - -def _discover_local_pluggables(directory=os.path.dirname(__file__), - parentname=os.path.splitext(__name__)[0], - names_to_exclude=None, - folders_to_exclude=None): - """ - Discovers the pluggable modules on the directory and subdirectories of the current module - and attempts to register them. Pluggable modules should subclass Pluggable Base classes. - Args: - directory (Optional(str)): Directory to search for pluggable. Defaults - to the directory of this module. - parentname (Optional(str)): Module parent name. Defaults to current directory name - names_to_exclude (Optional(list[str])): File names to exclude. - Defaults to _NAMES_TO_EXCLUDE - folders_to_exclude (Optional(list[str])): Folders to exclude. - Defaults to _FOLDERS_TO_EXCLUDE - """ - names_to_exclude = names_to_exclude if names_to_exclude is not None else _NAMES_TO_EXCLUDE - folders_to_exclude = folders_to_exclude \ - if folders_to_exclude is not None else _FOLDERS_TO_EXCLUDE - for _, name, ispackage in pkgutil.iter_modules([directory]): - if ispackage: - continue - - # Iterate through the modules - if name not in names_to_exclude: # skip those modules - try: - fullname = parentname + '.' + name - modspec = importlib.util.find_spec(fullname) - mod = importlib.util.module_from_spec(modspec) - modspec.loader.exec_module(mod) - for _, cls in inspect.getmembers(mod, inspect.isclass): - # Iterate through the classes defined on the module. - try: - if cls.__module__ == modspec.name: - for pluggable_type, c in _get_pluggables_types_dict().items(): - if not inspect.isabstract(cls) and issubclass(cls, c): - _register_pluggable(pluggable_type, cls) - importlib.import_module(fullname) - break - except Exception as ex: # pylint: disable=broad-except - # Ignore pluggables that could not be initialized. - # print('Failed to load pluggable {} error {}'.format(fullname, str(ex))) - logger.debug('Failed to load pluggable %s error %s', fullname, str(ex)) - - except Exception as ex: # pylint: disable=broad-except - # Ignore pluggables that could not be initialized. - # print('Failed to load {} error {}'.format(fullname, str(ex))) - logger.debug('Failed to load %s error %s', fullname, str(ex)) - - for item in sorted(os.listdir(directory)): - fullpath = os.path.join(directory, item) - if item not in folders_to_exclude and not item.endswith('dSYM') and os.path.isdir(fullpath): - _discover_local_pluggables(fullpath, parentname + '.' + item, - names_to_exclude, folders_to_exclude) - - -def register_pluggable(cls): - """ - Registers a pluggable class - Args: - cls (Pluggable): Pluggable class. - Returns: - str: pluggable name - Raises: - AquaError: Class doesn't derive from known pluggable - """ - _discover_on_demand() - pluggable_type = None - for p_type, c in _get_pluggables_types_dict().items(): - if issubclass(cls, c): - pluggable_type = p_type - break - - if pluggable_type is None: - raise AquaError( - 'Could not register class {} is not subclass of any known pluggable'.format(cls)) - - return _register_pluggable(pluggable_type, cls) - - -GLOBAL_CLASS = None - - -def _register_pluggable(pluggable_type, cls): - """ - Registers a pluggable class - Args: - pluggable_type(PluggableType): The pluggable type - cls (Pluggable): Pluggable class. - Returns: - str: pluggable name - Raises: - AquaError: if the class is already registered or could not be registered - """ - if pluggable_type not in _REGISTRY_PLUGGABLE.registry: - _REGISTRY_PLUGGABLE.registry[pluggable_type] = {} - - # fix pickle problems - method = 'from {} import {}\nglobal GLOBAL_CLASS\nGLOBAL_CLASS = {}'.format( - cls.__module__, cls.__qualname__, cls.__qualname__) - exec(method) # pylint: disable=exec-used - cls = GLOBAL_CLASS - - # Verify that the pluggable is not already registered. - registered_classes = _REGISTRY_PLUGGABLE.registry[pluggable_type] - if cls in [pluggable.cls for pluggable in registered_classes.values()]: - raise AquaError( - 'Could not register class {} is already registered'.format(cls)) - - # Verify that it has a minimal valid configuration. - try: - pluggable_name = cls.CONFIGURATION['name'] - except (LookupError, TypeError): - raise AquaError('Could not register pluggable: invalid configuration') - - # Verify that the pluggable is valid - check_pluggable_valid = getattr(cls, 'check_pluggable_valid', None) - if check_pluggable_valid is not None: - try: - # pylint: disable=not-callable - check_pluggable_valid() - except Exception as ex: # pylint: disable=broad-except - logger.debug(str(ex)) - raise AquaError('Could not register class {}. Name {} is not valid'.format( - cls, pluggable_name)) from ex - - if pluggable_name in _REGISTRY_PLUGGABLE.registry[pluggable_type]: - raise AquaError('Could not register class {}. Name {} {} ' - 'is already registered'.format( - cls, pluggable_name, - _REGISTRY_PLUGGABLE.registry[pluggable_type][pluggable_name].cls)) - - # Append the pluggable to the `registered_classes` dict. - _REGISTRY_PLUGGABLE.registry[pluggable_type][pluggable_name] = DiscoverRegistry.REGISTERED_INFO( - pluggable_name, cls, copy.deepcopy(cls.CONFIGURATION)) - return pluggable_name - - -def deregister_pluggable(pluggable_type, pluggable_name): - """ - Deregisters a pluggable class - Args: - pluggable_type(PluggableType): The pluggable type - pluggable_name (str): The pluggable name - Raises: - AquaError: if the class is not registered - """ - _discover_on_demand() - - if pluggable_type not in _REGISTRY_PLUGGABLE.registry: - raise AquaError('Could not deregister {} {} not registered'.format( - pluggable_type, pluggable_name)) - - if pluggable_name not in _REGISTRY_PLUGGABLE.registry[pluggable_type]: - raise AquaError('Could not deregister {} {} not registered'.format( - pluggable_type, pluggable_name)) - - _REGISTRY_PLUGGABLE.registry[pluggable_type].pop(pluggable_name) - - -def get_pluggable_class(pluggable_type, pluggable_name): - """ - Accesses pluggable class - Args: - pluggable_type(Union(PluggableType,str)): The pluggable type - pluggable_name (str): The pluggable name - Returns: - Pluggable: pluggable class - Raises: - AquaError: if the class is not registered - """ - _discover_on_demand() - - if isinstance(pluggable_type, str): - for ptype in PluggableType: - if ptype.value == pluggable_type: - pluggable_type = ptype - break - - if not isinstance(pluggable_type, PluggableType): - raise AquaError('Invalid pluggable type {} {}'.format(pluggable_type, pluggable_name)) - - if pluggable_type not in _REGISTRY_PLUGGABLE.registry: - raise AquaError('{} {} not registered'.format(pluggable_type, pluggable_name)) - - if not pluggable_name: - raise AquaError( - 'Unable to get class for pluggable {}: Missing name.'.format(pluggable_type)) - - if pluggable_name not in _REGISTRY_PLUGGABLE.registry[pluggable_type]: - raise AquaError("{} '{}' not registered".format(pluggable_type, pluggable_name)) - - return _REGISTRY_PLUGGABLE.registry[pluggable_type][pluggable_name].cls - - -def get_pluggable_configuration(pluggable_type, pluggable_name): - """ - Accesses pluggable configuration - Args: - pluggable_type(Union(PluggableType,str)): The pluggable type - pluggable_name (str): The pluggable name - Returns: - dict: pluggable configuration - Raises: - AquaError: if the class is not registered - """ - _discover_on_demand() - - if isinstance(pluggable_type, str): - for ptype in PluggableType: - if ptype.value == pluggable_type: - pluggable_type = ptype - break - - if not isinstance(pluggable_type, PluggableType): - raise AquaError('Invalid pluggable type {} {}'.format(pluggable_type, pluggable_name)) - - if pluggable_type not in _REGISTRY_PLUGGABLE.registry: - raise AquaError('{} {} not registered'.format(pluggable_type, pluggable_name)) - - if not pluggable_name: - raise AquaError( - 'Unable to get configuration for pluggable {}: Missing name.'.format(pluggable_type)) - - if pluggable_name not in _REGISTRY_PLUGGABLE.registry[pluggable_type]: - raise AquaError('{} {} not registered'.format(pluggable_type, pluggable_name)) - - return copy.deepcopy(_REGISTRY_PLUGGABLE.registry[pluggable_type][pluggable_name].configuration) - - -def local_pluggables_types(): - """ - Accesses all pluggable types - Returns: - list[PluggableType]: pluggable types - """ - _discover_on_demand() - return list(_REGISTRY_PLUGGABLE.registry.keys()) - - -def local_pluggables(pluggable_type): - """ - Accesses pluggable names - Args: - pluggable_type (Union(PluggableType,str)): The pluggable type - Returns: - list[str]: pluggable names - Raises: - AquaError: if the type is not registered - """ - _discover_on_demand() - - if isinstance(pluggable_type, str): - for ptype in PluggableType: - if ptype.value == pluggable_type: - pluggable_type = ptype - break - - if not isinstance(pluggable_type, PluggableType): - raise AquaError( - 'Invalid pluggable type {}'.format(pluggable_type)) - - if pluggable_type not in _REGISTRY_PLUGGABLE.registry: - raise AquaError('{} not registered'.format(pluggable_type)) - - return [pluggable.name for pluggable in _REGISTRY_PLUGGABLE.registry[pluggable_type].values()] diff --git a/qiskit/aqua/_ibmq_credentials_preferences.py b/qiskit/aqua/_ibmq_credentials_preferences.py deleted file mode 100644 index a3054dd42e..0000000000 --- a/qiskit/aqua/_ibmq_credentials_preferences.py +++ /dev/null @@ -1,185 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - - -"""IBMQ Credential preferences""" - -import copy -import logging -from collections import OrderedDict -# pylint: disable=no-name-in-module, import-error -from qiskit.providers.ibmq.ibmqfactory import QX_AUTH_URL -from qiskit.providers.ibmq.credentials import Credentials -# pylint: disable=syntax-error -from qiskit.providers.ibmq.credentials.configrc import (read_credentials_from_qiskitrc, - write_qiskit_rc) -from qiskit.providers.ibmq.credentials.updater import is_directly_updatable, QE2_AUTH_URL - -logger = logging.getLogger(__name__) - - -class IBMQCredentialsPreferences: - """IBMQ Credential preferences""" - _IBMQ_KEY = 'ibmq' - _HUB_KEY = 'hub' - _GROUP_KEY = 'group' - _PROJECT_KEY = 'project' - - def __init__(self, preferences_dict): - """Create IBMQCredentialsPreferences object.""" - self._ibmq_dict = preferences_dict.get(IBMQCredentialsPreferences._IBMQ_KEY, {}) - self._ibmq_changed = False - self._credentials_changed = False - self._credentials = None - self._read_credentials() - - def _read_credentials(self): - """Read first credential from file and attempt to convert to v2""" - self._credentials = None - try: - credentials = read_credentials_from_qiskitrc() - if credentials: - credentials = list(credentials.values())[0] - if credentials: - if is_directly_updatable(credentials): - self._credentials = Credentials(credentials.token, - QE2_AUTH_URL, - proxies=credentials.proxies, - verify=credentials.verify) - elif credentials.url == QE2_AUTH_URL: - self._credentials = credentials - elif credentials.is_ibmq(): - self._credentials = Credentials(credentials.token, - QE2_AUTH_URL, - proxies=credentials.proxies, - verify=credentials.verify) - self._ibmq_dict[IBMQCredentialsPreferences._HUB_KEY] = credentials.hub - self._ibmq_dict[IBMQCredentialsPreferences._GROUP_KEY] = credentials.group - self._ibmq_dict[IBMQCredentialsPreferences._PROJECT_KEY] = \ - credentials.project - else: - # Unknown URL - do not act on it. - logger.debug('The stored account with url "%s" could not be ' - 'parsed.', credentials.url) - except Exception as ex: # pylint: disable=broad-except - logger.debug("Failed to read IBM credentials: '%s'", str(ex)) - - def save(self, preferences_dict): - """Save credentials, always keep only one""" - if self._credentials_changed: - try: - stored_credentials = OrderedDict() - if self._credentials is not None: - stored_credentials[self._credentials.unique_id()] = self._credentials - - write_qiskit_rc(stored_credentials) - except Exception as ex: # pylint: disable=broad-except - logger.debug("Failed to store IBM credentials: '%s'", str(ex)) - - self._credentials_changed = False - self._read_credentials() - - if self._ibmq_changed: - preferences_dict[IBMQCredentialsPreferences._IBMQ_KEY] = self._ibmq_dict - self._ibmq_changed = False - - @property - def credentials(self): - """ returns credentials """ - return self._credentials - - def set_credentials(self, token, proxy_urls=None): - """ set credentials """ - if token is not None: - proxies = {} if proxy_urls is None else {'urls': proxy_urls} - cred = Credentials(token, QX_AUTH_URL, proxies=proxies) - if self._credentials is None or self._credentials != cred: - self._credentials = cred - self._credentials_changed = True - else: - if self._credentials is not None: - self._credentials_changed = True - - self._credentials = None - self.hub = None - self.group = None - self.project = None - - return self._credentials - - @property - def url(self): - """ returns URL """ - if self._credentials is not None: - return self._credentials.url - - return None - - @property - def token(self): - """ returns token """ - if self._credentials is not None: - return self._credentials.token - - return None - - @property - def proxies(self): - """ returns proxies """ - if self._credentials is not None: - return copy.deepcopy(self._credentials.proxies) - - return None - - @property - def proxy_urls(self): - """ returns proxy URL list """ - if self._credentials is not None and \ - 'urls' in self._credentials.proxies: - return copy.deepcopy(self._credentials.proxies['urls']) - - return None - - @property - def hub(self): - """ return hub """ - return self._ibmq_dict.get(IBMQCredentialsPreferences._HUB_KEY) - - @hub.setter - def hub(self, hub): - """Set hub.""" - self._ibmq_dict[IBMQCredentialsPreferences._HUB_KEY] = hub - self._ibmq_changed = True - - @property - def group(self): - """ returns group """ - return self._ibmq_dict.get(IBMQCredentialsPreferences._GROUP_KEY) - - @group.setter - def group(self, group): - """Set group.""" - self._ibmq_dict[IBMQCredentialsPreferences._GROUP_KEY] = group - self._ibmq_changed = True - - @property - def project(self): - """ returns project """ - return self._ibmq_dict.get(IBMQCredentialsPreferences._PROJECT_KEY) - - @project.setter - def project(self, project): - """Set project.""" - self._ibmq_dict[IBMQCredentialsPreferences._PROJECT_KEY] = project - self._ibmq_changed = True diff --git a/qiskit/aqua/_logging.py b/qiskit/aqua/_logging.py index f3dd316479..bf52cd2f79 100644 --- a/qiskit/aqua/_logging.py +++ b/qiskit/aqua/_logging.py @@ -17,8 +17,6 @@ import copy import logging from logging.config import dictConfig -from collections import OrderedDict -import pkg_resources _ALGO_LOGGING_CONFIG = { 'version': 1, @@ -39,14 +37,7 @@ def _get_logging_names(): - # pylint: disable=import-outside-toplevel - from qiskit.aqua import PLUGGABLES_ENTRY_POINT - names = OrderedDict() - names['qiskit.aqua'] = None - for entry_point in pkg_resources.iter_entry_points(PLUGGABLES_ENTRY_POINT): - names[entry_point.module_name] = None - - return list(names.keys()) + return ['qiskit.aqua'] def build_logging_config(level, filepath=None): diff --git a/qiskit/aqua/algorithms/adaptive/qaoa/qaoa.py b/qiskit/aqua/algorithms/adaptive/qaoa/qaoa.py index f19c3b2b58..0d0fd02dfd 100644 --- a/qiskit/aqua/algorithms/adaptive/qaoa/qaoa.py +++ b/qiskit/aqua/algorithms/adaptive/qaoa/qaoa.py @@ -17,13 +17,7 @@ # pylint: disable=unused-import import logging -import warnings - -from qiskit.aqua import AquaError, Pluggable, PluggableType, get_pluggable_class -from qiskit.aqua.operators import BaseOperator from qiskit.aqua.algorithms.adaptive import VQE -from qiskit.aqua.components.optimizers import Optimizer -from qiskit.aqua.components.initial_states import InitialState from .var_form import QAOAVarForm logger = logging.getLogger(__name__) @@ -118,40 +112,3 @@ def __init__(self, operator, optimizer, p=1, initial_state=None, mixer=None, super().__init__(operator, var_form, optimizer, initial_point=initial_point, max_evals_grouped=max_evals_grouped, aux_operators=aux_operators, callback=callback, auto_conversion=auto_conversion) - - @classmethod - def init_params(cls, params, algo_input): - """ - Initialize via parameters dictionary and algorithm input instance - - Args: - params (dict): parameters dictionary - algo_input (EnergyInput): EnergyInput instance - Returns: - QAOA: instance of this class - Raises: - AquaError: invalid input - """ - if algo_input is None: - raise AquaError("EnergyInput instance is required.") - - operator = algo_input.qubit_op - - qaoa_params = params.get(Pluggable.SECTION_KEY_ALGORITHM) - p = qaoa_params.get('p') - initial_point = qaoa_params.get('initial_point') - max_evals_grouped = qaoa_params.get('max_evals_grouped') - - init_state_params = params.get(Pluggable.SECTION_KEY_INITIAL_STATE) - init_state_params['num_qubits'] = operator.num_qubits - init_state = get_pluggable_class(PluggableType.INITIAL_STATE, - init_state_params['name']).init_params(params) - - # Set up optimizer - opt_params = params.get(Pluggable.SECTION_KEY_OPTIMIZER) - optimizer = get_pluggable_class(PluggableType.OPTIMIZER, - opt_params['name']).init_params(params) - - return cls(operator, optimizer, p=p, initial_state=init_state, - initial_point=initial_point, max_evals_grouped=max_evals_grouped, - aux_operators=algo_input.aux_ops) diff --git a/qiskit/aqua/algorithms/adaptive/qgan/qgan.py b/qiskit/aqua/algorithms/adaptive/qgan/qgan.py index 6f366db9bc..68a92a8805 100644 --- a/qiskit/aqua/algorithms/adaptive/qgan/qgan.py +++ b/qiskit/aqua/algorithms/adaptive/qgan/qgan.py @@ -24,7 +24,6 @@ from scipy.stats import entropy from qiskit.aqua import AquaError, aqua_globals -from qiskit.aqua import Pluggable, get_pluggable_class, PluggableType from qiskit.aqua.algorithms import QuantumAlgorithm from qiskit.aqua.components.neural_networks.quantum_generator import QuantumGenerator from qiskit.aqua.components.neural_networks.numpy_discriminator import NumpyDiscriminator @@ -175,44 +174,6 @@ def __init__(self, data, bounds=None, num_qubits=None, batch_size=500, num_epoch self._ret = {} - @classmethod - def init_params(cls, params, algo_input): - """ - Initialize qGAN via parameters dictionary and algorithm input instance. - - Args: - params (dict): parameters dictionary - algo_input (AlgorithmInput): Input instance - Returns: - QGAN: qgan object - Raises: - AquaError: invalid input - """ - - if algo_input is None: - raise AquaError("Input instance not supported.") - - qgan_params = params.get(Pluggable.SECTION_KEY_ALGORITHM) - num_qubits = qgan_params.get('num_qubits') - batch_size = qgan_params.get('batch_size') - num_epochs = qgan_params.get('num_epochs') - seed = qgan_params.get('seed') - tol_rel_ent = qgan_params.get('tol_rel_ent') - snapshot_dir = qgan_params.get('snapshot_dir') - - discriminator_params = params.get(Pluggable.SECTION_KEY_DISCRIMINATIVE_NET) - generator_params = params.get(Pluggable.SECTION_KEY_GENERATIVE_NETWORK) - generator_params['num_qubits'] = num_qubits - - discriminator = get_pluggable_class(PluggableType.DISCRIMINATIVE_NETWORK, - discriminator_params['name']).init_params(params) - generator = get_pluggable_class(PluggableType.GENERATIVE_NETWORK, - generator_params['name']).init_params(params) - - return cls(algo_input.data, algo_input.bounds, - num_qubits, batch_size, num_epochs, seed, discriminator, - generator, tol_rel_ent, snapshot_dir) - @property def seed(self): """ returns seed """ diff --git a/qiskit/aqua/algorithms/adaptive/vqc/vqc.py b/qiskit/aqua/algorithms/adaptive/vqc/vqc.py index b3fcaf6746..082d2b8038 100644 --- a/qiskit/aqua/algorithms/adaptive/vqc/vqc.py +++ b/qiskit/aqua/algorithms/adaptive/vqc/vqc.py @@ -22,8 +22,7 @@ from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister from qiskit.circuit import ParameterVector -from qiskit.aqua import Pluggable, PluggableType, get_pluggable_class, AquaError -from qiskit.aqua.utils import get_feature_dimension +from qiskit.aqua import AquaError from qiskit.aqua.utils import map_label_to_class_name from qiskit.aqua.utils import split_dataset_to_data_and_labels from qiskit.aqua.algorithms.adaptive.vq_algorithm import VQAlgorithm @@ -275,45 +274,6 @@ def __init__( self._feature_map_params = ParameterVector('x', self._feature_map.feature_dimension) self._parameterized_circuits = None - @classmethod - def init_params(cls, params, algo_input): - """ init params """ - algo_params = params.get(Pluggable.SECTION_KEY_ALGORITHM) - override_spsa_params = algo_params.get('override_SPSA_params') - max_evals_grouped = algo_params.get('max_evals_grouped') - minibatch_size = algo_params.get('minibatch_size') - - # Set up optimizer - opt_params = params.get(Pluggable.SECTION_KEY_OPTIMIZER) - # If SPSA then override SPSA params as reqd to our predetermined values - if opt_params['name'] == 'SPSA' and override_spsa_params: - opt_params['c0'] = 4.0 - opt_params['c1'] = 0.1 - opt_params['c2'] = 0.602 - opt_params['c3'] = 0.101 - opt_params['c4'] = 0.0 - opt_params['skip_calibration'] = True - optimizer = get_pluggable_class(PluggableType.OPTIMIZER, - opt_params['name']).init_params(params) - - # Set up feature map - fea_map_params = params.get(Pluggable.SECTION_KEY_FEATURE_MAP) - feature_dimension = get_feature_dimension(algo_input.training_dataset) - fea_map_params['feature_dimension'] = feature_dimension - feature_map = get_pluggable_class(PluggableType.FEATURE_MAP, - fea_map_params['name']).init_params(params) - - # Set up variational form, we need to add computed num qubits - # Pass all parameters so that Variational Form can create its dependents - var_form_params = params.get(Pluggable.SECTION_KEY_VAR_FORM) - var_form_params['num_qubits'] = feature_map.num_qubits - var_form = get_pluggable_class(PluggableType.VARIATIONAL_FORM, - var_form_params['name']).init_params(params) - - return cls(optimizer, feature_map, var_form, algo_input.training_dataset, - algo_input.test_dataset, algo_input.datapoints, max_evals_grouped, - minibatch_size) - def construct_circuit(self, x, theta, measurement=False): """ Construct circuit based on data and parameters in variational form. diff --git a/qiskit/aqua/algorithms/adaptive/vqe/vqe.py b/qiskit/aqua/algorithms/adaptive/vqe/vqe.py index 30217f2eb0..a6ecc6424a 100644 --- a/qiskit/aqua/algorithms/adaptive/vqe/vqe.py +++ b/qiskit/aqua/algorithms/adaptive/vqe/vqe.py @@ -26,7 +26,7 @@ from qiskit.circuit import ParameterVector from qiskit.aqua.algorithms.adaptive.vq_algorithm import VQAlgorithm -from qiskit.aqua import AquaError, Pluggable, PluggableType, get_pluggable_class +from qiskit.aqua import AquaError from qiskit.aqua.operators import (TPBGroupedWeightedPauliOperator, WeightedPauliOperator, MatrixOperator, op_converter) from qiskit.aqua.utils.backend_utils import (is_statevector_backend, @@ -135,45 +135,6 @@ def __init__(self, operator, var_form, optimizer, self._parameterized_circuits = None - @classmethod - def init_params(cls, params, algo_input): - """ - Initialize via parameters dictionary and algorithm input instance. - - Args: - params (dict): parameters dictionary - algo_input (EnergyInput): EnergyInput instance - - Returns: - VQE: vqe object - Raises: - AquaError: invalid input - """ - if algo_input is None: - raise AquaError("EnergyInput instance is required.") - - operator = algo_input.qubit_op - - vqe_params = params.get(Pluggable.SECTION_KEY_ALGORITHM) - initial_point = vqe_params.get('initial_point') - max_evals_grouped = vqe_params.get('max_evals_grouped') - - # Set up variational form, we need to add computed num qubits - # Pass all parameters so that Variational Form can create its dependents - var_form_params = params.get(Pluggable.SECTION_KEY_VAR_FORM) - var_form_params['num_qubits'] = operator.num_qubits - var_form = get_pluggable_class(PluggableType.VARIATIONAL_FORM, - var_form_params['name']).init_params(params) - - # Set up optimizer - opt_params = params.get(Pluggable.SECTION_KEY_OPTIMIZER) - optimizer = get_pluggable_class(PluggableType.OPTIMIZER, - opt_params['name']).init_params(params) - - return cls(operator, var_form, optimizer, - initial_point=initial_point, max_evals_grouped=max_evals_grouped, - aux_operators=algo_input.aux_ops) - @property def setting(self): """Prepare the setting of VQE as a string.""" diff --git a/qiskit/aqua/algorithms/classical/cplex/cplex_ising.py b/qiskit/aqua/algorithms/classical/cplex/cplex_ising.py index 70533ae8dc..b1ba7d90db 100644 --- a/qiskit/aqua/algorithms/classical/cplex/cplex_ising.py +++ b/qiskit/aqua/algorithms/classical/cplex/cplex_ising.py @@ -22,7 +22,7 @@ import importlib import numpy as np -from qiskit.aqua import QuantumAlgorithm, Pluggable, AquaError +from qiskit.aqua import QuantumAlgorithm, AquaError from qiskit.aqua.algorithms.classical.cplex.simple_cplex import SimpleCPLEX logger = logging.getLogger(__name__) @@ -73,17 +73,6 @@ def __init__(self, operator, timelimit=600, thread=1, display=2): self._display = display self._sol = None - @classmethod - def init_params(cls, params, algo_input): - """ init params """ - if algo_input is None: - raise AquaError("EnergyInput instance is required.") - algo_params = params.get(Pluggable.SECTION_KEY_ALGORITHM) - timelimit = algo_params['timelimit'] - thread = algo_params['thread'] - display = algo_params['display'] - return cls(algo_input.qubit_op, timelimit, thread, display) - @staticmethod def check_pluggable_valid(): """ check pluggable valid """ diff --git a/qiskit/aqua/algorithms/classical/exact_eigen_solver/exact_eigen_solver.py b/qiskit/aqua/algorithms/classical/exact_eigen_solver/exact_eigen_solver.py index 011ed5b7f9..914c517aeb 100644 --- a/qiskit/aqua/algorithms/classical/exact_eigen_solver/exact_eigen_solver.py +++ b/qiskit/aqua/algorithms/classical/exact_eigen_solver/exact_eigen_solver.py @@ -19,7 +19,6 @@ from scipy import sparse as scisparse from qiskit.aqua.algorithms import QuantumAlgorithm -from qiskit.aqua import AquaError, Pluggable from qiskit.aqua.operators import MatrixOperator, op_converter # pylint: disable=unused-import logger = logging.getLogger(__name__) @@ -76,24 +75,6 @@ def __init__(self, operator, k=1, aux_operators=None): logger.debug("WARNING: Asked for %s eigenvalues but max possible is %s.", k, self._k) self._ret = {} - @classmethod - def init_params(cls, params, algo_input): - """ - Initialize via parameters dictionary and algorithm input instance - Args: - params (dict): parameters dictionary - algo_input (EnergyInput): instance - Returns: - ExactEigensolver: an instance of this class - Raises: - AquaError: invalid input - """ - if algo_input is None: - raise AquaError("EnergyInput instance is required.") - ee_params = params.get(Pluggable.SECTION_KEY_ALGORITHM) - k = ee_params.get('k') - return cls(algo_input.qubit_op, k, algo_input.aux_ops) - def _solve(self): if self._operator.dia_matrix is None: if self._k >= self._operator.matrix.shape[0] - 1: diff --git a/qiskit/aqua/algorithms/classical/exact_ls_solver/exact_ls_solver.py b/qiskit/aqua/algorithms/classical/exact_ls_solver/exact_ls_solver.py index 369f09cdc5..64d3d3da06 100644 --- a/qiskit/aqua/algorithms/classical/exact_ls_solver/exact_ls_solver.py +++ b/qiskit/aqua/algorithms/classical/exact_ls_solver/exact_ls_solver.py @@ -18,7 +18,6 @@ import numpy as np from qiskit.aqua.algorithms import QuantumAlgorithm -from qiskit.aqua import AquaError logger = logging.getLogger(__name__) @@ -54,37 +53,6 @@ def __init__(self, matrix=None, vector=None): self._vector = vector self._ret = {} - @classmethod - def init_params(cls, params, algo_input): # pylint: disable=unused-argument - """ - Initialize via parameters dictionary and algorithm input instance - Args: - params (dict): parameters dictionary - algo_input (LinearSystemInput): instance - Returns: - ExactLSsolver: an instance of this class - Raises: - AquaError: invalid input - ValueError: invalid input - """ - if algo_input is None: - raise AquaError("LinearSystemInput instance is required.") - - matrix = algo_input.matrix - vector = algo_input.vector - if not isinstance(matrix, np.ndarray): - matrix = np.asarray(matrix) - if not isinstance(vector, np.ndarray): - vector = np.asarray(vector) - - if matrix.shape[0] != len(vector): - raise ValueError("Input vector dimension does not match input " - "matrix dimension!") - if matrix.shape[0] != matrix.shape[1]: - raise ValueError("Input matrix must be square!") - - return cls(matrix, vector) - def _solve(self): self._ret['eigvals'] = np.linalg.eig(self._matrix)[0] self._ret['solution'] = list(np.linalg.solve(self._matrix, self._vector)) diff --git a/qiskit/aqua/algorithms/classical/svm/svm_classical.py b/qiskit/aqua/algorithms/classical/svm/svm_classical.py index 42a206e389..2657cdf663 100644 --- a/qiskit/aqua/algorithms/classical/svm/svm_classical.py +++ b/qiskit/aqua/algorithms/classical/svm/svm_classical.py @@ -19,10 +19,9 @@ import logging from qiskit.aqua.algorithms import QuantumAlgorithm -from qiskit.aqua import AquaError, Pluggable, PluggableType, get_pluggable_class +from qiskit.aqua import AquaError from qiskit.aqua.algorithms.classical.svm import (_SVM_Classical_Binary, - _SVM_Classical_Multiclass, - _RBF_SVC_Estimator) + _SVM_Classical_Multiclass) from qiskit.aqua.utils import get_num_classes logger = logging.getLogger(__name__) @@ -103,26 +102,6 @@ def __init__(self, training_dataset, test_dataset=None, datapoints=None, self.instance = svm_instance - @classmethod - def init_params(cls, params, algo_input): - """ init params """ - svm_params = params.get(Pluggable.SECTION_KEY_ALGORITHM) - gamma = svm_params.get('gamma', None) - - multiclass_extension = None - multiclass_extension_params = params.get(Pluggable.SECTION_KEY_MULTICLASS_EXT) - if multiclass_extension_params is not None: - multiclass_extension_params['estimator_cls'] = _RBF_SVC_Estimator - - multiclass_extension = get_pluggable_class( - PluggableType.MULTICLASS_EXTENSION, - multiclass_extension_params['name']).init_params(params) - logger.info("Multiclass dataset with extension: %s", - multiclass_extension_params['name']) - - return cls(algo_input.training_dataset, algo_input.test_dataset, - algo_input.datapoints, gamma, multiclass_extension) - def train(self, data, labels): """ Train the SVM diff --git a/qiskit/aqua/algorithms/many_sample/eoh/eoh.py b/qiskit/aqua/algorithms/many_sample/eoh/eoh.py index 8c09c3ddb4..5ecfa8944d 100644 --- a/qiskit/aqua/algorithms/many_sample/eoh/eoh.py +++ b/qiskit/aqua/algorithms/many_sample/eoh/eoh.py @@ -21,7 +21,6 @@ from qiskit.aqua.algorithms import QuantumAlgorithm from qiskit.aqua.operators import op_converter -from qiskit.aqua import AquaError, Pluggable, PluggableType, get_pluggable_class logger = logging.getLogger(__name__) @@ -94,47 +93,6 @@ def __init__(self, operator, initial_state, evo_operator, evo_time=1, num_time_s self._expansion_order = expansion_order self._ret = {} - @classmethod - def init_params(cls, params, algo_input): - """ - Initialize via parameters dictionary and algorithm input instance - Args: - params (dict): parameters dictionary - algo_input (EnergyInput): instance - Returns: - EOH: and instance of this class - Raises: - AquaError: invalid input - """ - if algo_input is None: - raise AquaError("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 AquaError("EnergyInput, a single aux op is required for evaluation.") - evo_operator = aux_ops[0] - if evo_operator is None: - raise AquaError("EnergyInput, invalid aux op.") - - dynamics_params = params.get(Pluggable.SECTION_KEY_ALGORITHM) - evo_time = dynamics_params.get(EOH.PROP_EVO_TIME) - num_time_slices = dynamics_params.get(EOH.PROP_NUM_TIME_SLICES) - expansion_mode = dynamics_params.get(EOH.PROP_EXPANSION_MODE) - expansion_order = dynamics_params.get(EOH.PROP_EXPANSION_ORDER) - - # Set up initial state, we need to add computed num qubits to params - initial_state_params = params.get(Pluggable.SECTION_KEY_INITIAL_STATE) - initial_state_params['num_qubits'] = operator.num_qubits - initial_state = get_pluggable_class(PluggableType.INITIAL_STATE, - initial_state_params['name']).init_params(params) - - return cls(operator, initial_state, evo_operator, evo_time=evo_time, - num_time_slices=num_time_slices, expansion_mode=expansion_mode, - expansion_order=expansion_order) - def construct_circuit(self): """ Construct the circuit. diff --git a/qiskit/aqua/algorithms/many_sample/qsvm/qsvm.py b/qiskit/aqua/algorithms/many_sample/qsvm/qsvm.py index ff597247b0..168ee3983a 100644 --- a/qiskit/aqua/algorithms/many_sample/qsvm/qsvm.py +++ b/qiskit/aqua/algorithms/many_sample/qsvm/qsvm.py @@ -25,11 +25,10 @@ from qiskit.aqua import aqua_globals from qiskit.aqua.algorithms import QuantumAlgorithm -from qiskit.aqua import AquaError, Pluggable, PluggableType, get_pluggable_class +from qiskit.aqua import AquaError from qiskit.aqua.algorithms.many_sample.qsvm._qsvm_binary import _QSVM_Binary from qiskit.aqua.algorithms.many_sample.qsvm._qsvm_multiclass import _QSVM_Multiclass -from qiskit.aqua.algorithms.many_sample.qsvm._qsvm_estimator import _QSVM_Estimator -from qiskit.aqua.utils.dataset_helper import get_feature_dimension, get_num_classes +from qiskit.aqua.utils.dataset_helper import get_num_classes from qiskit.aqua.utils import split_dataset_to_data_and_labels logger = logging.getLogger(__name__) @@ -119,30 +118,6 @@ def __init__(self, feature_map, training_dataset=None, test_dataset=None, datapo self.instance = qsvm_instance - @classmethod - def init_params(cls, params, algo_input): - """Constructor from params.""" - feature_dimension = get_feature_dimension(algo_input.training_dataset) - fea_map_params = params.get(Pluggable.SECTION_KEY_FEATURE_MAP) - fea_map_params['feature_dimension'] = feature_dimension - - feature_map = get_pluggable_class(PluggableType.FEATURE_MAP, - fea_map_params['name']).init_params(params) - - multiclass_extension = None - multiclass_extension_params = params.get(Pluggable.SECTION_KEY_MULTICLASS_EXT) - if multiclass_extension_params is not None: - multiclass_extension_params['params'] = [feature_map] - multiclass_extension_params['estimator_cls'] = _QSVM_Estimator - - multiclass_extension = \ - get_pluggable_class(PluggableType.MULTICLASS_EXTENSION, - multiclass_extension_params['name']).init_params(params) - logger.info("Multiclass classifier based on %s", multiclass_extension_params['name']) - - return cls(feature_map, algo_input.training_dataset, algo_input.test_dataset, - algo_input.datapoints, multiclass_extension) - @staticmethod def _construct_circuit(x, feature_map, measurement, is_statevector_sim=False): """ diff --git a/qiskit/aqua/algorithms/single_sample/amplitude_estimation/ae.py b/qiskit/aqua/algorithms/single_sample/amplitude_estimation/ae.py index 36605259d5..18ffde28ea 100644 --- a/qiskit/aqua/algorithms/single_sample/amplitude_estimation/ae.py +++ b/qiskit/aqua/algorithms/single_sample/amplitude_estimation/ae.py @@ -22,7 +22,6 @@ from scipy.optimize import bisect from qiskit.aqua import AquaError -from qiskit.aqua import Pluggable, PluggableType, get_pluggable_class from qiskit.aqua.circuits import PhaseEstimationCircuit from qiskit.aqua.components.iqfts import Standard @@ -100,41 +99,6 @@ def __init__(self, num_eval_qubits, a_factory=None, self._circuit = None self._ret = {} - @classmethod - def init_params(cls, params, algo_input): - """ - Initialize via parameters dictionary and algorithm input instance - Args: - params (dict): parameters dictionary - algo_input (AlgorithmInput): Input instance - Returns: - AmplitudeEstimation: instance of this class - Raises: - AquaError: Input instance not supported - """ - if algo_input is not None: - raise AquaError('Input instance not supported.') - - ae_params = params.get(Pluggable.SECTION_KEY_ALGORITHM) - num_eval_qubits = ae_params.get('num_eval_qubits') - - # Set up uncertainty problem. The params can include an uncertainty model - # type dependent on the uncertainty problem and is this its responsibility - # to create for itself from the complete params set that is passed to it. - uncertainty_problem_params = params.get( - Pluggable.SECTION_KEY_UNCERTAINTY_PROBLEM) - uncertainty_problem = get_pluggable_class( - PluggableType.UNCERTAINTY_PROBLEM, - uncertainty_problem_params['name']).init_params(params) - - # Set up iqft, we need to add num qubits to params which is our num_ancillae bits here - iqft_params = params.get(Pluggable.SECTION_KEY_IQFT) - iqft_params['num_qubits'] = num_eval_qubits - iqft = get_pluggable_class( - PluggableType.IQFT, iqft_params['name']).init_params(params) - - return cls(num_eval_qubits, uncertainty_problem, q_factory=None, iqft=iqft) - @property def _num_qubits(self): if self.a_factory is None: # if A factory is not set, no qubits are specified diff --git a/qiskit/aqua/algorithms/single_sample/amplitude_estimation/mlae.py b/qiskit/aqua/algorithms/single_sample/amplitude_estimation/mlae.py index 413af427c3..705c9eb3aa 100644 --- a/qiskit/aqua/algorithms/single_sample/amplitude_estimation/mlae.py +++ b/qiskit/aqua/algorithms/single_sample/amplitude_estimation/mlae.py @@ -22,7 +22,6 @@ from qiskit import ClassicalRegister, QuantumRegister, QuantumCircuit from qiskit.aqua import AquaError -from qiskit.aqua import Pluggable, PluggableType, get_pluggable_class from .ae_algorithm import AmplitudeEstimationAlgorithm @@ -94,34 +93,6 @@ def __init__(self, log_max_evals, a_factory=None, i_objective=None, self._circuits = [] self._ret = {} - @classmethod - def init_params(cls, params, algo_input): - """ - Initialize via parameters dictionary and algorithm input instance - Args: - params (dict): parameters dictionary - algo_input (AlgorithmInput): Input instance - Returns: - MaximumLikelihoodAmplitudeEstimation: instance of this class - Raises: - AquaError: input instance not supported - """ - if algo_input is not None: - raise AquaError("Input instance not supported.") - - ae_params = params.get(Pluggable.SECTION_KEY_ALGORITHM) - log_max_evals = ae_params.get('log_max_evals') - - # Set up uncertainty problem. The params can include an uncertainty model - # type dependent on the uncertainty problem and is this its responsibility - # to create for itself from the complete params set that is passed to it. - uncertainty_problem_params = params.get(Pluggable.SECTION_KEY_UNCERTAINTY_PROBLEM) - uncertainty_problem = get_pluggable_class( - PluggableType.UNCERTAINTY_PROBLEM, - uncertainty_problem_params['name']).init_params(params) - - return cls(log_max_evals, uncertainty_problem, q_factory=None) - @property def _num_qubits(self): if self.a_factory is None: # if A factory is not set, no qubits are specified diff --git a/qiskit/aqua/algorithms/single_sample/bernstein_vazirani/bv.py b/qiskit/aqua/algorithms/single_sample/bernstein_vazirani/bv.py index a659c058c7..f25cc8acd6 100644 --- a/qiskit/aqua/algorithms/single_sample/bernstein_vazirani/bv.py +++ b/qiskit/aqua/algorithms/single_sample/bernstein_vazirani/bv.py @@ -20,8 +20,6 @@ import numpy as np from qiskit import ClassicalRegister, QuantumCircuit - -from qiskit.aqua import AquaError, Pluggable, PluggableType, get_pluggable_class from qiskit.aqua.algorithms import QuantumAlgorithm from qiskit.aqua.utils import get_subsystem_density_matrix @@ -63,18 +61,6 @@ def __init__(self, oracle): self._circuit = None self._ret = {} - @classmethod - def init_params(cls, params, algo_input): - """ init params """ - if algo_input is not None: - raise AquaError("Input instance not supported.") - - oracle_params = params.get(Pluggable.SECTION_KEY_ORACLE) - oracle = get_pluggable_class( - PluggableType.ORACLE, - oracle_params['name']).init_params(params) - return cls(oracle) - def construct_circuit(self, measurement=False): """ Construct the quantum circuit diff --git a/qiskit/aqua/algorithms/single_sample/deutsch_jozsa/dj.py b/qiskit/aqua/algorithms/single_sample/deutsch_jozsa/dj.py index 3e7ea8236d..88da0eb928 100644 --- a/qiskit/aqua/algorithms/single_sample/deutsch_jozsa/dj.py +++ b/qiskit/aqua/algorithms/single_sample/deutsch_jozsa/dj.py @@ -21,7 +21,6 @@ from qiskit import ClassicalRegister, QuantumCircuit -from qiskit.aqua import AquaError, Pluggable, PluggableType, get_pluggable_class from qiskit.aqua.algorithms import QuantumAlgorithm from qiskit.aqua.utils import get_subsystem_density_matrix @@ -63,18 +62,6 @@ def __init__(self, oracle): self._circuit = None self._ret = {} - @classmethod - def init_params(cls, params, algo_input): - """ init params """ - if algo_input is not None: - raise AquaError("Input instance not supported.") - - oracle_params = params.get(Pluggable.SECTION_KEY_ORACLE) - oracle = get_pluggable_class( - PluggableType.ORACLE, - oracle_params['name']).init_params(params) - return cls(oracle) - def construct_circuit(self, measurement=False): """ Construct the quantum circuit diff --git a/qiskit/aqua/algorithms/single_sample/grover/grover.py b/qiskit/aqua/algorithms/single_sample/grover/grover.py index c5b812865d..2bf155d8ec 100644 --- a/qiskit/aqua/algorithms/single_sample/grover/grover.py +++ b/qiskit/aqua/algorithms/single_sample/grover/grover.py @@ -22,7 +22,7 @@ from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister from qiskit.qasm import pi -from qiskit.aqua import AquaError, Pluggable, PluggableType, get_pluggable_class +from qiskit.aqua import AquaError from qiskit.aqua.utils import get_subsystem_density_matrix from qiskit.aqua.algorithms import QuantumAlgorithm from qiskit.aqua.components.initial_states import Custom @@ -184,39 +184,6 @@ def _construct_diffusion_circuit(self): qc.barrier(self._oracle.variable_register) return qc - @classmethod - def init_params(cls, params, algo_input): - """ - Initialize via parameters dictionary and algorithm input instance - Args: - params (dict): parameters dictionary - algo_input (AlgorithmInput): input instance - Returns: - Grover: and instance of this class - Raises: - AquaError: invalid input - """ - if algo_input is not None: - raise AquaError("Input instance not supported.") - - grover_params = params.get(Pluggable.SECTION_KEY_ALGORITHM) - incremental = grover_params.get(Grover.PROP_INCREMENTAL) - num_iterations = grover_params.get(Grover.PROP_NUM_ITERATIONS) - mct_mode = grover_params.get(Grover.PROP_MCT_MODE) - - oracle_params = params.get(Pluggable.SECTION_KEY_ORACLE) - oracle = get_pluggable_class(PluggableType.ORACLE, - oracle_params['name']).init_params(params) - - # Set up initial state, we need to add computed num qubits to params - init_state_params = params.get(Pluggable.SECTION_KEY_INITIAL_STATE) - init_state_params['num_qubits'] = len(oracle.variable_register) - init_state = get_pluggable_class(PluggableType.INITIAL_STATE, - init_state_params['name']).init_params(params) - - return cls(oracle, init_state=init_state, - incremental=incremental, num_iterations=num_iterations, mct_mode=mct_mode) - @property def qc_amplitude_amplification_iteration(self): """ qc amplitude amplification iteration """ diff --git a/qiskit/aqua/algorithms/single_sample/hhl/hhl.py b/qiskit/aqua/algorithms/single_sample/hhl/hhl.py index 71a42cf73f..774bd7b723 100644 --- a/qiskit/aqua/algorithms/single_sample/hhl/hhl.py +++ b/qiskit/aqua/algorithms/single_sample/hhl/hhl.py @@ -21,7 +21,6 @@ from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit from qiskit.aqua.algorithms import QuantumAlgorithm -from qiskit.aqua import AquaError, Pluggable, PluggableType, get_pluggable_class from qiskit.ignis.verification.tomography import state_tomography_circuits, \ StateTomographyFitter from qiskit.converters import circuit_to_dag @@ -199,80 +198,6 @@ def matrix_resize(matrix, vector): return (matrix, vector, truncate_powerdim, truncate_hermitian) - @classmethod - def init_params(cls, params, algo_input): - """Initialize via parameters dictionary and algorithm input instance - - Args: - params (dict): parameters dictionary - algo_input (LinearSystemInput): LinearSystemInput instance - Returns: - HHL: an instance of this class - Raises: - AquaError: invalid input - ValueError: invalid input - """ - if algo_input is None: - raise AquaError("LinearSystemInput instance is required.") - - matrix = algo_input.matrix - vector = algo_input.vector - if not isinstance(matrix, np.ndarray): - matrix = np.asarray(matrix) - if not isinstance(vector, np.ndarray): - vector = np.asarray(vector) - - if matrix.shape[0] != matrix.shape[1]: - raise ValueError("Input matrix must be square!") - if matrix.shape[0] != len(vector): - raise ValueError("Input vector dimension does not match input " - "matrix dimension!") - - hhl_params = params.get(Pluggable.SECTION_KEY_ALGORITHM) - truncate_powerdim = hhl_params.get('truncate_powerdim') - truncate_hermitian = hhl_params.get('truncate_hermitian') - orig_size = hhl_params.get('orig_size') - if orig_size is None: - orig_size = len(vector) - - is_powerdim = np.log2(matrix.shape[0]) % 1 == 0 - if not is_powerdim: - logger.warning("Input matrix does not have dimension 2**n. It " - "will be expanded automatically.") - matrix, vector = cls.expand_to_powerdim(matrix, vector) - truncate_powerdim = True - - is_hermitian = np.allclose(matrix, matrix.conj().T) - if not is_hermitian: - logger.warning("Input matrix is not hermitian. It will be " - "expanded to a hermitian matrix automatically.") - matrix, vector = cls.expand_to_hermitian(matrix, vector) - truncate_hermitian = True - - # Initialize eigenvalue finding module - eigs_params = params.get(Pluggable.SECTION_KEY_EIGS) - eigs = get_pluggable_class(PluggableType.EIGENVALUES, - eigs_params['name']).init_params(params, matrix) - num_q, num_a = eigs.get_register_sizes() - - # Initialize initial state module - tmpvec = vector - init_state_params = params.get(Pluggable.SECTION_KEY_INITIAL_STATE) - init_state_params["num_qubits"] = num_q - init_state_params["state_vector"] = tmpvec - init_state = get_pluggable_class(PluggableType.INITIAL_STATE, - init_state_params['name']).init_params(params) - - # Initialize reciprocal rotation module - reciprocal_params = params.get(Pluggable.SECTION_KEY_RECIPROCAL) - reciprocal_params["negative_evals"] = eigs._negative_evals - reciprocal_params["evo_time"] = eigs._evo_time - reci = get_pluggable_class(PluggableType.RECIPROCAL, - reciprocal_params['name']).init_params(params) - - return cls(matrix, vector, truncate_powerdim, truncate_hermitian, eigs, - init_state, reci, num_q, num_a, orig_size) - def construct_circuit(self, measurement=False): """Construct the HHL circuit. diff --git a/qiskit/aqua/algorithms/single_sample/iterative_qpe/iqpe.py b/qiskit/aqua/algorithms/single_sample/iterative_qpe/iqpe.py index 6e25e6392d..e56de2d680 100644 --- a/qiskit/aqua/algorithms/single_sample/iterative_qpe/iqpe.py +++ b/qiskit/aqua/algorithms/single_sample/iterative_qpe/iqpe.py @@ -22,8 +22,6 @@ from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit from qiskit.quantum_info import Pauli -from qiskit.aqua import AquaError -from qiskit.aqua import Pluggable, PluggableType, get_pluggable_class from qiskit.aqua.operators import (WeightedPauliOperator, suzuki_expansion_slice_pauli_list, evolution_instruction, op_converter) from qiskit.aqua.utils import get_subsystem_density_matrix @@ -123,41 +121,6 @@ def __init__(self, operator, state_in, num_time_slices=1, num_iterations=1, self._ancilla_phase_coef = None self._setup() - @classmethod - def init_params(cls, params, algo_input): - """ - Initialize via parameters dictionary and algorithm input instance. - - Args: - params (dict): parameters dictionary - algo_input (EnergyInput): instance - Returns: - IQPE: instance of this class - Raises: - AquaError: EnergyInput instance is required - """ - if algo_input is None: - raise AquaError("EnergyInput instance is required.") - - operator = algo_input.qubit_op - - iqpe_params = params.get(Pluggable.SECTION_KEY_ALGORITHM) - num_time_slices = iqpe_params.get(IQPE.PROP_NUM_TIME_SLICES) - 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(Pluggable.SECTION_KEY_INITIAL_STATE) - init_state_params['num_qubits'] = operator.num_qubits - init_state = get_pluggable_class(PluggableType.INITIAL_STATE, - init_state_params['name']).init_params(params) - - return cls(operator, init_state, - num_time_slices=num_time_slices, num_iterations=num_iterations, - expansion_mode=expansion_mode, - expansion_order=expansion_order) - def _setup(self): self._ret['translation'] = sum([abs(p[0]) for p in self._operator.reorder_paulis()]) self._ret['stretch'] = 0.5 / self._ret['translation'] diff --git a/qiskit/aqua/algorithms/single_sample/qpe/qpe.py b/qiskit/aqua/algorithms/single_sample/qpe/qpe.py index 52082ad4d7..e9235a4ce7 100644 --- a/qiskit/aqua/algorithms/single_sample/qpe/qpe.py +++ b/qiskit/aqua/algorithms/single_sample/qpe/qpe.py @@ -20,8 +20,6 @@ import numpy as np from qiskit.quantum_info import Pauli -from qiskit.aqua import AquaError -from qiskit.aqua import Pluggable, PluggableType, get_pluggable_class from qiskit.aqua.operators import op_converter from qiskit.aqua.utils import get_subsystem_density_matrix from qiskit.aqua.algorithms import QuantumAlgorithm @@ -147,45 +145,6 @@ def __init__( ) self._binary_fractions = [1 / 2 ** p for p in range(1, num_ancillae + 1)] - @classmethod - def init_params(cls, params, algo_input): - """ - Initialize via parameters dictionary and algorithm input instance. - - Args: - params (dict): parameters dictionary - algo_input (EnergyInput): instance - Returns: - QPE: instance of this class - Raises: - AquaError: EnergyInput instance is required. - """ - if algo_input is None: - raise AquaError("EnergyInput instance is required.") - - operator = algo_input.qubit_op - - qpe_params = params.get(Pluggable.SECTION_KEY_ALGORITHM) - num_time_slices = qpe_params.get(QPE.PROP_NUM_TIME_SLICES) - 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) - - # Set up initial state, we need to add computed num qubits to params - init_state_params = params.get(Pluggable.SECTION_KEY_INITIAL_STATE) - init_state_params['num_qubits'] = operator.num_qubits - init_state = get_pluggable_class(PluggableType.INITIAL_STATE, - init_state_params['name']).init_params(params) - - # Set up iqft, we need to add num qubits to params which is our num_ancillae bits here - iqft_params = params.get(Pluggable.SECTION_KEY_IQFT) - iqft_params['num_qubits'] = num_ancillae - iqft = get_pluggable_class(PluggableType.IQFT, iqft_params['name']).init_params(params) - - return cls(operator, init_state, iqft, num_time_slices, num_ancillae, - expansion_mode=expansion_mode, - expansion_order=expansion_order) - def construct_circuit(self, measurement=False): """ Construct circuit. diff --git a/qiskit/aqua/algorithms/single_sample/shor/shor.py b/qiskit/aqua/algorithms/single_sample/shor/shor.py index b785b82fbb..4e17e00fcf 100644 --- a/qiskit/aqua/algorithms/single_sample/shor/shor.py +++ b/qiskit/aqua/algorithms/single_sample/shor/shor.py @@ -26,7 +26,7 @@ from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister from qiskit.aqua.utils.arithmetic import is_power -from qiskit.aqua import AquaError, Pluggable +from qiskit.aqua import AquaError from qiskit.aqua.utils import get_subsystem_density_matrix from qiskit.aqua.algorithms import QuantumAlgorithm from qiskit.aqua.circuits import FourierTransformCircuits as ftc @@ -109,28 +109,6 @@ def __init__(self, N=15, a=2): logger.info('The input integer is a power: %s=%s^%s.', N, b, p) self._ret['factors'].append(b) - @classmethod - def init_params(cls, params, algo_input): - """ - Initialize via parameters dictionary and algorithm input instance. - - Args: - params (dict): parameters dictionary - algo_input (AlgorithmInput): input instance - Returns: - Shor: instance of this class - Raises: - AquaError: invalid input - """ - - if algo_input is not None: - raise AquaError("Input instance not supported.") - - shor_params = params.get(Pluggable.SECTION_KEY_ALGORITHM) - N = shor_params.get(Shor.PROP_N) - - return cls(N) - def _get_angles(self, a): """ Calculate the array of angles to be used in the addition in Fourier Space diff --git a/qiskit/aqua/algorithms/single_sample/simon/simon.py b/qiskit/aqua/algorithms/single_sample/simon/simon.py index 0538fe6749..9685d8f45a 100644 --- a/qiskit/aqua/algorithms/single_sample/simon/simon.py +++ b/qiskit/aqua/algorithms/single_sample/simon/simon.py @@ -21,7 +21,6 @@ from qiskit import ClassicalRegister, QuantumCircuit -from qiskit.aqua import AquaError, Pluggable, PluggableType, get_pluggable_class from qiskit.aqua.algorithms import QuantumAlgorithm from qiskit.aqua.utils import get_subsystem_density_matrix @@ -61,18 +60,6 @@ def __init__(self, oracle): self._circuit = None self._ret = {} - @classmethod - def init_params(cls, params, algo_input): - """ init params """ - if algo_input is not None: - raise AquaError("Input instance not supported.") - - oracle_params = params.get(Pluggable.SECTION_KEY_ORACLE) - oracle = get_pluggable_class( - PluggableType.ORACLE, - oracle_params['name']).init_params(params) - return cls(oracle) - def construct_circuit(self, measurement=False): """ Construct the quantum circuit diff --git a/qiskit/aqua/components/eigs/eigs.py b/qiskit/aqua/components/eigs/eigs.py index 0ef6bbaa66..daa548e7a8 100644 --- a/qiskit/aqua/components/eigs/eigs.py +++ b/qiskit/aqua/components/eigs/eigs.py @@ -32,13 +32,6 @@ def __init__(self): super().__init__() self._inverse = None - @classmethod - def init_params(cls, params): - """ init params """ - eigs_params = params.get(Pluggable.SECTION_KEY_EIGS) - args = {k: v for k, v in eigs_params.items() if k != 'name'} - return cls(**args) - @abstractmethod def get_register_sizes(self): """ get register sizes """ diff --git a/qiskit/aqua/components/eigs/eigs_qpe.py b/qiskit/aqua/components/eigs/eigs_qpe.py index b817b080d5..dd100b4aaa 100644 --- a/qiskit/aqua/components/eigs/eigs_qpe.py +++ b/qiskit/aqua/components/eigs/eigs_qpe.py @@ -17,11 +17,9 @@ import numpy as np from qiskit import QuantumRegister -from qiskit.aqua import AquaError -from qiskit.aqua import Pluggable, PluggableType, get_pluggable_class from qiskit.aqua.components.eigs import Eigenvalues from qiskit.aqua.circuits import PhaseEstimationCircuit -from qiskit.aqua.operators import MatrixOperator, op_converter +from qiskit.aqua.operators import op_converter # pylint: disable=invalid-name @@ -134,63 +132,6 @@ def __init__( self._input_register = None self._init_constants() - @classmethod - def init_params(cls, params, matrix): # pylint: disable=arguments-differ - """ - Initialize via parameters dictionary and algorithm input instance - - Args: - params (dict): parameters dictionary - matrix (numpy.ndarray): two dimensional array which represents the operator - Returns: - EigsQPE: instance of this class - Raises: - AquaError: Operator instance is required - """ - if matrix is None: - raise AquaError("Operator instance is required.") - - if not isinstance(matrix, np.ndarray): - matrix = np.array(matrix) - - eigs_params = params.get(Pluggable.SECTION_KEY_EIGS) - args = {k: v for k, v in eigs_params.items() if k != 'name'} - num_ancillae = eigs_params['num_ancillae'] - negative_evals = eigs_params['negative_evals'] - - # Adding an additional flag qubit for negative eigenvalues - if negative_evals: - num_ancillae += 1 - args['num_ancillae'] = num_ancillae - - args['operator'] = MatrixOperator(matrix=matrix) - - # Set up iqft, we need to add num qubits to params which is our num_ancillae bits here - iqft_params = params.get(Pluggable.SECTION_KEY_IQFT) - iqft_params['num_qubits'] = num_ancillae - args['iqft'] = get_pluggable_class(PluggableType.IQFT, - iqft_params['name']).init_params(params) - - # For converting the encoding of the negative eigenvalues, we need two - # additional instances for QFT and IQFT - if negative_evals: - ne_params = params - qft_num_qubits = iqft_params['num_qubits'] - ne_qft_params = params.get(Pluggable.SECTION_KEY_QFT) - ne_qft_params['num_qubits'] = qft_num_qubits - 1 - ne_iqft_params = params.get(Pluggable.SECTION_KEY_IQFT) - ne_iqft_params['num_qubits'] = qft_num_qubits - 1 - ne_params['qft'] = ne_qft_params - ne_params['iqft'] = ne_iqft_params - args['ne_qfts'] = [get_pluggable_class(PluggableType.QFT, - ne_qft_params['name']).init_params(ne_params), - get_pluggable_class(PluggableType.IQFT, - ne_iqft_params['name']).init_params(ne_params)] - else: - args['ne_qfts'] = [None, None] - - return cls(**args) - def _init_constants(self): # estimate evolution time if self._evo_time is None: diff --git a/qiskit/aqua/components/feature_maps/feature_map.py b/qiskit/aqua/components/feature_maps/feature_map.py index 1360aa1149..520b4c7ae3 100644 --- a/qiskit/aqua/components/feature_maps/feature_map.py +++ b/qiskit/aqua/components/feature_maps/feature_map.py @@ -38,13 +38,6 @@ def __init__(self): self._feature_dimension = 0 self._support_parameterized_circuit = False - @classmethod - def init_params(cls, params): - """ init params """ - feat_map__params = params.get(Pluggable.SECTION_KEY_FEATURE_MAP) - args = {k: v for k, v in feat_map__params.items() if k != 'name'} - return cls(**args) - @abstractmethod def construct_circuit(self, x, qr=None, inverse=False): """Construct the variational form, given its parameters. diff --git a/qiskit/aqua/components/initial_states/initial_state.py b/qiskit/aqua/components/initial_states/initial_state.py index 4c0ec31585..408722c64b 100644 --- a/qiskit/aqua/components/initial_states/initial_state.py +++ b/qiskit/aqua/components/initial_states/initial_state.py @@ -34,13 +34,6 @@ class InitialState(Pluggable): def __init__(self): super().__init__() - @classmethod - def init_params(cls, params): - """ init params """ - init_state_params = params.get(Pluggable.SECTION_KEY_INITIAL_STATE) - args = {k: v for k, v in init_state_params.items() if k != 'name'} - return cls(**args) - @abstractmethod def construct_circuit(self, mode='circuit', register=None): """ diff --git a/qiskit/aqua/components/iqfts/iqft.py b/qiskit/aqua/components/iqfts/iqft.py index e5e7cc5230..a7691f3555 100644 --- a/qiskit/aqua/components/iqfts/iqft.py +++ b/qiskit/aqua/components/iqfts/iqft.py @@ -39,13 +39,6 @@ class IQFT(Pluggable): def __init__(self, *args, **kwargs): super().__init__() - @classmethod - def init_params(cls, params): - """ init params """ - iqft_params = params.get(Pluggable.SECTION_KEY_IQFT) - kwargs = {k: v for k, v in iqft_params.items() if k != 'name'} - return cls(**kwargs) - @abstractmethod def _build_matrix(self): raise NotImplementedError diff --git a/qiskit/aqua/components/multiclass_extensions/multiclass_extension.py b/qiskit/aqua/components/multiclass_extensions/multiclass_extension.py index 2e541fc5c9..d8de6dd1d8 100644 --- a/qiskit/aqua/components/multiclass_extensions/multiclass_extension.py +++ b/qiskit/aqua/components/multiclass_extensions/multiclass_extension.py @@ -30,13 +30,6 @@ class MulticlassExtension(Pluggable): def __init__(self): super().__init__() - @classmethod - def init_params(cls, params): - """ init params """ - multiclass_extension_params = params.get(Pluggable.SECTION_KEY_MULTICLASS_EXT) - args = {k: v for k, v in multiclass_extension_params.items() if k != 'name'} - return cls(**args) - @abstractmethod def train(self, x, y): """ diff --git a/qiskit/aqua/components/neural_networks/discriminative_network.py b/qiskit/aqua/components/neural_networks/discriminative_network.py index f12f5980ea..c63c55af7e 100644 --- a/qiskit/aqua/components/neural_networks/discriminative_network.py +++ b/qiskit/aqua/components/neural_networks/discriminative_network.py @@ -32,21 +32,6 @@ def __init__(self): self._num_parameters = 0 self._num_qubits = 0 self._bounds = list() - pass - - @classmethod - def init_params(cls, params): - """ init params """ - discriminative_params = params.get(Pluggable.SECTION_KEY_DISCRIMINATIVE_NET) - args = {k: v for k, v in discriminative_params.items() if k != 'name'} - - return cls(**args) - - @classmethod - @abstractmethod - def get_section_key_name(cls): - """ get section key names """ - pass @abstractmethod def set_seed(self, seed): diff --git a/qiskit/aqua/components/neural_networks/generative_network.py b/qiskit/aqua/components/neural_networks/generative_network.py index 569b948e8a..d235e32be0 100644 --- a/qiskit/aqua/components/neural_networks/generative_network.py +++ b/qiskit/aqua/components/neural_networks/generative_network.py @@ -32,21 +32,6 @@ def __init__(self): self._num_parameters = 0 self._num_qubits = 0 self._bounds = list() - pass - - @classmethod - def init_params(cls, params): - """ init params """ - generative_params = params.get(Pluggable.SECTION_KEY_GENERATIVE_NETWORK) - args = {k: v for k, v in generative_params.items() if k != 'name'} - - return cls(**args) - - @classmethod - @abstractmethod - def get_section_key_name(cls): - """ get section key name """ - pass @abstractmethod def set_seed(self, seed): diff --git a/qiskit/aqua/components/neural_networks/numpy_discriminator.py b/qiskit/aqua/components/neural_networks/numpy_discriminator.py index a2a522c6aa..14812ba648 100644 --- a/qiskit/aqua/components/neural_networks/numpy_discriminator.py +++ b/qiskit/aqua/components/neural_networks/numpy_discriminator.py @@ -22,7 +22,6 @@ import os import logging import numpy as np -from qiskit.aqua import Pluggable from qiskit.aqua.components.optimizers import ADAM from .discriminative_network import DiscriminativeNetwork @@ -247,10 +246,6 @@ def __init__(self, n_features=1, n_out=1): self._ret = {} - @classmethod - def get_section_key_name(cls): - return Pluggable.SECTION_KEY_DISCRIMINATIVE_NET - @staticmethod def check_pluggable_valid(): return diff --git a/qiskit/aqua/components/neural_networks/pytorch_discriminator.py b/qiskit/aqua/components/neural_networks/pytorch_discriminator.py index 5fb6a1ee97..a18632daea 100644 --- a/qiskit/aqua/components/neural_networks/pytorch_discriminator.py +++ b/qiskit/aqua/components/neural_networks/pytorch_discriminator.py @@ -22,7 +22,7 @@ import numpy as np -from qiskit.aqua import AquaError, Pluggable +from qiskit.aqua import AquaError from .discriminative_network import DiscriminativeNetwork logger = logging.getLogger(__name__) @@ -137,10 +137,6 @@ def __init__(self, n_features=1, n_out=1): self._ret = {} - @classmethod - def get_section_key_name(cls): - return Pluggable.SECTION_KEY_DISCRIMINATIVE_NET - @staticmethod def check_pluggable_valid(): err_msg = \ diff --git a/qiskit/aqua/components/neural_networks/quantum_generator.py b/qiskit/aqua/components/neural_networks/quantum_generator.py index 463edab92b..6cc7db88af 100644 --- a/qiskit/aqua/components/neural_networks/quantum_generator.py +++ b/qiskit/aqua/components/neural_networks/quantum_generator.py @@ -27,7 +27,7 @@ from qiskit.aqua.components.uncertainty_models import UnivariateVariationalDistribution, \ MultivariateVariationalDistribution from qiskit.aqua.components.variational_forms import RY -from qiskit.aqua import AquaError, Pluggable +from qiskit.aqua import AquaError from qiskit.aqua.components.neural_networks.generative_network import GenerativeNetwork from qiskit.aqua.components.initial_states import Custom @@ -186,38 +186,6 @@ def __init__(self, bounds, num_qubits, generator_circuit=None, self._discriminator = None self._ret = {} - @classmethod - def init_params(cls, params): - """ - Initialize via parameters dictionary and algorithm input instance. - - Args: - params (dict): parameters dictionary - - Returns: - QuantumGenerator: vqe object - - Raises: - AquaError: invalid input - """ - generator_params = params.get(Pluggable.SECTION_KEY_GENERATIVE_NETWORK) - bounds = generator_params.get('bounds') - if bounds is None: - raise AquaError("Data value bounds are required.") - num_qubits = generator_params.get('num_qubits') - if num_qubits is None: - raise AquaError("Numbers of qubits per dimension required.") - - init_params = generator_params.get('init_params') - snapshot_dir = generator_params.get('snapshot_dir') - - return cls(bounds, num_qubits, generator_circuit=None, init_params=init_params, - snapshot_dir=snapshot_dir) - - @classmethod - def get_section_key_name(cls): - return Pluggable.SECTION_KEY_GENERATIVE_NETWORK - def set_seed(self, seed): """ Set seed. diff --git a/qiskit/aqua/components/optimizers/optimizer.py b/qiskit/aqua/components/optimizers/optimizer.py index c22c7b5a95..c5a78310fe 100644 --- a/qiskit/aqua/components/optimizers/optimizer.py +++ b/qiskit/aqua/components/optimizers/optimizer.py @@ -65,26 +65,6 @@ def __init__(self): self._options = {} self._max_evals_grouped = 1 - @classmethod - def init_params(cls, params): - """Initialize with a params dictionary. - - A dictionary of config params as per the configuration object. Some of these params get - passed to scipy optimizers in an options dictionary. We can specify an options array of - names in config dictionary to have the options dictionary automatically populated. All - other config items, excluding name, will be passed to init_args - - Args: - params (dict): configuration dict - Returns: - Optimizer: instance of this class - """ - opt_params = params.get(Pluggable.SECTION_KEY_OPTIMIZER) - logger.debug('init_params: %s', opt_params) - args = {k: v for k, v in opt_params.items() if k != 'name'} - optimizer = cls(**args) - return optimizer - def set_options(self, **kwargs): """ Sets or updates values in the options dictionary. diff --git a/qiskit/aqua/components/oracles/oracle.py b/qiskit/aqua/components/oracles/oracle.py index a7634374bc..6598e96dcf 100644 --- a/qiskit/aqua/components/oracles/oracle.py +++ b/qiskit/aqua/components/oracles/oracle.py @@ -44,13 +44,6 @@ def __init__(self, *args, **kwargs): self._ancillary_register = None self._circuit = None - @classmethod - def init_params(cls, params): - """ init params """ - oracle_params = params.get(Pluggable.SECTION_KEY_ORACLE) - args = {k: v for k, v in oracle_params.items() if k != 'name'} - return cls(**args) - @property def circuit(self): """ circuit """ diff --git a/qiskit/aqua/components/qfts/qft.py b/qiskit/aqua/components/qfts/qft.py index 18f5260fd0..bb3c949589 100644 --- a/qiskit/aqua/components/qfts/qft.py +++ b/qiskit/aqua/components/qfts/qft.py @@ -39,13 +39,6 @@ class QFT(Pluggable): def __init__(self, *args, **kwargs): super().__init__() - @classmethod - def init_params(cls, params): - """ init params """ - qft_params = params.get(Pluggable.SECTION_KEY_QFT) - kwargs = {k: v for k, v in qft_params.items() if k != 'name'} - return cls(**kwargs) - @abstractmethod def _build_matrix(self): raise NotImplementedError diff --git a/qiskit/aqua/components/reciprocals/reciprocal.py b/qiskit/aqua/components/reciprocals/reciprocal.py index d4df89c1f3..04f44478e7 100644 --- a/qiskit/aqua/components/reciprocals/reciprocal.py +++ b/qiskit/aqua/components/reciprocals/reciprocal.py @@ -32,13 +32,6 @@ class Reciprocal(Pluggable): def __init__(self): super().__init__() - @classmethod - def init_params(cls, params): - """ init params """ - reci_params = params.get(Pluggable.SECTION_KEY_RECIPROCAL) - args = {k: v for k, v in reci_params.items() if k != 'name'} - return cls(**args) - @abstractmethod def sv_to_resvec(self, statevector, num_q): """Convert statevector to result vector. diff --git a/qiskit/aqua/components/uncertainty_models/multivariate_distribution.py b/qiskit/aqua/components/uncertainty_models/multivariate_distribution.py index 1f215c0bb6..8f70d9a203 100644 --- a/qiskit/aqua/components/uncertainty_models/multivariate_distribution.py +++ b/qiskit/aqua/components/uncertainty_models/multivariate_distribution.py @@ -19,7 +19,6 @@ from abc import ABC import numpy as np -from qiskit.aqua import Pluggable from qiskit.aqua.components.initial_states import Custom from .uncertainty_model import UncertaintyModel @@ -30,10 +29,6 @@ class MultivariateDistribution(UncertaintyModel, ABC): (Interface for discrete bounded uncertainty models assuming an equidistant grid) """ - @classmethod - def get_section_key_name(cls): - return Pluggable.SECTION_KEY_MULTIVARIATE_DIST - def __init__(self, num_qubits, probabilities=None, low=None, high=None): """ Constructor. diff --git a/qiskit/aqua/components/uncertainty_models/multivariate_variational_distribution.py b/qiskit/aqua/components/uncertainty_models/multivariate_variational_distribution.py index f90863c984..e8f9d00ce3 100644 --- a/qiskit/aqua/components/uncertainty_models/multivariate_variational_distribution.py +++ b/qiskit/aqua/components/uncertainty_models/multivariate_variational_distribution.py @@ -17,7 +17,6 @@ import numpy as np from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit -from qiskit.aqua import Pluggable, get_pluggable_class, PluggableType from .multivariate_distribution import MultivariateDistribution # pylint: disable=invalid-name @@ -89,28 +88,6 @@ def __init__(self, num_qubits, var_form, params, low=None, high=None): self._var_form = var_form self.params = params - @classmethod - def init_params(cls, params): - """ - Initialize via parameters dictionary. - Args: - params (dict): parameters dictionary - Returns: - MultivariateVariationalDistribution: An object instance of this class - """ - - multi_var_params_params = params.get(Pluggable.SECTION_KEY_UNIVARIATE_DIST) - num_qubits = multi_var_params_params.get('num_qubits') - params = multi_var_params_params.get('params') - low = multi_var_params_params.get('low') - high = multi_var_params_params.get('high') - - var_form_params = params.get(Pluggable.SECTION_KEY_VAR_FORM) - var_form = get_pluggable_class(PluggableType.VARIATIONAL_FORM, - var_form_params['name']).init_params(params) - - return cls(num_qubits, var_form, params, low, high) - def build(self, qc, q, q_ancillas=None, params=None): circuit_var_form = self._var_form.construct_circuit(self.params) qc.append(circuit_var_form.to_instruction(), q) diff --git a/qiskit/aqua/components/uncertainty_models/uncertainty_model.py b/qiskit/aqua/components/uncertainty_models/uncertainty_model.py index 90ef9af59d..d1b26cb73c 100644 --- a/qiskit/aqua/components/uncertainty_models/uncertainty_model.py +++ b/qiskit/aqua/components/uncertainty_models/uncertainty_model.py @@ -27,19 +27,10 @@ class UncertaintyModel(CircuitFactory, Pluggable, ABC): The abstract Uncertainty Model """ - @classmethod - def init_params(cls, params): - """ init params """ - uncertainty_model_params = params.get(cls.get_section_key_name()) - args = {k: v for k, v in uncertainty_model_params.items() if k != 'name'} - return cls(**args) - - @classmethod - @abstractmethod - def get_section_key_name(cls): - """ get section key name """ - pass - # pylint: disable=useless-super-delegation def __init__(self, num_target_qubits): super().__init__(num_target_qubits) + + @abstractmethod + def build(self, qc, q, q_ancillas=None, params=None): + raise NotImplementedError() diff --git a/qiskit/aqua/components/uncertainty_models/univariate_distribution.py b/qiskit/aqua/components/uncertainty_models/univariate_distribution.py index c67955142b..7fd87cae1d 100644 --- a/qiskit/aqua/components/uncertainty_models/univariate_distribution.py +++ b/qiskit/aqua/components/uncertainty_models/univariate_distribution.py @@ -19,7 +19,7 @@ from abc import ABC import numpy as np -from qiskit.aqua import AquaError, Pluggable +from qiskit.aqua import AquaError from qiskit.aqua.components.initial_states import Custom from .uncertainty_model import UncertaintyModel @@ -30,10 +30,6 @@ class UnivariateDistribution(UncertaintyModel, ABC): (Interface for discrete bounded uncertainty models assuming an equidistant grid) """ - @classmethod - def get_section_key_name(cls): - return Pluggable.SECTION_KEY_UNIVARIATE_DIST - def __init__(self, num_target_qubits, probabilities=None, low=0, high=1): r""" Abstract univariate distribution class diff --git a/qiskit/aqua/components/uncertainty_models/univariate_variational_distribution.py b/qiskit/aqua/components/uncertainty_models/univariate_variational_distribution.py index 6a55c23d00..13392d32de 100644 --- a/qiskit/aqua/components/uncertainty_models/univariate_variational_distribution.py +++ b/qiskit/aqua/components/uncertainty_models/univariate_variational_distribution.py @@ -19,7 +19,6 @@ import numpy as np from qiskit import ClassicalRegister -from qiskit.aqua import Pluggable, get_pluggable_class, PluggableType from .univariate_distribution import UnivariateDistribution @@ -79,28 +78,6 @@ def __init__(self, num_qubits, var_form, params, low=0, high=1): probabilities = np.zeros(2 ** sum(num_qubits)) super().__init__(num_qubits, probabilities, low, high) - @classmethod - def init_params(cls, params): - """ - Initialize via parameters dictionary. - Args: - params (dict): parameters dictionary - Returns: - UnivariateVariationalDistribution: An object instance of this class - """ - - uni_var_params_params = params.get(Pluggable.SECTION_KEY_UNIVARIATE_DIST) - num_qubits = uni_var_params_params.get('num_qubits') - params = uni_var_params_params.get('params') - low = uni_var_params_params.get('low') - high = uni_var_params_params.get('high') - - var_form_params = params.get(Pluggable.SECTION_KEY_VAR_FORM) - var_form = get_pluggable_class(PluggableType.VARIATIONAL_FORM, - var_form_params['name']).init_params(params) - - return cls(num_qubits, var_form, params, low, high) - def build(self, qc, q, q_ancillas=None, params=None): circuit_var_form = self._var_form.construct_circuit(self.params) qc.append(circuit_var_form.to_instruction(), q) diff --git a/qiskit/aqua/components/uncertainty_problems/uncertainty_problem.py b/qiskit/aqua/components/uncertainty_problems/uncertainty_problem.py index 2fa3e03e8f..fccbf4bb8c 100644 --- a/qiskit/aqua/components/uncertainty_problems/uncertainty_problem.py +++ b/qiskit/aqua/components/uncertainty_problems/uncertainty_problem.py @@ -17,7 +17,7 @@ """ from abc import ABC -from qiskit.aqua import AquaError, Pluggable, PluggableType, get_pluggable_class +from qiskit.aqua import Pluggable from qiskit.aqua.utils import CircuitFactory # pylint: disable=abstract-method @@ -28,29 +28,6 @@ class UncertaintyProblem(CircuitFactory, Pluggable, ABC): The abstract Uncertainty Problem pluggable component. """ - @classmethod - def init_params(cls, params): - """ init params """ - uncertainty_problem_params = params.get(Pluggable.SECTION_KEY_UNCERTAINTY_PROBLEM) - args = {k: v for k, v in uncertainty_problem_params.items() if k != 'name'} - - # Uncertainty problems take an uncertainty model. Each can take a specific type as - # a dependent. We currently have two known types and to save having init_params in - # each of the problems a problem can use this base class method that tries to find - # params for the set of known uncertainty model types. - uncertainty_model_params = params.get(Pluggable.SECTION_KEY_UNIVARIATE_DIST) - pluggable_type = PluggableType.UNIVARIATE_DISTRIBUTION - if uncertainty_model_params is None: - uncertainty_model_params = params.get(Pluggable.SECTION_KEY_MULTIVARIATE_DIST) - pluggable_type = PluggableType.MULTIVARIATE_DISTRIBUTION - if uncertainty_model_params is None: - raise AquaError("No params for known uncertainty model types found") - uncertainty_model = \ - get_pluggable_class(pluggable_type, - uncertainty_model_params['name']).init_params(params) - - return cls(uncertainty_model, **args) - # pylint: disable=useless-super-delegation def __init__(self, num_qubits): super().__init__(num_qubits) diff --git a/qiskit/aqua/components/variational_forms/variational_form.py b/qiskit/aqua/components/variational_forms/variational_form.py index 6b35f7c172..d7878192f9 100644 --- a/qiskit/aqua/components/variational_forms/variational_form.py +++ b/qiskit/aqua/components/variational_forms/variational_form.py @@ -18,7 +18,7 @@ from abc import abstractmethod -from qiskit.aqua import Pluggable, PluggableType, get_pluggable_class +from qiskit.aqua import Pluggable from qiskit.aqua.utils import get_entangler_map, validate_entangler_map @@ -40,20 +40,6 @@ def __init__(self): self._support_parameterized_circuit = False pass - @classmethod - def init_params(cls, params): - """ init params """ - var_form_params = params.get(Pluggable.SECTION_KEY_VAR_FORM) - args = {k: v for k, v in var_form_params.items() if k != 'name'} - - # We pass on num_qubits to initial state since we know our dependent needs this - init_state_params = params.get(Pluggable.SECTION_KEY_INITIAL_STATE) - init_state_params['num_qubits'] = var_form_params['num_qubits'] - args['initial_state'] = get_pluggable_class(PluggableType.INITIAL_STATE, - init_state_params['name']).init_params(params) - - return cls(**args) - @abstractmethod def construct_circuit(self, parameters, q=None): """Construct the variational form, given its parameters. diff --git a/qiskit/aqua/input/__init__.py b/qiskit/aqua/input/__init__.py deleted file mode 100644 index 9f3a78dcd2..0000000000 --- a/qiskit/aqua/input/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" Input Packages """ - -from .algorithm_input import AlgorithmInput -from .energy_input import EnergyInput -from .linear_system_input import LinearSystemInput -from .classification_input import ClassificationInput -from .qgan_input import QGANInput - -__all__ = ['AlgorithmInput', - 'EnergyInput', - 'LinearSystemInput', - 'ClassificationInput', - 'QGANInput'] diff --git a/qiskit/aqua/input/algorithm_input.py b/qiskit/aqua/input/algorithm_input.py deleted file mode 100644 index fb0d3ca861..0000000000 --- a/qiskit/aqua/input/algorithm_input.py +++ /dev/null @@ -1,70 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" Algorithm Input """ - -import copy -from abc import abstractmethod -from qiskit.aqua import Pluggable -from qiskit.aqua import AquaError - - -class AlgorithmInput(Pluggable): - """ Algorithm Input """ - _PROBLEM_SET = ['energy', 'excited_states', 'eoh', 'classification', 'ising', 'linear_system', - 'distribution_learning_loading'] - - @abstractmethod - def __init__(self): - super().__init__() - if 'problems' not in self.configuration or not self.configuration['problems']: - raise AquaError('Algorithm Input missing or empty configuration problems') - - for problem in self.configuration['problems']: - if problem not in AlgorithmInput._PROBLEM_SET: - raise AquaError( - 'Problem {} not in known problem set {}'.format(problem, - AlgorithmInput._PROBLEM_SET)) - - @property - def all_problems(self): - """ returns all problems """ - return copy.deepcopy(self._PROBLEM_SET) - - @property - def problems(self): - """ - Gets the set of problems that this input form supports - """ - return self.configuration.problems - - @abstractmethod - def to_params(self): - """ - Convert the derived algorithminput class fields to a dictionary where the values are in a - form that can be saved to json - Returns: - Dictionary of input fields - """ - raise NotImplementedError() - - @abstractmethod - def from_params(self, params): - """ - Load the dictionary into the algorithminput class fields. This dictionary being that as - created by to_params() - Args: - params (dict): A dictionary as originally created by to_params() - """ - raise NotImplementedError() diff --git a/qiskit/aqua/input/classification_input.py b/qiskit/aqua/input/classification_input.py deleted file mode 100644 index e3211acee8..0000000000 --- a/qiskit/aqua/input/classification_input.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" Classification Input """ - -from qiskit.aqua import AquaError -from qiskit.aqua.input import AlgorithmInput -from qiskit.aqua.utils import convert_dict_to_json - - -class ClassificationInput(AlgorithmInput): - """ Classification Input """ - CONFIGURATION = { - 'name': 'ClassificationInput', - 'description': 'SVM input', - 'input_schema': { - '$schema': 'http://json-schema.org/draft-07/schema#', - 'id': 'classification_input_schema', - 'type': 'object', - 'properties': { - 'training_dataset': { - 'type': ['object', 'null'], - 'default': None - }, - 'test_dataset': { - 'type': ['object', 'null'], - 'default': None - }, - 'datapoints': { - 'type': ['array', 'null'], - 'default': None - } - }, - 'additionalProperties': False - }, - 'problems': ['classification'] - } - - def __init__(self, training_dataset, test_dataset=None, datapoints=None): - self.validate(locals()) - super().__init__() - self.training_dataset = training_dataset or {} - self.test_dataset = test_dataset or {} - self.datapoints = datapoints if datapoints is not None else [] - - def validate(self, args_dict): - params = {key: value for key, value in args_dict.items() - if key in ['training_dataset', 'test_dataset', 'datapoints']} - super().validate(convert_dict_to_json(params)) - - def to_params(self): - params = {} - params['training_dataset'] = self.training_dataset - params['test_dataset'] = self.test_dataset - params['datapoints'] = self.datapoints - return params - - @classmethod - def from_params(cls, params): - if 'training_dataset' not in params: - raise AquaError("training_dataset is required.") - training_dataset = params['training_dataset'] - test_dataset = params['test_dataset'] - datapoints = params['datapoints'] - return cls(training_dataset, test_dataset, datapoints) diff --git a/qiskit/aqua/input/energy_input.py b/qiskit/aqua/input/energy_input.py deleted file mode 100644 index 8b6d6da768..0000000000 --- a/qiskit/aqua/input/energy_input.py +++ /dev/null @@ -1,110 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" Energy Input """ - -from qiskit.aqua import AquaError -from qiskit.aqua.input import AlgorithmInput -from qiskit.aqua.operators import WeightedPauliOperator - - -class EnergyInput(AlgorithmInput): - """ Energy Input """ - PROP_KEY_QUBITOP = 'qubit_op' - PROP_KEY_AUXOPS = 'aux_ops' - - CONFIGURATION = { - 'name': 'EnergyInput', - 'description': 'Energy problem input', - 'input_schema': { - '$schema': 'http://json-schema.org/draft-07/schema#', - 'id': 'energy_state_schema', - 'type': 'object', - 'properties': { - PROP_KEY_QUBITOP: { - 'type': 'object', - 'default': {} - }, - PROP_KEY_AUXOPS: { - 'type': ['array', 'null'], - 'default': None - } - }, - 'additionalProperties': False - }, - 'problems': ['energy', 'excited_states', 'eoh', 'ising'] - } - - def __init__(self, qubit_op, aux_ops=None): - self.validate(locals()) - super().__init__() - self._qubit_op = qubit_op - self._aux_ops = aux_ops if aux_ops is not None else [] - - @property - def qubit_op(self): - """ returns qubit op """ - return self._qubit_op - - @qubit_op.setter - def qubit_op(self, qubit_op): - """ set qubit op """ - self._qubit_op = qubit_op - - @property - def aux_ops(self): - """ returns aux ops """ - return self._aux_ops - - def validate(self, args_dict): - """ validate input """ - params = {} - for key, value in args_dict.items(): - if key == EnergyInput.PROP_KEY_QUBITOP: - value = value.to_dict() if value is not None else {} - elif key == EnergyInput.PROP_KEY_AUXOPS: - value = \ - [value[i].to_dict() for i in range(len(value))] if value is not None else None - - params[key] = value - - super().validate(params) - - def add_aux_op(self, aux_op): - """ add aux ops """ - self._aux_ops.append(aux_op) - - def has_aux_ops(self): - """ check f has aux ops """ - return len(self._aux_ops) > 0 - - def to_params(self): - """ to params """ - params = {} - params[EnergyInput.PROP_KEY_QUBITOP] = self._qubit_op.to_dict() - params[EnergyInput.PROP_KEY_AUXOPS] = \ - [self._aux_ops[i].to_dict() for i in range(len(self._aux_ops))] - return params - - @classmethod - def from_params(cls, params): - """ from params """ - if EnergyInput.PROP_KEY_QUBITOP not in params: - raise AquaError("Qubit operator is required.") - qparams = params[EnergyInput.PROP_KEY_QUBITOP] - qubit_op = WeightedPauliOperator.from_dict(qparams) - if EnergyInput.PROP_KEY_AUXOPS in params: - auxparams = params[EnergyInput.PROP_KEY_AUXOPS] - aux_ops = [WeightedPauliOperator.from_dict(auxparams[i]) for i in range(len(auxparams))] - return cls(qubit_op, aux_ops) diff --git a/qiskit/aqua/input/linear_system_input.py b/qiskit/aqua/input/linear_system_input.py deleted file mode 100644 index dc2b0070e3..0000000000 --- a/qiskit/aqua/input/linear_system_input.py +++ /dev/null @@ -1,141 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" Linear System Input """ - -import numpy as np - -from qiskit.aqua import AquaError -from qiskit.aqua.input import AlgorithmInput - - -class LinearSystemInput(AlgorithmInput): - """ Linear System Input """ - PROP_KEY_MATRIX = 'matrix' - PROP_KEY_VECTOR = 'vector' - - CONFIGURATION = { - 'name': 'LinearSystemInput', - 'description': 'Linear System problem input', - 'input_schema': { - '$schema': 'http://json-schema.org/draft-07/schema#', - 'id': 'linear_system_state_schema', - 'type': 'object', - 'properties': { - PROP_KEY_MATRIX: { - 'type': ['array', 'null'], - 'default': None - }, - PROP_KEY_VECTOR: { - 'type': ['array', 'null'], - 'default': None - } - }, - 'additionalProperties': False - }, - 'problems': ['linear_system'] - } - - def __init__(self, matrix=None, vector=None): - super().__init__() - self._matrix = matrix if matrix is not None else [] - self._vector = vector if vector is not None else [] - - @property - def matrix(self): - """ returns matrix """ - return self._matrix - - @matrix.setter - def matrix(self, matrix): - """ sets matrix """ - self._matrix = matrix - - @property - def vector(self): - """ returns vector """ - return self._vector - - @vector.setter - def vector(self, vector): - """ sets vector """ - self._vector = vector - - def validate(self, args_dict): - """ validate input """ - params = {} - for key, value in args_dict.items(): - if key == LinearSystemInput.PROP_KEY_MATRIX: - value = value.save_to_list() if value is not None else {} - elif key == LinearSystemInput.PROP_KEY_VECTOR: - value = value.save_to_list() if value is not None else {} - - params[key] = value - - super().validate(params) - - def to_params(self): - """ to params """ - params = {} - params[LinearSystemInput.PROP_KEY_MATRIX] = self.save_to_list(self._matrix) - params[LinearSystemInput.PROP_KEY_VECTOR] = self.save_to_list(self._vector) - return params - - @classmethod - def from_params(cls, params): - """ from params """ - if LinearSystemInput.PROP_KEY_MATRIX not in params: - raise AquaError("Matrix is required.") - if LinearSystemInput.PROP_KEY_VECTOR not in params: - raise AquaError("Vector is required.") - mat_params = params[LinearSystemInput.PROP_KEY_MATRIX] - matrix = cls.load_mat_from_list(mat_params) - vec_params = params[LinearSystemInput.PROP_KEY_VECTOR] - vector = cls.load_vec_from_list(vec_params) - return cls(matrix, vector) - - @staticmethod - def load_mat_from_list(mat): - """ load matrix from list """ - - def depth(x): - return isinstance(x, list) and max(map(depth, x))+1 - if depth(mat) == 3: - return np.array(mat[0])+1j*np.array(mat[1]) - elif depth(mat) == 2: - return np.array(mat) - else: - raise AquaError("Matrix list must be depth 2 or 3") - - @staticmethod - def load_vec_from_list(vec): - """ load vector from list """ - - def depth(x): - return isinstance(x, list) and max(map(depth, x))+1 - if depth(vec) == 2: - return np.array(vec[0])+1j*np.array(vec[1]) - elif depth(vec) == 1: - return np.array(vec) - else: - raise AquaError("Vector list must be depth 2 or 3") - - def save_to_list(self, mat): - """ save to list """ - if not isinstance(mat, np.ndarray): - return mat - if mat.dtype == complex: - return [mat.real.tolist(), mat.imag.tolist()] - else: - return mat.tolist() diff --git a/qiskit/aqua/input/qgan_input.py b/qiskit/aqua/input/qgan_input.py deleted file mode 100644 index a6c2741fe9..0000000000 --- a/qiskit/aqua/input/qgan_input.py +++ /dev/null @@ -1,70 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" qgan input """ - -from qiskit.aqua import AquaError -from qiskit.aqua.input import AlgorithmInput -from qiskit.aqua.utils import convert_dict_to_json - - -class QGANInput(AlgorithmInput): - """ qgan input """ - CONFIGURATION = { - 'name': 'QGANInput', - 'description': 'QGAN input', - 'input_schema': { - '$schema': 'http://json-schema.org/draft-07/schema#', - 'id': 'qgan_input_schema', - 'type': 'object', - 'properties': { - 'data': { - 'type': ['array', 'null'], - 'default': None - }, - 'bounds': { - 'type': ['array', 'null'], - 'default': None - } - }, - 'additionalProperties': False - }, - 'problems': ['distribution_learning_loading'] - } - - def __init__(self, data, bounds): - self.validate(locals()) - super().__init__() - self.data = data - self.bounds = bounds - - def validate(self, args_dict): - params = {key: value for key, value in args_dict.items() if key in ['data', 'bounds']} - super().validate(convert_dict_to_json(params)) - - def to_params(self): - params = {} - params['data'] = self.data - params['bounds'] = self.bounds - return params - - @classmethod - def from_params(cls, params): - if 'data' not in params: - raise AquaError("Training data not given.") - if 'bounds' not in params: - raise AquaError("Data bounds not given.") - data = params['data'] - bounds = params['bounds'] - return cls(data, bounds) diff --git a/qiskit/aqua/parser/__init__.py b/qiskit/aqua/parser/__init__.py deleted file mode 100644 index 9e7374abd1..0000000000 --- a/qiskit/aqua/parser/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" Parser and schema packages """ - -from .json_schema import JSONSchema -from .base_parser import BaseParser - -__all__ = ['JSONSchema', - 'BaseParser'] diff --git a/qiskit/aqua/parser/_inputparser.py b/qiskit/aqua/parser/_inputparser.py deleted file mode 100644 index dfbb05a568..0000000000 --- a/qiskit/aqua/parser/_inputparser.py +++ /dev/null @@ -1,252 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Aqua input Parser.""" - -import json -import logging -import os -import copy -from qiskit.aqua.aqua_error import AquaError -from qiskit.aqua import (local_pluggables_types, - PluggableType, - get_pluggable_configuration, - local_pluggables) -from .base_parser import BaseParser -from .json_schema import JSONSchema - -logger = logging.getLogger(__name__) - - -class InputParser(BaseParser): - """Aqua input Parser.""" - - def __init__(self, input_value=None): - """Create Parser object.""" - super().__init__(JSONSchema(os.path.join(os.path.dirname(__file__), 'input_schema.json'))) - if input is not None: - if isinstance(input_value, dict): - self._sections = input_value - elif isinstance(input_value, str): - self._filename = input_value - else: - raise AquaError("Invalid parser input type.") - - self._section_order = [JSONSchema.PROBLEM, - PluggableType.INPUT.value, - PluggableType.ALGORITHM.value] - for pluggable_type in local_pluggables_types(): - if pluggable_type not in [PluggableType.INPUT, PluggableType.ALGORITHM]: - self._section_order.append(pluggable_type.value) - - self._section_order.extend([JSONSchema.BACKEND, InputParser._UNKNOWN]) - - def parse(self): - """Parse the data.""" - if self._sections is None: - if self._filename is None: - raise AquaError("Missing input file") - - with open(self._filename) as json_file: - self._sections = json.load(json_file) - - self.json_schema.update_backend_schema(self) - self.json_schema.update_pluggable_schemas(self) - self._update_algorithm_input_schema() - self._sections = self._order_sections(self._sections) - self._original_sections = copy.deepcopy(self._sections) - - def get_default_sections(self): - return self.json_schema.get_default_sections() - - def merge_default_values(self): - section_names = self.get_section_names() - if PluggableType.ALGORITHM.value in section_names: - if JSONSchema.PROBLEM not in section_names: - self.set_section(JSONSchema.PROBLEM) - - self.json_schema.update_backend_schema(self) - self.json_schema.update_pluggable_schemas(self) - self._update_algorithm_input_schema() - self._merge_dependencies() - - # do not merge any pluggable that doesn't have name default in schema - default_section_names = [] - pluggable_type_names = [pluggable_type.value for pluggable_type in local_pluggables_types()] - for section_name in self.get_default_section_names(): - if section_name in pluggable_type_names: - if self.get_property_default_value(section_name, JSONSchema.NAME) is not None: - default_section_names.append(section_name) - else: - default_section_names.append(section_name) - - section_names = set(self.get_section_names()) | set(default_section_names) - for section_name in section_names: - if section_name not in self._sections: - self.set_section(section_name) - - new_properties = self.get_section_default_properties(section_name) - if new_properties is not None: - if self.section_is_text(section_name): - text = self.get_section_text(section_name) - if not text and isinstance(new_properties, str) and new_properties: - self.set_section_data(section_name, new_properties) - else: - properties = self.get_section_properties(section_name) - new_properties.update(properties) - self.set_section_properties(section_name, new_properties) - - self._sections = self._order_sections(self._sections) - - def validate_merge_defaults(self): - super().validate_merge_defaults() - self._validate_input_problem() - - def save_to_file(self, file_name): - if file_name is None: - raise AquaError('Missing file path') - - file_name = file_name.strip() - if not file_name: - raise AquaError('Missing file path') - - with open(file_name, 'w') as file: - print(json.dumps(self.get_sections(), sort_keys=True, indent=4), file=file) - - def delete_section(self, section_name): - """ - Args: - section_name (str): the name of the section, case insensitive - """ - super().delete_section(section_name) - self._update_algorithm_input_schema() - - def post_set_section_property(self, section_name, property_name): - property_name = JSONSchema.format_property_name(property_name) - if property_name == JSONSchema.NAME: - section_name = JSONSchema.format_section_name(section_name).lower() - if PluggableType.INPUT.value == section_name: - self._update_algorithm_input_schema() - elif JSONSchema.PROBLEM == section_name: - self._update_input_problem() - self._update_algorithm_input_schema() - # remove properties that are not valid for this input - default_properties = self.get_section_default_properties(PluggableType.INPUT.value) - if isinstance(default_properties, dict): - properties = self.get_section_properties(PluggableType.INPUT.value) - for p_name in list(properties.keys()): - if p_name != JSONSchema.NAME and p_name not in default_properties: - self.delete_section_property(PluggableType.INPUT.value, p_name) - - @staticmethod - def get_input_problems(input_name): - """ returns input problems """ - config = get_pluggable_configuration(PluggableType.INPUT, input_name) - if 'problems' in config: - return config['problems'] - - return [] - - def _update_algorithm_input_schema(self): - # find algorithm input - default_name = self.get_property_default_value(PluggableType.INPUT.value, JSONSchema.NAME) - input_name = self.get_section_property(PluggableType.INPUT.value, - JSONSchema.NAME, default_name) - if input_name is None: - # find the first valid input for the problem - problem_name = self.get_section_property(JSONSchema.PROBLEM, JSONSchema.NAME) - if problem_name is None: - problem_name = self.get_property_default_value(JSONSchema.PROBLEM, - JSONSchema.NAME) - - if problem_name is None: - raise AquaError("No algorithm 'problem' section found on input.") - - for name in local_pluggables(PluggableType.INPUT): - if problem_name in self.get_input_problems(name): - # set to the first input to solve the problem - input_name = name - break - - if input_name is None: - # just remove from schema if none solves the problem - if PluggableType.INPUT.value in self.json_schema.schema['properties']: - del self.json_schema.schema['properties'][PluggableType.INPUT.value] - return - - if default_name is None: - default_name = input_name - - config = {} - try: - config = get_pluggable_configuration(PluggableType.INPUT, input_name) - except Exception: # pylint: disable=broad-except - pass - - input_schema = config['input_schema'] if 'input_schema' in config else {} - properties = input_schema['properties'] if 'properties' in input_schema else {} - properties[JSONSchema.NAME] = {'type': 'string'} - required = input_schema['required'] if 'required' in input_schema else [] - additional_properties = input_schema['additionalProperties'] \ - if 'additionalProperties' in input_schema else True - if default_name is not None: - properties[JSONSchema.NAME]['default'] = default_name - required.append(JSONSchema.NAME) - - if PluggableType.INPUT.value not in self.json_schema.schema['properties']: - self.json_schema.schema['properties'][PluggableType.INPUT.value] = {'type': 'object'} - - self.json_schema.schema['properties'][PluggableType.INPUT.value]['properties'] = properties - self.json_schema.schema['properties'][PluggableType.INPUT.value]['required'] = required - self.json_schema.schema['properties'][PluggableType.INPUT.value]['additionalProperties'] = \ - additional_properties - - def _validate_input_problem(self): - input_name = self.get_section_property(PluggableType.INPUT.value, JSONSchema.NAME) - if input_name is None: - return - - problem_name = self.get_section_property(JSONSchema.PROBLEM, JSONSchema.NAME) - if problem_name is None: - problem_name = self.get_property_default_value(JSONSchema.PROBLEM, JSONSchema.NAME) - - if problem_name is None: - raise AquaError("No algorithm 'problem' section found on input.") - - problems = InputParser.get_input_problems(input_name) - if problem_name not in problems: - raise AquaError( - "Problem: {} not in the list of problems: {} for input: {}.".format( - problem_name, problems, input_name)) - - def _update_input_problem(self): - problem_name = self.get_section_property(JSONSchema.PROBLEM, JSONSchema.NAME) - if problem_name is None: - problem_name = self.get_property_default_value(JSONSchema.PROBLEM, JSONSchema.NAME) - - if problem_name is None: - raise AquaError("No algorithm 'problem' section found on input.") - - input_name = self.get_section_property(PluggableType.INPUT.value, JSONSchema.NAME) - if input_name is not None and problem_name in InputParser.get_input_problems(input_name): - return - - for input_name in local_pluggables(PluggableType.INPUT): - if problem_name in self.get_input_problems(input_name): - # set to the first input to solve the problem - self.set_section_property(PluggableType.INPUT.value, JSONSchema.NAME, input_name) - return - - # no input solve this problem, remove section - self.delete_section(PluggableType.INPUT.value) diff --git a/qiskit/aqua/parser/base_parser.py b/qiskit/aqua/parser/base_parser.py deleted file mode 100644 index 82f91aa685..0000000000 --- a/qiskit/aqua/parser/base_parser.py +++ /dev/null @@ -1,736 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Base Aqua Parser.""" - -from abc import ABC, abstractmethod -import json -from collections import OrderedDict -import logging -import copy -import traceback -from qiskit.aqua import (local_pluggables_types, - PluggableType, - get_pluggable_configuration, - local_pluggables) -from qiskit.aqua.utils.backend_utils import (get_backends_from_provider, - get_provider_from_backend) -from qiskit.aqua.aqua_error import AquaError -from .json_schema import JSONSchema - - -def exception_to_string(excp): - """ returns exception stack trace in string format """ - stack = traceback.extract_stack()[:-3] + traceback.extract_tb(excp.__traceback__) - pretty = traceback.format_list(stack) - return ''.join(pretty) + '\n {} {}'.format(excp.__class__, excp) - - -logger = logging.getLogger(__name__) - - -class BaseParser(ABC): - """Base Aqua Parser.""" - - _UNKNOWN = 'unknown' - _DEFAULT_PROPERTY_ORDER = [JSONSchema.NAME, _UNKNOWN] - _BACKEND_PROPERTY_ORDER = [JSONSchema.PROVIDER, JSONSchema.NAME, _UNKNOWN] - - def __init__(self, jsonSchema): - """Create InputParser object.""" - self._section_order = None - self._original_sections = None - self._filename = None - self._sections = None - self._json_schema = jsonSchema - self._json_schema._initialize_problem_section() - self._json_schema.commit_changes() - - def _order_sections(self, sections): - sections_sorted = OrderedDict(sorted(list(sections.items()), - key=lambda x: self._section_order.index(x[0]) - if x[0] in self._section_order - else self._section_order.index(BaseParser._UNKNOWN))) - - # pylint: disable=cell-var-from-loop - for section, properties in sections_sorted.items(): - if isinstance(properties, dict): - _property_order = \ - BaseParser._BACKEND_PROPERTY_ORDER \ - if section == JSONSchema.BACKEND else BaseParser._DEFAULT_PROPERTY_ORDER - sections_sorted[section] = \ - OrderedDict( - sorted(list(properties.items()), - key=lambda x: _property_order.index(x[0]) - if x[0] in _property_order else - _property_order.index(BaseParser._UNKNOWN))) - - return sections_sorted - - @property - def backend(self): - """Getter of backend.""" - return self.json_schema.backend - - @backend.setter - def backend(self, new_value): - self.json_schema.backend = new_value - - @property - def json_schema(self): - """Getter of _json_schema.""" - return self._json_schema - - @abstractmethod - def parse(self): - """Parse the data.""" - pass - - def is_modified(self): - """ - Returns true if data has been changed - """ - return self._original_sections != self._sections - - @staticmethod - def is_pluggable_section(section_name): - """ check if section is for a pluggable """ - section_name = JSONSchema.format_section_name(section_name) - for pluggable_type in local_pluggables_types(): - if section_name == pluggable_type.value: - return True - - return False - - def get_section_types(self, section_name): - """ return section types """ - return self._json_schema.get_section_types(section_name) - - def get_property_types(self, section_name, property_name): - """ return property types """ - return self._json_schema.get_property_types(section_name, property_name) - - @abstractmethod - def get_default_sections(self): - """ returns default sections dict """ - pass - - def get_default_section_names(self): - """ returns default section names """ - sections = self.get_default_sections() - return list(sections.keys()) if sections is not None else [] - - def get_section_default_properties(self, section_name): - """ returns section default properties """ - return self._json_schema.get_section_default_properties(section_name) - - def allows_additional_properties(self, section_name): - """ checks if section allows additional properties """ - return self._json_schema.allows_additional_properties(section_name) - - def get_property_default_values(self, section_name, property_name): - """ return property default values """ - return self._json_schema.get_property_default_values(section_name, property_name) - - def get_property_default_value(self, section_name, property_name): - """ return property default value """ - return self._json_schema.get_property_default_value(section_name, property_name) - - def get_filename(self): - """Return the filename.""" - return self._filename - - @staticmethod - def get_algorithm_problems(algo_name): - """ return algorithm problems list """ - return JSONSchema.get_algorithm_problems(algo_name) - - def _merge_dependencies(self): - algo_name = self.get_section_property(PluggableType.ALGORITHM.value, JSONSchema.NAME) - if algo_name is None: - return - - config = get_pluggable_configuration(PluggableType.ALGORITHM, algo_name) - pluggable_dependencies = config.get('depends', []) - - section_names = self.get_section_names() - for pluggable_type_dict in pluggable_dependencies: - pluggable_type = pluggable_type_dict.get('pluggable_type') - if pluggable_type is None: - continue - - pluggable_name = None - pluggable_defaults = pluggable_type_dict.get('default') - new_properties = {} - if pluggable_defaults is not None: - for key, value in pluggable_defaults.items(): - if key == JSONSchema.NAME: - pluggable_name = value - else: - new_properties[key] = value - - if pluggable_name is None: - continue - - if pluggable_type not in section_names: - self.set_section(pluggable_type) - - if self.get_section_property(pluggable_type, JSONSchema.NAME) is None: - self.set_section_property(pluggable_type, JSONSchema.NAME, pluggable_name) - - if pluggable_name == self.get_section_property(pluggable_type, JSONSchema.NAME): - properties = self.get_section_properties(pluggable_type) - if new_properties: - new_properties.update(properties) - else: - new_properties = properties - - self.set_section_properties(pluggable_type, new_properties) - - @abstractmethod - def validate_merge_defaults(self): - """ validate after merging defaults """ - self.merge_default_values() - self._json_schema.validate(self.get_sections()) - self._validate_algorithm_problem() - - @abstractmethod - def merge_default_values(self): - """ merge defaults with current values """ - pass - - def _validate_algorithm_problem(self): - algo_name = self.get_section_property(PluggableType.ALGORITHM.value, JSONSchema.NAME) - if algo_name is None: - return - - problem_name = self.get_section_property(JSONSchema.PROBLEM, JSONSchema.NAME) - if problem_name is None: - problem_name = self.get_property_default_value(JSONSchema.PROBLEM, JSONSchema.NAME) - - if problem_name is None: - raise AquaError("No algorithm 'problem' section found on input.") - - problems = BaseParser.get_algorithm_problems(algo_name) - if problem_name not in problems: - raise AquaError( - "Problem: {} not in the list of problems: {} for algorithm: {}.".format( - problem_name, problems, algo_name)) - - def commit_changes(self): - """ commit data changes """ - self._original_sections = copy.deepcopy(self._sections) - - @abstractmethod - def save_to_file(self, file_name): - """ save to file """ - pass - - def section_is_text(self, section_name): - """ check if section is text """ - section_name = JSONSchema.format_section_name(section_name).lower() - types = self.get_section_types(section_name) - if types: - return 'object' not in types - - section = self._sections.get(section_name) - if section is None: - return False - - return not isinstance(section, dict) - - def get_sections(self): - """ get sections dictionary """ - return self._sections - - def get_section(self, section_name): - """Return a Section by name. - Args: - section_name (str): the name of the section, case insensitive - Returns: - Section: The section with this name - Raises: - AquaError: if the section does not exist. - """ - section_name = JSONSchema.format_section_name(section_name).lower() - try: - return self._sections[section_name] - except KeyError: - raise AquaError('No section "{0}"'.format(section_name)) - - def get_section_text(self, section_name): - """ get section text """ - section_name = JSONSchema.format_section_name(section_name).lower() - section = self._sections.get(section_name) - if section is None: - return '' - - if isinstance(section, str): - return section - - return json.dumps(section, sort_keys=True, indent=4) - - def get_section_properties(self, section_name): - """ get section properties dictionary """ - section_name = JSONSchema.format_section_name(section_name).lower() - section = self._sections.get(section_name) - if section is None: - return {} - - return section - - def get_section_property(self, section_name, property_name, default_value=None): - """Return a property by name. - Args: - section_name (str): the name of the section, case insensitive - property_name (str): the property name in the section - default_value (Union(dict,list,int,float,str)): default value - in case it is not found - Returns: - Union(dict,list,int,float,str): The property value - """ - section_name = JSONSchema.format_section_name(section_name) - property_name = JSONSchema.format_property_name(property_name) - if section_name in self._sections: - section = self._sections[section_name] - if property_name in section: - return section[property_name] - - return default_value - - def set_section(self, section_name): - """ - Args: - section_name (str): the name of the section, case insensitive - Returns: - Bool: True if updated - """ - updated = False - section_name = JSONSchema.format_section_name(section_name) - if section_name not in self._sections: - self._sections[section_name] = \ - '' if self.section_is_text(section_name) else OrderedDict() - self._sections = self._order_sections(self._sections) - updated = True - - return updated - - @abstractmethod - def delete_section(self, section_name): - """ - Args: - section_name (str): the name of the section, case insensitive - Returns: - Bool: True if deleted - """ - section_name = JSONSchema.format_section_name(section_name).lower() - if section_name not in self._sections: - return False - - del self._sections[section_name] - - # update schema - self._json_schema.rollback_changes() - self._json_schema.update_backend_schema(self) - self._json_schema.update_pluggable_schemas(self) - return True - - def add_section_properties(self, section_name, new_properties): - """ - Add new properties if don't exist, update the existent ones, - other properties are unchanged - Args: - section_name (str): the name of the section, case insensitive - new_properties (dict): property name: value - Returns: - Bool: True if changed - """ - key_value_changed = False - set_properties = copy.deepcopy(new_properties) - - # update backend provider first - if JSONSchema.BACKEND == section_name and JSONSchema.PROVIDER in set_properties: - if self._set_section_property_without_checking_defaults( - section_name, JSONSchema.PROVIDER, set_properties[JSONSchema.PROVIDER]): - key_value_changed = True - del set_properties[JSONSchema.PROVIDER] - - # update name first - if JSONSchema.NAME in set_properties: - if self._set_section_property_without_checking_defaults( - section_name, JSONSchema.NAME, set_properties[JSONSchema.NAME]): - key_value_changed = True - del set_properties[JSONSchema.NAME] - - # update remaining properties - for property_name, value in set_properties.items(): - if self._set_section_property_without_checking_defaults(section_name, - property_name, - value): - key_value_changed = True - - # nothing changed, return - if not key_value_changed: - return False - - # remove properties that are not valid for this section - default_properties = self.get_section_default_properties(section_name) - if isinstance(default_properties, dict): - properties = self.get_section_properties(section_name) - for p_name in list(properties.keys()): - if p_name != JSONSchema.NAME and p_name not in default_properties: - self.delete_section_property(section_name, p_name) - - self._sections = self._order_sections(self._sections) - return True - - def set_section_properties(self, section_name, new_properties): - """ - Replace all old properties with new ones - Args: - section_name (str): the name of the section, case insensitive - new_properties (dict): property name: value - Returns: - Bool: True if changed - """ - old_properties = self.get_section_properties(section_name) - set_properties = copy.deepcopy(new_properties) - del_properties = [] - for key, value in old_properties.items(): - if key in set_properties: - if value == set_properties[key]: - del set_properties[key] - else: - del_properties.append(key) - - key_value_changed = False - - # first delete - for property_name in del_properties: - if self.delete_section_property(section_name, property_name): - key_value_changed = True - - # update backend provider first - if JSONSchema.BACKEND == section_name and JSONSchema.PROVIDER in set_properties: - if self._set_section_property_without_checking_defaults( - section_name, JSONSchema.PROVIDER, set_properties[JSONSchema.PROVIDER]): - key_value_changed = True - del set_properties[JSONSchema.PROVIDER] - - # update name first - if JSONSchema.NAME in set_properties: - if self._set_section_property_without_checking_defaults( - section_name, JSONSchema.NAME, set_properties[JSONSchema.NAME]): - key_value_changed = True - del set_properties[JSONSchema.NAME] - - # update remaining properties - for property_name, value in set_properties.items(): - if self._set_section_property_without_checking_defaults(section_name, - property_name, - value): - key_value_changed = True - - # nothing changed, return - if not key_value_changed: - return False - - self._sections = self._order_sections(self._sections) - return True - - @abstractmethod - def post_set_section_property(self, section_name, property_name): - """ executed after set section property """ - pass - - def set_section_property(self, section_name, property_name, value): - """ - Args: - section_name (str): the name of the section, case insensitive - property_name (str): the name of the property - value (obj): the value of the property - Returns: - Bool: True if value changed - """ - if not self._set_section_property_without_checking_defaults(section_name, - property_name, - value): - return False - - # remove properties that are not valid for this section - default_properties = self.get_section_default_properties(section_name) - if isinstance(default_properties, dict): - properties = self.get_section_properties(section_name) - for p_name in list(properties.keys()): - if p_name != JSONSchema.NAME and p_name not in default_properties: - self.delete_section_property(section_name, p_name) - - self._sections = self._order_sections(self._sections) - return True - - def _set_section_property_without_checking_defaults(self, section_name, property_name, value): - """ - Args: - section_name (str): the name of the section, case insensitive - property_name (str): the name of the property - value (obj): the value of the property - Returns: - Bool: True if value changed - Raises: - AquaError: validation error - """ - section_name = JSONSchema.format_section_name(section_name).lower() - property_name = JSONSchema.format_property_name(property_name) - value = self._json_schema.check_property_value(section_name, property_name, value) - types = self.get_property_types(section_name, property_name) - sections_temp = copy.deepcopy(self._sections) - BaseParser._set_section_property(sections_temp, section_name, property_name, value, types) - msg = self._json_schema.validate_property(sections_temp, section_name, property_name) - if msg is not None: - raise AquaError( - "{}.{}: Value '{}': '{}'".format(section_name, property_name, value, msg)) - - value_changed = False - old_value = None - if section_name not in self._sections: - value_changed = True - elif property_name not in self._sections[section_name]: - value_changed = True - else: - old_value = self.get_section_property(section_name, property_name) - value_changed = (old_value != value) - - if not value_changed: - # nothing changed - return False - - # check if the provider/backend is loadable and valid - # set values from self.backend if exists - if JSONSchema.BACKEND == section_name and \ - property_name in [JSONSchema.PROVIDER, JSONSchema.NAME]: - if self.backend is not None: - value = self.backend.name() \ - if property_name == JSONSchema.NAME else get_provider_from_backend(self.backend) - elif property_name == JSONSchema.NAME: - provider_name = self.get_section_property(section_name, JSONSchema.PROVIDER) - backend_names = get_backends_from_provider(provider_name) - if value not in backend_names: - raise AquaError( - "Backend '{}' not valid for provider: '{}' backends: '{}'".format( - value, provider_name, backend_names)) - - # update value internally - BaseParser._set_section_property(self._sections, section_name, property_name, value, types) - - if JSONSchema.BACKEND == section_name and property_name == JSONSchema.PROVIDER: - if self.backend is not None: - # set value from self.backend if exists - BaseParser._set_section_property(self._sections, - section_name, - JSONSchema.NAME, self.backend.name(), ['string']) - else: - backend_name = self.get_section_property(section_name, JSONSchema.NAME) - backend_names = get_backends_from_provider(value) - if backend_name not in backend_names: - # use first backend available in provider - backend_name = backend_names[0] if backend_names else '' - BaseParser._set_section_property(self._sections, - section_name, - JSONSchema.NAME, backend_name, ['string']) - - # update backend schema - if JSONSchema.BACKEND == section_name and \ - property_name in [JSONSchema.PROVIDER, JSONSchema.NAME]: - # update backend schema - self._json_schema.update_backend_schema(self) - return True - - if property_name == JSONSchema.NAME: - if BaseParser.is_pluggable_section(section_name): - self._json_schema.update_pluggable_schemas(self) - self._update_dependency_sections(section_name) - # remove any previous pluggable sections not in new dependency list - old_dependencies = \ - self._get_dependency_sections(section_name, old_value) \ - if old_value is not None else set() - new_dependencies = \ - self._get_dependency_sections(section_name, value) \ - if value is not None else set() - for pluggable_name in old_dependencies.difference(new_dependencies): - if pluggable_name in self._sections: - del self._sections[pluggable_name] - - # reorder sections - self._sections = self._order_sections(self._sections) - return True - - if JSONSchema.PROBLEM == section_name: - self._update_algorithm_problem() - - self.post_set_section_property(section_name, property_name) - - return True - - def _update_algorithm_problem(self): - problem_name = self.get_section_property(JSONSchema.PROBLEM, JSONSchema.NAME) - if problem_name is None: - problem_name = self.get_property_default_value(JSONSchema.PROBLEM, JSONSchema.NAME) - - if problem_name is None: - raise AquaError("No algorithm 'problem' section found on input.") - - algo_name = self.get_section_property(PluggableType.ALGORITHM.value, JSONSchema.NAME) - if algo_name is not None and problem_name in BaseParser.get_algorithm_problems(algo_name): - return - - for algo_name in local_pluggables(PluggableType.ALGORITHM): - if problem_name in self.get_algorithm_problems(algo_name): - # set to the first algorithm to solve the problem - self.set_section_property(PluggableType.ALGORITHM.value, JSONSchema.NAME, algo_name) - return - - # no algorithm solve this problem, remove section - self.delete_section(PluggableType.ALGORITHM.value) - - def _get_dependency_sections(self, pluggable_type, pluggable_name): - config = get_pluggable_configuration(pluggable_type, pluggable_name) - dependency_sections = set() - pluggable_dependencies = config.get('depends', []) - for dependency_pluggable_type_dict in pluggable_dependencies: - dependency_pluggable_type = dependency_pluggable_type_dict.get('pluggable_type') - if dependency_pluggable_type is not None: - dependency_sections.add(dependency_pluggable_type) - dependency_pluggable_name = \ - dependency_pluggable_type_dict.get('default', {}).get(JSONSchema.NAME) - if dependency_pluggable_name is not None: - dependency_sections.update( - self._get_dependency_sections(dependency_pluggable_type, - dependency_pluggable_name)) - - return dependency_sections - - def _update_dependency_sections(self, section_name): - prop_name = self.get_section_property(section_name, JSONSchema.NAME) - config = {} if prop_name is None else get_pluggable_configuration(section_name, prop_name) - pluggable_dependencies = config.get('depends', []) - if section_name == PluggableType.ALGORITHM.value: - classical = config.get('classical', False) - # update backend based on classical - if classical: - if JSONSchema.BACKEND in self._sections: - del self._sections[JSONSchema.BACKEND] - else: - if JSONSchema.BACKEND not in self._sections: - self.set_section_properties( - JSONSchema.BACKEND, - self.get_section_default_properties(JSONSchema.BACKEND)) - - # update dependencies recursively - self._update_dependencies(pluggable_dependencies) - - def _update_dependencies(self, pluggable_dependencies): - # update sections with dependencies recursively - for pluggable_type_dict in pluggable_dependencies: - pluggable_type = pluggable_type_dict.get('pluggable_type') - if pluggable_type is None: - continue - - pluggable_name = pluggable_type_dict.get('default', {}).get(JSONSchema.NAME) - if pluggable_name is not None: - if pluggable_type not in self._sections: - # update default values for new dependency pluggable types - default_properties = self.get_section_default_properties(pluggable_type) - if isinstance(default_properties, dict): - self.set_section_properties(pluggable_type, default_properties) - - config = get_pluggable_configuration(pluggable_type, pluggable_name) - self._update_dependencies(config.get('depends', [])) - - @staticmethod - def _set_section_property(sections, section_name, property_name, value, types): - """ - Args: - sections (dict): sections dictionary - section_name (str): the name of the section, case insensitive - property_name (str): the property name in the section - value (Union(dict,list,int,float,str)): property value - types (list): schema types - Raises: - AquaError: failed to set pluggable - """ - section_name = JSONSchema.format_section_name(section_name) - property_name = JSONSchema.format_property_name(property_name) - value = JSONSchema.get_value(value, types) - - if JSONSchema.NAME == property_name and not value and \ - BaseParser.is_pluggable_section(section_name): - raise AquaError("Unable to set pluggable '{}' name: Missing name.".format(section_name)) - - if section_name not in sections: - sections[section_name] = OrderedDict() - - # name should come first - if JSONSchema.NAME == property_name and property_name not in sections[section_name]: - new_dict = OrderedDict([(property_name, value)]) - new_dict.update(sections[section_name]) - sections[section_name] = new_dict - else: - sections[section_name][property_name] = value - - def delete_section_property(self, section_name, property_name): - """ - Args: - section_name (str): the name of the section, case insensitive - property_name (str): the property name in the section - Returns: - Bool: True if deleted - """ - section_name = JSONSchema.format_section_name(section_name) - property_name = JSONSchema.format_property_name(property_name) - if section_name in self._sections and property_name in self._sections[section_name]: - del self._sections[section_name][property_name] - return True - - return False - - def delete_section_properties(self, section_name): - """ - Args: - section_name (str): the name of the section, case insensitive - Returns: - Bool: True if deleted - """ - section_name = JSONSchema.format_section_name(section_name).lower() - if section_name in self._sections: - del self._sections[section_name] - return True - - return False - - def set_section_data(self, section_name, value): - """ - Sets a section data. - Args: - section_name (str): the name of the section, case insensitive - value (Union(dict,list,int,float,str)): value to set - Returns: - Bool: True if updated - """ - section_name = JSONSchema.format_section_name(section_name) - self._sections[section_name] = self._json_schema.check_section_value(section_name, value) - return True - - def get_section_names(self): - """Return all the names of the sections.""" - return list(self._sections.keys()) diff --git a/qiskit/aqua/parser/input_schema.json b/qiskit/aqua/parser/input_schema.json deleted file mode 100644 index f59ab78c5f..0000000000 --- a/qiskit/aqua/parser/input_schema.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "id": "input_schema.json", - - "definitions": { - "problem": { - "type": "object", - "properties": { - "name": { - "type": "string", - "default": "energy" - }, - "random_seed": { - "type": ["integer", "null"], - "default": null - }, - "num_processes": { - "type": ["integer", "null"], - "default": null, - "minimum": 1 - }, - "circuit_caching": { - "type": "boolean", - "default": false - }, - "circuit_optimization_level": { - "type": ["integer", "string"], - "enum": [0, 1, 2, 3, "default"], - "default": "default" - }, - "skip_qobj_deepcopy": { - "type": "boolean", - "default": false - }, - "circuit_cache_file": { - "type": ["string", "null"], - "default": null - }, - "skip_qobj_validation": { - "type": "boolean", - "default": true - }, - "measurement_error_mitigation": { - "type": "boolean", - "default": false - }, - "measurement_error_mitigation_shots": { - "type": ["integer", "null"], - "default": null - }, - "measurement_error_mitigation_refresh_period": { - "type": "integer", - "default": 30 - } - }, - "required": ["name"], - "additionalProperties": false - }, - "algorithm": { - "type": "object", - "properties": { - "name": { - "type": "string", - "default": "VQE" - } - }, - "required": ["name"], - "additionalProperties": false - }, - "backend": { - "type": "object", - "properties": { - "provider": { - "type": "string", - "default": "qiskit.BasicAer" - }, - "name": { - "type": "string", - "default": "statevector_simulator" - } - }, - "required": ["provider", "name"], - "additionalProperties": false - } - }, - - "type": "object", - "properties": { - "problem": { "$ref": "#/definitions/problem" }, - "algorithm": { "$ref": "#/definitions/algorithm" }, - "backend": { "$ref": "#/definitions/backend" } - }, - "required": ["algorithm"], - "additionalProperties": false -} diff --git a/qiskit/aqua/parser/json_schema.py b/qiskit/aqua/parser/json_schema.py deleted file mode 100644 index b5e609f3b8..0000000000 --- a/qiskit/aqua/parser/json_schema.py +++ /dev/null @@ -1,902 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""JSON schema Utilities.""" - -import json -import os -import logging -from collections import OrderedDict -import ast -import copy -import jsonschema -from qiskit.aqua import AquaError, aqua_globals -from qiskit.aqua import (local_pluggables_types, - PluggableType, - get_pluggable_configuration, - local_pluggables, - get_local_providers) -from qiskit.aqua.utils.backend_utils import (is_statevector_backend, - is_simulator_backend, - has_ibmq, - get_backend_from_provider, - get_backends_from_provider, - get_provider_from_backend, - is_local_backend, - is_aer_provider, - is_aer_statevector_backend) - -logger = logging.getLogger(__name__) - - -class JSONSchema: - """JSON schema Utilities class.""" - - NAME = 'name' - PROVIDER = 'provider' - PROBLEM = 'problem' - BACKEND = 'backend' - - def __init__(self, schema_input): - """Create JSONSchema object.""" - self._backend = None - self._schema = None - self._original_schema = None - self.aqua_jsonschema = None - if isinstance(schema_input, dict): - self._schema = copy.deepcopy(schema_input) - elif isinstance(schema_input, str): - with open(schema_input) as json_file: - self._schema = json.load(json_file) - else: - raise AquaError("Invalid JSONSchema input type.") - - validator = jsonschema.Draft4Validator(self._schema) - self._schema = JSONSchema._resolve_schema_references(validator.schema, validator.resolver) - self.commit_changes() - - @property - def backend(self): - """Getter of backend.""" - return self._backend - - @backend.setter - def backend(self, new_value): - self._backend = new_value - - @property - def schema(self): - """Returns json schema""" - return self._schema - - @property - def original_schema(self): - """Returns original json schema""" - return self._original_schema - - def commit_changes(self): - """Saves changes to original json schema""" - self._original_schema = copy.deepcopy(self._schema) - - def rollback_changes(self): - """Restores schema from original json schema""" - self._schema = copy.deepcopy(self._original_schema) - - def _initialize_problem_section(self): - """Initialize problem""" - self._schema['properties'][JSONSchema.PROBLEM]['properties']['num_processes']['maximum'] = \ - aqua_globals.CPU_COUNT - problems_dict = OrderedDict() - for algo_name in local_pluggables(PluggableType.ALGORITHM): - problems = JSONSchema.get_algorithm_problems(algo_name) - for problem in problems: - problems_dict[problem] = None - - self._schema['properties'][JSONSchema.PROBLEM]['properties'][JSONSchema.NAME]['enum'] = \ - list(problems_dict.keys()) - - def copy_section_from_aqua_schema(self, section_name): - """ - Copy a section from aqua json schema if if exists - Args: - section_name (str): schema section to copy - """ - section_name = JSONSchema.format_section_name(section_name) - if self.aqua_jsonschema is None: - self.aqua_jsonschema = \ - JSONSchema(os.path.join(os.path.dirname(__file__), 'input_schema.json')) - - if section_name in self.aqua_jsonschema.schema['properties']: - self._schema['properties'][section_name] = \ - self.aqua_jsonschema.schema['properties'][section_name] - - def get_section_types(self, section_name): - """ - Returns types for a schema section - - Args: - section_name (str): schema section - - Returns: - list: schema type - Raises: - AquaError: Schema invalid - """ - section_name = JSONSchema.format_section_name(section_name) - if 'properties' not in self._schema: - raise AquaError("Schema missing 'properties' section.") - - if section_name not in self._schema['properties']: - return [] - - if 'type' not in self._schema['properties'][section_name]: - raise AquaError("Schema property section '{}' missing type.".format(section_name)) - - schema_type = self._schema['properties'][section_name]['type'] - if isinstance(schema_type, list): - return schema_type - - schema_type = str(schema_type).strip() - if schema_type == '': - raise AquaError("Schema property section '{}' empty type.".format(section_name)) - - return [schema_type] - - def get_property_types(self, section_name, property_name): - """ - Returns types for a schema section property - Args: - section_name (str): schema section - property_name (str): schema section property - - Returns: - list: schema type list - Raises: - AquaError: Schema invalid - """ - section_name = JSONSchema.format_section_name(section_name) - property_name = JSONSchema.format_property_name(property_name) - if 'properties' not in self._schema: - raise AquaError("Schema missing 'properties' section.") - - if section_name not in self._schema['properties']: - raise AquaError("Schema properties missing section '{}'.".format(section_name)) - - if 'properties' not in self._schema['properties'][section_name]: - raise AquaError( - "Schema properties missing section '{}' properties.".format(section_name)) - - if property_name not in self._schema['properties'][section_name]['properties']: - raise AquaError( - "Schema properties section '{}' missing '{}' property.".format(section_name, - property_name)) - - schema_property = self._schema['properties'][section_name]['properties'][property_name] - if 'type' not in schema_property: - raise AquaError( - "Schema properties section '{}' missing '{}' property type.".format(section_name, - property_name)) - - schema_type = schema_property['type'] - if isinstance(schema_type, list): - return schema_type - - schema_type = str(schema_type).strip() - if schema_type == '': - raise AquaError( - "Schema properties section '{}' empty '{}' property type.".format(section_name, - property_name)) - - return [schema_type] - - def get_default_sections(self): - """ - Returns default sections - """ - if 'properties' not in self._schema: - return None - - return copy.deepcopy(self._schema['properties']) - - def get_default_section_names(self): - """ - Returns default section names - """ - sections = self.get_default_sections() - return list(sections.keys()) if sections is not None else [] - - def get_section_default_properties(self, section_name): - """ - Returns default properties for a schema section - - Args: - section_name (str): schema section - - Returns: - dict: properties dictionary - """ - section_name = JSONSchema.format_section_name(section_name) - if 'properties' not in self._schema: - return None - - if section_name not in self._schema['properties']: - return None - - schema_types = self.get_section_types(section_name) - if 'default' in self._schema['properties'][section_name]: - return JSONSchema.get_value(self._schema['properties'][section_name]['default'], - schema_types) - - if 'object' not in schema_types: - return JSONSchema.get_value(None, schema_types) - - if 'properties' not in self._schema['properties'][section_name]: - return None - - properties = OrderedDict() - for property_name, values in self._schema['properties'][section_name]['properties'].items(): - default_value = values['default'] if 'default' in values else None - properties[property_name] = JSONSchema.get_value(default_value, - self.get_property_types(section_name, - property_name)) - - return properties - - def allows_additional_properties(self, section_name): - """ - Returns allows additional properties flag for a schema section - Args: - section_name (str): schema section - - Returns: - bool: allows additional properties - """ - section_name = JSONSchema.format_section_name(section_name) - if 'properties' not in self._schema: - return True - - if section_name not in self._schema['properties']: - return True - - additional_properties = \ - str(self._schema['properties'][section_name].get( - 'additionalProperties', 'true')).strip().lower() - return additional_properties == 'true' - - def get_property_default_values(self, section_name, property_name): - """ - Returns default values for a schema section property - Args: - section_name (str): schema section - property_name (str): schema section property - - Returns: - list: default values - """ - # pylint: disable=too-many-return-statements - section_name = JSONSchema.format_section_name(section_name) - property_name = JSONSchema.format_property_name(property_name) - if 'properties' not in self._schema: - return None - - if section_name not in self._schema['properties']: - return None - - if 'properties' not in self._schema['properties'][section_name]: - return None - - if property_name not in self._schema['properties'][section_name]['properties']: - return None - - prop = self._schema['properties'][section_name]['properties'][property_name] - if 'type' in prop: - types = prop['type'] - if not isinstance(types, list): - types = [types] - - if 'boolean' in types: - return [True, False] - - if 'enum' in prop: - return prop['enum'] - - if 'oneOf' not in prop: - return None - - for item in prop['oneOf']: - if 'enum' in item: - return item['enum'] - - return None - - def get_property_default_value(self, section_name, property_name): - """ - Returns default value for a schema section property - - Args: - section_name (str): schema section - property_name (str): schema section property - - Returns: - object: default value - """ - section_name = JSONSchema.format_section_name(section_name) - property_name = JSONSchema.format_property_name(property_name) - if 'properties' not in self._schema: - return None - - if section_name not in self._schema['properties']: - return None - - if 'properties' not in self._schema['properties'][section_name]: - return None - - if property_name not in self._schema['properties'][section_name]['properties']: - return None - - schema_property = self._schema['properties'][section_name]['properties'][property_name] - if 'default' in schema_property: - return JSONSchema.get_value(schema_property['default'], - self.get_property_types(section_name, property_name)) - - return None - - def update_backend_schema(self, input_parser): - """ - Updates backend schema - """ - if JSONSchema.BACKEND not in self._schema['properties']: - return - - # Updates defaults provider/backend - provider_name = default_provider_name = None - backend_name = default_backend_name = None - backend = None - if self.backend is not None: - backend = self.backend - provider_name = default_provider_name = get_provider_from_backend(backend) - backend_name = default_backend_name = backend.name() - else: - orig_backend_properties = \ - self._original_schema.get('properties', {}).\ - get(JSONSchema.BACKEND, {}).get('properties') - if orig_backend_properties is not None: - default_provider_name = \ - orig_backend_properties.get(JSONSchema.PROVIDER, {}).get('default') - default_backend_name = \ - orig_backend_properties.get(JSONSchema.NAME, {}).get('default') - - providers = get_local_providers() - if default_provider_name is None or default_provider_name not in providers: - # use first provider available - providers_items = providers.items() - provider_tuple = next(iter(providers_items)) \ - if providers_items else ('', []) - default_provider_name = provider_tuple[0] - - if default_backend_name is None or \ - default_backend_name not in providers.get(default_provider_name, []): - # use first backend available in provider - default_backend_name = \ - providers.get( - default_provider_name)[0] \ - if providers.get(default_provider_name, []) else '' - - provider_name = input_parser.get_section_property(JSONSchema.BACKEND, - JSONSchema.PROVIDER, - default_provider_name) - backend_names = get_backends_from_provider(provider_name) - backend_name = input_parser.get_section_property(JSONSchema.BACKEND, - JSONSchema.NAME, default_backend_name) - if backend_name not in backend_names: - # use first backend available in provider - backend_name = backend_names[0] if backend_names else '' - - backend = get_backend_from_provider(provider_name, backend_name) - - self._schema['properties'][JSONSchema.BACKEND] = { - 'type': 'object', - 'properties': { - JSONSchema.PROVIDER: { - 'type': 'string', - 'default': default_provider_name - }, - JSONSchema.NAME: { - 'type': 'string', - 'default': default_backend_name - }, - }, - 'required': [JSONSchema.PROVIDER, JSONSchema.NAME], - 'additionalProperties': False, - } - - config = backend.configuration() - - # Include shots in schema only if not a statevector backend. - # For statevector, shots will be set to 1, in QiskitAqua - if not is_statevector_backend(backend): - self._schema['properties'][JSONSchema.BACKEND]['properties']['shots'] = { - 'type': 'integer', - 'minimum': 1, - } - default_shots = 1024 - # ensure default_shots <= max_shots - if config.max_shots: - default_shots = min(default_shots, config.max_shots) - self._schema['properties'][JSONSchema.BACKEND]['properties']['shots']['maximum'] = \ - config.max_shots - - self._schema['properties'][JSONSchema.BACKEND]['properties']['shots']['default'] = \ - default_shots - - self._schema['properties'][JSONSchema.BACKEND]['properties']['skip_transpiler'] = { - 'type': 'boolean', - 'default': False, - } - - coupling_map_devices = [] - noise_model_devices = [] - check_coupling_map = is_simulator_backend(backend) - check_noise_model = is_aer_provider(backend) and not is_aer_statevector_backend(backend) - try: - if (check_coupling_map or check_noise_model) and has_ibmq(): - backend_names = get_backends_from_provider('qiskit.IBMQ') - for backend_name in backend_names: - ibmq_backend = get_backend_from_provider('qiskit.IBMQ', backend_name) - if is_simulator_backend(ibmq_backend): - continue - if check_noise_model: - noise_model_devices.append('qiskit.IBMQ:' + backend_name) - if check_coupling_map and ibmq_backend.configuration().coupling_map: - coupling_map_devices.append('qiskit.IBMQ:' + backend_name) - except Exception as ex: # pylint: disable=broad-except - logger.debug("Failed to load IBMQ backends. Error %s", str(ex)) - - # Includes 'coupling map' and 'coupling_map_from_device' in schema only if - # a simulator backend. - # Actual devices have a coupling map based on the physical configuration of the device. - # The user can configure the coupling map so its the same as the coupling map - # of a given device in order to better simulate running on the device. - # Property 'coupling_map_from_device' is a list of provider:name backends that are - # real devices e.g qiskit.IBMQ:ibmqx5. - # If property 'coupling_map', an array, is provided, it overrides coupling_map_from_device, - # the latter defaults to 'None'. So in total no coupling map is a default, i.e. all to all - # coupling is possible. - if is_simulator_backend(backend): - self._schema['properties'][JSONSchema.BACKEND]['properties']['coupling_map'] = { - 'type': ['array', 'null'], - 'default': None, - } - if coupling_map_devices: - coupling_map_devices.append(None) - self._schema['properties'][ - JSONSchema.BACKEND]['properties']['coupling_map_from_device'] = \ - { - 'type': ['string', 'null'], - 'default': None, - 'enum': coupling_map_devices, - } - - # noise model that can be setup for Aer simulator so as to model noise of an actual device. - if noise_model_devices: - noise_model_devices.append(None) - self._schema['properties'][JSONSchema.BACKEND]['properties']['noise_model'] = { - 'type': ['string', 'null'], - 'default': None, - 'enum': noise_model_devices, - } - - # If a noise model is supplied then the basis gates is set as per the noise model - # unless basis gates is not None in which case it overrides noise model and a - # warning msg is logged. - # as it is an advanced use case. - self._schema['properties'][JSONSchema.BACKEND]['properties']['basis_gates'] = { - 'type': ['array', 'null'], - 'default': None, - } - - # TODO: Not sure if we want to continue with initial_layout in declarative form. - # It requires knowledge of circuit registers etc. Perhaps its best to leave - # this detail to programming API. - self._schema['properties'][JSONSchema.BACKEND]['properties']['initial_layout'] = { - 'type': ['object', 'null'], - 'default': None, - } - - # The same default and minimum as current RunConfig values - self._schema['properties'][JSONSchema.BACKEND]['properties']['max_credits'] = { - 'type': 'integer', - 'default': 10, - 'minimum': 3, - 'maximum': 10, - } - - # Timeout and wait are for remote backends where we have to connect over network - if not is_local_backend(backend): - self._schema['properties'][JSONSchema.BACKEND]['properties']['timeout'] = { - "type": ["number", "null"], - 'default': None, - } - self._schema['properties'][JSONSchema.BACKEND]['properties']['wait'] = { - 'type': 'number', - 'default': 5.0, - 'minimum': 0.0, - } - - def update_pluggable_schemas(self, input_parser): - """ - Updates schemas of all pluggables - - Args: - input_parser (obj): input parser - """ - # find algorithm - default_algo_name = self.get_property_default_value(PluggableType.ALGORITHM.value, - JSONSchema.NAME) - algo_name = input_parser.get_section_property(PluggableType.ALGORITHM.value, - JSONSchema.NAME, default_algo_name) - - # update algorithm scheme - if algo_name is not None: - self._update_pluggable_schema(PluggableType.ALGORITHM.value, - algo_name, default_algo_name) - - # update algorithm dependencies scheme - config = {} if algo_name is None else get_pluggable_configuration(PluggableType.ALGORITHM, - algo_name) - classical = config.get('classical', False) - # update algorithm backend from schema if it is classical or not - if classical: - if JSONSchema.BACKEND in self._schema['properties']: - del self._schema['properties'][JSONSchema.BACKEND] - else: - if JSONSchema.BACKEND not in self._schema['properties']: - self._schema['properties'][JSONSchema.BACKEND] = \ - self._original_schema['properties'][JSONSchema.BACKEND] - self.update_backend_schema(input_parser) - - pluggable_dependencies = config.get('depends', []) - - # remove pluggables from schema that are not in the dependencies of algorithm - pluggable_dependency_names = \ - [item['pluggable_type'] for item in pluggable_dependencies if 'pluggable_type' in item] - for pluggable_type in local_pluggables_types(): - if pluggable_type not in [PluggableType.INPUT, PluggableType.ALGORITHM] and \ - pluggable_type.value not in pluggable_dependency_names and \ - pluggable_type.value in self._schema['properties']: - del self._schema['properties'][pluggable_type.value] - - self._update_dependency_schemas(pluggable_dependencies, input_parser) - - def _update_dependency_schemas(self, pluggable_dependencies, input_parser): - # update schema with dependencies recursively - for pluggable_type_dict in pluggable_dependencies: - pluggable_type = pluggable_type_dict.get('pluggable_type') - if pluggable_type is None: - continue - - pluggable_name = None - pluggable_defaults = pluggable_type_dict.get('default') - default_properties = {} - if pluggable_defaults is not None: - for key, value in pluggable_defaults.items(): - if key == JSONSchema.NAME: - pluggable_name = value - else: - default_properties[key] = value - - default_name = pluggable_name - pluggable_name = input_parser.get_section_property(pluggable_type, - JSONSchema.NAME, pluggable_name) - if default_name is None: - default_name = pluggable_name - - # update dependency schema - self._update_pluggable_schema(pluggable_type, pluggable_name, default_name) - for property_name in self._schema['properties'][pluggable_type]['properties'].keys(): - if property_name in default_properties: - self._schema['properties'][ - pluggable_type]['properties'][property_name]['default'] =\ - default_properties[property_name] - - if pluggable_name is not None: - config = get_pluggable_configuration(pluggable_type, pluggable_name) - self._update_dependency_schemas(config.get('depends', []), input_parser) - - def _update_pluggable_schema(self, pluggable_type, pluggable_name, default_name): - config = {} - try: - if pluggable_type is not None and pluggable_name is not None: - config = get_pluggable_configuration(pluggable_type, pluggable_name) - except Exception: # pylint: disable=broad-except - pass - - input_schema = config.get('input_schema', {}) - properties = input_schema.get('properties', {}) - properties[JSONSchema.NAME] = {'type': 'string'} - required = input_schema.get('required', []) - additional_properties = input_schema.get('additionalProperties', True) - if default_name is not None: - properties[JSONSchema.NAME]['default'] = default_name - required.append(JSONSchema.NAME) - - if pluggable_type not in self._schema['properties']: - self._schema['properties'][pluggable_type] = {'type': 'object'} - - self._schema['properties'][pluggable_type]['properties'] = properties - if required: - self._schema['properties'][pluggable_type]['required'] = required - elif 'required' in self._schema['properties'][pluggable_type]: - del self._schema['properties'][pluggable_type]['required'] - - self._schema['properties'][pluggable_type]['additionalProperties'] = additional_properties - - def check_section_value(self, section_name, value): - """ - Check value for section name - - Args: - section_name (str): section name - value (obj): value - - Returns: - object: converted value if valid - Raises: - AquaError: value is not a valid type - """ - section_name = JSONSchema.format_section_name(section_name) - schema_types = self.get_section_types(section_name) - value = JSONSchema.get_value(value, schema_types) - if schema_types: - validator = jsonschema.Draft4Validator(self._schema) - valid = False - for schema_type in schema_types: - valid = validator.is_type(value, schema_type) - if valid: - break - - if not valid: - raise AquaError("{}: Value '{}' is not of types: '{}'".format(section_name, - value, schema_types)) - - return value - - def check_property_value(self, section_name, property_name, value): - """ - Check value for property name - - Args: - section_name (str): section name - property_name (str): property name - value (obj): value - - Returns: - object: converted value if valid - Raises: - AquaError: value is not valid type - """ - section_name = JSONSchema.format_section_name(section_name) - property_name = JSONSchema.format_property_name(property_name) - schema_types = self.get_property_types(section_name, property_name) - value = JSONSchema.get_value(value, schema_types) - if schema_types: - validator = jsonschema.Draft4Validator(self._schema) - valid = False - for schema_type in schema_types: - valid = validator.is_type(value, schema_type) - if valid: - break - - if not valid: - raise AquaError("{}.{} Value '{}' is not of types: '{}'".format(section_name, - property_name, - value, - schema_types)) - - return value - - def validate(self, sections_json): - """ json schema validation """ - try: - logger.debug('Input: %s', json.dumps(sections_json, sort_keys=True, indent=4)) - logger.debug('Input Schema: %s', json.dumps(self._schema, sort_keys=True, indent=4)) - jsonschema.validate(sections_json, self._schema) - except jsonschema.exceptions.ValidationError as vex: - logger.info('JSON Validation error: %s', str(vex)) - raise AquaError(vex.message) - - def validate_property(self, sections_json, section_name, property_name): - """ - Validates the property and returns error message - Args: - sections_json(dict): sections - section_name (str): section name - property_name (str): property name - - Returns: - str: error message or None - """ - validator = jsonschema.Draft4Validator(self._schema) - for error in sorted(validator.iter_errors(sections_json), key=str): - if len(error.path) == 2 and error.path[0] == section_name and \ - error.path[1] == property_name: - return error.message - - return None - - @staticmethod - def get_algorithm_problems(algo_name): - """ - Get algorithm problem name list - Args: - algo_name (str): algorithm name - - Returns: - list: problem names - """ - config = get_pluggable_configuration(PluggableType.ALGORITHM, algo_name) - if 'problems' in config: - return config['problems'] - - return [] - - @staticmethod - def _evaluate_value(value): - try: - str_value = str(value).strip().replace('\n', '').replace('\r', '') - if str_value.lower() == 'true': - return True - elif str_value.lower() == 'false': - return False - - v = ast.literal_eval(str_value) - if isinstance(v, dict): - v = json.loads(json.dumps(v)) - - return v - except Exception: # pylint: disable=broad-except - return value - - @staticmethod - def _get_value_for_type(value, schema_type): - # pylint: disable=too-many-return-statements - if value is None or (isinstance(value, str) and not value.strip()): - if schema_type == 'null': - return None, True - if schema_type == 'string': - return '', True - if schema_type == 'array': - return [], True - if schema_type == 'object': - return {}, True - if schema_type == 'boolean': - return False, True - if schema_type in ['integer', 'number']: - return 0, True - - return value, False - elif schema_type == 'null': - return None, False - - if schema_type == 'string': - return str(value), True - - if schema_type in ['array', 'object', 'boolean']: - value = JSONSchema._evaluate_value(value) - if schema_type == 'array' and isinstance(value, list): - return value, True - if schema_type == 'object' and isinstance(value, dict): - return value, True - if schema_type == 'boolean'and isinstance(value, bool): - return value, True - - return value, False - - if schema_type in ['integer', 'number']: - try: - if schema_type == 'integer': - return int(value), True - else: - return float(value), True - except Exception: # pylint: disable=broad-except - value = 0 - - return value, False - - @staticmethod - def get_value(value, types=None): - """ - Returns a converted value based on schema types - Args: - value (obj): value - types (list): schema types - - Returns: - object: a valid value in the type list, or the first converted value, valid or not - """ - types = types if types is not None else [] - values_for_type = OrderedDict() - for schema_type in types: - values_for_type[schema_type] = JSONSchema._get_value_for_type(value, schema_type) - - # first check for a valid schema type null - value_for_type = values_for_type.get('null') - if value_for_type is not None and value_for_type[1]: - return value_for_type[0] - - new_value = None - new_value_set = False - for value_for_type in values_for_type.values(): - if value_for_type[1]: - return value_for_type[0] - elif not new_value_set: - new_value = value_for_type[0] - new_value_set = True - - if new_value_set: - return new_value - - return JSONSchema._evaluate_value(value) - - @staticmethod - def format_section_name(section_name): - """ format section name """ - if section_name is None: - section_name = '' - section_name = section_name.strip() - if not section_name: - raise AquaError("Empty section name.") - - return section_name - - @staticmethod - def format_property_name(property_name): - """ format property name """ - if property_name is None: - property_name = '' - property_name = property_name.strip() - if not property_name: - raise AquaError("Empty property name.") - - return property_name - - @staticmethod - def _resolve_schema_references(schema, resolver): - """ - Resolves json references and merges them into the schema - Args: - schema (dict): schema - resolver (ob): Validator Resolver - - Returns: - dict: schema merged with resolved references - """ - if isinstance(schema, dict): - for key, value in schema.items(): - if key == '$ref': - ref_schema = resolver.resolve(value) - if ref_schema: - return ref_schema[1] - - resolved_ref = JSONSchema._resolve_schema_references(value, resolver) - if resolved_ref: - schema[key] = resolved_ref - - elif isinstance(schema, list): - for (idx, value) in enumerate(schema): - resolved_ref = JSONSchema._resolve_schema_references(value, resolver) - if resolved_ref: - schema[idx] = resolved_ref - - return schema diff --git a/qiskit/aqua/pluggable.py b/qiskit/aqua/pluggable.py index d0a965a781..8c09512849 100644 --- a/qiskit/aqua/pluggable.py +++ b/qiskit/aqua/pluggable.py @@ -24,9 +24,8 @@ class in this module. import logging import copy import numpy as np -from qiskit.aqua import PluggableType -from qiskit.aqua.parser import JSONSchema - +import jsonschema +from qiskit.aqua import AquaError logger = logging.getLogger(__name__) @@ -42,24 +41,6 @@ class Pluggable(ABC): CONFIGURATION = None - # Configuration dictionary keys - SECTION_KEY_ALGORITHM = PluggableType.ALGORITHM.value - SECTION_KEY_OPTIMIZER = PluggableType.OPTIMIZER.value - SECTION_KEY_VAR_FORM = PluggableType.VARIATIONAL_FORM.value - SECTION_KEY_INITIAL_STATE = PluggableType.INITIAL_STATE.value - SECTION_KEY_IQFT = PluggableType.IQFT.value - SECTION_KEY_QFT = PluggableType.QFT.value - SECTION_KEY_ORACLE = PluggableType.ORACLE.value - SECTION_KEY_FEATURE_MAP = PluggableType.FEATURE_MAP.value - SECTION_KEY_MULTICLASS_EXT = PluggableType.MULTICLASS_EXTENSION.value - SECTION_KEY_UNCERTAINTY_PROBLEM = PluggableType.UNCERTAINTY_PROBLEM.value - SECTION_KEY_UNIVARIATE_DIST = PluggableType.UNIVARIATE_DISTRIBUTION.value - SECTION_KEY_MULTIVARIATE_DIST = PluggableType.MULTIVARIATE_DISTRIBUTION.value - SECTION_KEY_EIGS = PluggableType.EIGENVALUES.value - SECTION_KEY_RECIPROCAL = PluggableType.RECIPROCAL.value - SECTION_KEY_DISCRIMINATIVE_NET = PluggableType.DISCRIMINATIVE_NETWORK.value - SECTION_KEY_GENERATIVE_NETWORK = PluggableType.GENERATIVE_NETWORK.value - @abstractmethod def __init__(self): self.check_pluggable_valid() @@ -76,19 +57,24 @@ def check_pluggable_valid(): pass def validate(self, args_dict): - """ validate input data """ - schema_dict = self.CONFIGURATION.get('input_schema') + """ validate input """ + schema_dict = self.CONFIGURATION.get('input_schema', None) if schema_dict is None: return - json_schema = JSONSchema(schema_dict) - schema_property_names = json_schema.get_default_section_names() + properties_dict = schema_dict.get('properties', None) + if properties_dict is None: + return + json_dict = {} - for property_name in schema_property_names: + for property_name, _ in properties_dict.items(): if property_name in args_dict: value = args_dict[property_name] if isinstance(value, np.ndarray): value = value.tolist() - json_dict[property_name] = value - json_schema.validate(json_dict) + json_dict[property_name] = value + try: + jsonschema.validate(json_dict, schema_dict) + except jsonschema.exceptions.ValidationError as vex: + raise AquaError(vex.message) diff --git a/qiskit/aqua/preferences.py b/qiskit/aqua/preferences.py deleted file mode 100644 index 96f04c9545..0000000000 --- a/qiskit/aqua/preferences.py +++ /dev/null @@ -1,83 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Qiskit Aqua preferences""" - -import os -import json -import copy -import logging - -logger = logging.getLogger(__name__) - - -class Preferences: - """Qiskit Aqua preferences""" - - _FILENAME = '.qiskit_aqua' - _VERSION = '2.0' - - def __init__(self): - """Create Preferences object.""" - self._preferences = { - 'version': Preferences._VERSION - } - self._ibmq_credentials_preferences = None - - home = os.path.expanduser("~") - self._filepath = os.path.join(home, Preferences._FILENAME) - try: - with open(self._filepath) as json_pref: - self._preferences = json.load(json_pref) - # remove old no more valid entries - if 'packages' in self._preferences: - del self._preferences['packages'] - if 'logging_config' in self._preferences: - del self._preferences['logging_config'] - if 'selected_ibmq_credentials_url' in self._preferences: - del self._preferences['selected_ibmq_credentials_url'] - except Exception: # pylint: disable=broad-except - pass - - self._old_preferences = copy.deepcopy(self._preferences) - - def save(self): - """Saves Preferences""" - if self._ibmq_credentials_preferences is not None: - self._ibmq_credentials_preferences.save(self._preferences) - if self._preferences != self._old_preferences: - with open(self._filepath, 'w') as file: - json.dump(self._preferences, file, sort_keys=True, indent=4) - - self._old_preferences = copy.deepcopy(self._preferences) - - def get_version(self): - """Return Preferences version""" - if 'version' in self._preferences: - return self._preferences['version'] - - return None - - @property - def ibmq_credentials_preferences(self): - """Return IBMQ Credentials Preferences""" - if self._ibmq_credentials_preferences is None: - try: - # pylint: disable=import-outside-toplevel - from ._ibmq_credentials_preferences import IBMQCredentialsPreferences - self._ibmq_credentials_preferences = IBMQCredentialsPreferences(self._preferences) - except Exception as ex: # pylint: disable=broad-except - logger.debug("IBMQCredentialsPreferences not created: '%s'", str(ex)) - - return self._ibmq_credentials_preferences diff --git a/qiskit/aqua/qiskit_aqua.py b/qiskit/aqua/qiskit_aqua.py deleted file mode 100644 index 98f0559105..0000000000 --- a/qiskit/aqua/qiskit_aqua.py +++ /dev/null @@ -1,394 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Algorithm functions for running etc.""" - -import copy -import json -import logging -import warnings - -from qiskit.transpiler import PassManager -from qiskit.ignis.mitigation.measurement import CompleteMeasFitter - -from .aqua_error import AquaError -from ._discover import (_discover_on_demand, - local_pluggables, - PluggableType, - get_pluggable_class) -from .utils.json_utils import convert_dict_to_json, convert_json_to_dict -from .parser._inputparser import InputParser -from .parser import JSONSchema -from .quantum_instance import QuantumInstance -from .aqua_globals import aqua_globals -from .utils.backend_utils import (get_backend_from_provider, - get_provider_from_backend, - is_statevector_backend) - -logger = logging.getLogger(__name__) - - -def execute_algorithm(algorithm, backend=None, **kwargs): - """ - Execute the supplied algorithm using the supplied backend or QuantumInstance that was - built using a backend. - - Args: - algorithm (QuantumAlgorithm): A quantum algorithm i.e. a concrete sub-class - implementing QuantumAlgorithm - backend (BaseBackend or QuantumInstance): The backend i.e. quantum simulator or real device - upon which the algorithm is to be run. - kwargs: optional arguments that can be used when supplying a - Basebackend which will be passed - to the set_config of the QuantumInstance that is used to hold the backend. - - Returns: - dict: Result dictionary containing result of algorithm computation - - """ - return algorithm.run(quantum_instance=backend, **kwargs) - - -def run_algorithm(params, algo_input=None, json_output=False, backend=None): - """ - Run algorithm as named in params. The input params being the declarative form of a - dictionary/json. - - Using params and algo_input as input data and returning a result dictionary - - 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 - json_output (bool): False for regular python dictionary return, True for json conversion - backend (BaseBackend or QuantumInstance): the experimental settings to be used in place - of backend name - - Returns: - dict: Result dictionary containing result of algorithm computation - """ - qiskit_aqua = QiskitAqua(params, algo_input, backend) - return qiskit_aqua.run(json_output) - - -def run_algorithm_to_json(params, algo_input=None, jsonfile='algorithm.json'): - """ - Run algorithm as named in params. - - Using params and algo_input as input data - and save the combined input as a json file. This json is self-contained and - can later be used as a basis to call run_algorithm - - 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 - jsonfile (str): Name of file in which json should be saved - - Returns: - dict: Result dictionary containing the jsonfile name - """ - return QiskitAqua.run_algorithm_to_json(params, algo_input, jsonfile) - - -class QiskitAqua: - """Main Aqua class.""" - - def __init__(self, params, algo_input=None, quantum_instance=None): - """ - Create an QiskitAqua object - - 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 - quantum_instance (QuantumInstance or BaseBackend): the experimental - settings to be used in place of backend name - """ - warnings.warn(aqua_globals.CONFIG_DEPRECATION_MSG, DeprecationWarning) - self._params = params - self._algorithm_input = algo_input - self._quantum_instance = None - self._quantum_algorithm = None - self._result = {} - self._parser = None - self._build_algorithm_from_dict(quantum_instance) - - @property - def params(self): - """Return Aqua params.""" - return self._params - - @property - def algorithm_input(self): - """Return Algorithm Input.""" - return self._algorithm_input - - @property - def quantum_instance(self): - """Return Quantum Instance.""" - return self._quantum_instance - - @property - def quantum_algorithm(self): - """Return Quantum Algorithm.""" - return self._quantum_algorithm - - @property - def result(self): - """Return Experiment Result.""" - return self._result - - @property - def json_result(self): - """Return Experiment Result as JSON.""" - return convert_dict_to_json(self.result) if isinstance(self.result, dict) else None - - @property - def parser(self): - """Return Aqua parser.""" - return self._parser - - def _build_algorithm_from_dict(self, quantum_instance): - # pylint: disable=import-outside-toplevel - from qiskit.providers import BaseBackend - - _discover_on_demand() - - # check quantum_instance parameter - backend = None - if isinstance(quantum_instance, BaseBackend): - backend = quantum_instance - elif isinstance(quantum_instance, QuantumInstance): - self._quantum_instance = quantum_instance - elif quantum_instance is not None: - raise AquaError( - 'Invalid QuantumInstance or BaseBackend parameter {}.'.format(quantum_instance)) - - self._parser = InputParser(self._params) - self._parser.backend = backend - 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)) - - # set provider and name in input file for proper backend schema dictionary build - if backend is not None: - self._parser.add_section_properties( - JSONSchema.BACKEND, - { - JSONSchema.PROVIDER: get_provider_from_backend(backend), - JSONSchema.NAME: backend.name(), - }) - - self._parser.validate_merge_defaults() - logger.debug('Algorithm Input: %s', - 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) - num_processes = self._parser.get_section_property(JSONSchema.PROBLEM, 'num_processes') - aqua_globals.num_processes = \ - num_processes if num_processes is not None else aqua_globals.CPU_COUNT - random_seed = self._parser.get_section_property(JSONSchema.PROBLEM, 'random_seed') - aqua_globals.random_seed = random_seed - if self._quantum_instance is not None: - return - - # 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 - if backend is None: - backend = get_backend_from_provider(backend_provider, backend_name) - - backend_cfg = {k: v for k, v in self._parser.get_section(JSONSchema.BACKEND).items() if - k not in [JSONSchema.PROVIDER, JSONSchema.NAME]} - - # set shots for state vector - if is_statevector_backend(backend): - backend_cfg['shots'] = 1 - - # check coupling map - if 'coupling_map_from_device' in backend_cfg: - coupling_map_from_device = backend_cfg.get('coupling_map_from_device') - del backend_cfg['coupling_map_from_device'] - if coupling_map_from_device is not None: - names = coupling_map_from_device.split(':') - if len(names) == 2: - device_backend = get_backend_from_provider(names[0], names[1]) - device_coupling_map = device_backend.configuration().coupling_map - if device_coupling_map is not None: - coupling_map = backend_cfg.get('coupling_map') - if coupling_map is None: - backend_cfg['coupling_map'] = device_coupling_map - else: - if coupling_map != device_coupling_map: - logger.warning( - "Coupling map '%s' used instead of " - "device coupling map '%s'.", - coupling_map, device_coupling_map) - - # check noise model - if 'noise_model' in backend_cfg: - noise_model = backend_cfg.get('noise_model') - del backend_cfg['noise_model'] - if noise_model is not None: - names = noise_model.split(':') - if len(names) == 2: - # Generate an Aer noise model for device - # pylint: disable=import-outside-toplevel - from qiskit.providers.aer import noise - device_backend = get_backend_from_provider(names[0], names[1]) - noise_model = \ - noise.device.basic_device_noise_model(device_backend.properties()) - noise_basis_gates = None - if noise_model is not None and noise_model.basis_gates is not None: - noise_basis_gates = noise_model.basis_gates - noise_basis_gates = \ - noise_basis_gates.split(',') if isinstance(noise_basis_gates, str) \ - else noise_basis_gates - if noise_basis_gates is not None: - basis_gates = backend_cfg.get('basis_gates') - if basis_gates is None: - backend_cfg['basis_gates'] = noise_basis_gates - else: - if basis_gates != noise_basis_gates: - logger.warning( - "Basis gates '%s' used instead of " - "noise model basis gates '%s'.", - basis_gates, noise_basis_gates) - - backend_cfg['seed_transpiler'] = 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 - - optimization_level = self._parser.get_section_property(JSONSchema.PROBLEM, - 'circuit_optimization_level') - if optimization_level == "default": - optimization_level = None - backend_cfg['optimization_level'] = optimization_level - - backend_cfg['backend'] = backend - if random_seed is not None: - backend_cfg['seed_simulator'] = random_seed - skip_qobj_validation = self._parser.get_section_property(JSONSchema.PROBLEM, - 'skip_qobj_validation') - if skip_qobj_validation is not None: - backend_cfg['skip_qobj_validation'] = skip_qobj_validation - - circuit_caching = self._parser.get_section_property(JSONSchema.PROBLEM, - 'circuit_caching') - if circuit_caching is not None: - backend_cfg['circuit_caching'] = circuit_caching - - skip_qobj_deepcopy = \ - self._parser.get_section_property(JSONSchema.PROBLEM, 'skip_qobj_deepcopy') - if skip_qobj_deepcopy is not None: - backend_cfg['skip_qobj_deepcopy'] = skip_qobj_deepcopy - - cache_file = self._parser.get_section_property(JSONSchema.PROBLEM, 'circuit_cache_file') - if cache_file is not None: - backend_cfg['cache_file'] = cache_file - - measurement_error_mitigation = \ - self._parser.get_section_property(JSONSchema.PROBLEM, - 'measurement_error_mitigation') - if measurement_error_mitigation: - backend_cfg['measurement_error_mitigation_cls'] = CompleteMeasFitter - - m_e_s = self._parser.get_section_property(JSONSchema.PROBLEM, - 'measurement_error_mitigation_shots') - if measurement_error_mitigation: - backend_cfg['measurement_error_mitigation_shots'] = m_e_s - - m_e = self._parser.get_section_property(JSONSchema.PROBLEM, - 'measurement_error_mitigation_refresh_period') - backend_cfg['cals_matrix_refresh_period'] = m_e - - self._quantum_instance = QuantumInstance(**backend_cfg) - - def run(self, json_output=False): - """ run algorithm """ - if self.quantum_algorithm is None: - raise AquaError('Missing Quantum Algorithm.') - - self._result = self.quantum_algorithm.run(self.quantum_instance) - return self.json_result if json_output else self.result - - @staticmethod - def run_algorithm_to_json(params, algo_input=None, jsonfile='algorithm.json'): - """ - Run algorithm as named in params. - - Using params and algo_input as input data - and save the combined input as a json file. This json is self-contained and - can later be used as a basis to call run_algorithm - - 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 - jsonfile (str): Name of file in which json should be saved - - Returns: - dict: Result dictionary containing the jsonfile name - """ - _discover_on_demand() - - inputparser = InputParser(params) - inputparser.parse() - inputparser.validate_merge_defaults() - - algo_params = copy.deepcopy(inputparser.get_sections()) - - if algo_input is not None: - input_params = algo_input.to_params() - convert_dict_to_json(input_params) - algo_params['input'] = input_params - algo_params['input']['name'] = algo_input.configuration['name'] - - logger.debug('Result: %s', json.dumps(algo_params, sort_keys=True, indent=4)) - with open(jsonfile, 'w') as file: - json.dump(algo_params, file, sort_keys=True, indent=4) - - logger.info("Algorithm input file saved: '%s'", jsonfile) - - return {'jsonfile': jsonfile} diff --git a/qiskit/aqua/utils/backend_utils.py b/qiskit/aqua/utils/backend_utils.py index 192e7b45c7..6b89ce1b79 100644 --- a/qiskit/aqua/utils/backend_utils.py +++ b/qiskit/aqua/utils/backend_utils.py @@ -14,10 +14,7 @@ """ backend utility functions """ -from collections import OrderedDict -import importlib import logging -from qiskit.aqua import Preferences logger = logging.getLogger(__name__) @@ -196,235 +193,3 @@ def support_backend_options(backend): if is_basicaer_provider(backend) or is_aer_provider(backend): ret = True return ret - - -def get_aer_backend(backend_name): - """ returns Aer backend """ - providers = ['qiskit.Aer', 'qiskit.BasicAer'] - for provider in providers: - try: - return get_backend_from_provider(provider, backend_name) - except Exception: # pylint: disable=broad-except - pass - - raise ImportError("Backend '{}' not found in providers {}".format(backend_name, providers)) - - -def get_backends_from_provider(provider_name): - """ - Backends access method. - - Args: - provider_name (str): Fullname of provider instance global property or class - Returns: - list: backend names - Raises: - ImportError: Invalid provider name or failed to find provider - """ - provider_object = _load_provider(provider_name) - is_ibmq = False - if has_ibmq(): - # pylint: disable=import-outside-toplevel - from qiskit.providers.ibmq import IBMQFactory - if isinstance(provider_object, IBMQFactory): - is_ibmq = True - # enable IBMQ account - provider = _refresh_ibmq_account() - if provider is not None: - return [x.name() for x in provider.backends() - if x.name() not in _UNSUPPORTED_BACKENDS] - - if not is_ibmq: - try: - # try as variable containing provider instance - return [x.name() for x in provider_object.backends() - if x.name() not in _UNSUPPORTED_BACKENDS] - except Exception: # pylint: disable=broad-except - # try as provider class then - try: - provider_instance = provider_object() - return [x.name() for x in provider_instance.backends() - if x.name() not in _UNSUPPORTED_BACKENDS] - except Exception: # pylint: disable=broad-except - pass - - raise ImportError("'Backends not found for provider '{}'".format(provider_name)) - - -def get_backend_from_provider(provider_name, backend_name): - """ - Backend access method. - - Args: - provider_name (str): Fullname of provider instance global property or class - backend_name (str): name of backend for this provider - Returns: - BaseBackend: backend object - Raises: - ImportError: Invalid provider name or failed to find provider - """ - provider_object = _load_provider(provider_name) - is_ibmq = False - if has_ibmq(): - # pylint: disable=import-outside-toplevel - from qiskit.providers.ibmq import IBMQFactory - if isinstance(provider_object, IBMQFactory): - is_ibmq = True - # enable IBMQ account - provider = _refresh_ibmq_account() - if provider is not None: - return provider.get_backend(backend_name) - - if not is_ibmq: - try: - # try as variable containing provider instance - return provider_object.get_backend(backend_name) - except Exception: # pylint: disable=broad-except - # try as provider class then - try: - provider_instance = provider_object() - return provider_instance.get_backend(backend_name) - except Exception: # pylint: disable=broad-except - pass - - raise ImportError("'{} not found in provider '{}'".format(backend_name, provider_name)) - - -def get_local_providers(): - """ returns local providers """ - providers = OrderedDict() - for provider in ['qiskit.Aer', 'qiskit.BasicAer']: - try: - providers[provider] = get_backends_from_provider(provider) - except Exception as ex: # pylint: disable=broad-except - logger.debug("'%s' not loaded: '%s'.", provider, str(ex)) - - return providers - - -def register_ibmq_and_get_known_providers(): # pylint: disable=invalid-name - """Gets known local providers and registers IBMQ.""" - providers = get_local_providers() - if has_ibmq(): - providers.update(_get_ibmq_provider()) - return providers - - -def get_provider_from_backend(backend): - """ - Attempts to find a known provider that provides this backend. - - Args: - backend (BaseBackend or str): backend object or backend name - Returns: - str: provider name - Raises: - ImportError: Failed to find provider - """ - # pylint: disable=import-outside-toplevel - from qiskit.providers import BaseBackend - - known_providers = { - 'BasicAerProvider': 'qiskit.BasicAer', - 'AerProvider': 'qiskit.Aer', - 'IBMQFactory': 'qiskit.IBMQ', - } - if isinstance(backend, BaseBackend): - provider = backend.provider() - if provider is None: - raise ImportError("Backend object '{}' has no provider".format(backend.name())) - - return known_providers.get(provider.__class__.__name__, provider.__class__.__qualname__) - elif not isinstance(backend, str): - raise ImportError("Invalid Backend '{}'".format(backend)) - - for provider in known_providers.values(): - try: - if get_backend_from_provider(provider, backend) is not None: - return provider - except Exception: # pylint: disable=broad-except - pass - - raise ImportError( - "Backend '{}' not found in providers {}".format(backend, list(known_providers.values()))) - - -def _load_provider(provider_name): - index = provider_name.rfind(".") - if index < 1: - raise ImportError("Invalid provider name '{}'".format(provider_name)) - - modulename = provider_name[0:index] - objectname = provider_name[index + 1:len(provider_name)] - - module = importlib.import_module(modulename) - if module is None: - raise ImportError("Failed to import provider '{}'".format(provider_name)) - - provider_object = getattr(module, objectname) - if provider_object is None: - raise ImportError("Failed to import provider '{}'".format(provider_name)) - - return provider_object - - -def _refresh_ibmq_account(): - """ - Refresh IBMQ account by enabling or disabling it depending on preferences stored values - """ - preferences = Preferences().ibmq_credentials_preferences - token = preferences.token or '' - proxies = preferences.proxies or {} - hub = preferences.hub - group = preferences.group - project = preferences.project - provider = None - try: - # pylint: disable=no-name-in-module,import-error,import-outside-toplevel - from qiskit import IBMQ - providers = IBMQ.providers() - if token != '': - # check if there was a previous account that needs to be disabled first - disable_account = False - enable_account = True - for provider in providers: - if provider.credentials.token == token and provider.credentials.proxies == proxies: - enable_account = False - else: - disable_account = True - - if disable_account: - IBMQ.disable_account() - logger.info('Disabled IBMQ account.') - - if enable_account: - IBMQ.enable_account(token, proxies=proxies) - logger.info('Enabled IBMQ account.') - - providers = IBMQ.providers(hub=hub, group=group, project=project) - provider = providers[0] if providers else None - if provider is None: - logger.info("No Provider found for IBMQ account. " - "Hub/Group/Project: '%s/%s/%s' Proxies:'%s'", - hub, group, project, proxies) - else: - if providers: - IBMQ.disable_account() - logger.info('Disabled IBMQ account.') - except Exception as ex: # pylint: disable=broad-except - logger.warning("IBMQ account Account Failure. " - "Hub/Group/Project: '%s/%s/%s' " - "Proxies:'%s' :%s", hub, group, project, proxies, str(ex)) - - return provider - - -def _get_ibmq_provider(): - """Registers IBMQ and return it.""" - providers = OrderedDict() - try: - providers['qiskit.IBMQ'] = get_backends_from_provider('qiskit.IBMQ') - except Exception as ex: # pylint: disable=broad-except - logger.warning("Failed to access IBMQ: %s", str(ex)) - - return providers diff --git a/qiskit/chemistry/README.md b/qiskit/chemistry/README.md index c48224cfd0..5535234028 100644 --- a/qiskit/chemistry/README.md +++ b/qiskit/chemistry/README.md @@ -10,274 +10,14 @@ If you need introductory material see the main [readme](../../README.md) which h This readme contains the following sections: -* [Input file](#input-file) * [Developers](#developers) * [Additional reading](#additional-reading) - -## Input file - -An input file is used to define your chemistry problem. It contains at a minimum a definition of the molecule and -associated configuration, such as a basis set, in order to compute the electronic structure using an external ab-initio -chemistry program or chemistry library via a chemistry driver. Further configuration can also be supplied to explicitly -control the processing and the quantum algorithm, used for the computation, instead of using defaulted values when -none are supplied. - -Several sample input files can be found in the chemistry folder of -[qiskit-tutorials](https://github.com/Qiskit/qiskit-tutorials/tree/master/chemistry/input_files) - -An input file comprises the following main sections, although not all are mandatory: - -#### NAME - -NAME is an optional free format text section. Here you can name and describe the problem solved by the input file. For -example: - -``` -&NAME -H2 molecule experiment -Ground state energy computed via Variational Quantum Eigensolver -&END -``` - -#### DRIVER - -DRIVER is a mandatory section. This section defines the molecule and associated configuration for the electronic -structure computation by the chosen driver via its external chemistry program or library. The exact form on the -configuration depends on the specific driver being used. See the chemistry drivers -[readme](drivers/README.md) for more information about the drivers and their configuration. - -You will need to look at the readme of the driver you are using to find out about its specific configuration. -Here are a couple of examples. Note that the DRIVER section names which specific chemistry driver will be used and -that a subsequent section, in the name of the driver, then supplies the driver specific configuration. - -Here is an example using the [PYSCF driver](drivers/pyscfd/README.md). -The DRIVER section names PYSCF as the driver and then a PYSCF section, corresponding to the name, provides the -molecule and basis set that will be used by the PYSCF driver and hence the PySCF library to compute the electronic -structure. - -``` -&DRIVER - name=PYSCF -&END - -&PYSCF - atom=H .0 .0 .0; H .0 .0 0.74 - basis=sto3g -&END -``` - -Here is another example using the [PSI4 driver](drivers/psi4d/README.md). Here PSI4 is named -as the driver to be used and the PSI4 section contains the molecule and basis set directly in a form that PSI4 -understands. This is the Psithon input file language for PSI4, and thus should be familiar to existing users of PSI4. - -``` -&DRIVER - name=PSI4 -&END - -&PSI4 -molecule h2 { - 0 1 - H .0000000000 0.0 0.0 - H .0000000000 0.0 .2 -} - -set { - basis sto-3g - scf_type pk -} -&END -``` - -#### OPERATOR - -OPERATOR is an optional section. This section can be configured to control the specific way the electronic -structure information, from the driver, is converted to QuBit operator form in order to be processed by the ALGORITHM. -The following parameters may be set: - -* `name`=hamiltonian - - Currently 'hamiltonian' should be used as the name since there only one operator entity at present - -* `transformation`=**full** | particle_hole - - Do *full* transformation or use *particle_hole* - - The 'standard' second quantized Hamiltonian can be transformed using the particle-hole (p/h) option, which makes the - expansion of the trial wavefunction from the HartreeFock reference state more natural. For trial wavefunctions - in Qiskit Aqua, such as UCCSD, the p/h Hamiltonian can improve the speed of convergence of the - VQE algorithm for the calculation of the electronic ground state properties. - For more information on the p/h formalism see: [P. Barkoutsos, arXiv:1805.04340](https://arxiv.org/abs/1805.04340). - -* `qubit_mapping`=jordan_wigner | **parity** | bravyi_kitaev - - Desired mapping from fermion to qubit. Note: bravyi_kitaev is also known as the binary-tree-based qubit mapping. - -* `two_qubit_reduction`=**true** | false - - With parity mapping the operator can be reduced by two qubits - -* `freeze_core`=true | **false** - - Whether to freeze core orbitals in the computation or not. Frozen core orbitals are removed from the - subsequent computation by the ALGORITHM and a corresponding offset from this removal is added back into the - final computed result. This may be combined with orbital_reduction below. - -* `orbital_reduction`=*array of integers* - - The orbitals from the electronic structure can be simplified for the subsequent computation. - - With this parameter you can specify a list of orbitals, the default being an empty list, to be removed from the - subsequent computation. The list should be indices of the orbitals from 0 to n-1, where the electronic structure - has n orbitals. Note: for ease of referring to the higher orbitals the list also supports negative values with -1 - being the highest unoccupied orbital, -2 the next one down and so on. Also note, that while orbitals may be listed to - reduce the overall size of the problem, the result can be less accurate as a result of using this simplification. - - Any orbitals in the list that are occupied are frozen and an offset is computed from their removal. This is the same - procedure as happens when freeze_core is specified except here you can specify exactly the orbitals you want. - - Any orbitals in the list that are unoccupied virtual orbitals are simply eliminated entirely from the - subsequent computation. - - When a list is specified along with freeze_core of true the effective orbitals being acted up is the set - from freeze_core combined with those specified here. - -Here is an example below where in addition to freezing the core orbitals a couple of other orbitals are listed. In this -example it assumes there were 10 orbitals so the highest two, unoccupied virtual orbitals, will be eliminated from the -subsequent computation in addition to the frozen core treatment: - -``` -&OPERATOR - name=hamiltonian - qubit_mapping=jordan_wigner - freeze_core=true - orbital_reduction=[8,9] -&END -``` - -Note the above could be specified the following way, which simplifies expressing the higher orbitals since the numbering -is relative to the highest orbital and will always refer to the highest two orbitals. -``` -&OPERATOR - name=hamiltonian - qubit_mapping=jordan_wigner - freeze_core=true - orbital_reduction=[-2,-1] -&END -``` - -#### ALGORITHM - -ALGORITHM is an optional section that allows you to define which quantum algorithm will be used by the computation. -Algorithms are provided by [QISKIt Aqua](https://github.com/Qiskit/qiskit-aqua/blob/master/qiskit/aqua/README.md) -The algorithm defaults to VQE (Variational Quantum Eigensolver), with a set of default parameters. - -According to each ALGORITHM you may add further sections to optionally configure the algorithm further. These sections -correspond to the pluggable entities that [developers](#developers) may choose to create and add more to the set -currently provided. - -Here is an example showing the VQE algorithm along with OPTIMIZER and VARIATIONAL_FORM sections for the optimizer and -variational forms that are used by VQE. - -``` -&ALGORITHM - name=VQE - shots=1 -&END - -&OPTIMIZER - name=L_BFGS_B - factr=10 -&END - -&VARIATIONAL_FORM - name=RYRZ - entangler_map={0: [1]} -&END -``` - -For more information on algorithms, and any pluggable entities it may use, see -[Qiskit Aqua](https://github.com/Qiskit/qiskit-aqua/blob/master/qiskit/aqua/README.md) for more specifics -about them and their configuration options. - - -#### BACKEND - -BACKEND is an optional section that includes naming the [Qiskit](https://www.qiskit.org/) quantum computational -backend to be used for the quantum algorithm computation. This defaults to a local quantum simulator backend. See -[Qiskit Aqua](https://github.com/Qiskit/qiskit-aqua/blob/master/qiskit/aqua/README.md#backend) for more -information. - -#### PROBLEM - -PROBLEM is an optional section that includes the overall problem being solved and overall problem level configuration -See [Qiskit Aqua](https://github.com/Qiskit/qiskit-aqua/blob/master/qiskit/aqua/README.md#problem) for more -information. - -This is the same PROBLEM specification but - -* `name`=**energy** | excited_states - - Specifies the problem being solved. Ensures that algorithms that can handle this class of problem are used. - Restricted to `energy` and `excited_states` computations for the chemistry stack and therefore algorithms that - can handle these problems. - -* `auto_substitutions`=**true** | false - - *This field is only support by Qiskit Chemistry.* - - During configuration some items may require matching their settings e.g. UCCSD variation form and HartreeFock - initial state configuration need qubit_mapping and two_qubit_reduction to match what is set in [OPERATOR](#operator) - section hamiltonian. Also some objects, like the aforementioned, may require the user to know number of particles, - number of orbitals etc. for their configuration. To assist the user in this regard configuration substitutions - are enabled by default. - - Substitutions use a predefined set of intra-section and computed values that are used to substitute (overwrite) - any values in the targeted fields appropriately. If auto_substitutions is set false then the end user has the - full responsibility for the entire configuration. - -* `random_seed`=*An integer, default None* - - See [Qiskit Aqua](https://github.com/Qiskit/qiskit-aqua/blob/master/qiskit/aqua/README.md#problem) - `random_seed` for more information. - ## Developers -### Programming interface - -The UI and Command line tools use qiskit_chemistry.py when solving the chemistry problem given by the supplied -input file. A programmatic interface is also available that can be called using a dictionary in the same formula as the -input file. Like the input file its parameters take on the same values and same defaults. - -The dictionary can be manipulated programmatically, if desired, to vary the problem e.g. changing the interatomic -distance of the molecule, changing basis set, algorithm etc. You can find notebooks in the -[qiskit-tutorials](https://github.com/Qiskit/qiskit-tutorials/tree/master/chemistry) -chemistry folder demonstrating this usage. - -The code fragment below also shows such a dictionary and a simple usage. - -``` -qiskit_chemistry_dict = { - 'driver': {'name': 'PYSCF'}, - 'PYSCF': {'atom': '', 'basis': 'sto3g'}, - 'algorithm': {'name': 'VQE'} -} -molecule = 'H .0 .0 -{0}; H .0 .0 {0}' -d = 0.74 - -qiskit_chemistry_dict['PYSCF']['atom'] = molecule.format(d/2) -solver = QiskitChemistry() -result = solver.run(qiskit_chemistry_dict) -print('Ground state energy {}'.format(result['energy'])) -``` - -Note: the [GUI](../../README.md#gui) tool can export a dictionary from an [input file](#input-file). You can load an -existing input file or create a new one and then simply export it as a dictionary for use in a program. - ### Result dictionary -As can be seen in the programming interface example above the QiskitChemistry run() method returns a result dictionary. +The ChemistryOperator process_algorithm_result() method returns a result dictionary. Energies are in units of `Hartree` and dipole moment in units of `a.u.`. The dictionary contains the following fields of note: @@ -330,7 +70,7 @@ For guidance look at the tests cases implemented at https://github.com/Qiskit/qi To run all unit tests: `python -m unittest discover` -To run a particular unit test module: `python -m unittest test/test_end2end.py` +To run a particular unit test module: `python -m unittest test/chemistry/test_end2end_with_iqpe.py` For help: `python -m unittest -h` diff --git a/qiskit/chemistry/__init__.py b/qiskit/chemistry/__init__.py index 8c51aa334b..b9e34c49e9 100644 --- a/qiskit/chemistry/__init__.py +++ b/qiskit/chemistry/__init__.py @@ -54,8 +54,6 @@ from .qiskit_chemistry_error import QiskitChemistryError from .qmolecule import QMolecule -from .qiskit_chemistry_problem import ChemistryProblem -from .qiskit_chemistry import (QiskitChemistry, run_experiment, run_driver_to_json) from .fermionic_operator import FermionicOperator from .mp2info import MP2Info from ._logging import (get_logging_level, @@ -66,10 +64,6 @@ __all__ = ['QiskitChemistryError', 'QMolecule', - 'ChemistryProblem', - 'QiskitChemistry', - 'run_experiment', - 'run_driver_to_json', 'FermionicOperator', 'MP2Info', 'get_logging_level', diff --git a/qiskit/chemistry/_logging.py b/qiskit/chemistry/_logging.py index 680b1dd2cc..7a865a66d9 100644 --- a/qiskit/chemistry/_logging.py +++ b/qiskit/chemistry/_logging.py @@ -15,14 +15,9 @@ """Utilities for logging.""" import os -import itertools import copy import logging from logging.config import dictConfig -from collections import OrderedDict -import pkg_resources -from qiskit.chemistry.core import OPERATORS_ENTRY_POINT -from qiskit.chemistry.drivers import DRIVERS_ENTRY_POINT _QISKIT_CHEMISTRY_LOGGING_CONFIG = { 'version': 1, @@ -43,17 +38,7 @@ def _get_logging_names(): - # pylint: disable=import-outside-toplevel - from qiskit.aqua import PLUGGABLES_ENTRY_POINT - names = OrderedDict() - names['qiskit.chemistry'] = None - for entry_point in itertools.chain(pkg_resources.iter_entry_points(PLUGGABLES_ENTRY_POINT), - pkg_resources.iter_entry_points(OPERATORS_ENTRY_POINT), - pkg_resources.iter_entry_points(DRIVERS_ENTRY_POINT)): - names[entry_point.module_name] = None - - names['qiskit.aqua'] = None - return list(names.keys()) + return ['qiskit.aqua', 'qiskit.chemistry'] def build_logging_config(level, filepath=None): diff --git a/qiskit/chemistry/algorithms/adaptive/vqe_adapt/vqe_adapt.py b/qiskit/chemistry/algorithms/adaptive/vqe_adapt/vqe_adapt.py index af5439877c..6b24aebf8a 100644 --- a/qiskit/chemistry/algorithms/adaptive/vqe_adapt/vqe_adapt.py +++ b/qiskit/chemistry/algorithms/adaptive/vqe_adapt/vqe_adapt.py @@ -23,7 +23,7 @@ import numpy as np from qiskit import ClassicalRegister -from qiskit.aqua import AquaError, Pluggable, PluggableType, get_pluggable_class +from qiskit.aqua import AquaError from qiskit.aqua.algorithms.adaptive.vq_algorithm import VQAlgorithm from qiskit.aqua.algorithms.adaptive.vqe.vqe import VQE from qiskit.chemistry.components.variational_forms import UCCSD @@ -135,48 +135,6 @@ def __init__(self, operator, var_form_base, optimizer, initial_point=None, for aux_op in aux_operators: self._aux_operators.append(aux_op) - @classmethod - def init_params(cls, params, algo_input): - """ - Initialize via parameters dictionary and algorithm input instance. - - Args: - params (dict): parameters dictionary - algo_input (EnergyInput): EnergyInput instance - - Returns: - VQEAdapt: VQEAdapt object - Raises: - AquaError: invalid input - """ - if algo_input is None: - raise AquaError("EnergyInput instance is required.") - - operator = algo_input.qubit_op - - vqe_params = params.get(Pluggable.SECTION_KEY_ALGORITHM) - initial_point = vqe_params.get('initial_point') - excitation_pool = vqe_params.get('excitation_pool') - threshold = vqe_params.get('threshold') - delta = vqe_params.get('delta') - max_evals_grouped = vqe_params.get('max_evals_grouped') - - # Set up variational form, we need to add computed num qubits - # Pass all parameters so that Variational Form can create its dependents - var_form_params = params.get(Pluggable.SECTION_KEY_VAR_FORM) - var_form_params['num_qubits'] = operator.num_qubits - var_form = get_pluggable_class(PluggableType.VARIATIONAL_FORM, - var_form_params['name']).init_params(params) - - # Set up optimizer - opt_params = params.get(Pluggable.SECTION_KEY_OPTIMIZER) - optimizer = get_pluggable_class(PluggableType.OPTIMIZER, - opt_params['name']).init_params(params) - - return cls(operator, var_form, optimizer, excitation_pool=excitation_pool, - initial_point=initial_point, threshold=threshold, delta=delta, - max_evals_grouped=max_evals_grouped, aux_operators=algo_input.aux_ops) - def _compute_gradients(self, excitation_pool, theta, delta, var_form, operator, optimizer): """ diff --git a/qiskit/chemistry/algorithms/q_equation_of_motion/q_eom_ee.py b/qiskit/chemistry/algorithms/q_equation_of_motion/q_eom_ee.py index d1920ec17e..3b86eca8b8 100644 --- a/qiskit/chemistry/algorithms/q_equation_of_motion/q_eom_ee.py +++ b/qiskit/chemistry/algorithms/q_equation_of_motion/q_eom_ee.py @@ -18,7 +18,6 @@ import numpy as np -from qiskit.aqua import QuantumAlgorithm, AquaError from qiskit.aqua.algorithms import ExactEigensolver from .q_equation_of_motion import QEquationOfMotion @@ -109,37 +108,6 @@ def __init__(self, operator, num_orbitals, num_particles, qubit_mapping='parity' is_eom_matrix_symmetric, se_list, de_list, z2_symmetries, untapered_op) - @classmethod - def init_params(cls, params, algo_input): - """ - Initialize via parameters dictionary and algorithm input instance. - - Args: - params (dict): parameters dictionary - algo_input (EnergyInput): EnergyInput instance - Returns: - QEomEE: Newly created instance - Raises: - AquaError: EnergyInput instance is required - """ - if algo_input is None: - raise AquaError("EnergyInput instance is required.") - - operator = algo_input.qubit_op - - q_eom_ee_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) - num_orbitals = q_eom_ee_params.get('num_orbitals') - num_particles = q_eom_ee_params.get('num_particles') - qubit_mapping = q_eom_ee_params.get('qubit_mapping') - two_qubit_reduction = q_eom_ee_params.get('two_qubit_reduction') - active_occupied = q_eom_ee_params.get('active_occupied') - active_unoccupied = q_eom_ee_params.get('active_unoccupied') - - return cls(operator, aux_operators=algo_input.aux_ops, num_orbitals=num_orbitals, - num_particles=num_particles, - qubit_mapping=qubit_mapping, two_qubit_reduction=two_qubit_reduction, - active_occupied=active_occupied, active_unoccupied=active_unoccupied) - def _run(self): super()._run() wave_fn = self._ret['eigvecs'][0] diff --git a/qiskit/chemistry/algorithms/q_equation_of_motion/q_eom_vqe.py b/qiskit/chemistry/algorithms/q_equation_of_motion/q_eom_vqe.py index eba45d392d..2480b2ee58 100644 --- a/qiskit/chemistry/algorithms/q_equation_of_motion/q_eom_vqe.py +++ b/qiskit/chemistry/algorithms/q_equation_of_motion/q_eom_vqe.py @@ -18,8 +18,6 @@ import numpy as np -from qiskit.aqua import QuantumAlgorithm, AquaError -from qiskit.aqua import PluggableType, get_pluggable_class, Pluggable from qiskit.aqua.algorithms import VQE from .q_equation_of_motion import QEquationOfMotion @@ -154,52 +152,6 @@ def __init__(self, operator, var_form, optimizer, num_orbitals, num_particles, is_eom_matrix_symmetric, se_list, de_list, z2_symmetries, untapered_op) - @classmethod - def init_params(cls, params, algo_input): - """ - Initialize via parameters dictionary and algorithm input instance. - - Args: - params (dict): parameters dictionary - algo_input (EnergyInput): EnergyInput instance - Returns: - QEomVQE: Newly created instance - Raises: - AquaError: EnergyInput instance is required - """ - if algo_input is None: - raise AquaError("EnergyInput instance is required.") - - operator = algo_input.qubit_op - - q_eom_vqe_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) - initial_point = q_eom_vqe_params.get('initial_point') - max_evals_grouped = q_eom_vqe_params.get('max_evals_grouped') - num_orbitals = q_eom_vqe_params.get('num_orbitals') - num_particles = q_eom_vqe_params.get('num_particles') - qubit_mapping = q_eom_vqe_params.get('qubit_mapping') - two_qubit_reduction = q_eom_vqe_params.get('two_qubit_reduction') - active_occupied = q_eom_vqe_params.get('active_occupied') - active_unoccupied = q_eom_vqe_params.get('active_unoccupied') - - # Set up variational form, we need to add computed num qubits, and initial state to params - var_form_params = params.get(Pluggable.SECTION_KEY_VAR_FORM) - var_form_params['num_qubits'] = operator.num_qubits - var_form = get_pluggable_class(PluggableType.VARIATIONAL_FORM, - var_form_params['name']).init_params(params) - - # Set up optimizer - opt_params = params.get(Pluggable.SECTION_KEY_OPTIMIZER) - optimizer = get_pluggable_class(PluggableType.OPTIMIZER, - opt_params['name']).init_params(params) - - return cls(operator, var_form, optimizer, - initial_point=initial_point, max_evals_grouped=max_evals_grouped, - aux_operators=algo_input.aux_ops, num_orbitals=num_orbitals, - num_particles=num_particles, - qubit_mapping=qubit_mapping, two_qubit_reduction=two_qubit_reduction, - active_occupied=active_occupied, active_unoccupied=active_unoccupied) - def _run(self): super()._run() self._quantum_instance.circuit_summary = True diff --git a/qiskit/chemistry/core/__init__.py b/qiskit/chemistry/core/__init__.py index 7d57151e91..4f252b14f5 100644 --- a/qiskit/chemistry/core/__init__.py +++ b/qiskit/chemistry/core/__init__.py @@ -51,22 +51,8 @@ from .chemistry_operator import ChemistryOperator from .hamiltonian import Hamiltonian, TransformationType, QubitMappingType -from ._discover_chemoperator import (OPERATORS_ENTRY_POINT, - refresh_operators, - register_chemistry_operator, - deregister_chemistry_operator, - get_chemistry_operator_class, - get_chem_operator_config, - local_chemistry_operators) __all__ = ['ChemistryOperator', 'Hamiltonian', 'TransformationType', - 'QubitMappingType', - 'OPERATORS_ENTRY_POINT', - 'refresh_operators', - 'register_chemistry_operator', - 'deregister_chemistry_operator', - 'get_chemistry_operator_class', - 'get_chem_operator_config', - 'local_chemistry_operators'] + 'QubitMappingType'] diff --git a/qiskit/chemistry/core/_discover_chemoperator.py b/qiskit/chemistry/core/_discover_chemoperator.py deleted file mode 100644 index b788cd9869..0000000000 --- a/qiskit/chemistry/core/_discover_chemoperator.py +++ /dev/null @@ -1,289 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" -Methods for chemistry operators objects discovery, registration, information -""" - -import os -import pkgutil -import importlib -import inspect -from collections import namedtuple -import copy -import logging -import pkg_resources -from qiskit.chemistry import QiskitChemistryError -from .chemistry_operator import ChemistryOperator - -logger = logging.getLogger(__name__) - -OPERATORS_ENTRY_POINT = 'qiskit.chemistry.operators' - -_NAMES_TO_EXCLUDE = [os.path.basename(__file__)] - -_FOLDERS_TO_EXCLUDE = ['__pycache__'] - - -class RegistryChemOps: - """Contains Registered Chemistry Operator.""" - - REGISTERED_CHEM_OP = namedtuple( - 'REGISTERED_CHEM_OP', ['name', 'cls', 'configuration']) - - def __init__(self) -> None: - self._discovered = False - self._registry = {} - - @property - def discovered(self): - """ Returns discovered flag """ - return self._discovered - - def set_discovered(self): - """ Set registry as discovered """ - self._discovered = True - - @property - def registry(self): - """ Return registry dictionary """ - return self._registry - - def reset(self): - """ reset registry data """ - self._discovered = False - self._registry = {} - - -# Registry Global Instance -_REGISTRY_CHEM_OPS = RegistryChemOps() - - -def refresh_operators(): - """ - Attempts to rediscover all operator modules - """ - _REGISTRY_CHEM_OPS.reset() - _REGISTRY_CHEM_OPS.set_discovered() - _discover_local_chem_ops() - _discover_entry_pt_chem_ops() - if logger.isEnabledFor(logging.DEBUG): - logger.debug("Found: chemistry operators %s ", local_chemistry_operators()) - - -def _discover_on_demand(): - """ - Attempts to discover operator modules, if not already discovered - """ - if not _REGISTRY_CHEM_OPS.discovered: - _REGISTRY_CHEM_OPS.reset() - _REGISTRY_CHEM_OPS.set_discovered() - _discover_local_chem_ops() - _discover_entry_pt_chem_ops() - if logger.isEnabledFor(logging.DEBUG): - logger.debug("Found: chemistry operators %s ", local_chemistry_operators()) - - -def _discover_entry_pt_chem_ops(): - """ - Discovers the chemistry operators modules defined by entry_points in setup - and attempts to register them. Chem.Operator modules should subclass - ChemistryOperator Base class. - """ - for entry_point in pkg_resources.iter_entry_points(OPERATORS_ENTRY_POINT): - # first calls require and log any errors returned due to dependencies mismatches - try: - entry_point.require() - except Exception as ex: # pylint: disable=broad-except - logger.warning("Entry point '%s' requirements issue: %s", entry_point, str(ex)) - - # now call resolve and try to load entry point - try: - e_p = entry_point.resolve() - _registered = False - if not inspect.isabstract(e_p) and issubclass(e_p, ChemistryOperator): - register_chemistry_operator(e_p) - _registered = True - logger.debug( - "Registered entry point chemistry operator '%s' class '%s'", entry_point, e_p) - break - - if not _registered: - logger.debug( - "Unknown entry point chemistry operator '%s' class '%s'", entry_point, e_p) - except Exception as ex: # pylint: disable=broad-except - # Ignore entry point that could not be initialized. - # print("Failed to load entry point '{}' error {}".format(entry_point, str(e))) - logger.debug("Failed to load entry point '%s' error %s", entry_point, str(ex)) - - -def _discover_local_chem_ops(directory=os.path.dirname(__file__), - parentname=os.path.splitext(__name__)[0], - names_to_exclude=None, - folders_to_exclude=None): - """ - Discovers the chemistry operators modules on the directory and - subdirectories of the current module - and attempts to register them. Chem.Operator modules should subclass - ChemistryOperator Base class. - Args: - directory (Optional(str)): Directory to search for input modules. Defaults - to the directory of this module. - parentname (Optional(str)): Module parent name. - Defaults to current directory name - names_to_exclude (Optional(list[str])): File names to exclude. - Defaults to _NAMES_TO_EXCLUDE - folders_to_exclude (Optional(list[str])): Folders to exclude. - Defaults to _FOLDERS_TO_EXCLUDE - """ - names_to_exclude = names_to_exclude if names_to_exclude is not None else _NAMES_TO_EXCLUDE - folders_to_exclude = folders_to_exclude \ - if folders_to_exclude is not None else _FOLDERS_TO_EXCLUDE - for _, name, ispackage in pkgutil.iter_modules([directory]): - if ispackage: - continue - - # Iterate through the modules - if name not in names_to_exclude: # skip those modules - try: - fullname = parentname + '.' + name - modspec = importlib.util.find_spec(fullname) - mod = importlib.util.module_from_spec(modspec) - modspec.loader.exec_module(mod) - for _, cls in inspect.getmembers(mod, inspect.isclass): - # Iterate through the classes defined on the module. - try: - if cls.__module__ == modspec.name and \ - not inspect.isabstract(cls) and \ - issubclass(cls, ChemistryOperator): - _register_chemistry_operator(cls) - importlib.import_module(fullname) - except Exception as ex: # pylint: disable=broad-except - # Ignore operator that could not be initialized. - logger.debug('Failed to load %s error %s', fullname, str(ex)) - except Exception as ex: # pylint: disable=broad-except - # Ignore operator that could not be initialized. - logger.debug('Failed to load %s error %s', fullname, str(ex)) - - for item in os.listdir(directory): - fullpath = os.path.join(directory, item) - if item not in folders_to_exclude and not item.endswith('dSYM') and os.path.isdir(fullpath): - _discover_local_chem_ops(fullpath, parentname + '.' + item, - names_to_exclude, folders_to_exclude) - - -def register_chemistry_operator(cls): - """ - Registers a chemistry operator class - Args: - cls (ChemistryOperator): chemistry operator class. - Returns: - str: input name - Raises: - QiskitChemistryError: if the class is already registered or could not be registered - """ - _discover_on_demand() - if not issubclass(cls, ChemistryOperator): - raise QiskitChemistryError( - 'Could not register class {} is not subclass of ChemistryOperator'.format(cls)) - - return _register_chemistry_operator(cls) - - -def _register_chemistry_operator(cls): - # Verify that the pluggable is not already registered - if cls in [input.cls for input in _REGISTRY_CHEM_OPS.registry.values()]: - raise QiskitChemistryError('Could not register class {} is already registered'.format(cls)) - - # Verify that it has a minimal valid configuration. - try: - chemistry_operator_name = cls.CONFIGURATION['name'] - except (LookupError, TypeError): - raise QiskitChemistryError('Could not register chemistry operator: invalid configuration') - - if chemistry_operator_name in _REGISTRY_CHEM_OPS.registry: - raise QiskitChemistryError( - 'Could not register class {}. Name {} {} is already registered'.format( - cls, - chemistry_operator_name, - _REGISTRY_CHEM_OPS.registry[chemistry_operator_name].cls)) - - # Append the pluggable to the `registered_classes` dict. - _REGISTRY_CHEM_OPS.registry[chemistry_operator_name] = RegistryChemOps.REGISTERED_CHEM_OP( - chemistry_operator_name, cls, copy.deepcopy(cls.CONFIGURATION)) - return chemistry_operator_name - - -def deregister_chemistry_operator(chemistry_operator_name): - """ - Deregisters a chemistry operator class - Args: - chemistry_operator_name(str): The chemistry operator name - Raises: - QiskitChemistryError: if the class is not registered - """ - _discover_on_demand() - - if chemistry_operator_name not in _REGISTRY_CHEM_OPS.registry: - raise QiskitChemistryError( - 'Could not deregister {} not registered'.format(chemistry_operator_name)) - - _REGISTRY_CHEM_OPS.registry.pop(chemistry_operator_name) - - -def get_chemistry_operator_class(chemistry_operator_name): - """ - Accesses chemistry operator class - Args: - chemistry_operator_name (str): The chemistry operator name - Returns: - ChemistryOperator: chemistry operator class - Raises: - QiskitChemistryError: if the class is not registered - """ - _discover_on_demand() - - if chemistry_operator_name not in _REGISTRY_CHEM_OPS.registry: - raise QiskitChemistryError( - '{} not registered'.format(chemistry_operator_name)) - - return _REGISTRY_CHEM_OPS.registry[chemistry_operator_name].cls - - -def get_chem_operator_config(chemistry_operator_name): - """ - Accesses chemistry operator configuration - Args: - chemistry_operator_name (str): The chemistry operator name - Returns: - configuration: chemistry operator configuration - Raises: - QiskitChemistryError: if the class is not registered - """ - _discover_on_demand() - - if chemistry_operator_name not in _REGISTRY_CHEM_OPS.registry: - raise QiskitChemistryError('{} not registered'.format(chemistry_operator_name)) - - return copy.deepcopy(_REGISTRY_CHEM_OPS.registry[chemistry_operator_name].configuration) - - -def local_chemistry_operators(): - """ - Accesses chemistry operator names - Returns: - list[str]: chemistry operator names - """ - _discover_on_demand() - return [input.name for input in _REGISTRY_CHEM_OPS.registry.values()] diff --git a/qiskit/chemistry/core/chemistry_operator.py b/qiskit/chemistry/core/chemistry_operator.py index 7ae77f8343..7c5e420e80 100644 --- a/qiskit/chemistry/core/chemistry_operator.py +++ b/qiskit/chemistry/core/chemistry_operator.py @@ -19,7 +19,9 @@ from abc import ABC, abstractmethod import logging import copy -from qiskit.aqua.parser import JSONSchema +import numpy as np +import jsonschema +from qiskit.chemistry import QiskitChemistryError logger = logging.getLogger(__name__) @@ -54,34 +56,27 @@ def check_chemistry_operator_valid(): pass def validate(self, args_dict): - """ schema input validation """ + """ validate input """ schema_dict = self.CONFIGURATION.get('input_schema', None) if schema_dict is None: return - json_schema = JSONSchema(schema_dict) - schema_property_names = json_schema.get_default_section_names() + properties_dict = schema_dict.get('properties', None) + if properties_dict is None: + return + json_dict = {} - for property_name in schema_property_names: + for property_name, _ in properties_dict.items(): if property_name in args_dict: - json_dict[property_name] = args_dict[property_name] - - json_schema.validate(json_dict) - - @classmethod - def init_params(cls, params): - """ - Initialize via parameters dictionary. - - Args: - params (dict): parameters dictionary - - Returns: - ChemistryOperator: Chemistry Operator object - """ - kwargs = {k: v for k, v in params.items() if k != 'name'} - logger.debug('init_params: %s', kwargs) - return cls(**kwargs) + value = args_dict[property_name] + if isinstance(value, np.ndarray): + value = value.tolist() + + json_dict[property_name] = value + try: + jsonschema.validate(json_dict, schema_dict) + except jsonschema.exceptions.ValidationError as vex: + raise QiskitChemistryError(vex.message) @abstractmethod def run(self, qmolecule): diff --git a/qiskit/chemistry/core/hamiltonian.py b/qiskit/chemistry/core/hamiltonian.py index 4829299370..11d9f9298e 100644 --- a/qiskit/chemistry/core/hamiltonian.py +++ b/qiskit/chemistry/core/hamiltonian.py @@ -21,9 +21,8 @@ import numpy as np -from qiskit.aqua.input import EnergyInput from qiskit.aqua.operators import Z2Symmetries -from qiskit.chemistry import ChemistryProblem, QMolecule +from qiskit.chemistry import QMolecule from qiskit.chemistry.fermionic_operator import FermionicOperator from .chemistry_operator import ChemistryOperator @@ -99,7 +98,7 @@ class Hamiltonian(ChemistryOperator): }, "additionalProperties": False }, - 'problems': [ChemistryProblem.ENERGY.value, ChemistryProblem.EXCITED_STATES.value] + 'problems': ['energy', 'excited_states'] } def __init__(self, @@ -145,32 +144,6 @@ def __init__(self, self._ph_y_dipole_shift = 0.0 self._ph_z_dipole_shift = 0.0 - @classmethod - def init_params(cls, params): - """ - Initialize via parameters dictionary. - - Args: - params (dict): parameters dictionary - - Returns: - Hamiltonian: hamiltonian object - """ - kwargs = {} - for k, v in params.items(): - if k == 'name': - continue - - if k == Hamiltonian.KEY_TRANSFORMATION: - v = TransformationType(v) - elif k == Hamiltonian.KEY_QUBIT_MAPPING: - v = QubitMappingType(v) - - kwargs[k] = v - - logger.debug('init_params: %s', kwargs) - return cls(**kwargs) - def run(self, qmolecule): logger.debug('Processing started...') # Save these values for later combination with the quantum computation result @@ -255,13 +228,14 @@ def run(self, qmolecule): self._two_qubit_reduction) logger.debug(' num paulis: %s, num qubits: %s', len(qubit_op.paulis), qubit_op.num_qubits) - algo_input = EnergyInput(qubit_op) + + aux_ops = [] def _add_aux_op(aux_op): - algo_input.add_aux_op( + aux_ops.append( Hamiltonian._map_fermionic_operator_to_qubit(aux_op, self._qubit_mapping, new_nel, self._two_qubit_reduction)) - logger.debug(' num paulis: %s', len(algo_input.aux_ops[-1].paulis)) + logger.debug(' num paulis: %s', len(aux_ops[-1].paulis)) logger.debug('Creating aux op for Number of Particles') _add_aux_op(fer_op.total_particle_number()) @@ -298,9 +272,9 @@ def _dipole_op(dipole_integrals, axis): op_dipole_z, self._z_dipole_shift, self._ph_z_dipole_shift = \ _dipole_op(qmolecule.z_dipole_integrals, 'z') - algo_input.add_aux_op(op_dipole_x) - algo_input.add_aux_op(op_dipole_y) - algo_input.add_aux_op(op_dipole_z) + aux_ops.append(op_dipole_x) + aux_ops.append(op_dipole_y) + aux_ops.append(op_dipole_z) logger.info('Molecule num electrons: %s, remaining for processing: %s', [num_alpha, num_beta], new_nel) @@ -316,7 +290,7 @@ def _dipole_op(dipole_integrals, axis): if self._qubit_mapping == 'parity' else False) logger.debug('Processing complete ready to run algorithm') - return algo_input.qubit_op, algo_input.aux_ops + return qubit_op, aux_ops # Called by public superclass method process_algorithm_result to complete specific processing def _process_algorithm_result(self, algo_result): diff --git a/qiskit/chemistry/drivers/__init__.py b/qiskit/chemistry/drivers/__init__.py index 0d3414e01c..a8a9dc3e67 100644 --- a/qiskit/chemistry/drivers/__init__.py +++ b/qiskit/chemistry/drivers/__init__.py @@ -78,13 +78,6 @@ """ from ._basedriver import BaseDriver, UnitsType, HFMethodType -from ._discover_driver import (DRIVERS_ENTRY_POINT, - refresh_drivers, - register_driver, - deregister_driver, - get_driver_class, - get_driver_configuration, - local_drivers) from .gaussiand import GaussianDriver from .hdf5d import HDF5Driver from .psi4d import PSI4Driver @@ -94,13 +87,6 @@ __all__ = ['BaseDriver', 'UnitsType', 'HFMethodType', - 'DRIVERS_ENTRY_POINT', - 'refresh_drivers', - 'register_driver', - 'deregister_driver', - 'get_driver_class', - 'get_driver_configuration', - 'local_drivers', 'GaussianDriver', 'HDF5Driver', 'PSI4Driver', diff --git a/qiskit/chemistry/drivers/_basedriver.py b/qiskit/chemistry/drivers/_basedriver.py index 179b9bacb3..7d6a314367 100644 --- a/qiskit/chemistry/drivers/_basedriver.py +++ b/qiskit/chemistry/drivers/_basedriver.py @@ -23,7 +23,9 @@ import copy from enum import Enum import logging -from qiskit.aqua.parser import JSONSchema +import numpy as np +import jsonschema +from qiskit.chemistry import QiskitChemistryError logger = logging.getLogger(__name__) @@ -82,19 +84,27 @@ def check_driver_valid(): pass def validate(self, args_dict): - """ validate driver input """ + """ validate input """ schema_dict = self.CONFIGURATION.get('input_schema', None) if schema_dict is None: return - json_schema = JSONSchema(schema_dict) - schema_property_names = json_schema.get_default_section_names() + properties_dict = schema_dict.get('properties', None) + if properties_dict is None: + return + json_dict = {} - for property_name in schema_property_names: + for property_name, _ in properties_dict.items(): if property_name in args_dict: - json_dict[property_name] = args_dict[property_name] - - json_schema.validate(json_dict) + value = args_dict[property_name] + if isinstance(value, np.ndarray): + value = value.tolist() + + json_dict[property_name] = value + try: + jsonschema.validate(json_dict, schema_dict) + except jsonschema.exceptions.ValidationError as vex: + raise QiskitChemistryError(vex.message) @property def work_path(self): diff --git a/qiskit/chemistry/drivers/_discover_driver.py b/qiskit/chemistry/drivers/_discover_driver.py deleted file mode 100644 index 3b7a77780f..0000000000 --- a/qiskit/chemistry/drivers/_discover_driver.py +++ /dev/null @@ -1,289 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" Driver Classes Discovery """ - -import os -import logging -import pkgutil -import importlib -import inspect -import copy -from collections import namedtuple -import pkg_resources -from qiskit.chemistry import QiskitChemistryError -from ._basedriver import BaseDriver - -logger = logging.getLogger(__name__) - -DRIVERS_ENTRY_POINT = 'qiskit.chemistry.drivers' - -_NAMES_TO_EXCLUDE = [os.path.basename(__file__)] - -_FOLDERS_TO_EXCLUDE = ['__pycache__', 'gauopen'] - - -class RegistryChemDriver: - """Contains Registered Chemistry Driver.""" - - REGISTERED_DRIVER = namedtuple( - 'REGISTERED_DRIVER', ['name', 'cls', 'configuration']) - - def __init__(self) -> None: - self._discovered = False - self._registry = {} - - @property - def discovered(self): - """ Returns discovered flag """ - return self._discovered - - def set_discovered(self): - """ Set registry as discovered """ - self._discovered = True - - @property - def registry(self): - """ Return registry dictionary """ - return self._registry - - def reset(self): - """ reset registry data """ - self._discovered = False - self._registry = {} - - -# Registry Global Instance -_REGISTRY_CHEM_DRIVER = RegistryChemDriver() - - -def refresh_drivers(): - """ - Attempts to rediscover all driver modules - """ - _REGISTRY_CHEM_DRIVER.reset() - _REGISTRY_CHEM_DRIVER.set_discovered() - _discover_local_drivers() - _discover_entry_pt_chem_drivers() - if logger.isEnabledFor(logging.DEBUG): - logger.debug("Found: drivers %s", local_drivers()) - - -def _discover_on_demand(): - """ - Attempts to discover drivers modules, if not already discovered - """ - if not _REGISTRY_CHEM_DRIVER.discovered: - _REGISTRY_CHEM_DRIVER.reset() - _REGISTRY_CHEM_DRIVER.set_discovered() - _discover_local_drivers() - _discover_entry_pt_chem_drivers() - if logger.isEnabledFor(logging.DEBUG): - logger.debug("Found: has drivers %s ", local_drivers()) - - -def _discover_entry_pt_chem_drivers(): - """ - Discovers the chemistry driver modules defined by entry_points in setup - and attempts to register them. Chem.Drivers modules should subclass BaseDriver Base class. - """ - for entry_point in pkg_resources.iter_entry_points(DRIVERS_ENTRY_POINT): - # first calls require and log any errors returned due to dependencies mismatches - try: - entry_point.require() - except Exception as ex: # pylint: disable=broad-except - logger.warning("Entry point '%s' requirements issue: %s", entry_point, str(ex)) - - # now call resolve and try to load entry point - try: - e_p = entry_point.resolve() - _registered = False - if not inspect.isabstract(e_p) and issubclass(e_p, BaseDriver): - _register_driver(e_p) - _registered = True - logger.debug( - "Registered entry point chemistry driver '%s' class '%s'", entry_point, e_p) - break - - if not _registered: - logger.debug( - "Unknown entry point chemistry driver '%s' class '%s'", entry_point, e_p) - except Exception as ex: # pylint: disable=broad-except - # Ignore entry point that could not be initialized. - # print("Failed to load entry point '{}' error {}".format(entry_point, str(e))) - logger.debug("Failed to load entry point '%s' error %s", entry_point, str(ex)) - - -def _discover_local_drivers(directory=os.path.dirname(__file__), - parentname=os.path.splitext(__name__)[0], - names_to_exclude=None, - folders_to_exclude=None): - """ - Discovers the chemistry drivers modules on the directory and - subdirectories of the current module and attempts to register them. - Driver modules should subclass BaseDriver Base class. - Args: - directory (Optional(str)): Directory to search for input modules. Defaults - to the directory of this module. - parentname (Optional(str)): Module parent name. Defaults to current directory name - names_to_exclude (Optional(list[str])): File names to exclude. - Defaults to _NAMES_TO_EXCLUDE - folders_to_exclude (Optional(list[str])): Folders to exclude. - Defaults to _FOLDERS_TO_EXCLUDE - """ - names_to_exclude = names_to_exclude if names_to_exclude is not None else _NAMES_TO_EXCLUDE - folders_to_exclude = folders_to_exclude \ - if folders_to_exclude is not None else _FOLDERS_TO_EXCLUDE - for _, name, ispackage in pkgutil.iter_modules([directory]): - if ispackage: - continue - - # Iterate through the modules - if name not in names_to_exclude: # skip those modules - try: - fullname = parentname + '.' + name - modspec = importlib.util.find_spec(fullname) - mod = importlib.util.module_from_spec(modspec) - modspec.loader.exec_module(mod) - for _, cls in inspect.getmembers(mod, inspect.isclass): - # Iterate through the classes defined on the module. - try: - if cls.__module__ == modspec.name and \ - not inspect.isabstract(cls) and \ - issubclass(cls, BaseDriver): - _register_driver(cls) - importlib.import_module(fullname) - except Exception as ex: # pylint: disable=broad-except - # Ignore operator that could not be initialized. - logger.debug('Failed to load %s error %s', fullname, str(ex)) - except Exception as ex: # pylint: disable=broad-except - # Ignore operator that could not be initialized. - logger.debug('Failed to load %s error %s', fullname, str(ex)) - - for item in os.listdir(directory): - fullpath = os.path.join(directory, item) - if item not in folders_to_exclude and \ - not item.endswith('dSYM') and os.path.isdir(fullpath): - _discover_local_drivers(fullpath, parentname + '.' + item, names_to_exclude, - folders_to_exclude) - - -def register_driver(cls): - """ - Registers a driver class - Args: - cls (BaseDriver): Driver class. - Returns: - str: driver name - Raises: - QiskitChemistryError: if not derived from BaseDriver - """ - _discover_on_demand() - if not issubclass(cls, BaseDriver): - raise QiskitChemistryError( - 'Could not register class {} is not subclass of BaseDriver'.format(cls)) - - return _register_driver(cls) - - -def _register_driver(cls): - # Verify that the driver is not already registered. - if cls in [driver.cls for driver in _REGISTRY_CHEM_DRIVER.registry.values()]: - raise QiskitChemistryError('Could not register class {} is already registered'.format(cls)) - - # Verify that it has a minimal valid configuration. - try: - driver_name = cls.CONFIGURATION['name'] - except (LookupError, TypeError): - raise QiskitChemistryError('Could not register driver: invalid configuration') - - # Verify that the driver is valid - check_driver_valid = getattr(cls, 'check_driver_valid', None) - if check_driver_valid is not None: - try: - check_driver_valid() - except Exception as ex: # pylint: disable=broad-except - logger.debug(str(ex)) - raise QiskitChemistryError( - 'Could not register class {}. Name {} is not valid'.format( - cls, driver_name)) from ex - - if driver_name in _REGISTRY_CHEM_DRIVER.registry: - raise QiskitChemistryError( - 'Could not register class {}. Name {} {} is already registered'.format( - cls, driver_name, _REGISTRY_CHEM_DRIVER.registry[driver_name].cls)) - - # Append the driver to the `registered_classes` dict. - _REGISTRY_CHEM_DRIVER.registry[driver_name] = \ - RegistryChemDriver.REGISTERED_DRIVER(driver_name, cls, copy.deepcopy(cls.CONFIGURATION)) - return driver_name - - -def deregister_driver(driver_name): - """Remove driver from list of available drivers - Args: - driver_name (str): name of driver to unregister - Raises: - QiskitChemistryError: if name is not registered. - """ - _discover_on_demand() - - if driver_name not in _REGISTRY_CHEM_DRIVER.registry: - raise QiskitChemistryError('Could not deregister {} not registered'.format(driver_name)) - - _REGISTRY_CHEM_DRIVER.registry.pop(driver_name) - - -def get_driver_class(driver_name): - """Return the class object for the named module. - Args: - driver_name (str): the module name - Returns: - BaseDriver: class object for module - Raises: - QiskitChemistryError: if module is unavailable - """ - _discover_on_demand() - - if driver_name not in _REGISTRY_CHEM_DRIVER.registry: - raise QiskitChemistryError('{} not registered'.format(driver_name)) - - return _REGISTRY_CHEM_DRIVER.registry[driver_name].cls - - -def get_driver_configuration(driver_name): - """Return the configuration for the named module. - Args: - driver_name (str): the module name - Returns: - dict: configuration dict - Raises: - QiskitChemistryError: if module is unavailable - """ - _discover_on_demand() - - if driver_name not in _REGISTRY_CHEM_DRIVER.registry: - raise QiskitChemistryError('{} not registered'.format(driver_name)) - - return copy.deepcopy(_REGISTRY_CHEM_DRIVER.registry[driver_name].configuration) - - -def local_drivers(): - """ - Accesses chemistry drivers names - Returns: - list[str]: chemistry drivers names - """ - _discover_on_demand() - return [input.name for input in _REGISTRY_CHEM_DRIVER.registry.values()] diff --git a/qiskit/chemistry/parser/__init__.py b/qiskit/chemistry/parser/__init__.py deleted file mode 100644 index e853196c11..0000000000 --- a/qiskit/chemistry/parser/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" Input Parser modules """ - -from ._inputparser import InputParser - -__all__ = ['InputParser'] diff --git a/qiskit/chemistry/parser/_inputparser.py b/qiskit/chemistry/parser/_inputparser.py deleted file mode 100644 index 3f8ac3e17d..0000000000 --- a/qiskit/chemistry/parser/_inputparser.py +++ /dev/null @@ -1,683 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" Input Parser """ - -import logging -import pprint -import ast -import os -import copy -import json -from collections import OrderedDict -from qiskit.aqua.parser import BaseParser -from qiskit.aqua import local_pluggables_types, PluggableType -from qiskit.chemistry import QiskitChemistryError, ChemistryProblem -from qiskit.aqua.parser import JSONSchema -from qiskit.chemistry.core import local_chemistry_operators, get_chem_operator_config -from qiskit.chemistry.drivers import local_drivers, get_driver_configuration - -logger = logging.getLogger(__name__) - - -class InputParser(BaseParser): - """Chemistry input file parser.""" - - OPERATOR = 'operator' - DRIVER = 'driver' - AUTO_SUBSTITUTIONS = 'auto_substitutions' - _OLD_ENABLE_SUBSTITUTIONS = 'enable_substitutions' - - _START_COMMENTS = ['#', '%'] - _START_SECTION = '&' - _END_SECTION = '&end' - _PROPVALUE_SEPARATOR = '=' - - _OPTIMIZER = 'optimizer' - _VARIATIONAL_FORM = 'variational_form' - _HDF5_INPUT = 'hdf5_input' - HDF5_OUTPUT = 'hdf5_output' - _DRIVER_NAMES = None - - def __init__(self, input_value=None): - """Create Parser object.""" - json_schema = JSONSchema(os.path.join(os.path.dirname(__file__), 'input_schema.json')) - - # get some properties from algorithms schema - json_schema.copy_section_from_aqua_schema(PluggableType.ALGORITHM.value) - json_schema.copy_section_from_aqua_schema(JSONSchema.BACKEND) - json_schema.copy_section_from_aqua_schema(JSONSchema.PROBLEM) - json_schema.schema['properties'][JSONSchema.PROBLEM]['properties'][ - InputParser.AUTO_SUBSTITUTIONS] = { - "type": "boolean", - "default": "true" - } - super().__init__(json_schema) - - # limit Chemistry problems to only valid for chemistry - chemistry_problems = [problem for problem in - self.json_schema.get_property_default_values(JSONSchema.PROBLEM, - JSONSchema.NAME) - if any(problem == item.value for item in ChemistryProblem)] - self.json_schema.schema['properties'][JSONSchema.PROBLEM]['properties'][ - JSONSchema.NAME]['enum'] = chemistry_problems - self.json_schema.commit_changes() - # --- - - self._inputdict = None - if input_value is not None: - if isinstance(input_value, dict): - self._inputdict = input_value - elif isinstance(input_value, str): - self._filename = input_value - else: - raise QiskitChemistryError("Invalid parser input type.") - - self._section_order = [JSONSchema.NAME, - JSONSchema.PROBLEM, - InputParser.DRIVER, - InputParser._UNKNOWN, - InputParser.OPERATOR, - PluggableType.ALGORITHM.value] - for pluggable_type in local_pluggables_types(): - if pluggable_type not in [PluggableType.INPUT, PluggableType.ALGORITHM]: - self._section_order.append(pluggable_type.value) - - self._section_order.extend([JSONSchema.BACKEND, InputParser._UNKNOWN]) - - jsonfile = os.path.join(os.path.dirname(__file__), 'substitutions.json') - with open(jsonfile) as json_file: - self._substitutions = json.load(json_file) - - def parse(self): - """Parse the data.""" - if self._inputdict is None: - if self._filename is None: - raise QiskitChemistryError("Missing input file") - - section = None - self._sections = OrderedDict() - contents = '' - with open(self._filename, 'rt', encoding="utf8", errors='ignore') as file: - for line in file: - contents += line - section = self._process_line(section, line) - - if self._sections: - # convert to aqua compatible json dictionary based on schema - driver_configs = OrderedDict() - for driver_name in local_drivers(): - driver_configs[driver_name.lower()] = get_driver_configuration(driver_name) - - json_dict = OrderedDict() - for section_name, section in self._sections.items(): - types = [] - if section_name.lower() in driver_configs: - config = driver_configs[section_name.lower()] - input_schema = copy.deepcopy(config['input_schema']) \ - if 'input_schema' in config else {'type': 'string'} - if 'type' not in input_schema: - input_schema['type'] = 'string' - - types = [input_schema['type']] - else: - types = self.get_section_types(section_name.lower()) - - if 'string' in types: - json_dict[section_name] = section['data'] if 'data' in section else '' - else: - json_dict[section_name] = section['properties'] \ - if 'properties' in section else OrderedDict() - - self._sections = json_dict - else: - contents = contents.strip().replace('\n', '').replace('\r', '') - if contents: - # check if input file was dictionary - try: - v = ast.literal_eval(contents) - if isinstance(v, dict): - self._inputdict = json.loads(json.dumps(v)) - self._load_parser_from_dict() - except Exception: # pylint: disable=broad-except - pass - else: - self._load_parser_from_dict() - - # check for old enable_substitutions name - old_enable_substitutions = self.get_section_property(JSONSchema.PROBLEM, - InputParser._OLD_ENABLE_SUBSTITUTIONS) - if old_enable_substitutions is not None: - self.delete_section_property(JSONSchema.PROBLEM, InputParser._OLD_ENABLE_SUBSTITUTIONS) - self.set_section_property(JSONSchema.PROBLEM, - InputParser.AUTO_SUBSTITUTIONS, old_enable_substitutions) - - self.json_schema.update_backend_schema(self) - self.json_schema.update_pluggable_schemas(self) - self._update_driver_input_schemas() - self._update_operator_input_schema() - self._sections = self._order_sections(self._sections) - self._original_sections = copy.deepcopy(self._sections) - - def get_default_sections(self): - properties = self.json_schema.get_default_sections() - driver_name = self.get_section_property(InputParser.DRIVER, JSONSchema.NAME) - if driver_name is not None: - properties[driver_name.lower()] = { - "type": "object" - } - return properties - - def merge_default_values(self): - section_names = self.get_section_names() - if JSONSchema.NAME not in section_names: - self.set_section(JSONSchema.NAME) - - if PluggableType.ALGORITHM.value in section_names: - if JSONSchema.PROBLEM not in section_names: - self.set_section(JSONSchema.PROBLEM) - - self.json_schema.update_backend_schema(self) - self.json_schema.update_pluggable_schemas(self) - self._merge_dependencies() - self._update_driver_sections() - self._update_driver_input_schemas() - self._update_operator_input_schema() - - # do not merge any pluggable that doesn't have name default in schema - default_section_names = [] - pluggable_type_names = [pluggable_type.value for pluggable_type in local_pluggables_types()] - for section_name in self.get_default_section_names(): - if section_name in pluggable_type_names: - if self.get_property_default_value(section_name, JSONSchema.NAME) is not None: - default_section_names.append(section_name) - else: - default_section_names.append(section_name) - - section_names = set(self.get_section_names()) | set(default_section_names) - for section_name in section_names: - if section_name not in self._sections: - self.set_section(section_name) - - new_properties = self.get_section_default_properties(section_name) - if new_properties is not None: - if self.section_is_text(section_name): - text = self.get_section_text(section_name) - if not text and \ - isinstance(new_properties, str) and \ - new_properties and \ - text != new_properties: - self.set_section_data(section_name, new_properties) - else: - properties = self.get_section_properties(section_name) - new_properties.update(properties) - self.set_section_properties(section_name, new_properties) - - self._sections = self._order_sections(self._sections) - - def validate_merge_defaults(self): - super().validate_merge_defaults() - self._validate_operator_problem() - - def save_to_file(self, file_name): - if file_name is None: - raise QiskitChemistryError('Missing file path') - - file_name = file_name.strip() - if not file_name: - raise QiskitChemistryError('Missing file path') - - prev_filename = self.get_filename() - sections = copy.deepcopy(self.get_sections()) - if prev_filename is not None: - prev_dirname = os.path.dirname(os.path.realpath(prev_filename)) - dirname = os.path.dirname(os.path.realpath(file_name)) - if prev_dirname != dirname: - InputParser._from_relative_to_abs_paths(sections, prev_filename) - - contents = '' - last_index = len(sections) - 1 - for i, (section_name, section) in enumerate(sections.items()): - contents += '{}{}'.format(InputParser._START_SECTION, section_name) - if self.section_is_text(section_name): - value = section if isinstance(section, str) \ - else json.dumps(section, sort_keys=True, indent=4) - contents += '\n{}'.format(value) - else: - for k, v in section.items(): - contents += '\n {}{}{}'.format(k, InputParser._PROPVALUE_SEPARATOR, str(v)) - - contents += '\n{}'.format(InputParser._END_SECTION) - if i < last_index: - contents += '\n\n' - - with open(file_name, 'w') as file: - print(contents, file=file) - - def delete_section(self, section_name): - """ - Args: - section_name (str): the name of the section, case insensitive - """ - section_name = JSONSchema.format_section_name(section_name).lower() - driver_name = None - if section_name == InputParser.DRIVER: - driver_name = self.get_section_property(section_name, JSONSchema.NAME) - if driver_name is not None: - driver_name = driver_name.strip().lower() - - super().delete_section(section_name) - if driver_name is not None: - # delete correspondent driver name section - super().delete_section(driver_name) - - self._update_driver_input_schemas() - self._update_operator_input_schema() - - def post_set_section_property(self, section_name, property_name): - property_name = JSONSchema.format_property_name(property_name) - if property_name == JSONSchema.NAME: - section_name = JSONSchema.format_section_name(section_name).lower() - value = self.get_section_property(section_name, property_name) - if InputParser.OPERATOR == section_name: - self._update_operator_input_schema() - elif JSONSchema.PROBLEM == section_name: - self._update_operator_problem() - self._update_operator_input_schema() - # remove properties that are not valid for this operator - default_properties = self.get_section_default_properties(InputParser.OPERATOR) - if isinstance(default_properties, dict): - properties = self.get_section_properties(InputParser.OPERATOR) - for p_name in list(properties.keys()): - if p_name != JSONSchema.NAME and p_name not in default_properties: - self.delete_section_property(InputParser.OPERATOR, p_name) - elif value is not None: - value = str(value).lower().strip() - if value and self.section_is_driver(value): - self._update_driver_input_schemas() - self._update_driver_sections() - - def is_substitution_allowed(self): - """ check if substitutions were allowed for this data """ - auto_substitutions = self.get_property_default_value(JSONSchema.PROBLEM, - InputParser.AUTO_SUBSTITUTIONS) - auto_substitutions = self.get_section_property(JSONSchema.PROBLEM, - InputParser.AUTO_SUBSTITUTIONS, - auto_substitutions) - if auto_substitutions is None: - auto_substitutions = True - - return auto_substitutions - - def check_if_substitution_key(self, section_name, property_names): - """ return property names that need to be substituted """ - result = [(property_name, False) for property_name in property_names] - if not self.is_substitution_allowed(): - return result - - section_name = JSONSchema.format_section_name(section_name).lower() - property_names = [JSONSchema.format_property_name(property_name) - for property_name in property_names] - section_property_name = self.get_property_default_value(section_name, JSONSchema.NAME) - section_property_name = self.get_section_property(section_name, - JSONSchema.NAME, section_property_name) - for key in self._substitutions.keys(): - key_items = key.split('.') - if len(key_items) == 3 and \ - key_items[0] == section_name and \ - key_items[1] == section_property_name and \ - key_items[2] in property_names: - result[property_names.index(key_items[2])] = ( - key_items[2], True) - continue - - return result - - def process_substitutions(self, substitutions=None): - """ change property values by their corresponding substitutions """ - if substitutions is not None and not isinstance(substitutions, dict): - raise QiskitChemistryError( - 'Invalid substitution parameter: {}'.format(substitutions)) - - if not self.is_substitution_allowed(): - return {} - - result = {} - for key, value in self._substitutions.items(): - key_items = key.split('.') - if len(key_items) != 3: - raise QiskitChemistryError('Invalid substitution key: {}'.format(key)) - - name = self.get_property_default_value(key_items[0], JSONSchema.NAME) - name = self.get_section_property(key_items[0], JSONSchema.NAME, name) - if name != key_items[1]: - continue - - value_set = False - value_items = value.split('.') - if len(value_items) == 3: - name = self.get_section_property(value_items[0], JSONSchema.NAME) - if name == value_items[1]: - v = self.get_property_default_value(value_items[0], value_items[2]) - v = self.get_section_property(value_items[0], value_items[2], v) - if v is not None: - self.set_section_property(key_items[0], key_items[2], v) - result[key] = v - value_set = True - - if value_set or substitutions is None: - continue - - if value in substitutions: - self.set_section_property(key_items[0], key_items[2], substitutions[value]) - result[key] = substitutions[value] - - return result - - def _process_line(self, section, line): - strip_line = line.strip() - if not strip_line: - if section is not None: - section['data'].append(line) - - return section - - if strip_line.lower().startswith(InputParser._END_SECTION): - if section is not None: - self._sections[section[JSONSchema.NAME]] = self._process_section(section) - return None - - if strip_line.startswith(InputParser._START_SECTION): - if section is not None: - raise QiskitChemistryError( - 'New section "{0}" starting before the end of previuos section "{1}"'.format( - line, section[JSONSchema.NAME])) - - return OrderedDict([(JSONSchema.NAME, strip_line[1:].lower()), ('data', [])]) - - if section is None: - return section - - section['data'].append(line) - - return section - - def _process_section(self, section): - contents = '' - sep_pos = -len(os.linesep) - last_index = len(section['data']) - 1 - for i, line in enumerate(section['data']): - key, value = self._get_key_value(line) - if key is not None and value is not None: - if 'properties' not in section: - section['properties'] = OrderedDict() - - section['properties'][key] = value - - if i == last_index: - if len(line) >= len(os.linesep) and line[sep_pos:] == os.linesep: - line = line[:sep_pos] - - contents += line - - section['data'] = contents - return section - - @staticmethod - def _get_key_value(line): - strip_line = line.strip() - pos = -1 - for start_comment in InputParser._START_COMMENTS: - pos = strip_line.find(start_comment) - if pos >= 0: - break - - if pos == 0: - return (None, None) - - if pos > 0: - strip_line = strip_line[:pos].strip() - - pos = strip_line.find(InputParser._PROPVALUE_SEPARATOR) - if pos > 0: - key = strip_line[0:pos].strip() - value = strip_line[pos + 1:].strip() - return (key, JSONSchema.get_value(value)) - - return (None, None) - - @staticmethod - def get_operator_problems(input_name): - """ get problems names related to this operator """ - config = get_chem_operator_config(input_name) - if 'problems' in config: - return config['problems'] - - return [] - - def _load_parser_from_dict(self): - self._sections = OrderedDict() - for section_name, value in self._inputdict.items(): - section_name = JSONSchema.format_section_name(section_name).lower() - if isinstance(value, dict): - self._sections[section_name] = OrderedDict(value) - elif isinstance(value, (list, str)): - if isinstance(value, list): - self._sections[section_name] = '\n'.join(str(e) for e in value) - else: - self._sections[section_name] = value - else: - raise QiskitChemistryError( - "Invalid parser input type for section {}".format(section_name)) - - def _update_operator_input_schema(self): - # find operator - default_name = self.get_property_default_value(InputParser.OPERATOR, JSONSchema.NAME) - operator_name = self.get_section_property(InputParser.OPERATOR, - JSONSchema.NAME, default_name) - if operator_name is None: - # find the first valid input for the problem - problem_name = self.get_section_property(JSONSchema.PROBLEM, JSONSchema.NAME) - if problem_name is None: - problem_name = self.get_property_default_value(JSONSchema.PROBLEM, JSONSchema.NAME) - - if problem_name is None: - raise QiskitChemistryError("No algorithm 'problem' section found on input.") - - for name in local_chemistry_operators(): - if problem_name in self.get_operator_problems(name): - # set to the first input to solve the problem - operator_name = name - break - - if operator_name is None: - # just remove from schema if none solves the problem - if InputParser.OPERATOR in self.json_schema.schema['properties']: - del self.json_schema.schema['properties'][InputParser.OPERATOR] - - return - - if default_name is None: - default_name = operator_name - - config = {} - try: - config = get_chem_operator_config(operator_name) - except Exception: # pylint: disable=broad-except - pass - - input_schema = config['input_schema'] if 'input_schema' in config else {} - properties = input_schema['properties'] if 'properties' in input_schema else {} - properties[JSONSchema.NAME] = {'type': 'string'} - required = input_schema['required'] if 'required' in input_schema else [] - additional_properties = input_schema['additionalProperties'] \ - if 'additionalProperties' in input_schema else True - if default_name is not None: - properties[JSONSchema.NAME]['default'] = default_name - required.append(JSONSchema.NAME) - - if InputParser.OPERATOR not in self.json_schema.schema['properties']: - self.json_schema.schema['properties'][InputParser.OPERATOR] = {'type': 'object'} - - self.json_schema.schema['properties'][InputParser.OPERATOR]['properties'] = properties - self.json_schema.schema['properties'][InputParser.OPERATOR]['required'] = required - self.json_schema.schema['properties'][InputParser.OPERATOR]['additionalProperties'] = \ - additional_properties - - def _update_driver_input_schemas(self): - # find driver name - default_name = self.get_property_default_value(InputParser.DRIVER, JSONSchema.NAME) - driver_name = self.get_section_property(InputParser.DRIVER, JSONSchema.NAME, default_name) - if driver_name is not None: - driver_name = driver_name.strip().lower() - - for name in local_drivers(): - name_orig = name - name = name.lower() - if driver_name is not None and driver_name == name: - config = get_driver_configuration(name_orig) - input_schema = copy.deepcopy(config['input_schema']) \ - if 'input_schema' in config else {'type': 'object'} - if '$schema' in input_schema: - del input_schema['$schema'] - if 'id' in input_schema: - del input_schema['id'] - - self.json_schema.schema['properties'][driver_name] = input_schema - else: - if name in self.json_schema.schema['properties']: - del self.json_schema.schema['properties'][name] - - @staticmethod - def _load_driver_names(): - if InputParser._DRIVER_NAMES is None: - InputParser._DRIVER_NAMES = [name.lower() for name in local_drivers()] - - def _validate_operator_problem(self): - operator_name = self.get_section_property(InputParser.OPERATOR, JSONSchema.NAME) - if operator_name is None: - return - - problem_name = self.get_section_property(JSONSchema.PROBLEM, JSONSchema.NAME) - if problem_name is None: - problem_name = self.get_property_default_value(JSONSchema.PROBLEM, JSONSchema.NAME) - - if problem_name is None: - raise QiskitChemistryError("No algorithm 'problem' section found on input.") - - problems = InputParser.get_operator_problems(operator_name) - if problem_name not in problems: - raise QiskitChemistryError( - "Problem: {} not in the list of problems: {} for operator: {}.".format( - problem_name, problems, operator_name)) - - def to_dictionary(self): - """ export data to python dictionary """ - dictionary = OrderedDict() - for section_name in self.get_section_names(): - if self.section_is_text(section_name): - dictionary[section_name] = self.get_section_text(section_name).splitlines() - else: - dictionary[section_name] = self.get_section_properties(section_name) - - return dictionary - - def export_dictionary(self, file_name): - """ export data to python dictionary, saving to file """ - if file_name is None: - raise QiskitChemistryError('Missing file path') - - file_name = file_name.strip() - if not file_name: - raise QiskitChemistryError('Missing file path') - - value = json.loads(json.dumps(self.to_dictionary())) - value = pprint.pformat(value, indent=4) - with open(file_name, 'w') as file: - print(value, file=file) - - @staticmethod - def _from_relative_to_abs_paths(sections, filename): - directory = os.path.dirname(filename) - for section_name, section in sections.items(): - if isinstance(section, dict): - for key, value in section.items(): - if key == InputParser._HDF5_INPUT: - if value is not None and not os.path.isabs(value): - value = os.path.abspath(os.path.join(directory, value)) - InputParser._set_section_property(sections, - section_name, - key, value, ['string']) - - def section_is_driver(self, section_name): - """ check if this section is a chemistry driver """ - section_name = JSONSchema.format_section_name(section_name).lower() - InputParser._load_driver_names() - driver_names = InputParser._DRIVER_NAMES \ - if isinstance(InputParser._DRIVER_NAMES, list) else [] - return section_name in driver_names - - def _update_operator_problem(self): - problem_name = self.get_section_property(JSONSchema.PROBLEM, JSONSchema.NAME) - if problem_name is None: - problem_name = self.get_property_default_value(JSONSchema.PROBLEM, JSONSchema.NAME) - - if problem_name is None: - raise QiskitChemistryError("No algorithm 'problem' section found on input.") - - operator_name = self.get_section_property(InputParser.OPERATOR, JSONSchema.NAME) - if operator_name is not None and \ - problem_name in InputParser.get_operator_problems(operator_name): - return - - for operator_name in local_chemistry_operators(): - if problem_name in self.get_operator_problems(operator_name): - # set to the first input to solve the problem - self.set_section_property(InputParser.OPERATOR, JSONSchema.NAME, operator_name) - return - - # no input solve this problem, remove section - self.delete_section(InputParser.OPERATOR) - - def _update_driver_sections(self): - driver_name = self.get_section_property(InputParser.DRIVER, JSONSchema.NAME) - if driver_name is not None: - driver_name = driver_name.strip().lower() - - for name in local_drivers(): - name = name.lower() - if driver_name is not None and driver_name == name: - continue - - if name in self._sections: - del self._sections[name] - - if driver_name is not None and driver_name not in self._sections: - self.set_section(driver_name) - value = self.get_section_default_properties(driver_name) - if isinstance(value, dict): - for property_name, property_value in value.items(): - self.set_section_property(driver_name, property_name, property_value) - else: - if value is None: - types = self.get_section_types(driver_name) - if 'null' not in types: - if 'string' in types: - value = '' - elif 'object' in types: - value = {} - elif 'array' in types: - value = [] - - self.set_section_data(driver_name, value) diff --git a/qiskit/chemistry/parser/input_schema.json b/qiskit/chemistry/parser/input_schema.json deleted file mode 100644 index e284ec3958..0000000000 --- a/qiskit/chemistry/parser/input_schema.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "id": "input_schema.json", - - "definitions": { - "name": { - "type": "string", - "default": "Quantum Chemistry experiment" - }, - "driver": { - "type": "object", - "properties": { - "name": { - "type": "string", - "default": "HDF5" - }, - "hdf5_output": { - "type": ["string","null"], - "default" : null - } - }, - "required": ["name"], - "additionalProperties": false - } - }, - - "type": "object", - "properties": { - "name": { "$ref": "#/definitions/name" }, - "driver": { "$ref": "#/definitions/driver" } - }, - "required": ["driver"], - "additionalProperties": false -} \ No newline at end of file diff --git a/qiskit/chemistry/parser/substitutions.json b/qiskit/chemistry/parser/substitutions.json deleted file mode 100644 index aa417475e8..0000000000 --- a/qiskit/chemistry/parser/substitutions.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "initial_state.HartreeFock.qubit_mapping" : "operator.hamiltonian.qubit_mapping", - "initial_state.HartreeFock.two_qubit_reduction" : "two_qubit_reduction", - "initial_state.HartreeFock.num_particles" : "num_particles", - "initial_state.HartreeFock.num_orbitals" : "num_orbitals", - "variational_form.UCCSD.qubit_mapping" : "operator.hamiltonian.qubit_mapping", - "variational_form.UCCSD.two_qubit_reduction" : "two_qubit_reduction", - "variational_form.UCCSD.num_particles" : "num_particles", - "variational_form.UCCSD.num_orbitals" : "num_orbitals", - "algorithm.QEomVQE.qubit_mapping" : "operator.hamiltonian.qubit_mapping", - "algorithm.QEomVQE.two_qubit_reduction" : "two_qubit_reduction", - "algorithm.QEomVQE.num_particles" : "num_particles", - "algorithm.QEomVQE.num_orbitals" : "num_orbitals", - "algorithm.QEomEE.qubit_mapping" : "operator.hamiltonian.qubit_mapping", - "algorithm.QEomEE.two_qubit_reduction" : "two_qubit_reduction", - "algorithm.QEomEE.num_particles" : "num_particles", - "algorithm.QEomEE.num_orbitals" : "num_orbitals" -} \ No newline at end of file diff --git a/qiskit/chemistry/qiskit_chemistry.py b/qiskit/chemistry/qiskit_chemistry.py deleted file mode 100644 index a8d106d1cc..0000000000 --- a/qiskit/chemistry/qiskit_chemistry.py +++ /dev/null @@ -1,267 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" Qiskit Chemistry Main Entry points """ - -import json -import os -import copy -import pprint -import logging -import warnings -from qiskit.providers import BaseBackend -from qiskit.chemistry.drivers import local_drivers, get_driver_class -from qiskit.aqua import QiskitAqua, get_provider_from_backend, aqua_globals -from qiskit.aqua.input import EnergyInput -from qiskit.chemistry.parser import InputParser -from qiskit.aqua.parser import JSONSchema -from qiskit.chemistry.core import get_chemistry_operator_class -from .qiskit_chemistry_error import QiskitChemistryError - -logger = logging.getLogger(__name__) - - -def run_experiment(params, output=None, backend=None): - """ - Run Chemistry from params. - - Using params and returning a result dictionary - - 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 containing result of chemistry computation - """ - qiskit_chemistry = QiskitChemistry() - return qiskit_chemistry.run(params, output, backend) - - -def run_driver_to_json(params, jsonfile='algorithm.json'): - """ - Runs the Aqua Chemistry driver only - - Args: - params (Union(dictionary/filename)): Chemistry input data - jsonfile (filename): Name of file that will contain the Aqua JSON input data - - Returns: - dict: Result dictionary containing the jsonfile name - """ - qiskit_chemistry = QiskitChemistry() - qiskit_chemistry.run_driver(params) - data = copy.deepcopy(qiskit_chemistry.qiskit_aqua.params) - data['input'] = qiskit_chemistry.qiskit_aqua.algorithm_input.to_params() - data['input']['name'] = qiskit_chemistry.qiskit_aqua.algorithm_input.configuration['name'] - with open(jsonfile, 'w') as file: - json.dump(data, file, sort_keys=True, indent=4) - - print("Algorithm input file saved: '{}'".format(jsonfile)) - return {'jsonfile': jsonfile} - - -class QiskitChemistry: - """Main Chemistry class.""" - - def __init__(self): - """Create an QiskitChemistry object.""" - warnings.warn(aqua_globals.CONFIG_DEPRECATION_MSG, DeprecationWarning) - 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) diff --git a/qiskit/chemistry/qiskit_chemistry_problem.py b/qiskit/chemistry/qiskit_chemistry_problem.py deleted file mode 100644 index 31472689d3..0000000000 --- a/qiskit/chemistry/qiskit_chemistry_problem.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" Chemistry Problem """ - -from enum import Enum - - -class ChemistryProblem(Enum): - """ Chemistry Problem Enum """ - ENERGY = 'energy' - EXCITED_STATES = 'excited_states' diff --git a/qiskit/finance/data_providers/_base_data_provider.py b/qiskit/finance/data_providers/_base_data_provider.py index 204f1c36f4..fe6c7dd782 100644 --- a/qiskit/finance/data_providers/_base_data_provider.py +++ b/qiskit/finance/data_providers/_base_data_provider.py @@ -24,9 +24,8 @@ import numpy as np import fastdtw - +import jsonschema from qiskit.aqua import AquaError -from qiskit.aqua.parser import JSONSchema logger = logging.getLogger(__name__) @@ -109,20 +108,21 @@ def check_driver_valid(): pass def validate(self, args_dict): - """ Validates the configuration against the input schema. N.B. Not in use at the moment. """ - + """ validate driver input """ schema_dict = self.CONFIGURATION.get('input_schema', None) if schema_dict is None: return - json_schema = JSONSchema(schema_dict) - schema_property_names = json_schema.get_default_section_names() + properties_dict = schema_dict.get('properties', None) + if properties_dict is None: + return + json_dict = {} - for property_name in schema_property_names: + for property_name, _ in properties_dict.items(): if property_name in args_dict: json_dict[property_name] = args_dict[property_name] - json_schema.validate(json_dict) + jsonschema.validate(json_dict, schema_dict) @abstractmethod def run(self): diff --git a/test/aqua/ExactEigensolver.json b/test/aqua/ExactEigensolver.json deleted file mode 100644 index 5a39fad194..0000000000 --- a/test/aqua/ExactEigensolver.json +++ /dev/null @@ -1,123 +0,0 @@ -{ - "algorithm": { - "k": 1, - "name": "ExactEigensolver" - }, - "input": { - "aux_ops": [], - "name": "EnergyInput", - "qubit_op": { - "paulis": [ - { - "coeff": { - "imag": 0.0, - "real": -0.8105479862761009 - }, - "label": "IIII" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.1721839427308565 - }, - "label": "ZIII" - }, - { - "coeff": { - "imag": 0.0, - "real": -0.22575350251540538 - }, - "label": "IZII" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.1721839427308564 - }, - "label": "IIZI" - }, - { - "coeff": { - "imag": 0.0, - "real": -0.2257535025154054 - }, - "label": "IIIZ" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.12091263358560006 - }, - "label": "ZZII" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.16892754048859018 - }, - "label": "ZIZI" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.045232799794893475 - }, - "label": "YYXX" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.045232799794893475 - }, - "label": "YYYY" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.045232799794893475 - }, - "label": "XXXX" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.045232799794893475 - }, - "label": "XXYY" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.16614543338049353 - }, - "label": "ZIIZ" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.16614543338049353 - }, - "label": "IZZI" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.174643431424422 - }, - "label": "IZIZ" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.12091263358560006 - }, - "label": "IIZZ" - } - ] - } - }, - "problem": { - "name": "energy", - "random_seed": null - } -} diff --git a/test/aqua/H2-0.735.json b/test/aqua/H2-0.735.json deleted file mode 100644 index 2257793e87..0000000000 --- a/test/aqua/H2-0.735.json +++ /dev/null @@ -1,144 +0,0 @@ -{ - "algorithm": { - "initial_point": null, - "name": "VQE" - }, - "backend": { - "name": "statevector_simulator", - "skip_transpiler": false - }, - "initial_state": { - "name": "ZERO" - }, - "problem": { - "name": "energy" - }, - "optimizer": { - "factr": 10, - "iprint": -1, - "maxfun": 1000, - "name": "L_BFGS_B" - }, - "problem": { - "name": "energy" - }, - "variational_form": { - "depth": 3, - "entanglement": "full", - "entangler_map": null, - "name": "RYRZ" - }, - "input": { - "aux_ops": [], - "name": "EnergyInput", - "qubit_op": { - "paulis": [ - { - "coeff": { - "imag": 0.0, - "real": -0.8105479862761009 - }, - "label": "IIII" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.1721839427308565 - }, - "label": "ZIII" - }, - { - "coeff": { - "imag": 0.0, - "real": -0.22575350251540538 - }, - "label": "IZII" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.1721839427308564 - }, - "label": "IIZI" - }, - { - "coeff": { - "imag": 0.0, - "real": -0.2257535025154054 - }, - "label": "IIIZ" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.12091263358560006 - }, - "label": "ZZII" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.16892754048859018 - }, - "label": "ZIZI" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.045232799794893475 - }, - "label": "YYXX" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.045232799794893475 - }, - "label": "YYYY" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.045232799794893475 - }, - "label": "XXXX" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.045232799794893475 - }, - "label": "XXYY" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.16614543338049353 - }, - "label": "ZIIZ" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.16614543338049353 - }, - "label": "IZZI" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.174643431424422 - }, - "label": "IZIZ" - }, - { - "coeff": { - "imag": 0.0, - "real": 0.12091263358560006 - }, - "label": "IIZZ" - } - ] - } - } -} diff --git a/test/aqua/integrity/__init__.py b/test/aqua/integrity/__init__.py deleted file mode 100644 index 7909fc6dac..0000000000 --- a/test/aqua/integrity/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. diff --git a/test/aqua/integrity/load_aqua.py b/test/aqua/integrity/load_aqua.py deleted file mode 100644 index 0517befa0a..0000000000 --- a/test/aqua/integrity/load_aqua.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Check if Aqua loads correctly.""" - -import traceback - - -def _exception_to_string(excp): - stack = traceback.extract_stack()[:-3] + traceback.extract_tb(excp.__traceback__) - pretty = traceback.format_list(stack) - return ''.join(pretty) + '\n {} {}'.format(excp.__class__, excp) - - -def _load_aqua(): - try: - import qiskit # pylint: disable=import-outside-toplevel - qiskit.aqua.__version__ # pylint: disable=pointless-statement - except Exception as ex: # pylint: disable=broad-except - return _exception_to_string(ex) - - return None - - -if __name__ == '__main__': - OUT = _load_aqua() - if OUT: - print(OUT) diff --git a/test/aqua/integrity/test_configuration_integrity.py b/test/aqua/integrity/test_configuration_integrity.py deleted file mode 100644 index e02fb303ea..0000000000 --- a/test/aqua/integrity/test_configuration_integrity.py +++ /dev/null @@ -1,255 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" Test Configuration Integrity """ - -import unittest -import inspect -import os -import subprocess -from test.aqua.common import QiskitAquaTestCase -import jsonschema -from qiskit.aqua import (local_pluggables_types, - local_pluggables, - get_pluggable_class, - get_pluggable_configuration, - PluggableType) -from qiskit.aqua.input import AlgorithmInput - -ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) - - -class TestConfigurationIntegrity(QiskitAquaTestCase): - """ Test Configuration Integrity """ - @staticmethod - def _minimal_ext_cmd(cmd): - # construct minimal environment - env = {} - for k in ['SYSTEMROOT', 'PATH']: - v = os.environ.get(k) - if v is not None: - env[k] = v - # LANGUAGE is used on win32 - env['LANGUAGE'] = 'C' - env['LANG'] = 'C' - env['LC_ALL'] = 'C' - proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, env=env, - cwd=os.path.join(ROOT_DIR)) - stdout, stderr = proc.communicate() - if proc.returncode > 0: - raise OSError('Command {} exited with code {}: {}'.format( - cmd, proc.returncode, stderr.strip().decode('ascii'))) - return stdout - - # TODO: disable this test for now, run locally - # because devs may have a hard time finding the cause - def disable_test_load_aqua(self): - """ load aqua test """ - try: - out = TestConfigurationIntegrity._minimal_ext_cmd( - ['python', os.path.join(ROOT_DIR, 'load_aqua.py')]) - out = out.strip().decode('ascii') - if out: - self.fail( - 'One or more qiskit imports are interfering with Aqua loading: {}'.format(out)) - except OSError as ex: - self.fail(str(ex)) - - def test_pluggable_inputs(self): - """ pluggable inputs test """ - algorithm_problems = set() - for pluggable_name in local_pluggables(PluggableType.ALGORITHM): - configuration = get_pluggable_configuration(PluggableType.ALGORITHM, pluggable_name) - if isinstance(configuration, dict): - algorithm_problems.update(configuration.get('problems', [])) - - err_msgs = [] - all_problems = set() - for pluggable_name in local_pluggables(PluggableType.INPUT): - cls = get_pluggable_class(PluggableType.INPUT, pluggable_name) - configuration = get_pluggable_configuration(PluggableType.INPUT, pluggable_name) - missing_problems = [] - if isinstance(configuration, dict): - problem_names = configuration.get('problems', []) - all_problems.update(problem_names) - for problem_name in problem_names: - if problem_name not in algorithm_problems: - missing_problems.append(problem_name) - - if missing_problems: - err_msgs.append( - "{}: No algorithm declares the problems {}.".format(cls, missing_problems)) - - invalid_problems = list(set(AlgorithmInput._PROBLEM_SET).difference(all_problems)) - if invalid_problems: - err_msgs.append("Base Class AlgorithmInput contains problems " - "{} that don't belong to any Input class.".format(invalid_problems)) - - if err_msgs: - self.fail('\n'.join(err_msgs)) - - def test_pluggable_configuration(self): - """ pluggable configuration tests """ - err_msgs = [] - for pluggable_type in local_pluggables_types(): - for pluggable_name in local_pluggables(pluggable_type): - cls = get_pluggable_class(pluggable_type, pluggable_name) - configuration = get_pluggable_configuration(pluggable_type, pluggable_name) - if not isinstance(configuration, dict): - err_msgs.append("{} configuration isn't a dictionary.".format(cls)) - continue - - if pluggable_type in [PluggableType.ALGORITHM, PluggableType.INPUT]: - if not configuration.get('problems', []): - err_msgs.append("{} missing or empty 'problems' section.".format(cls)) - - schema_found = False - for configuration_name, configuration_value in configuration.items(): - if configuration_name in ['problems', 'depends']: - if not isinstance(configuration_value, list): - err_msgs.append("{} configuration section:'{}' isn't a list.".format( - cls, configuration_name)) - continue - - if configuration_name == 'depends': - err_msgs.extend(self._validate_depends(cls, configuration_value)) - - continue - - if configuration_name == 'input_schema': - schema_found = True - if not isinstance(configuration_value, dict): - err_msgs.append( - "{} configuration section:'{}' isn't a dictionary.".format( - cls, configuration_name)) - continue - - err_msgs.extend(self._validate_schema(cls, configuration_value)) - continue - - if not schema_found: - err_msgs.append("{} configuration missing schema.".format(cls)) - - if err_msgs: - self.fail('\n'.join(err_msgs)) - - def _validate_schema(self, cls, schema): - properties = schema.get('properties', {}) - if not isinstance(properties, dict): - return ["{} configuration schema '{}' isn't a dictionary.".format(cls, 'properties')] - - try: - validator_class = jsonschema.validators.validator_for(schema) - if validator_class: - validator_class.check_schema(schema) - except Exception as ex: # pylint: disable=broad-except - return ["{} configuration schema invalid. Error: {}.".format(cls, str(ex))] - - parameters = inspect.signature(cls.__init__).parameters - err_msgs = [] - for prop_name, value in properties.items(): - if not isinstance(properties, dict): - err_msgs.append("{} configuration schema '{}/{}' isn't a dictionary.".format( - cls, 'properties', prop_name)) - continue - - parameter = parameters.get(prop_name) - if parameter is None: - # It is not mandatory that all schema parameters be in the constructor - continue - - if 'default' in value: - default_value = value['default'] - if parameter.default != inspect.Parameter.empty and \ - parameter.default != default_value: - err_msgs.append( - "{} __init__ param '{}' default value '{}' " - "different from default value '{}' " - "found on its configuration schema.".format( - cls, prop_name, parameter.default, default_value)) - else: - if parameter.default != inspect.Parameter.empty: - err_msgs.append("{} __init__ param '{}' default value '{}' missing " - "in its configuration schema.".format( - cls, prop_name, parameter.default)) - - return err_msgs - - def _validate_depends(self, cls, dependencies): - err_msgs = [] - for dependency in dependencies: - if not isinstance(dependency, dict): - err_msgs.append("{} configuration section:'{}' item isn't a dictionary.".format( - cls, 'depends')) - continue - - dependency_pluggable_type = dependency.get('pluggable_type') - if not isinstance(dependency_pluggable_type, str): - err_msgs.append("{} configuration section:'{}' item:'{}' isn't a string.".format( - cls, 'depends', 'pluggable_type')) - continue - - if not any(x for x in PluggableType if x.value == dependency_pluggable_type): - err_msgs.append("{} configuration section:'{}' item:'{}/{}' " - "doesn't exist.".format( - cls, 'depends', 'pluggable_type', dependency_pluggable_type)) - continue - - defaults = dependency.get('default') - if not isinstance(defaults, dict): - continue - - default_name = defaults.get('name') - if default_name not in local_pluggables(dependency_pluggable_type): - err_msgs.append("{} configuration section:'{}' item:'{}/{}/{}/{}' " - "not found.".format( - cls, 'depends', dependency_pluggable_type, - 'default', 'name', default_name)) - continue - - del defaults['name'] - if defaults: - err_msgs.extend(self._validate_defaults_against_schema(dependency_pluggable_type, - default_name, defaults)) - - return err_msgs - - def _validate_defaults_against_schema(self, dependency_pluggable_type, default_name, defaults): - cls = get_pluggable_class(dependency_pluggable_type, default_name) - default_config = get_pluggable_configuration(dependency_pluggable_type, default_name) - if not isinstance(default_config, dict): - return ["{} configuration isn't a dictionary.".format(cls)] - - schema = default_config.get('input_schema') - if not isinstance(default_config, dict): - return ["{} configuration schema missing or isn't a dictionary.".format(cls)] - - properties = schema.get('properties') - if not isinstance(properties, dict): - return ["{} configuration schema '{}' missing or isn't a dictionary.".format( - cls, 'properties')] - - err_msgs = [] - for default_property_name, _ in defaults.items(): - prop = properties.get(default_property_name) - if not isinstance(prop, dict): - err_msgs.append("{} configuration schema '{}/{}' " - "missing or isn't a dictionary.".format( - cls, 'properties', default_property_name)) - return err_msgs - - -if __name__ == '__main__': - unittest.main() diff --git a/test/aqua/test_exact_eigen_solver.py b/test/aqua/test_exact_eigen_solver.py index 8215f01765..f9334291ad 100644 --- a/test/aqua/test_exact_eigen_solver.py +++ b/test/aqua/test_exact_eigen_solver.py @@ -15,11 +15,8 @@ """ Test Exact Eigen solver """ import unittest -import warnings from test.aqua.common import QiskitAquaTestCase import numpy as np -from qiskit.aqua import run_algorithm, aqua_globals -from qiskit.aqua.input import EnergyInput from qiskit.aqua.algorithms import ExactEigensolver from qiskit.aqua.operators import WeightedPauliOperator @@ -28,8 +25,6 @@ class TestExactEigensolver(QiskitAquaTestCase): """ Test Exact Eigen solver """ def setUp(self): super().setUp() - warnings.filterwarnings("ignore", message=aqua_globals.CONFIG_DEPRECATION_MSG, - category=DeprecationWarning) pauli_dict = { 'paulis': [{"coeff": {"imag": 0.0, "real": -1.052373245772859}, "label": "II"}, {"coeff": {"imag": 0.0, "real": 0.39793742484318045}, "label": "ZI"}, @@ -40,38 +35,16 @@ def setUp(self): } self.qubit_op = WeightedPauliOperator.from_dict(pauli_dict) - def test_ee_via_run_algorithm(self): - """ ee via run algorithm test """ - params = { - 'algorithm': {'name': 'ExactEigensolver'} - } - result = run_algorithm(params, EnergyInput(self.qubit_op)) - self.assertAlmostEqual(result['energy'], -1.85727503) - np.testing.assert_array_almost_equal(result['energies'], [-1.85727503]) - np.testing.assert_array_almost_equal(result['eigvals'], [-1.85727503 + 0j]) - - def test_ee_via_run_algorithm_k4(self): - """ ee via run algorithm k4 test """ - params = { - 'algorithm': {'name': 'ExactEigensolver', 'k': 4} - } - result = run_algorithm(params, EnergyInput(self.qubit_op)) - self.assertAlmostEqual(result['energy'], -1.85727503) - self.assertEqual(len(result['eigvals']), 4) - self.assertEqual(len(result['eigvecs']), 4) - np.testing.assert_array_almost_equal(result['energies'], - [-1.85727503, -1.24458455, -0.88272215, -0.22491125]) - - def test_ee_direct(self): - """ ee direct test """ + def test_ee(self): + """ ee test """ algo = ExactEigensolver(self.qubit_op, k=1, aux_operators=[]) result = algo.run() self.assertAlmostEqual(result['energy'], -1.85727503) np.testing.assert_array_almost_equal(result['energies'], [-1.85727503]) np.testing.assert_array_almost_equal(result['eigvals'], [-1.85727503 + 0j]) - def test_ee_direct_k4(self): - """ ee direct k4 test """ + def test_ee_k4(self): + """ ee k4 test """ algo = ExactEigensolver(self.qubit_op, k=4, aux_operators=[]) result = algo.run() self.assertAlmostEqual(result['energy'], -1.85727503) diff --git a/test/aqua/test_exact_ls_solver.py b/test/aqua/test_exact_ls_solver.py index 26c5214eef..ea35e4eded 100644 --- a/test/aqua/test_exact_ls_solver.py +++ b/test/aqua/test_exact_ls_solver.py @@ -16,10 +16,7 @@ import unittest from test.aqua.common import QiskitAquaTestCase -import warnings import numpy as np -from qiskit.aqua import run_algorithm, aqua_globals -from qiskit.aqua.input import LinearSystemInput from qiskit.aqua.algorithms import ExactLSsolver @@ -27,46 +24,11 @@ class TestExactLSsolver(QiskitAquaTestCase): """ Test Exact LS solver """ def setUp(self): super().setUp() - warnings.filterwarnings("ignore", message=aqua_globals.CONFIG_DEPRECATION_MSG, - category=DeprecationWarning) self.matrix = [[1, 2], [2, 1]] self.vector = [1, 2] - def test_els_via_run_algorithm_full_dict(self): - """ ELS Via Run Algorithm Full Dict test """ - params = { - 'algorithm': { - 'name': 'ExactLSsolver' - }, - 'problem': { - 'name': 'linear_system' - }, - 'input': { - 'name': 'LinearSystemInput', - 'matrix': self.matrix, - 'vector': self.vector - } - } - result = run_algorithm(params) - np.testing.assert_array_almost_equal(result['solution'], [1, 0]) - np.testing.assert_array_almost_equal(result['eigvals'], [3, -1]) - - def test_els_via_run_algorithm(self): - """ ELS Via Run Algorithm test """ - params = { - 'algorithm': { - 'name': 'ExactLSsolver' - }, - 'problem': { - 'name': 'linear_system' - } - } - result = run_algorithm(params, LinearSystemInput(self.matrix, self.vector)) - np.testing.assert_array_almost_equal(result['solution'], [1, 0]) - np.testing.assert_array_almost_equal(result['eigvals'], [3, -1]) - - def test_els_direct(self): - """ ELS Direct test """ + def test_els(self): + """ ELS test """ algo = ExactLSsolver(self.matrix, self.vector) result = algo.run() np.testing.assert_array_almost_equal(result['solution'], [1, 0]) diff --git a/test/aqua/test_input_parser.py b/test/aqua/test_input_parser.py deleted file mode 100644 index ee7d2e8e30..0000000000 --- a/test/aqua/test_input_parser.py +++ /dev/null @@ -1,100 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" Test InputParser """ - -import unittest -import os -import json -import warnings -from test.aqua.common import QiskitAquaTestCase -from qiskit.aqua import AquaError, run_algorithm, aqua_globals -from qiskit.aqua.parser._inputparser import InputParser - - -class TestInputParser(QiskitAquaTestCase): - """Input Parser and algorithms tests.""" - - def setUp(self): - super().setUp() - warnings.filterwarnings("ignore", message=aqua_globals.CONFIG_DEPRECATION_MSG, - category=DeprecationWarning) - filepath = self._get_resource_path('H2-0.735.json') - 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.get_sections())) - dict2 = json.loads(json.dumps(parse.get_sections())) - 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.get_sections())) - dict2 = json.loads(json.dumps(parse.get_sections())) - 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_run_algorithm(self): - """ run algorithm test """ - filepath = self._get_resource_path('ExactEigensolver.json') - params = None - with open(filepath) as json_file: - params = json.load(json_file) - - dict_ret = None - try: - dict_ret = run_algorithm(params, None, False) - except Exception as ex: # pylint: disable=broad-except - self.fail(str(ex)) - - self.assertIsInstance(dict_ret, dict) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/aqua/test_nlopt_optimizers.py b/test/aqua/test_nlopt_optimizers.py index 73753a3955..3ad0d5a541 100644 --- a/test/aqua/test_nlopt_optimizers.py +++ b/test/aqua/test_nlopt_optimizers.py @@ -21,7 +21,7 @@ from scipy.optimize import rosen import numpy as np -from qiskit.aqua import PluggableType, get_pluggable_class +# pylint: disable=unused-import,import-outside-toplevel class TestNLOptOptimizers(QiskitAquaTestCase): @@ -29,7 +29,10 @@ class TestNLOptOptimizers(QiskitAquaTestCase): def setUp(self): super().setUp() try: - import nlopt # pylint: disable=unused-import,import-outside-toplevel + from qiskit.aqua.components.optimizers import CRS, DIRECT_L, DIRECT_L_RAND + self.cls_dict = {CRS.__name__: CRS, + DIRECT_L.__name__: DIRECT_L, + DIRECT_L_RAND.__name__: DIRECT_L_RAND} except ImportError: self.skipTest('NLOpt dependency does not appear to be installed') pass @@ -46,12 +49,10 @@ def _optimize(self, optimizer): ['CRS'], ['DIRECT_L'], ['DIRECT_L_RAND'], - # ['ESCH'], - # ['ISRES'] ]) - def test_nlopt(self, name): + def test_nlopt(self, optimizer_name): """ NLopt test """ - optimizer = get_pluggable_class(PluggableType.OPTIMIZER, name)() + optimizer = self.cls_dict[optimizer_name]() optimizer.set_options(**{'max_evals': 50000}) res = self._optimize(optimizer) self.assertLessEqual(res[2], 50000) diff --git a/test/aqua/test_qsvm.py b/test/aqua/test_qsvm.py index 48ce99a964..49df8a6848 100644 --- a/test/aqua/test_qsvm.py +++ b/test/aqua/test_qsvm.py @@ -16,11 +16,9 @@ import os from test.aqua.common import QiskitAquaTestCase -import warnings import numpy as np from qiskit import BasicAer -from qiskit.aqua import run_algorithm, QuantumInstance, aqua_globals -from qiskit.aqua.input import ClassificationInput +from qiskit.aqua import QuantumInstance, aqua_globals from qiskit.aqua.components.feature_maps import SecondOrderExpansion from qiskit.aqua.components.multiclass_extensions import (ErrorCorrectingCode, AllPairs, @@ -34,8 +32,6 @@ class TestQSVM(QiskitAquaTestCase): """ Test QSVM """ def setUp(self): super().setUp() - warnings.filterwarnings("ignore", message=aqua_globals.CONFIG_DEPRECATION_MSG, - category=DeprecationWarning) self.random_seed = 10598 self.shots = 12000 aqua_globals.random_seed = self.random_seed @@ -46,42 +42,8 @@ def setUp(self): self.testing_data = {'A': np.asarray([[3.83274304, 2.45044227]]), 'B': np.asarray([[3.89557489, 0.31415927]])} - self.svm_input = ClassificationInput(self.training_data, self.testing_data) - - def test_qsvm_binary_via_run_algorithm(self): - """ QSVM Binary Via Run Algorithm test """ - training_input = {'A': np.asarray([[0.6560706, 0.17605998], [0.14154948, 0.06201424], - [0.80202323, 0.40582692], [0.46779595, 0.39946754], - [0.57660199, 0.21821317]]), - 'B': np.asarray([[0.38857596, -0.33775802], [0.49946978, -0.48727951], - [-0.30119743, -0.11221681], [-0.16479252, -0.08640519], - [0.49156185, -0.3660534]])} - - test_input = {'A': np.asarray([[0.57483139, 0.47120732], [0.48372348, 0.25438544], - [0.08791134, 0.11515506], [0.45988094, 0.32854319], - [0.53015085, 0.41539212]]), - 'B': np.asarray([[-0.06048935, -0.48345293], [-0.01065613, -0.33910828], - [-0.17323832, -0.49535592], [0.14043268, -0.87869109], - [-0.15046837, -0.47340207]])} - - total_array = np.concatenate((test_input['A'], test_input['B'])) - - params = { - 'problem': {'name': 'classification', 'random_seed': self.random_seed}, - 'backend': {'shots': self.shots}, - 'algorithm': { - 'name': 'QSVM' - } - } - backend = BasicAer.get_backend('qasm_simulator') - algo_input = ClassificationInput(training_input, test_input, total_array) - result = run_algorithm(params, algo_input, backend=backend) - self.assertEqual(result['testing_accuracy'], 0.6) - self.assertEqual(result['predicted_classes'], ['A', 'A', 'A', 'A', 'A', - 'A', 'B', 'A', 'A', 'A']) - - def test_qsvm_binary_directly(self): - """ QSVM Binary Directly test """ + def test_qsvm_binary(self): + """ QSVM Binary test """ ref_kernel_training = np.array([[1., 0.85366667, 0.12341667, 0.36408333], [0.85366667, 1., 0.11141667, 0.45491667], [0.12341667, 0.11141667, 1., 0.667], diff --git a/test/aqua/test_vqc.py b/test/aqua/test_vqc.py index cae699717f..364370fa59 100644 --- a/test/aqua/test_vqc.py +++ b/test/aqua/test_vqc.py @@ -17,7 +17,6 @@ import os import unittest from test.aqua.common import QiskitAquaTestCase -import warnings import numpy as np import scipy from sklearn import datasets @@ -25,21 +24,19 @@ from sklearn.preprocessing import StandardScaler, MinMaxScaler from sklearn.decomposition import PCA from qiskit import BasicAer -from qiskit.aqua.input import ClassificationInput -from qiskit.aqua import run_algorithm, QuantumInstance, aqua_globals +from qiskit.aqua import QuantumInstance, aqua_globals from qiskit.aqua.algorithms import VQC from qiskit.aqua.components.optimizers import SPSA, COBYLA from qiskit.aqua.components.feature_maps import SecondOrderExpansion, RawFeatureVector from qiskit.aqua.components.variational_forms import RYRZ, RY from qiskit.aqua.components.optimizers import L_BFGS_B +from qiskit.aqua.utils import get_feature_dimension class TestVQC(QiskitAquaTestCase): """ Test VQC """ def setUp(self): super().setUp() - warnings.filterwarnings("ignore", message=aqua_globals.CONFIG_DEPRECATION_MSG, - category=DeprecationWarning) self.seed = 1376 aqua_globals.random_seed = self.seed self.training_data = {'A': np.asarray([[2.95309709, 2.51327412], [3.14159265, 4.08407045]]), @@ -55,17 +52,20 @@ def setUp(self): self.ref_prediction_a_probs = [[0.79882812, 0.20117188]] self.ref_prediction_a_label = [0] - def test_vqc_via_run_algorithm(self): - """ vqc via run algorithm test """ - params = { - 'problem': {'name': 'classification', 'random_seed': self.seed}, - 'algorithm': {'name': 'VQC'}, - 'backend': {'provider': 'qiskit.BasicAer', 'name': 'qasm_simulator', 'shots': 1024}, - 'optimizer': {'name': 'SPSA', 'max_trials': 10, 'save_steps': 1}, - 'variational_form': {'name': 'RYRZ', 'depth': 3}, - 'feature_map': {'name': 'SecondOrderExpansion', 'depth': 2} - } - result = run_algorithm(params, ClassificationInput(self.training_data, self.testing_data)) + def test_vqc(self): + """ vqc test """ + aqua_globals.random_seed = self.seed + optimizer = SPSA(max_trials=10, save_steps=1, + c0=4.0, c1=0.1, c2=0.602, c3=0.101, c4=0.0, skip_calibration=True) + feature_map = SecondOrderExpansion( + feature_dimension=get_feature_dimension(self.training_data), depth=2) + var_form = RYRZ(num_qubits=feature_map.num_qubits, depth=3) + vqc = VQC(optimizer, feature_map, var_form, self.training_data, self.testing_data) + quantum_instance = QuantumInstance(BasicAer.get_backend('qasm_simulator'), + shots=1024, + seed_simulator=aqua_globals.random_seed, + seed_transpiler=aqua_globals.random_seed) + result = vqc.run(quantum_instance) np.testing.assert_array_almost_equal(result['opt_params'], self.ref_opt_params, decimal=8) @@ -76,16 +76,19 @@ def test_vqc_via_run_algorithm(self): def test_vqc_with_max_evals_grouped(self): """ vqc with max evals grouped test """ - params = { - 'problem': {'name': 'classification', 'random_seed': self.seed}, - 'algorithm': {'name': 'VQC', 'max_evals_grouped': 2}, - 'backend': {'provider': 'qiskit.BasicAer', 'name': 'qasm_simulator', 'shots': 1024}, - 'optimizer': {'name': 'SPSA', 'max_trials': 10, 'save_steps': 1}, - 'variational_form': {'name': 'RYRZ', 'depth': 3}, - 'feature_map': {'name': 'SecondOrderExpansion', 'depth': 2} - } - result = run_algorithm(params, ClassificationInput(self.training_data, self.testing_data)) - + aqua_globals.random_seed = self.seed + optimizer = SPSA(max_trials=10, save_steps=1, + c0=4.0, c1=0.1, c2=0.602, c3=0.101, c4=0.0, skip_calibration=True) + feature_map = SecondOrderExpansion( + feature_dimension=get_feature_dimension(self.training_data), depth=2) + var_form = RYRZ(num_qubits=feature_map.num_qubits, depth=3) + vqc = VQC(optimizer, feature_map, var_form, self.training_data, self.testing_data, + max_evals_grouped=2) + quantum_instance = QuantumInstance(BasicAer.get_backend('qasm_simulator'), + shots=1024, + seed_simulator=aqua_globals.random_seed, + seed_transpiler=aqua_globals.random_seed) + result = vqc.run(quantum_instance) np.testing.assert_array_almost_equal(result['opt_params'], self.ref_opt_params, decimal=8) np.testing.assert_array_almost_equal(result['training_loss'], @@ -93,20 +96,18 @@ def test_vqc_with_max_evals_grouped(self): self.assertEqual(1.0, result['testing_accuracy']) - def test_vqc_statevector_via_run_algorithm(self): - """ vqc statevector via run algorithm test """ - params = { - 'problem': {'name': 'classification', - 'random_seed': 10598, - 'skip_qobj_validation': True - }, - 'algorithm': {'name': 'VQC'}, - 'backend': {'provider': 'qiskit.BasicAer', 'name': 'statevector_simulator'}, - 'optimizer': {'name': 'COBYLA'}, - 'variational_form': {'name': 'RYRZ', 'depth': 3}, - 'feature_map': {'name': 'SecondOrderExpansion', 'depth': 2} - } - result = run_algorithm(params, ClassificationInput(self.training_data, self.testing_data)) + def test_vqc_statevector(self): + """ vqc statevector test """ + aqua_globals.random_seed = 10598 + optimizer = COBYLA() + feature_map = SecondOrderExpansion( + feature_dimension=get_feature_dimension(self.training_data), depth=2) + var_form = RYRZ(num_qubits=feature_map.num_qubits, depth=3) + vqc = VQC(optimizer, feature_map, var_form, self.training_data, self.testing_data) + quantum_instance = QuantumInstance(BasicAer.get_backend('statevector_simulator'), + seed_simulator=aqua_globals.random_seed, + seed_transpiler=aqua_globals.random_seed) + result = vqc.run(quantum_instance) ref_train_loss = 0.1059404 np.testing.assert_array_almost_equal(result['training_loss'], ref_train_loss, decimal=4) diff --git a/test/aqua/test_vqe.py b/test/aqua/test_vqe.py index 7c281959aa..124c2ffb06 100644 --- a/test/aqua/test_vqe.py +++ b/test/aqua/test_vqe.py @@ -17,13 +17,11 @@ import unittest import os from test.aqua.common import QiskitAquaTestCase -import warnings import numpy as np from parameterized import parameterized from qiskit import BasicAer -from qiskit.aqua import run_algorithm, QuantumInstance, aqua_globals -from qiskit.aqua.input import EnergyInput +from qiskit.aqua import QuantumInstance, aqua_globals from qiskit.aqua.operators import WeightedPauliOperator from qiskit.aqua.components.variational_forms import RY, RYRZ from qiskit.aqua.components.optimizers import L_BFGS_B, COBYLA, SPSA, SLSQP @@ -35,9 +33,6 @@ class TestVQE(QiskitAquaTestCase): """ Test VQE """ def setUp(self): super().setUp() - warnings.filterwarnings("ignore", message=aqua_globals.CONFIG_DEPRECATION_MSG, - category=DeprecationWarning) - # np.random.seed(50) self.seed = 50 aqua_globals.random_seed = self.seed pauli_dict = { @@ -50,20 +45,16 @@ def setUp(self): } self.qubit_op = WeightedPauliOperator.from_dict(pauli_dict) - def test_vqe_via_run_algorithm(self): - """ VQE Via Run Algorithm test """ - coupling_map = [[0, 1]] - basis_gates = ['u1', 'u2', 'u3', 'cx', 'id'] - - params = { - 'problem': {'random_seed': self.seed}, - 'algorithm': {'name': 'VQE'}, - 'backend': {'name': 'statevector_simulator', - 'provider': 'qiskit.BasicAer', - 'coupling_map': coupling_map, - 'basis_gates': basis_gates}, - } - result = run_algorithm(params, EnergyInput(self.qubit_op)) + def test_vqe(self): + """ VQE test """ + result = VQE(self.qubit_op, + RYRZ(self.qubit_op.num_qubits), + L_BFGS_B()).run( + QuantumInstance(BasicAer.get_backend('statevector_simulator'), + basis_gates=['u1', 'u2', 'u3', 'cx', 'id'], + coupling_map=[[0, 1]], + seed_simulator=aqua_globals.random_seed, + seed_transpiler=aqua_globals.random_seed)) self.assertAlmostEqual(result['energy'], -1.85727503) np.testing.assert_array_almost_equal(result['eigvals'], [-1.85727503], 5) ref_opt_params = [-0.58294401, -1.86141794, -1.97209632, -0.54796022, diff --git a/test/aqua/test_vqe2iqpe.py b/test/aqua/test_vqe2iqpe.py index d0e1f6e270..99bf1c6e92 100644 --- a/test/aqua/test_vqe2iqpe.py +++ b/test/aqua/test_vqe2iqpe.py @@ -21,7 +21,6 @@ from qiskit import BasicAer from qiskit.aqua import QuantumInstance, aqua_globals -from qiskit.aqua.input import EnergyInput from qiskit.aqua.utils import decimal_to_binary from qiskit.aqua.operators import WeightedPauliOperator from qiskit.aqua.components.initial_states import VarFormBased @@ -45,17 +44,16 @@ def setUp(self): {"coeff": {"imag": 0.0, "real": 0.18093119978423156}, "label": "XX"} ] } - qubit_op = WeightedPauliOperator.from_dict(pauli_dict) - self.algo_input = EnergyInput(qubit_op) + self.qubit_op = WeightedPauliOperator.from_dict(pauli_dict) def test_vqe_2_iqpe(self): """ vqe to iqpe test """ backend = BasicAer.get_backend('qasm_simulator') - num_qbits = self.algo_input.qubit_op.num_qubits + num_qbits = self.qubit_op.num_qubits var_form = RYRZ(num_qbits, 3) optimizer = SPSA(max_trials=10) # optimizer.set_options(**{'max_trials': 500}) - algo = VQE(self.algo_input.qubit_op, var_form, optimizer) + algo = VQE(self.qubit_op, var_form, optimizer) quantum_instance = QuantumInstance(backend, seed_simulator=self.seed, seed_transpiler=self.seed) result = algo.run(quantum_instance) @@ -68,7 +66,7 @@ def test_vqe_2_iqpe(self): num_iterations = 6 state_in = VarFormBased(var_form, result['opt_params']) - iqpe = IQPE(self.algo_input.qubit_op, state_in, num_time_slices, num_iterations, + iqpe = IQPE(self.qubit_op, state_in, num_time_slices, num_iterations, expansion_mode='suzuki', expansion_order=2, shallow_circuit_concat=True) quantum_instance = QuantumInstance( backend, shots=100, seed_transpiler=self.seed, seed_simulator=self.seed diff --git a/test/chemistry/test_input_parser.txt b/test/chemistry/test_input_parser.txt deleted file mode 100644 index 31be21d8ac..0000000000 --- a/test/chemistry/test_input_parser.txt +++ /dev/null @@ -1,61 +0,0 @@ -&name -H2 molecule experiment -&end - -&problem - name=energy - auto_substitutions=True - random_seed=None -&end - -&driver - name=PYSCF - hdf5_output=None -&end - -&pyscf - atom=H .0 .0 .0; H .0 .0 0.735 - unit=Angstrom - charge=0 - spin=0 - basis=sto3g - max_memory=None -&end - -&operator - name=hamiltonian - transformation=full - qubit_mapping=parity - two_qubit_reduction=True - freeze_core=False - orbital_reduction=[] -&end - -&algorithm - name=VQE - initial_point=None -&end - -&initial_state - name=ZERO -&end - -&optimizer - name=L_BFGS_B - maxfun=1000 - factr=10 - iprint=-1 -&end - -&variational_form - name=RYRZ - depth=3 - entanglement=full - entangler_map=None -&end - -&backend - provider=qiskit.BasicAer - name=statevector_simulator - skip_transpiler=False -&end diff --git a/test/chemistry/test_inputparser.py b/test/chemistry/test_inputparser.py deleted file mode 100644 index 19fdc76756..0000000000 --- a/test/chemistry/test_inputparser.py +++ /dev/null @@ -1,82 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" Test InputParser """ - -import unittest -import os -import json -from test.chemistry.common import QiskitChemistryTestCase -from qiskit.aqua import AquaError -from qiskit.chemistry.parser import InputParser - - -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) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/optimization/test_clique.py b/test/optimization/test_clique.py index b6445bea9e..b4c84b667f 100644 --- a/test/optimization/test_clique.py +++ b/test/optimization/test_clique.py @@ -15,12 +15,10 @@ """ Test Clique """ from test.optimization.common import QiskitOptimizationTestCase -import warnings import numpy as np from qiskit import BasicAer -from qiskit.aqua import run_algorithm, aqua_globals, QuantumInstance -from qiskit.aqua.input import EnergyInput +from qiskit.aqua import aqua_globals, QuantumInstance from qiskit.optimization.ising import clique from qiskit.optimization.ising.common import random_graph, sample_most_likely from qiskit.aqua.algorithms import ExactEigensolver, VQE @@ -33,8 +31,6 @@ class TestClique(QiskitOptimizationTestCase): def setUp(self): super().setUp() - warnings.filterwarnings("ignore", message=aqua_globals.CONFIG_DEPRECATION_MSG, - category=DeprecationWarning) self.k = 5 # K means the size of the clique self.seed = 100 aqua_globals.random_seed = self.seed @@ -61,19 +57,6 @@ def bitfield(n, length): def test_clique(self): """ Clique test """ - params = { - 'problem': {'name': 'ising'}, - 'algorithm': {'name': 'ExactEigensolver'} - } - result = run_algorithm(params, EnergyInput(self.qubit_op)) - x = sample_most_likely(result['eigvecs'][0]) - ising_sol = clique.get_graph_solution(x) - np.testing.assert_array_equal(ising_sol, [1, 1, 1, 1, 1]) - oracle = self._brute_force() - self.assertEqual(clique.satisfy_or_not(ising_sol, self.w, self.k), oracle) - - def test_clique_direct(self): - """ Clique Direct test """ algo = ExactEigensolver(self.qubit_op, k=1, aux_operators=[]) result = algo.run() x = sample_most_likely(result['eigvecs'][0]) diff --git a/test/optimization/test_cplex_ising.py b/test/optimization/test_cplex_ising.py index d2d213cbec..1cbb2be48d 100644 --- a/test/optimization/test_cplex_ising.py +++ b/test/optimization/test_cplex_ising.py @@ -15,11 +15,9 @@ """ Test Cplex Ising """ from test.optimization.common import QiskitOptimizationTestCase -import warnings import numpy as np -from qiskit.aqua import run_algorithm, AquaError, aqua_globals -from qiskit.aqua.input import EnergyInput +from qiskit.aqua import AquaError, aqua_globals from qiskit.optimization.ising import max_cut from qiskit.optimization.ising.common import random_graph from qiskit.aqua.algorithms.classical.cplex.cplex_ising import CPLEX_Ising @@ -30,34 +28,14 @@ class TestCplexIsing(QiskitOptimizationTestCase): def setUp(self): super().setUp() - warnings.filterwarnings("ignore", message=aqua_globals.CONFIG_DEPRECATION_MSG, - category=DeprecationWarning) aqua_globals.random_seed = 8123179 self.w = random_graph(4, edge_prob=0.5, weight_range=10) self.qubit_op, self.offset = max_cut.get_operator(self.w) - self.algo_input = EnergyInput(self.qubit_op) - def test_cplex_ising_via_run_algorithm(self): - """ CPlex ising via run algorithm test """ + def test_cplex_ising(self): + """ cplex ising test """ try: - params = { - 'problem': {'name': 'ising'}, - 'algorithm': {'name': 'CPLEX.Ising', 'display': 0} - } - result = run_algorithm(params, self.algo_input) - self.assertEqual(result['energy'], -20.5) - x_dict = result['x_sol'] - x = np.array([x_dict[i] for i in sorted(x_dict.keys())]) - np.testing.assert_array_equal( - max_cut.get_graph_solution(x), [1, 0, 1, 1]) - self.assertEqual(max_cut.max_cut_value(x, self.w), 24) - except AquaError as ex: - self.skipTest(str(ex)) - - def test_cplex_ising_direct(self): - """ cplex ising direct test """ - try: - algo = CPLEX_Ising(self.algo_input.qubit_op, display=0) + algo = CPLEX_Ising(self.qubit_op, display=0) result = algo.run() self.assertEqual(result['energy'], -20.5) x_dict = result['x_sol'] diff --git a/test/optimization/test_exact_cover.py b/test/optimization/test_exact_cover.py index f6127939f0..cbf85d3111 100644 --- a/test/optimization/test_exact_cover.py +++ b/test/optimization/test_exact_cover.py @@ -16,12 +16,10 @@ import json from test.optimization.common import QiskitOptimizationTestCase -import warnings import numpy as np from qiskit import BasicAer -from qiskit.aqua import run_algorithm, aqua_globals, QuantumInstance -from qiskit.aqua.input import EnergyInput +from qiskit.aqua import aqua_globals, QuantumInstance from qiskit.optimization.ising import exact_cover from qiskit.optimization.ising.common import sample_most_likely from qiskit.aqua.algorithms import ExactEigensolver, VQE @@ -34,8 +32,6 @@ class TestExactCover(QiskitOptimizationTestCase): def setUp(self): super().setUp() - warnings.filterwarnings("ignore", message=aqua_globals.CONFIG_DEPRECATION_MSG, - category=DeprecationWarning) input_file = self._get_resource_path('sample.exactcover') with open(input_file) as file: self.list_of_subsets = json.load(file) @@ -61,20 +57,6 @@ def bitfield(n, length): def test_exact_cover(self): """ Exact Cover test """ - params = { - 'problem': {'name': 'ising'}, - 'algorithm': {'name': 'ExactEigensolver'} - } - result = run_algorithm(params, EnergyInput(self.qubit_op)) - x = sample_most_likely(result['eigvecs'][0]) - ising_sol = exact_cover.get_solution(x) - np.testing.assert_array_equal(ising_sol, [0, 1, 1, 0]) - oracle = self._brute_force() - self.assertEqual(exact_cover.check_solution_satisfiability(ising_sol, self.list_of_subsets), - oracle) - - def test_exact_cover_direct(self): - """ Exact Cover Direct test """ algo = ExactEigensolver(self.qubit_op, k=1, aux_operators=[]) result = algo.run() x = sample_most_likely(result['eigvecs'][0]) diff --git a/test/optimization/test_graph_partition.py b/test/optimization/test_graph_partition.py index 20933c1a07..9d97799627 100644 --- a/test/optimization/test_graph_partition.py +++ b/test/optimization/test_graph_partition.py @@ -15,11 +15,9 @@ """ Test Graph Partition """ from test.optimization.common import QiskitOptimizationTestCase -import warnings import numpy as np from qiskit import BasicAer -from qiskit.aqua import run_algorithm, aqua_globals, QuantumInstance -from qiskit.aqua.input import EnergyInput +from qiskit.aqua import aqua_globals, QuantumInstance from qiskit.optimization.ising import graph_partition from qiskit.optimization.ising.common import random_graph, sample_most_likely from qiskit.aqua.algorithms import ExactEigensolver, VQE @@ -32,8 +30,6 @@ class TestGraphPartition(QiskitOptimizationTestCase): def setUp(self): super().setUp() - warnings.filterwarnings("ignore", message=aqua_globals.CONFIG_DEPRECATION_MSG, - category=DeprecationWarning) aqua_globals.random_seed = 100 self.num_nodes = 4 self.w = random_graph(self.num_nodes, edge_prob=0.8, weight_range=10) @@ -62,20 +58,6 @@ def bitfield(n, length): def test_graph_partition(self): """ Graph Partition test """ - params = { - 'problem': {'name': 'ising'}, - 'algorithm': {'name': 'ExactEigensolver'} - } - result = run_algorithm(params, EnergyInput(self.qubit_op)) - x = sample_most_likely(result['eigvecs'][0]) - # check against the oracle - ising_sol = graph_partition.get_graph_solution(x) - np.testing.assert_array_equal(ising_sol, [0, 1, 0, 1]) - oracle = self._brute_force() - self.assertEqual(graph_partition.objective_value(x, self.w), oracle) - - def test_graph_partition_direct(self): - """ Graph Partition Direct test """ algo = ExactEigensolver(self.qubit_op, k=1, aux_operators=[]) result = algo.run() x = sample_most_likely(result['eigvecs'][0]) diff --git a/test/optimization/test_partition.py b/test/optimization/test_partition.py index 3c8b8fc892..7bbdd0afb4 100644 --- a/test/optimization/test_partition.py +++ b/test/optimization/test_partition.py @@ -15,11 +15,9 @@ """ Test Partition """ from test.optimization.common import QiskitOptimizationTestCase -import warnings import numpy as np from qiskit import BasicAer -from qiskit.aqua import run_algorithm, aqua_globals, QuantumInstance -from qiskit.aqua.input import EnergyInput +from qiskit.aqua import aqua_globals, QuantumInstance from qiskit.optimization.ising import partition from qiskit.optimization.ising.common import read_numbers_from_file, sample_most_likely from qiskit.aqua.algorithms import ExactEigensolver, VQE @@ -32,25 +30,12 @@ class TestSetPacking(QiskitOptimizationTestCase): def setUp(self): super().setUp() - warnings.filterwarnings("ignore", message=aqua_globals.CONFIG_DEPRECATION_MSG, - category=DeprecationWarning) input_file = self._get_resource_path('sample.partition') number_list = read_numbers_from_file(input_file) self.qubit_op, _ = partition.get_operator(number_list) def test_partition(self): """ Partition test """ - params = { - 'problem': {'name': 'ising'}, - 'algorithm': {'name': 'ExactEigensolver'} - } - result = run_algorithm(params, EnergyInput(self.qubit_op)) - - x = sample_most_likely(result['eigvecs'][0]) - np.testing.assert_array_equal(x, [0, 1, 0]) - - def test_partition_direct(self): - """ Partition Direct test """ algo = ExactEigensolver(self.qubit_op, k=1, aux_operators=[]) result = algo.run() x = sample_most_likely(result['eigvecs'][0]) diff --git a/test/optimization/test_set_packing.py b/test/optimization/test_set_packing.py index 5e853d89ec..784cf4d6e4 100644 --- a/test/optimization/test_set_packing.py +++ b/test/optimization/test_set_packing.py @@ -16,13 +16,11 @@ import json from test.optimization.common import QiskitOptimizationTestCase -import warnings import numpy as np from qiskit.optimization.ising import set_packing from qiskit.optimization.ising.common import sample_most_likely -from qiskit.aqua import QuantumInstance, run_algorithm, aqua_globals -from qiskit.aqua.input import EnergyInput +from qiskit.aqua import QuantumInstance, aqua_globals from qiskit.aqua.algorithms import ExactEigensolver, VQE from qiskit.aqua.components.optimizers import SPSA from qiskit.aqua.components.variational_forms import RY @@ -33,8 +31,6 @@ class TestSetPacking(QiskitOptimizationTestCase): def setUp(self): super().setUp() - warnings.filterwarnings("ignore", message=aqua_globals.CONFIG_DEPRECATION_MSG, - category=DeprecationWarning) input_file = self._get_resource_path('sample.setpacking') with open(input_file) as file: self.list_of_subsets = json.load(file) @@ -59,19 +55,6 @@ def bitfield(n, length): def test_set_packing(self): """ set packing test """ - params = { - 'problem': {'name': 'ising'}, - 'algorithm': {'name': 'ExactEigensolver'} - } - result = run_algorithm(params, EnergyInput(self.qubit_op)) - x = sample_most_likely(result['eigvecs'][0]) - ising_sol = set_packing.get_solution(x) - np.testing.assert_array_equal(ising_sol, [0, 1, 1]) - oracle = self._brute_force() - self.assertEqual(np.count_nonzero(ising_sol), oracle) - - def test_set_packing_direct(self): - """ set packing direct test """ algo = ExactEigensolver(self.qubit_op, k=1, aux_operators=[]) result = algo.run() x = sample_most_likely(result['eigvecs'][0]) diff --git a/test/optimization/test_vertex_cover.py b/test/optimization/test_vertex_cover.py index bb20ab110a..b930690985 100644 --- a/test/optimization/test_vertex_cover.py +++ b/test/optimization/test_vertex_cover.py @@ -15,12 +15,10 @@ """ Text Vertex Cover """ from test.optimization.common import QiskitOptimizationTestCase -import warnings import numpy as np from qiskit import BasicAer -from qiskit.aqua import run_algorithm, aqua_globals, QuantumInstance -from qiskit.aqua.input import EnergyInput +from qiskit.aqua import aqua_globals, QuantumInstance from qiskit.optimization.ising import vertex_cover from qiskit.optimization.ising.common import random_graph, sample_most_likely from qiskit.aqua.algorithms import ExactEigensolver, VQE @@ -33,8 +31,6 @@ class TestVertexCover(QiskitOptimizationTestCase): def setUp(self): super().setUp() - warnings.filterwarnings("ignore", message=aqua_globals.CONFIG_DEPRECATION_MSG, - category=DeprecationWarning) self.seed = 100 aqua_globals.random_seed = self.seed self.num_nodes = 3 @@ -62,21 +58,7 @@ def bitfield(n, length): return minimal_v def test_vertex_cover(self): - """ Vertex cover test """ - params = { - 'problem': {'name': 'ising'}, - 'algorithm': {'name': 'ExactEigensolver'} - } - result = run_algorithm(params, EnergyInput(self.qubit_op)) - - x = sample_most_likely(result['eigvecs'][0]) - sol = vertex_cover.get_graph_solution(x) - np.testing.assert_array_equal(sol, [0, 1, 1]) - oracle = self._brute_force() - self.assertEqual(np.count_nonzero(sol), oracle) - - def test_vertex_cover_direct(self): - """ Vertex Cover Direct test """ + """ Vertex Cover test """ algo = ExactEigensolver(self.qubit_op, k=1, aux_operators=[]) result = algo.run() x = sample_most_likely(result['eigvecs'][0])