示例#1
0
    def cancel(self):
        """Attempt to cancel job. Currently this is only possible on
        commercial systems.
        Returns:
            bool: True if job can be cancelled, else False.

        Raises:
            QISKitError: if server returned error
        """
        if self._is_commercial:
            hub = self._api.config['hub']
            group = self._api.config['group']
            project = self._api.config['project']
            response = self._api.cancel_job(self._id, hub, group, project)
            if 'error' in response:
                err_msg = response.get('error', '')
                self._exception = QISKitError('Error cancelling job: %s' %
                                              err_msg)
                raise QISKitError('Error canceelling job: %s' % err_msg)
            else:
                self._cancelled = True
                return True
        else:
            self._cancelled = False
            return False
示例#2
0
 def _check_qreg(self, register):
     """Raise exception if r is not in this circuit or not qreg."""
     if not isinstance(register, QuantumRegister):
         raise QISKitError("expected quantum register")
     if not self.has_register(register):
         raise QISKitError("register '%s' not in this circuit" %
                           register.name)
示例#3
0
def load_result_from_file(filename):
    """Load a results dictionary file (.json) to a Result object.
    Note: The json file may not load properly if it was saved with a previous
    version of the SDK.

    Args:
        filename (str): filename of the dictionary

    Returns:
        tuple(Result, dict):
            The new Results object
            if the metadata exists it will get returned
    Raises:
        QISKitError: if the file does not exist or does not have the proper
            dictionary structure.
    """

    if not os.path.exists(filename):
        raise QISKitError('File %s does not exist' % filename)

    with open(filename, 'r') as load_file:
        master_dict = json.load(load_file)

    try:
        qresult_dict = master_dict['result']
        convert_json_to_qobj(qresult_dict)
        metadata = master_dict['metadata']
    except KeyError:
        raise QISKitError('File %s does not have the proper dictionary '
                          'structure')

    qresult = qiskit.Result(qresult_dict)

    return qresult, metadata
示例#4
0
 def _check_creg(self, register):
     """Raise exception if r is not in this circuit or not creg."""
     if not isinstance(register, ClassicalRegister):
         raise QISKitError("expected classical register")
     if not self.has_register(register):
         raise QISKitError("register '%s' not in this circuit" %
                           register.name)
示例#5
0
    def _get_backend_instance(cls, backend_cls):
        """
        Return an instance of a backend from its class.

        Args:
            backend_cls (class): Backend class.
        Returns:
            BaseBackend: a backend instance.
        Raises:
            QISKitError: if the backend could not be instantiated or does not
                provide a valid configuration containing a name.
        """
        # Verify that the backend can be instantiated.
        try:
            backend_instance = backend_cls()
        except Exception as err:
            raise QISKitError('Backend %s could not be instantiated: %s' %
                              (cls, err))

        # Verify that the instance has a minimal valid configuration.
        try:
            _ = backend_instance.configuration['name']
        except (LookupError, TypeError):
            raise QISKitError('Backend %s has an invalid configuration')

        return backend_instance
示例#6
0
def register(*args, provider_class=IBMQProvider, **kwargs):
    """
    Authenticate against an online backend provider.
    This is a factory method that returns the provider that gets registered.

    Note that if no parameters are passed, this method will try to
    automatically discover the credentials for IBMQ in the following places,
    in order::

        1. in the `Qconfig.py` file in the current working directory.
        2. in the environment variables.
        3. in the `qiskitrc` configuration file.

    Args:
        args (tuple): positional arguments passed to provider class initialization
        provider_class (BaseProvider): provider class
        kwargs (dict): keyword arguments passed to provider class initialization.
            For the IBMQProvider default this can include things such as:

                * token (str): The token used to register on the online backend such
                    as the quantum experience.
                * url (str): The url used for online backend such as the quantum
                    experience.
                * hub (str): The hub used for online backend.
                * group (str): The group used for online backend.
                * project (str): The project used for online backend.
                * proxies (dict): Proxy configuration for the API, as a dict with
                    'urls' and credential keys.
                * verify (bool): If False, ignores SSL certificates errors.

    Returns:
        BaseProvider: the provider instance that was just registered.

    Raises:
        QISKitError: if the provider could not be registered (e.g. due to
        conflict, or if no credentials were provided.)
    """
    # Try to autodiscover credentials if not passed.
    if not args and not kwargs and provider_class == IBMQProvider:
        kwargs = credentials.discover_credentials().get(
            credentials.get_account_name(IBMQProvider)) or {}
        if not kwargs:
            raise QISKitError(
                'No IBMQ credentials found. Please pass them explicitly or '
                'store them before calling register() with store_credentials()'
            )

    try:
        provider = provider_class(*args, **kwargs)
    except Exception as ex:
        raise QISKitError(
            "Couldn't instantiate provider! Error: {0}".format(ex))

    _DEFAULT_PROVIDER.add_provider(provider)
    return provider
示例#7
0
    def get_data(self, name):
        """Get the data of circuit name.

        The data format will depend on the backend. For a real device it
        will be for the form::

            "counts": {'00000': XXXX, '00001': XXXX},
            "time"  : xx.xxxxxxxx

        for the qasm simulators of 1 shot::

            'quantum_state': array([ XXX,  ..., XXX]),
            'classical_state': 0

        for the qasm simulators of n shots::

            'counts': {'0000': XXXX, '1001': XXXX}

        for the unitary simulators::

            'unitary': np.array([[ XX + XXj
                                   ...
                                   XX + XX]
                                 ...
                                 [ XX + XXj
                                   ...
                                   XX + XXj]]

        Args:
            name (str): the name of the quantum circuit.

        Returns:
            dict: A dictionary of data for the different backends.

        Raises:
            QISKitError: if there is no data for the circuit, or an unhandled
                error occurred while fetching the data.
            Exception: if a handled error occurred while fetching the data.
        """
        if self._is_error():
            exception = self._result['result']
            if isinstance(exception, BaseException):
                raise exception
            else:
                raise QISKitError(str(exception))

        try:
            qobj = self._qobj
            for index in range(len(qobj['circuits'])):
                if qobj['circuits'][index]['name'] == name:
                    return self._result['result'][index]['data']
        except (KeyError, TypeError):
            pass
        raise QISKitError('No data for circuit "{0}"'.format(name))
示例#8
0
 def add(self, *regs):
     """Add registers."""
     for register in regs:
         if register.name in self.qregs or register.name in self.cregs:
             raise QISKitError("register name \"%s\" already exists" %
                               register.name)
         if isinstance(register, QuantumRegister):
             self.qregs[register.name] = register
         elif isinstance(register, ClassicalRegister):
             self.cregs[register.name] = register
         else:
             raise QISKitError("expected a register")
示例#9
0
def _best_subset(backend, n_qubits):
    """Computes the qubit mapping with the best
    connectivity.

    Parameters:
        backend (Qiskit.BaseBackend): A QISKit backend instance.
        n_qubits (int): Number of subset qubits to consider.

    Returns:
        ndarray: Array of qubits to use for best
                connectivity mapping.

    Raises:
        QISKitError: Wrong number of qubits given.
    """
    if n_qubits == 1:
        return np.array([0])
    elif n_qubits <= 0:
        raise QISKitError('Number of qubits <= 0.')

    device_qubits = backend.configuration()['n_qubits']
    if n_qubits > device_qubits:
        raise QISKitError('Number of qubits greater than device.')

    cmap = np.asarray(backend.configuration()['coupling_map'])
    data = np.ones_like(cmap[:, 0])
    sp_cmap = sp.coo_matrix((data, (cmap[:, 0], cmap[:, 1])),
                            shape=(device_qubits, device_qubits)).tocsr()
    best = 0
    best_map = None
    # do bfs with each node as starting point
    for k in range(sp_cmap.shape[0]):
        bfs = cs.breadth_first_order(sp_cmap,
                                     i_start=k,
                                     directed=False,
                                     return_predecessors=False)

        connection_count = 0
        for i in range(n_qubits):
            node_idx = bfs[i]
            for j in range(sp_cmap.indptr[node_idx],
                           sp_cmap.indptr[node_idx + 1]):
                node = sp_cmap.indices[j]
                for counter in range(n_qubits):
                    if node == bfs[counter]:
                        connection_count += 1
                        break

        if connection_count > best:
            best = connection_count
            best_map = bfs[0:n_qubits]
    return best_map
    def get_data(self, name):
        """Get the data of cicuit name.

        The data format will depend on the backend. For a real device it
        will be for the form::

            "counts": {’00000’: XXXX, ’00001’: XXXX},
            "time"  : xx.xxxxxxxx

        for the qasm simulators of 1 shot::

            'quantum_state': array([ XXX,  ..., XXX]),
            'classical_state': 0

        for the qasm simulators of n shots::

            'counts': {'0000': XXXX, '1001': XXXX}

        for the unitary simulators::

            'unitary': np.array([[ XX + XXj
                                   ...
                                   XX + XX]
                                 ...
                                 [ XX + XXj
                                   ...
                                   XX + XXj]]

        Args:
            name (str): the name of the quantum circuit.

        Returns:
            A dictionary of data for the different backends.

        Raises:
            If there's an error the function will throw a QISKitError or a
            RegisterSizeError.
        """
        if self._is_error():
            exception = self.__result['result']
            if isinstance(exception, RegisterSizeError):
                raise exception # Re-throw RegisterSizeError
            raise QISKitError(str(exception))

        try:
            qobj = self.__qobj
            for index in range(len(qobj['circuits'])):
                if qobj['circuits'][index]['name'] == name:
                    return self.__result['result'][index]['data']
        except (KeyError, TypeError):
            raise QISKitError('No data for circuit "{0}"'.format(name))
示例#11
0
 def _check_qubit(self, qubit):
     """Raise exception if qubit is not in this circuit or bad format."""
     if not isinstance(qubit, tuple):
         raise QISKitError("%s is not a tuple."
                           "A qubit should be formated as a tuple." %
                           str(qubit))
     if not len(qubit) == 2:
         raise QISKitError(
             "%s is not a tuple with two elements, but %i instead" %
             len(qubit))
     if not isinstance(qubit[1], int):
         raise QISKitError(
             "The second element of a tuple defining a qubit should be an int:"
             "%s was found instead" % type(qubit[1]).__name__)
     self._check_qreg(qubit[0])
     qubit[0].check_range(qubit[1])
示例#12
0
def least_busy(names):
    """
    Return the least busy available backend for those that
    have a `pending_jobs` in their `status`. Backends such as
    local backends that do not have this are not considered.

    Args:
        names (list[str]): backend names to choose from
                    (e.g. output of ``available_backends()``)

    Returns:
        str: the name of the least busy backend

    Raises:
        QISKitError: if passing a list of backend names that is
            either empty or none have attribute ``pending_jobs``
    """
    backends = [get_backend(name) for name in names]
    try:
        return min([
            b for b in backends
            if b.status()['operational'] and 'pending_jobs' in b.status()
        ],
                   key=lambda b: b.status()['pending_jobs']).name()
    except (ValueError, TypeError):
        raise QISKitError(
            "Can only find least_busy backend from a non-empty list.")
示例#13
0
def job_monitor(job, interval=2, monitor_async=False):
    """Monitor the status of a IBMQJob instance.

    Args:
        job (BaseJob): Job to monitor.
        interval (int): Time interval between status queries.
        monitor_async (bool): Monitor asyncronously (in Jupyter only).

    Raises:
        QISKitError: When trying to run async outside of Jupyter
    """
    if _NOTEBOOK_ENV:
        style = "font-size:16px;"
        header = "<p style='{style}'>Job Status: %s </p>".format(style=style)
        status = widgets.HTML(value=header % job.status().value)
        display(status)
        if monitor_async:
            thread = threading.Thread(target=_html_checker,
                                      args=(job, interval, status, header))
            thread.start()
        else:
            _html_checker(job, interval, status, header)

    else:
        if monitor_async:
            raise QISKitError(
                'monitor_async only available in Jupyter notebooks.')
        _text_checker(job, interval)
示例#14
0
    def __init__(self, *regs, name=None):
        """Create a new circuit.

        A circuit is a list of instructions bound to some registers.

        Args:
            *regs (Registers): registers to include in the circuit.
            name (str or None): the name of the quantum circuit. If
                None, an automatically generated string will be assigned.

        Raises:
            QISKitError: if the circuit name, if given, is not valid.
        """
        if name is None:
            name = self.cls_prefix() + str(self.cls_instances())
        self._increment_instances()

        if not isinstance(name, str):
            raise QISKitError("The circuit name should be a string "
                              "(or None to auto-generate a name).")

        self.name = name

        # Data contains a list of instructions in the order they were applied.
        self.data = []

        # This is a map of registers bound to this circuit, by name.
        self.qregs = OrderedDict()
        self.cregs = OrderedDict()
        self.add(*regs)
示例#15
0
 def status(self):
     if self._status == JobStatus.INITIALIZING:
         stats = {
             'job_id': None,
             'status': self._status,
             'status_msg': 'job is begin initialized please wait a moment'
         }
         return stats
     job_result = self._api.get_job(self._job_id)
     stats = {'job_id': self._job_id}
     self._status = None
     _status_msg = None
     if 'status' not in job_result:
         self._exception = QISKitError("get_job didn't return status: %s" %
                                       (pprint.pformat(job_result)))
         raise QISKitError("get_job didn't return status: %s" %
                           (pprint.pformat(job_result)))
     elif job_result['status'] == 'RUNNING':
         self._status = JobStatus.RUNNING
         # we may have some other information here
         if 'infoQueue' in job_result:
             if 'status' in job_result['infoQueue']:
                 if job_result['infoQueue']['status'] == 'PENDING_IN_QUEUE':
                     self._status = JobStatus.QUEUED
             if 'position' in job_result['infoQueue']:
                 stats['queue_position'] = job_result['infoQueue'][
                     'position']
     elif job_result['status'] == 'COMPLETED':
         self._status = JobStatus.DONE
     elif self.cancelled:
         self._status = JobStatus.CANCELLED
     elif self.exception:
         self._status = JobStatus.ERROR
         if self._future_submit.exception():
             self._exception = self._future_submit.exception()
         self._status_msg = str(self.exception)
     elif 'ERROR' in job_result['status']:
         # ERROR_CREATING_JOB or ERROR_RUNNING_JOB
         self._status = JobStatus.ERROR
         self._status_msg = job_result['status']
     else:
         self._status = JobStatus.ERROR
         raise IBMQJobError('Unexpected behavior of {0}\n{1}'.format(
             self.__class__.__name__, pprint.pformat(job_result)))
     stats['status'] = self._status
     stats['status_msg'] = _status_msg
     return stats
示例#16
0
 def _check_compatible_regs(self, rhs):
     """Raise exception if the circuits are defined on incompatible registers"""
     lhs_regs = {**self.qregs, **self.cregs}
     rhs_regs = {**rhs.qregs, **rhs.cregs}
     common_registers = lhs_regs.keys() & rhs_regs.keys()
     for name in common_registers:
         if lhs_regs[name] != rhs_regs[name]:
             raise QISKitError("circuits are not compatible")
示例#17
0
def load_result_from_file(filename):
    """Load a results dictionary file (.json) to a Result object.
    Note: The json file may not load properly if it was saved with a previous
    version of the SDK.

    Args:
        filename (str): filename of the dictionary

    Returns:
        tuple(Result, dict):
            The new Results object
            if the metadata exists it will get returned
    Raises:
        QISKitError: if the file does not exist or does not have the proper
            dictionary structure.
    """

    if not os.path.exists(filename):
        raise QISKitError('File %s does not exist' % filename)

    with open(filename, 'r') as load_file:
        master_dict = json.load(load_file)

    try:
        qresult_dict = master_dict['result']
        convert_json_to_qobj(qresult_dict)
        metadata = master_dict['metadata']
    except KeyError:
        raise QISKitError('File %s does not have the proper dictionary '
                          'structure')

    # TODO: To keep backwards compatibility with previous saved versions,
    # the method adapts the recovered JSON to match the new format. Since
    # the save function takes a Result, not all the fields required by
    # the new Qobj are saved so they are marked with 'TODO'.
    qresult_dict['id'] = qresult_dict.get('id', 'TODO')
    for experiment in qresult_dict['result']:
        is_done = experiment['status'] == 'DONE'
        experiment['success'] = experiment.get('success', is_done)
        experiment['shots'] = experiment.get('shots', 'TODO')

    qresult = result_from_old_style_dict(
        qresult_dict,
        [circuit_data['name'] for circuit_data in qresult_dict['result']])

    return qresult, metadata
示例#18
0
    def _check_compatible_regs(self, rhs):
        """Raise exception if the circuits are defined on incompatible registers"""

        list1 = self.qregs + self.cregs
        list2 = rhs.qregs + rhs.cregs
        for element1 in list1:
            for element2 in list2:
                if element2.name == element1.name:
                    if element1 != element2:
                        raise QISKitError("circuits are not compatible")
示例#19
0
    def _update_status(self):
        """Query the API to update the status."""
        if (self._status in self._final_states or
                self._status == JobStatus.INITIALIZING):
            return None

        try:
            api_job = self._api.get_job(self.id)
            if 'status' not in api_job:
                raise QISKitError('get_job didn\'t return status: %s' %
                                  pprint.pformat(api_job))
        # pylint: disable=broad-except
        except Exception as err:
            self._status = JobStatus.ERROR
            self._exception = err
            self._status_msg = '{}'.format(err)
            return None

        if api_job['status'] == 'RUNNING':
            self._status = JobStatus.RUNNING
            self._status_msg = self._status.value
            queued, queue_position = self._is_job_queued(api_job)
            if queued:
                self._status = JobStatus.QUEUED
                self._status_msg = self._status.value
            if queue_position:
                self._queue_position = queue_position

        elif api_job['status'] == 'COMPLETED':
            self._status = JobStatus.DONE
            self._status_msg = self._status.value

        elif api_job['status'] == 'CANCELLED':
            self._status = JobStatus.CANCELLED
            self._status_msg = self._status.value
            self._cancelled = True

        elif 'ERROR' in api_job['status']:
            # ERROR_CREATING_JOB or ERROR_RUNNING_JOB
            self._status = JobStatus.ERROR
            self._status_msg = api_job['status']

        elif self.exception or self._future_submit.exception():
            self._status = JobStatus.ERROR
            if self._future_submit.exception():
                self._exception = self._future_submit.exception()
            self._status_msg = str(self.exception)

        else:
            self._status = JobStatus.ERROR
            self._exception = IBMQJobError(
                'Unrecognized result: \n{}'.format(pprint.pformat(api_job)))
            self._status_msg = '{}'.format(self._exception)

        return api_job
示例#20
0
    def remove_channel(self, index):
        """Remove a channel from the receiver by index number.

        Parameters:
            index (int): Index fo channel to remove.

        Raises:
            QISKitError: Index not in receiver keys.
        """
        if index in self._channels.keys():
            del self._channels[index]
        else:
            raise QISKitError('Index not in receiver channels.')
示例#21
0
def register(*args, provider_class=None, **kwargs):
    """
    Authenticate against an online backend provider.
    This is a factory method that returns the provider that gets registered.

    Args:
        args (tuple): positional arguments passed to provider class initialization
        provider_class (BaseProvider): provider class
        kwargs (dict): keyword arguments passed to provider class initialization.
            For the IBMQSingleProvider default this can include things such as:

                * token (str): The token used to register on the online backend such
                    as the quantum experience.
                * url (str): The url used for online backend such as the quantum
                    experience.
                * hub (str): The hub used for online backend.
                * group (str): The group used for online backend.
                * project (str): The project used for online backend.
                * proxies (dict): Proxy configuration for the API, as a dict with
                    'urls' and credential keys.
                * verify (bool): If False, ignores SSL certificates errors.

    Returns:
        BaseProvider: the provider instance that was just registered.

    Raises:
        QISKitError: if the provider could not be registered

    .. deprecated:: 0.6+
        After 0.6, this function is deprecated. Please use the methods in
        `qiskit.IBMQ` instead (`use_account()`) for using IBMQ
        accounts. For custom `Provider`s, please instantiate them directly.
    """
    if provider_class:
        warnings.warn(
            'The global registry of providers and register() is deprecated '
            'since 0.6. Please instantiate "{}()" directly.'.format(
                provider_class), DeprecationWarning)
        return provider_class(*args, **kwargs)
    else:
        warnings.warn(
            'register() will be deprecated after 0.6. Please use the '
            'qiskit.IBMQ.use_account() method instead.', DeprecationWarning)

    try:
        provider = IBMQ.use_account(*args, **kwargs)
    except Exception as ex:
        raise QISKitError(
            "Couldn't instantiate provider! Error: {0}".format(ex))

    return provider
示例#22
0
    def get_counts(self, name):
        """Get the histogram data of circuit name.

        The data from the a qasm circuit is dictionary of the format
        {’00000’: XXXX, ’00001’: XXXXX}.

        Args:
            name (str): the name of the quantum circuit.

        Returns:
            Dictionary: Counts {’00000’: XXXX, ’00001’: XXXXX}.
        """
        try:
            return self.get_data(name)['counts']
        except KeyError:
            raise QISKitError('No counts for circuit "{0}"'.format(name))
示例#23
0
    def get_ran_qasm(self, name):
        """Get the ran qasm for the named circuit and backend.

        Args:
            name (str): the name of the quantum circuit.

        Returns:
            A text version of the qasm file that has been run.
        """
        try:
            qobj = self._qobj
            for index in range(len(qobj["circuits"])):
                if qobj["circuits"][index]['name'] == name:
                    return qobj["circuits"][index]["compiled_circuit_qasm"]
        except KeyError:
            raise QISKitError('No  qasm for circuit "{0}"'.format(name))
示例#24
0
    def __iadd__(self, other):
        """Append a Result object to current Result object.

        Arg:
            other (Result): a Result object to append.
        Returns:
            The current object with appended results.
        """
        if self._qobj['config'] == other._qobj['config']:
            if isinstance(self._qobj['id'], str):
                self._qobj['id'] = [self._qobj['id']]
            self._qobj['id'].append(other._qobj['id'])
            self._qobj['circuits'] += other._qobj['circuits']
            self._result['result'] += other._result['result']
            return self
        else:
            raise QISKitError('Result objects have different configs and cannot be combined.')
示例#25
0
    def __init__(self, configuration):
        """Base class for backends.

        This method should initialize the module and its configuration, and
        raise an exception if a component of the module is
        not available.

        Args:
            configuration (dict): configuration dictionary

        Raises:
            FileNotFoundError if backend executable is not available.
            QISKitError: if there is no name in the configuration
        """
        if 'name' not in configuration:
            raise QISKitError('backend does not have a name.')
        self._configuration = configuration
示例#26
0
    def _get_backend_instance(self, backend_cls):
        """
        Return an instance of a backend from its class.

        Args:
            backend_cls (class): Backend class.
        Returns:
            BaseBackend: a backend instance.
        Raises:
            QISKitError: if the backend could not be instantiated.
        """
        # Verify that the backend can be instantiated.
        try:
            backend_instance = backend_cls(provider=self)
        except Exception as err:
            raise QISKitError('Backend %s could not be instantiated: %s' %
                              (backend_cls, err))

        return backend_instance
示例#27
0
    def get_counts(self, name=None):
        """Get the histogram data of circuit name.

        The data from the a qasm circuit is dictionary of the format
        {'00000': XXXX, '00001': XXXXX}.

        Args:
            name (hashable or None): the name of the quantum circuit.
                If None and there is only one circuit available, returns
                that one.

        Returns:
            Dictionary: Counts {'00000': XXXX, '00001': XXXXX}.

        Raises:
            QISKitError: if there are no counts for the circuit.
        """
        try:
            return self.get_data(name)['counts']
        except KeyError:
            raise QISKitError('No counts for circuit "{0}"'.format(name))
示例#28
0
def least_busy(backends):
    """
    Return the least busy available backend for those that
    have a `pending_jobs` in their `status`. Backends such as
    local backends that do not have this are not considered.

    Args:
        backends (list[BaseBackend]): backends to choose from

    Returns:
        BaseBackend: the the least busy backend

    Raises:
        QISKitError: if passing a list of backend names that is
            either empty or none have attribute ``pending_jobs``
    """
    try:
        return min([b for b in backends if b.status().operational],
                   key=lambda b: b.status().pending_jobs)
    except (ValueError, TypeError):
        raise QISKitError("Can only find least_busy backend from a non-empty list.")
示例#29
0
    def _wait_for_job(self, timeout=60, wait=5):
        """Wait until all online ran circuits of a qobj are 'COMPLETED'.

        Args:
            timeout (float or None): seconds to wait for job. If None, wait
                indefinitely.
            wait (float): seconds between queries

        Returns:
            Result: A result object.

        Raises:
            QISKitError: job didn't return status or reported error in status
        """
        start_time = time.time()
        api_result = self._update_status()
        while self._status not in self._final_states:
            elapsed_time = time.time() - start_time
            if timeout is not None and elapsed_time >= timeout:
                job_result = {
                    'id': self._id,
                    'status': 'ERROR',
                    'result': 'QISkit Time Out'
                }
                return Result(job_result)
            logger.info('status = %s (%d seconds)', api_result['status'],
                        elapsed_time)

            if 'status' not in api_result:
                self._exception = QISKitError(
                    "get_job didn't return status: %s" %
                    (pprint.pformat(api_result)))
                raise QISKitError("get_job didn't return status: %s" %
                                  (pprint.pformat(api_result)))

            if (api_result['status'] == 'ERROR_CREATING_JOB'
                    or api_result['status'] == 'ERROR_RUNNING_JOB'):
                job_result = {
                    'id': self._id,
                    'status': 'ERROR',
                    'result': api_result['status']
                }
                return Result(job_result)

            time.sleep(wait)
            api_result = self._update_status()

        if self.cancelled:
            job_result = {
                'id': self._id,
                'status': 'CANCELLED',
                'result': 'job cancelled'
            }
            return Result(job_result)

        elif self.exception:
            job_result = {
                'id': self._id,
                'status': 'ERROR',
                'result': str(self.exception)
            }
            return Result(job_result)

        if api_result is None:
            api_result = self._api.get_job(self._id)

        job_result_list = []
        for circuit_result in api_result['qasms']:
            this_result = {
                'data': circuit_result['data'],
                'name': circuit_result.get('name'),
                'compiled_circuit_qasm': circuit_result.get('qasm'),
                'status': circuit_result['status']
            }
            if 'metadata' in circuit_result:
                this_result['metadata'] = circuit_result['metadata']
            job_result_list.append(this_result)
        job_result = {
            'id': self._id,
            'status': api_result['status'],
            'used_credits': api_result.get('usedCredits'),
            'result': job_result_list
        }
        job_result['backend_name'] = self.backend_name
        return Result(job_result)
示例#30
0
def parallel_map(task, values, task_args=tuple(), task_kwargs={},  # pylint: disable=W0102
                 num_processes=CPU_COUNT):
    """
    Parallel execution of a mapping of `values` to the function `task`. This
    is functionally equivalent to::

        result = [task(value, *task_args, **task_kwargs) for value in values]

    On Windows this function defaults to a serial implimentation to avoid the
    overhead from spawning processes in Windows.

    Args:
        task (func): Function that is to be called for each value in ``task_vec``.
        values (array_like): List or array of values for which the ``task``
                            function is to be evaluated.
        task_args (list): Optional additional arguments to the ``task`` function.
        task_kwargs (dict): Optional additional keyword argument to the ``task`` function.
        num_processes (int): Number of processes to spawn.

    Returns:
        result: The result list contains the value of
                ``task(value, *task_args, **task_kwargs)`` for
                    each value in ``values``.

    Raises:
        QISKitError: If user interupts via keyboard.
    """
    # len(values) == 1
    if len(values) == 1:
        return [task(values[0], *task_args, **task_kwargs)]

    # Get last element of the receiver channels
    if any(rec.channels):
        progress_bar = None
        for idx in rec.channels:
            if rec.channels[idx].type == 'progressbar' and not rec.channels[idx].touched:
                progress_bar = rec.channels[idx]
                break
        if progress_bar is None:
            progress_bar = BaseProgressBar()
    else:
        progress_bar = BaseProgressBar()

    progress_bar.start(len(values))
    nfinished = [0]

    def _callback(x):  # pylint: disable=W0613
        nfinished[0] += 1
        progress_bar.update(nfinished[0])

    # Run in parallel if not Win and not in parallel already
    if platform.system() != 'Windows' and num_processes > 1 \
       and os.getenv('QISKIT_IN_PARALLEL') == 'FALSE':
        os.environ['QISKIT_IN_PARALLEL'] = 'TRUE'
        try:
            pool = Pool(processes=num_processes)

            async_res = [pool.apply_async(task, (value,) + task_args, task_kwargs,
                                          _callback) for value in values]

            while not all([item.ready() for item in async_res]):
                for item in async_res:
                    item.wait(timeout=0.1)

            pool.terminate()
            pool.join()

        except KeyboardInterrupt:
            pool.terminate()
            pool.join()
            progress_bar.finished()
            raise QISKitError('Keyboard interrupt in parallel_map.')

        progress_bar.finished()
        os.environ['QISKIT_IN_PARALLEL'] = 'FALSE'
        return [ar.get() for ar in async_res]

    # Cannot do parallel on Windows , if another parallel_map is running in parallel,
    # or len(values) == 1.
    results = []
    for _, value in enumerate(values):
        result = task(value, *task_args, **task_kwargs)
        results.append(result)
        _callback(0)
    progress_bar.finished()
    return results