예제 #1
0
def measure(self, qubit, cbit):
    """Measure quantum bit into classical bit (tuples).
     Args:
        qubit (QuantumRegister|tuple): quantum register
        cbit (ClassicalRegister|tuple): classical register
    Returns:
        qiskit.Instruction: the attached measure instruction.
    Raises:
        QiskitError: if qubit is not in this circuit or bad format;
            if cbit is not in this circuit or not creg.
    """
    if isinstance(qubit, QuantumRegister) and isinstance(cbit, ClassicalRegister) \
            and len(qubit) == len(cbit):
        instructions = InstructionSet()
        for i in range(qubit.size):
            instructions.add(self.measure((qubit, i), (cbit, i)))
        return instructions
    elif isinstance(qubit, QuantumRegister) and isinstance(
            cbit, ClassicalRegister) and len(qubit) != len(cbit):
        raise QiskitError(
            "qubit (%s) and cbit (%s) should have the same length" %
            (len(qubit), len(cbit)))
    elif not (isinstance(qubit, tuple) and isinstance(cbit, tuple)):
        raise QiskitError(
            "Both qubit <%s> and cbit <%s> should be Registers or formated as tuples. "
            "Hint: You can use subscript eg. cbit[0] to convert it into tuple."
            % (type(qubit).__name__, type(cbit).__name__))

    self._check_qubit(qubit)
    self._check_creg(cbit[0])
    cbit[0].check_range(cbit[1])
    return self._attach(Measure(qubit, cbit, self))
예제 #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 _check_creg(self, register):
     """Raise exception if r is not in this circuit or not creg."""
     if not isinstance(register, ClassicalRegister):
         raise QiskitError("Expected ClassicalRegister, but %s given" %
                           type(register))
     if not self.has_register(register):
         raise QiskitError("register '%s' not in this circuit" %
                           register.name)
예제 #4
0
 def add_register(self, *regs):
     """Add registers."""
     for register in regs:
         if register in self.qregs or register in self.cregs:
             raise QiskitError("register name \"%s\" already exists" %
                               register.name)
         if isinstance(register, QuantumRegister):
             self.qregs.append(register)
         elif isinstance(register, ClassicalRegister):
             self.cregs.append(register)
         else:
             raise QiskitError("expected a register")
예제 #5
0
def _best_subset(backend, n_qubits):
    """Computes the qubit mapping with the best
    connectivity.

    Parameters:
        backend (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(getattr(backend.configuration(), 'coupling_map', None))
    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
예제 #6
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])
예제 #7
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)
예제 #8
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 = []
        self.cregs = []
        self.add_register(*regs)
예제 #9
0
 def _modifiers(self, gate):
     """Apply any modifiers of this instruction to another one."""
     if self.control is not None:
         self.check_circuit()
         if not gate.circuit.has_register(self.control[0]):
             raise QiskitError("control register %s not found" %
                               self.control[0].name)
         gate.c_if(self.control[0], self.control[1])
예제 #10
0
 def c_if(self, classical, val):
     """Add classical control on register classical and value val."""
     self.check_circuit()
     self.circuit._check_creg(classical)
     if val < 0:
         raise QiskitError("control value should be non-negative")
     self.control = (classical, val)
     return self
예제 #11
0
    def _check_dups(self, qubits):
        """Raise exception.

        if list of qubits contains duplicates.
        """
        squbits = set(qubits)
        if len(squbits) != len(qubits):
            raise QiskitError("duplicate qubit arguments")
예제 #12
0
 def _check_qubit(self, qubit):
     """Raise exception if q is not an argument or not qreg in circuit."""
     self.check_circuit()
     self.circuit._check_qubit(qubit)
     if (qubit[0].name, qubit[1]) not in map(lambda x: (x[0].name, x[1]),
                                             self.qargs):
         raise QiskitError("qubit '%s[%d]' not argument of gate" %
                           (qubit[0].name, qubit[1]))
예제 #13
0
 def __init__(self, name, param, qargs, cargs, circuit=None):
     """Create a new instruction.
     Args:
         name (str): instruction name
         param (list[sympy.Basic|qasm.Node|int|float|complex|str]): list of parameters
         qargs (list[(QuantumRegister, index)]): list of quantum args
         cargs (list[(ClassicalRegister, index)]): list of classical args
         circuit (QuantumCircuit or Instruction): where the instruction is attached
     Raises:
         QiskitError: when the register is not in the correct format.
     """
     if not all(
         (type(i[0]), type(i[1])) == (QuantumRegister, int) for i in qargs):
         raise QiskitError("qarg not (QuantumRegister, int) tuple")
     if not all((type(i[0]), type(i[1])) == (ClassicalRegister, int)
                for i in cargs):
         raise QiskitError("carg not (ClassicalRegister, int) tuple")
     self.name = name
     self.param = []  # a list of gate params stored as sympy objects
     for single_param in param:
         # example: u2(pi/2, sin(pi/4))
         if isinstance(single_param, sympy.Basic):
             self.param.append(single_param)
         # example: OpenQASM parsed instruction
         elif isinstance(single_param, _node.Node):
             self.param.append(single_param.sym())
         # example: u3(0.1, 0.2, 0.3)
         elif isinstance(single_param, (int, float)):
             self.param.append(sympy.Number(single_param))
         # example: Initialize([complex(0,1), complex(0,0)])
         elif isinstance(single_param, complex):
             self.param.append(single_param.real +
                               single_param.imag * sympy.I)
         # example: snapshot('label')
         elif isinstance(single_param, str):
             self.param.append(sympy.Symbol(single_param))
         else:
             raise QiskitError("invalid param type {0} in instruction "
                               "{1}".format(type(single_param), name))
     self.qargs = qargs
     self.cargs = cargs
     self._decompositions = []
     self.control = None  # tuple (ClassicalRegister, int) for "if"
     self.circuit = circuit
예제 #14
0
    def __init__(self, size, name=None):
        """Create a new generic register.
        """

        if name is None:
            name = '%s%i' % (self.prefix, next(self.instances_counter))

        if not isinstance(name, str):
            raise QiskitError("The circuit name should be a string "
                              "(or None for autogenerate a name).")

        test = re.compile('[a-z][a-zA-Z0-9_]*')
        if test.match(name) is None:
            raise QiskitError("%s is an invalid OPENQASM register name." % name)

        self.name = name
        self.size = size
        if size <= 0:
            raise QiskitError("register size must be positive")
예제 #15
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")
예제 #16
0
    def __getitem__(self, key):
        """
        Arg:
            key (int): index of the bit/qubit to be retrieved.

        Returns:
            tuple[Register, int]: a tuple in the form `(self, key)`.

        Raises:
            QiskitError: if the `key` is not an integer.
            QiskitIndexError: if the `key` is not in the range
                `(0, self.size)`.
        """
        if not isinstance(key, int):
            raise QiskitError("expected integer index into register")
        self.check_range(key)
        return self, key
예제 #17
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
예제 #18
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.")
예제 #19
0
 def q_if(self, *qregs):
     """Add controls to this gate."""
     # pylint: disable=unused-argument
     raise QiskitError("control not implemented")
예제 #20
0
 def inverse(self):
     """Invert this gate."""
     raise QiskitError("inverse not implemented")
예제 #21
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 implementation 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 interrupts via keyboard.

    Events:
        terra.transpiler.parallel.start: The collection of parallel tasks are about to start.
        terra.transpiler.parallel.update: One of the parallel task has finished.
        terra.transpiler.parallel.finish: All the parallel tasks have finished.
    """
    if len(values) == 1:
        return [task(values[0], *task_args, **task_kwargs)]

    Publisher().publish("terra.transpiler.parallel.start", len(values))
    nfinished = [0]

    def _callback(_):
        nfinished[0] += 1
        Publisher().publish("terra.transpiler.parallel.done", 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()
            Publisher().publish("terra.parallel.parallel.finish")
            raise QiskitError('Keyboard interrupt in parallel_map.')

        Publisher().publish("terra.transpiler.parallel.finish")
        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)
    Publisher().publish("terra.transpiler.parallel.finish")
    return results
예제 #22
0
 def add(self, gate):
     """Add instruction to set."""
     if not isinstance(gate, Instruction):
         raise QiskitError("attempt to add non-Instruction" +
                           " to InstructionSet")
     self.instructions.append(gate)
예제 #23
0
 def check_circuit(self):
     """Raise exception if self.circuit is None."""
     if self.circuit is None:
         raise QiskitError("Instruction's circuit not assigned")