Skip to main content
IBM Quantum Platform

Notas de la versión de Qiskit 0.28


0.28.0

Terra 0.18.0

Preludio

Esta versión incluye muchas funciones nuevas y correcciones de errores. Lo más destacado de esta versión es la introducción de dos nuevos pases de transpilador, BIPMapping y DynamicalDecouplingque, combinados con el nuevo kwarg pulse_optimize en el pase UnitarySynthesis permite recrear los resultados de Quantum Volume 64 utilizando las técnicas descritas en : https://arxiv.org/abs/2008.08571. Estos nuevos pases y opciones del transpilador también son aplicables en general a la optimización de cualquier circuito.

Nuevas funciones

  • El kwarg measurement_error_mitgation para el constructor QuantumInstance constructor ahora se puede establecer en la clase TensoredMeasFitter de qiskit-ignis además de CompleteMeasFitter que ya era compatible. Si utiliza TensoredMeasFitter también podrá establecer el nuevo kwarg mit_pattern para especificar los qubits en los que utilizar TensoredMeasFitter . Puede consultar la documentación de mit_pattern en la documentación de TensoredMeasFitter para conocer el formato esperado.

  • Los métodos de descomposición para puertas de un solo qubit, especificados mediante el kwarg basis , en OneQubitEulerDecomposer se ha ampliado para incluir ahora también la base 'ZSXX' , para hacer uso de la puerta directa XX así como de la puerta X\sqrt{X}.

  • Añadidos dos nuevos pases AlignMeasures y ValidatePulseGates al módulo qiskit.transpiler.passes módulo. Estos pases son una optimización consciente del hardware y una rutina de validación que se utilizan para gestionar las restricciones de alineación en la asignación de tiempo de las instrucciones para un backend.

    Si un backend tiene una restricción en la alineación de las instrucciones Measure (en términos de cuantización en el tiempo), el paso AlignMeasures pass se utiliza para ajustar los retardos en un circuito programado para garantizar que cualquier instrucción Measure del circuito esté alineada dadas las restricciones del backend. El paso ValidatePulseGates pass se utiliza para comprobar si alguna puerta de impulsos personalizados (puertas que tienen una definición de impulsos personalizados en el atributo calibrations de un objeto QuantumCircuit ) son válidas dada una restricción de alineación para el backend de destino.

    En la página preset_passmangers utilizada por la función transpile() estos pases se activan automáticamente si la restricción de alineación, ya sea a través del kwarg dedicado timing_constraints en transpile() o tiene un atributo timing_constraints en el objeto BackendConfiguration del backend al que se dirige.

    Los backends de IBM Quantum Services (accesibles a través del paquete qiskit-ibmq-provider ) proporcionarán la información de alineación en un futuro próximo.

    Por ejemplo:

    from qiskit import circuit, transpile
    from qiskit.test.mock import FakeArmonk
    
    backend = FakeArmonk()
    
    qc = circuit.QuantumCircuit(1, 1)
    qc.x(0)
    qc.delay(110, 0, unit="dt")
    qc.measure(0, 0)
    qc.draw('mpl')
    qct = transpile(qc, backend, scheduling_method='alap',
                    timing_constraints={'acquire_alignment': 16})
    qct.draw('mpl')
  • Se ha añadido una nueva clase de pase de transpilador qiskit.transpiler.passes.BIPMapping que intenta encontrar el mejor diseño y enrutamiento a la vez resolviendo un problema BIP (programación binaria entera) como se describe en arXiv:2106.06446.

    El paso BIPMapping (denominado "mapping" para referirse a "layout and routing") representa el problema de mapping como un problema BIP (programación binaria entera) y se basa en CPLEX (cplex) para resolver el problema BIP. Las librerías dependientes incluyendo CPLEX pueden ser instaladas junto con qiskit-terra:

    pip install qiskit-terra[bip-mapper]

    Dado que la versión gratuita de CPLEX sólo puede resolver pequeños problemas BIP, es decir, el mapeo de circuitos con menos de unos 5 qubits, la versión de pago de CPLEX puede ser necesaria para mapear circuitos más grandes.

    El mapeador BIP se adapta mal al número de qubits o puertas. Por ejemplo, no funcionaría con coupling_map más allá de 10 qubits porque el solucionador BIP (CPLEX) no podría encontrar ninguna solución dentro del límite de tiempo predeterminado.

    Tenga en cuenta que, si desea fijar los qubits físicos que se utilizarán en el mapeo (por ejemplo, al ejecutar circuitos de volumen cuántico (QV)), deberá especificar coupling_map , que contiene únicamente los qubits que se utilizarán.

    He aquí un código de ejemplo mínimo para construir un gestor de pases para transpilar un circuito QV:

    num_qubits = 4  # QV16
    circ = QuantumVolume(num_qubits=num_qubits)
    
    backend = ...
    basis_gates = backend.configuration().basis_gates
    coupling_map = CouplingMap.from_line(num_qubits)  # supply your own coupling map
    
    def _not_mapped(property_set):
        return not property_set["is_swap_mapped"]
    
    def _opt_control(property_set):
        return not property_set["depth_fixed_point"]
    
    from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary as sel
    pm = PassManager()
    # preparation
    pm.append([
        Unroll3qOrMore(),
        TrivialLayout(coupling_map),
        FullAncillaAllocation(coupling_map),
        EnlargeWithAncilla(),
        BarrierBeforeFinalMeasurements()
    ])
    # mapping
    pm.append(BIPMapping(coupling_map))
    pm.append(CheckMap(coupling_map))
    pm.append(Error(msg="BIP mapper failed to map", action="raise"),
              condition=_not_mapped)
    # post optimization
    pm.append([
        Depth(),
        FixedPoint("depth"),
        Collect2qBlocks(),
        ConsolidateBlocks(basis_gates=basis_gates),
        UnitarySynthesis(basis_gates),
        Optimize1qGatesDecomposition(basis_gates),
        CommutativeCancellation(),
        UnrollCustomDefinitions(sel, basis_gates),
        BasisTranslator(sel, basis_gates)
    ], do_while=_opt_control)
    
    transpile_circ = pm.run(circ)
  • Se ha añadido un nuevo método constructor initialize_from() se ha añadido al método Schedule y ScheduleBlock . Este método inicializa un nuevo horario vacío que toma los atributos de otro horario. Por ejemplo:

    sched = Schedule(name='my_sched')
    new_sched = Schedule.initialize_from(sched)
    
    assert sched.name == new_sched.name
  • Se ha añadido un nuevo kwarg, line_discipline, a la función job_monitor() función. Este kwarg permite cambiar los caracteres de retorno de carro utilizados en la salida de job_monitor . El kwarg de line_discipline aparece por defecto en '\r', que es lo que se utilizaba antes.

  • La clase abstracta Pulse (que es la clase padre de clases como Waveform, Constanty Gaussian tiene ahora un nuevo kwarg en el constructor, limit_amplitude, que puede establecerse en False para desactivar el límite de amplitud previamente codificado en 1. También puede establecerse directamente como atributo de clase para cambiar el valor predeterminado global de una clase Pulse. Por ejemplo:

    from qiskit.pulse.library import Waveform
    
    # Change the default value of limit_amplitude to False
    Waveform.limit_amplitude = False
    wave = Waveform(2.0 * np.exp(1j * 2 * np.pi * np.linspace(0, 1, 1000)))
  • Se ha añadido una nueva clase PauliListse ha añadido al módulo qiskit.quantum_info módulo. Esta clase se utiliza para representar eficientemente una lista de Pauli operadores. Esta nueva clase hereda de la misma clase padre que la ya existente PauliTable (y por lo tanto se puede utilizar mayoritariamente de forma intercambiable), sin embargo difiere de la PauliTable porque la clase qiskit.quantum_info.PauliList puede gestionar las fases de Z4.

  • Añadido un nuevo pase de transpilador, RemoveBarriersa qiskit.transpiler.passes. Este pase se utiliza para eliminar todas las barreras de un circuito.

  • Añade una nueva clase de optimizador SciPyOptimizeral módulo qiskit.algorithms.optimizers módulo. Esta clase es una simple clase de envoltura de la función scipy.optimize.minimize (documentación ) que permite el uso de todos los solucionadores de optimización y todos los parámetros (por ejemplo, devolución de llamada) que son compatibles con scipy.optimize.minimize. Por ejemplo:

    from qiskit.algorithms.optimizers import SciPyOptimizer
    
    values = []
    
    def callback(x):
        values.append(x)
    
    optimizer = SciPyOptimizer("BFGS", options={"maxiter": 1000}, callback=callback)
  • El pase HoareOptimizer pass se ha mejorado de modo que ahora puede sustituir a a ControlledGate en un circuito con la puerta base si todos los qubits de control están en el estado 1|1\rangle.

  • Añadidos dos nuevos métodos is_successor() y is_predecessor()a la clase DAGCircuit clase. Estas funciones se utilizan para comprobar si un nodo es sucesor o predecesor de otro nodo de la tabla DAGCircuit.

  • Se ha añadido un nuevo pase de transpilador RZXCalibrationBuilderNoEchose ha añadido al módulo qiskit.transpiler.passes módulo. Este paso es similar al existente RZXCalibrationBuilder en que crea calibraciones para un RZXGate(theta), sin embargo RZXCalibrationBuilderNoEcho lo hace sin insertar los pulsos de eco en el programa de pulsos. Esto permite exponer el eco en la secuencia de resonancia cruzada como puertas para que el transpilador pueda simplificarlas. El RZXCalibrationBuilderNoEcho pass sólo admite la dirección nativa de hardware de la dirección CXGate.

  • Se ha añadido un nuevo kwarg, wrap, al compose() método de QuantumCircuit. Esto permite elegir si los circuitos compuestos deben envolverse en una instrucción o no. Por defecto es False, es decir, sin envoltorio. Por ejemplo:

    from qiskit import QuantumCircuit
    circuit = QuantumCircuit(2)
    circuit.h([0, 1])
    other = QuantumCircuit(2)
    other.x([0, 1])
    print(circuit.compose(other, wrap=True))  # wrapped
    print(circuit.compose(other, wrap=False))  # not wrapped
  • Se ha añadido un nuevo atributo control_channelsse ha añadido a la clase PulseBackendConfiguration clase. Este atributo representa los canales de control en un backend como un mapeo de qubits a una lista de ControlChannel objetos.

  • Se ha añadido un nuevo kwarg, epsilon, al constructor de la clase Isometry y al método correspondiente QuantumCircuit correspondiente isometry(). Este kwarg permite establecer opcionalmente la tolerancia épsilon utilizada por una puerta Isometry . Por ejemplo:

    import numpy as np
    from qiskit import QuantumRegister, QuantumCircuit
    
    tolerance = 1e-8
    iso = np.eye(2,2)
    num_q_output = int(np.log2(iso.shape[0]))
    num_q_input = int(np.log2(iso.shape[1]))
    q = QuantumRegister(num_q_output)
    qc = QuantumCircuit(q)
    
    qc.isometry(iso, q[:num_q_input], q[num_q_input:], epsilon=tolerance)
  • Añadido un pase transpiler, DynamicalDecouplinga qiskit.transpiler.passes para insertar secuencias de desacoplamiento dinámico en periodos inactivos de un circuito (después de mapear a qubits físicos y programar). El pase permite controlar la secuencia de puertas DD, el espaciado entre ellas y los qubits sobre los que aplicarlas. Por ejemplo:

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import XGate
    from qiskit.transpiler import PassManager, InstructionDurations
    from qiskit.transpiler.passes import ALAPSchedule, DynamicalDecoupling
    from qiskit.visualization import timeline_drawer
    
    circ = QuantumCircuit(4)
    circ.h(0)
    circ.cx(0, 1)
    circ.cx(1, 2)
    circ.cx(2, 3)
    circ.measure_all()
    
    durations = InstructionDurations(
        [("h", 0, 50), ("cx", [0, 1], 700), ("reset", None, 10),
         ("cx", [1, 2], 200), ("cx", [2, 3], 300),
         ("x", None, 50), ("measure", None, 1000)]
    )
    
    dd_sequence = [XGate(), XGate()]
    
    pm = PassManager([ALAPSchedule(durations),
                      DynamicalDecoupling(durations, dd_sequence)])
    circ_dd = pm.run(circ)
    timeline_drawer(circ_dd)
  • El método QuantumCircuit método qasm() tiene un nuevo kwarg, encoding, que puede utilizarse para establecer opcionalmente la codificación de caracteres de un archivo QASM de salida generado por la función. Puede definirse como cualquier códec válido o cadena de alias del módulo de códecs de la biblioteca estándar Python.

  • Añadida una nueva clase EvolvedOperatorAnsatzal módulo qiskit.circuit.library módulo. Este circuito de biblioteca, que anteriormente se encontraba en Qiskit Nature, se puede utilizar para construir circuitos ansatz que consisten en operadores evolucionados en el tiempo, donde el tiempo de evolución es un parámetro variacional. Ejemplos de tales circuitos ansatz incluyen la clase UCCSD en el módulo chemistry de Qiskit Nature o la clase QAOAAnsatz clase

  • Una nueva clase de backend falso está disponible en qiskit.test.mock para el backend ibmq_guadalupe . Al igual que los demás backends falsos, incluye una instantánea de los datos de calibración (es decir, backend.defaults()) y los datos de error (es decir, backend.properties()) tomados del sistema real, y pueden utilizarse para pruebas locales, compilación y simulación.

  • Un nuevo método children() para la clase Schedule se ha añadido un nuevo método para la clase Este método se utiliza para devolver los componentes del horario hijo del objeto Schedule como una tupla. Devuelve las programaciones anidadas sin aplanar. Este método es equivalente al método privado _children() pero tiene una interfaz pública y estable.

  • Se ha añadido una nueva clase de optimizador GradientDescentse ha añadido al módulo qiskit.algorithms.optimizers módulo. Esta clase optimizadora implementa un algoritmo estándar de optimización por descenso de gradiente para su uso con algoritmos variacionales cuánticos, como por ejemplo VQE. Para obtener una descripción detallada y ejemplos sobre cómo utilizar esta clase, consulte la documentación de la clase GradientDescent documentación de la clase.

  • Se ha añadido una nueva clase de optimizador QNSPSAse ha añadido al módulo qiskit.algorithms.optimizers módulo. Esta clase implementa el algoritmo SPSA Natural Cuántico (QN-SPSA), una generalización del algoritmo 2-SPSA, y estima la Matriz de Información Fisher Cuántica en lugar de la Hessiana para obtener una estimación estocástica del Gradiente Natural Cuántico. Para ver ejemplos de cómo utilizar este nuevo optimizador, consulte la documentación de la clase QNSPSA documentación de la clase.

  • Se ha añadido un nuevo kwarg, second_order, al constructor de la clase SPSA en el módulo qiskit.algorithms.optimizers módulo. Si se configura en True , permite utilizar SPSA de segundo orden. El SPSA de segundo orden, o 2-SPSA, es una extensión del algoritmo SPSA ordinario que permite estimar el hessiano junto con el gradiente, lo que se utiliza para precondicionar el gradiente antes del paso de actualización de parámetros. Como método de segundo orden, intenta mejorar la convergencia del SPSA. Para ver ejemplos de cómo utilizar esta opción, consulte la documentación de la clase SPSA documentación de la clase.

  • Cuando se utiliza el modo de salida latex o latex_source de circuit_drawer() o el modo draw() de QuantumCircuit el kwarg style puede utilizarse ahora igual que con el formato de salida mpl . Sin embargo, a diferencia del modo de salida mpl , sólo se utilizará el campo displaytext cuando se utilicen los modos de salida latex o latex_source (porque ninguno de los dos admite color).

  • Cuando se utilizan los métodos de salida mpl o latex para la función circuit_drawer() o la función draw() de QuantumCircuitahora puede utilizar el formato de modo matemático para el texto y establecer el formato de color (sólompl ) estableciendo el kwarg style como un dict con un nombre o etiqueta generado por el usuario. Por ejemplo, para añadir subíndices y cambiar el color de una puerta:

    from qiskit import QuantumCircuit
    from qiskit.circuit.library import HGate
    qc = QuantumCircuit(3)
    qc.append(HGate(label='h1'), [0])
    qc.append(HGate(label='h2'), [1])
    qc.append(HGate(label='h3'), [2])
    qc.draw('mpl', style={'displaytext': {'h1': 'H_1', 'h2': 'H_2', 'h3': 'H_3'},
        'displaycolor': {'h2': ('#EEDD00', '#FF0000')}})
  • Añadidas tres nuevas clases, CDKMRippleCarryAdderClassicalAdder y DraperQFTAdderal módulo qiskit.circuit.library módulo. Estas nuevas clases de circuitos se utilizan para realizar la suma clásica de dos registros de qubits de igual tamaño. Para dos registros an|a\rangle_n y bn|b\rangle_n en nn qubits, las tres nuevas clases realizan la operación:

anbnana+bn+1.|a\rangle_n |b\rangle_n \mapsto |a\rangle_n |a + b\rangle_{n + 1}.

Por ejemplo:

from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import CDKMRippleCarryAdder
from qiskit.quantum_info import Statevector

# a encodes |01> = 1
a = QuantumCircuit(2)
a.x(0)

# b encodes |10> = 2
b = QuantumCircuit(2)
b.x(1)

# adder on 2-bit numbers
adder = CDKMRippleCarryAdder(2)

# add the state preparations to the front of the circuit
adder.compose(a, [0, 1], inplace=True, front=True)
adder.compose(b, [2, 3], inplace=True, front=True)

# simulate and get the state of all qubits
sv = Statevector(adder)
counts = sv.probabilities_dict()
state = list(counts.keys())[0]  # we only have a single state

# skip the input carry (first bit) and the register |a> (last two bits)
result = state[1:-2]
print(result)  # '011' = 3 = 1 + 2
  • Añadidas dos nuevas clases RGQFTMultiplier y HRSCumulativeMultiplieral módulo qiskit.circuit.library módulo. Estas clases se utilizan para realizar la multiplicación clásica de dos registros qubit de igual tamaño. Para dos registros an|a\rangle_n y bn|b\rangle_n en nn qubits, las dos nuevas clases realizan la operación
anbn02nanbnab2n.|a\rangle_n |b\rangle_n |0\rangle_{2n} \mapsto |a\rangle_n |b\rangle_n |a \cdot b\rangle_{2n}.

Por ejemplo:

from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import RGQFTMultiplier
from qiskit.quantum_info import Statevector

num_state_qubits = 2

# a encodes |11> = 3
a = QuantumCircuit(num_state_qubits)
a.x(range(num_state_qubits))

# b encodes |11> = 3
b = QuantumCircuit(num_state_qubits)
b.x(range(num_state_qubits))

# multiplier on 2-bit numbers
multiplier = RGQFTMultiplier(num_state_qubits)

# add the state preparations to the front of the circuit
multiplier.compose(a, [0, 1], inplace=True, front=True)
multiplier.compose(b, [2, 3], inplace=True, front=True)

# simulate and get the state of all qubits
sv = Statevector(multiplier)
counts = sv.probabilities_dict(decimals=10)
state = list(counts.keys())[0]  # we only have a single state

# skip both input registers
result = state[:-2*num_state_qubits]
print(result)  # '1001' = 9 = 3 * 3
  • La clase Delay ahora puede aceptar una clase ParameterExpression o Parameter para el kwarg duration en su constructor y para su atributo duration atributo.

    Por ejemplo:

    idle_dur = Parameter('t')
    qc = QuantumCircuit(1, 1)
    qc.x(0)
    qc.delay(idle_dur, 0, 'us')
    qc.measure(0, 0)
    print(qc)  # parameterized delay in us (micro seconds)
    
    # assign before transpilation
    assigned = qc.assign_parameters({idle_dur: 0.1})
    print(assigned)  # delay in us
    transpiled = transpile(assigned, some_backend_with_dt)
    print(transpiled)  # delay in dt
    
    # assign after transpilation
    transpiled = transpile(qc, some_backend_with_dt)
    print(transpiled)  # parameterized delay in dt
    assigned = transpiled.assign_parameters({idle_dur: 0.1})
    print(assigned)  # delay in dt
  • Se ha introducido un nuevo formato de serialización binaria, QPY. Está diseñado para ser un formato de serialización binario rápido que es compatible con versiones anteriores (los archivos QPY generados con versiones anteriores de Qiskit pueden ser cargados por versiones más recientes de Qiskit) que es nativo de Qiskit. La herramienta de serialización QPY está disponible a través del módulo qiskit.circuit.qpy_serialization . Por ejemplo, para generar un fichero QPY:

    from datetime import datetime
    
    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit import qpy_serialization
    
    qc = QuantumCircuit(
      2, metadata={'created_at': datetime.utcnow().isoformat()}
    )
    qc.h(0)
    qc.cx(0, 1)
    qc.measure_all()
    
    circuits = [qc] * 5
    
    with open('five_bells.qpy', 'wb') as qpy_file:
        qpy_serialization.dump(circuits, qpy_file)

    A continuación, se pueden cargar los cinco circuitos guardados en el archivo QPY con:

    from qiskit.circuit.qpy_serialization
    
    with open('five_bells.qpy', 'rb') as qpy_file:
        circuits = qpy_serialization.load(qpy_file)

    La especificación del formato de archivo QPY está disponible en la documentación del módulo.

  • La clase TwoQubitBasisDecomposer clase se ha actualizado para realizar descomposiciones óptimas del pulso para una base con puertas CX, √X y Rz virtual como se describe en https://arxiv.org/pdf/2008.08571. Pulso óptimo significa aquí que la duración de las compuertas entre las compuertas CX de la descomposición se reduce a cambio de posiblemente más compuertas locales antes o después de todas las compuertas CX de tal manera que, cuando se compone en un circuito, existe la posibilidad de compresión de qubit único con compuertas vecinas reduciendo la duración total de la secuencia.

    Se ha añadido un nuevo argumento de palabra clave, `pulse_optimize, al constructor de TwoQubitBasisDecomposer para controlar esto:

    • None: Intento de descomposición óptima del pulso. Si se desconoce una descomposición óptima del pulso para la base del descomponedor, vuelve a la descomposición estándar sin previo aviso. Ésta es el ajuste predeterminado.
    • True: Intento de descomposición óptima del pulso. Si se desconoce una descomposición óptima del pulso para la base del descomponedor, plantee QiskitError.
    • False: No intente la descomposición óptima del pulso.

    Por ejemplo:

    from qiskit.quantum_info import TwoQubitBasisDecomposer
    from qiskit.circuit.library import CXGate
    from qiskit.quantum_info import random_unitary
    
    unitary_matrix = random_unitary(4)
    
    decomposer = TwoQubitBasisDecomposer(CXGate(), euler_basis="ZSX", pulse_optimize=True)
    circuit = decomposer(unitary_matrix)
  • El transpiler pass UnitarySynthesis situado en qiskit.transpiler.passes se ha actualizado para permitir la descomposición óptima del pulso. Esto se hace principalmente con el argumento de la palabra clave pulse_optimize que se añadió al constructor y se utiliza para controlar si se realiza la síntesis óptima del pulso. El comportamiento de este kwarg refleja el kwarg pulse_optimize en el constructor de la clase TwoQubitBasisDecomposer de la clase. Además, el constructor tiene otro nuevo argumento de palabra clave, synth_gates, que se utiliza para especificar la lista de nombres de puerta sobre la que se debe intentar la síntesis. Si None y pulse_optimize son False o None, utilice "unitary". Si None y pulse_optimize es True, utilice "unitary" y "swap". Dado que la dirección de la puerta CX en la síntesis es arbitraria, se añade otro argumento de palabra clave, natural_direction, para considerar primero un mapa de acoplamiento y después CXGate duraciones al elegir para qué dirección de CX generar la síntesis.

    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler import PassManager, CouplingMap
    from qiskit.transpiler.passes import TrivialLayout, UnitarySynthesis
    from qiskit.test.mock import FakeVigo
    from qiskit.quantum_info.random import random_unitary
    
    backend = FakeVigo()
    conf = backend.configuration()
    coupling_map = CouplingMap(conf.coupling_map)
    triv_layout_pass = TrivialLayout(coupling_map)
    circ = QuantumCircuit(2)
    circ.unitary(random_unitary(4), [0, 1])
    unisynth_pass = UnitarySynthesis(
        basis_gates=conf.basis_gates,
        coupling_map=None,
        backend_props=backend.properties(),
        pulse_optimize=True,
        natural_direction=True,
        synth_gates=['unitary'])
    pm = PassManager([triv_layout_pass, unisynth_pass])
    optimal_circ = pm.run(circ)
  • Se ha añadido una nueva opción de base, 'XZX', para el argumento basis OneQubitEulerDecomposer clase.

  • Se ha añadido un nuevo método, get_instructions()a la clase QuantumCircuit clase. Este método se utiliza para devolver todos los Instruction objetos del circuito que tengan un name que coincide con el argumento name proporcionado junto con sus listas asociadas qargs y cargs de Qubit y Clbit asociados.

  • Se ha añadido un nuevo extra opcional all al paquete qiskit-terra. Esto permite instalar todos los requisitos opcionales con un solo extra, por ejemplo: pip install 'qiskit-terra[all]', Anteriormente, era necesario listar todos los extras individualmente para instalar todas las dependencias opcionales simultáneamente.

  • Añadidas dos nuevas clases ProbDistribution y QuasiDistribution para tratar las distribuciones de probabilidad y las distribuciones de cuasiprobabilidad, respectivamente. Ambos objetos son subclases de diccionario que añaden métodos adicionales para trabajar con distribuciones de probabilidad y cuasiprobabilidad.

  • Se ha añadido una nueva propiedad settings a la clase base abstracta Optimizer clase base abstracta en la que se basan todas las clases optimizadoras del qiskit.algorithms.optimizers del módulo. Esta propiedad devolverá un diccionario Python de la configuración del optimizador que se puede utilizar para instanciar otra instancia de la misma clase de optimizador. Por ejemplo:

    from qiskit.algorithms.optimizers import GradientDescent
    
    optimizer = GradientDescent(maxiter=10, learning_rate=0.01)
    settings = optimizer.settings
    new_optimizer = GradientDescent(**settings)

    El diccionario settings también es potencialmente útil para serializar objetos del optimizador utilizando JSON u otro formato de serialización.

  • Se ha añadido una nueva función, set_config(), al módulo qiskit.user_config . Esta función permite establecer valores en una configuración de usuario desde la API de Qiskit. Por ejemplo:

    from qiskit.user_config import set_config
    set_config("circuit_drawer", "mpl", section="default", file="settings.conf")

    con lo que se añadirá el valor circuit_drawer = mpl a la sección default del archivo settings.conf .

    Si no se especifica ningún argumento file_path , se actualizará la ruta utilizada actualmente para el archivo de configuración del usuario (ya sea el valor de la variable de entorno QISKIT_SETTINGS si está establecida o la ubicación predeterminada ~/.qiskit/settings.conf). Sin embargo, los cambios en el archivo de configuración existente no se reflejarán en la sesión actual, ya que el archivo de configuración se analiza en el momento de la importación.

  • Añadida una nueva clase de estado StabilizerStateal módulo qiskit.quantum_info módulo. Esta clase representa el estado de un simulador de estabilizador utilizando la convención de Aaronson y Gottesman (2004).

  • Se han añadido dos nuevas opciones, 'value' y 'value_desc' , al kwarg sort de la función qiskit.visualization.plot_histogram() función. Cuando sort se establece en cualquiera de estas opciones, la visualización de salida ordenará el eje x en función de la probabilidad máxima para cada cadena de bits. Por ejemplo:

    from qiskit.visualization import plot_histogram
    
    counts = {
      '000': 5,
      '001': 25,
      '010': 125,
      '011': 625,
      '100': 3125,
      '101': 15625,
      '110': 78125,
      '111': 390625,
    }
    plot_histogram(counts, sort='value')

Problemas conocidos

  • Cuando se ejecuta parallel_map() (y las funciones que llaman internamente a parallel_map() como transpile() y assemble()) en Python 3.9 con QISKIT_PARALLEL establecido a True en algunos escenarios es posible que el programa se bloquee y nunca termine de ejecutarse. Para evitar que esto ocurra, se ha cambiado el valor por defecto de Python 3.9 para que no se ejecute en paralelo, pero si QISKIT_PARALLEL se activa explícitamente, esto puede seguir ocurriendo.

Notas de actualización

  • La versión mínima de la dependencia retworkx se ha aumentado a la versión 0.9.0. Esto se hizo para utilizar las nuevas API introducidas en esa versión, que mejoraron el rendimiento de algunos pases del transpilador.

  • El valor por defecto para QISKIT_PARALLEL en entornos Python 3.9 ha cambiado a False, esto significa que cuando se ejecute en Python 3.9 por defecto no se utilizará el multiprocesamiento. Esto se ha hecho para evitar un posible problema de bloqueo o cuelgue que puede producirse al ejecutar multiprocesamiento en Python 3.9 (para más detalles, consulte la sección de problemas conocidos). Aún es posible activarlo manualmente estableciendo explícitamente la variable de entorno QISKIT_PARALLEL en TRUE.

  • Las clases backend falsas existentes en qiskit.test.mock ahora implementan estrictamente la interfaz BackendV1 interfaz. Esto significa que si estuviera construyendo manualmente QasmQobj o PulseQobj para utilizarlo con el método run() ya no funcionará. El método run() sólo acepta QuantumCircuit o Schedule objetos ahora. Esto era necesario para permitir la prueba de nuevos backends implementados sin qobj que anteriormente no tenían ninguna prueba dentro de qiskit terra. Si necesita aprovechar los backends falsos con QasmQobj o PulseQobj se han añadido nuevos objetos backend heredados falsos para probar explícitamente la interfaz de proveedores heredados. Se eliminará una vez que la interfaz heredada sea obsoleta y eliminada. En el futuro, los nuevos backends falsos sólo implementarán la interfaz BackendV1 y no se añadirán nuevas clases de backend heredadas para los nuevos backends falsos.

  • Al crear un Pauli con una etiqueta de cadena no válida, se produce un error QiskitError . Se trata de un cambio con respecto a versiones anteriores, en las que se producía un mensaje AttributeError si la etiqueta de cadena no era válida. Este cambio se ha realizado para garantizar que el mensaje de error sea más informativo y distinto de un AttributeError genérico.

  • La representación del programa de salida del generador de impulsos (qiskit.pulse.builder.build()) ha cambiado de Schedule a a ScheduleBlock. Esta nueva representación desactiva algunas operaciones relacionadas con la temporización, como el desplazamiento y la inserción. Sin embargo, esto permite parametrizar la duración de las instrucciones en el contexto del constructor. Por ejemplo:

    from qiskit import pulse
    from qiskit.circuit import Parameter
    
    dur = Parameter('duration')
    
    with pulse.build() as sched:
        with pulse.align_sequential():
            pulse.delay(dur, pulse.DriveChannel(1))
            pulse.play(pulse.Gaussian(dur, 0.1, dur/4), pulse.DriveChannel(0))
    
    assigned0 = sched.assign_parameters({dur: 100})
    assigned1 = sched.assign_parameters({dur: 200})

    Puedes pasar directamente las programaciones de duración asignada al ensamblador (o backend), o puedes adjuntarlas a tu circuito cuántico como puertas de impulsos.

  • La biblioteca tweedledum, que antes era una dependencia opcional, se ha convertido en un requisito. Esto se hizo debido al amplio uso de la aplicación PhaseOracle (que depende de tener instalado tweedledum) con varios algoritmos de qiskit.algorithms.

  • El extra opcional full-featured-simulators que anteriormente podía utilizarse para instalar qiskit-aer con algo como pip install qiskit-terra[full-featured-simulators] ha sido eliminado del paquete qiskit-terra. Si esto se estaba utilizando para instalar qiskit-aer con qiskit-terra en su lugar debe confiar en el metapaquete qiskit o simplemente instalar qiskit-terra y qiskit-aer junto con pip install qiskit-terra qiskit-aer.

  • Se ha añadido un nuevo requisito symengine para los usuarios de Linux (en x86_64, aarch64, y ppc64le ) y macOS ( x86_64 y arm64 ). Es una dependencia opcional en Windows (y está disponible en PyPi como paquete precompilado para 64bit Windows) y otras arquitecturas. Si se instala proporciona un rendimiento significativamente mejorado para la evaluación de Parameter y ParameterExpression objetos.

  • Todas las clases de circuito de la biblioteca, es decir, todas las QuantumCircuit derivadas en qiskit.circuit.libraryestán ahora envueltas en un Instruction (o Gatesi son unitarias). Por ejemplo, importando y dibujando el QFT circuito:

    antes parecía

                                              ┌───┐
    q_0: ────────────────────■────────■───────┤ H ├─X─
                       ┌───┐ │        │P/2) └───┘ │
    q_1: ──────■───────┤ H ├─┼────────■─────────────┼─
         ┌───┐ │P/2) └───┘ │P/4)
    q_2: ┤ H ├─■─────────────■──────────────────────X─
         └───┘

    y ahora parece

         ┌──────┐
    q_0:0
         │      │
    q_1:1 QFT ├
         │      │
    q_2:2
         └──────┘

    Para obtener el circuito antiguo, puede llamar al método decompose() en el circuito

    Este cambio se hizo principalmente por coherencia, ya que antes de esta versión algunas clases de circuito en qiskit.circuit.library estaban antes envueltas en un Instruction o Gate pero no todas.

Notas sobre características en desuso

  • La clase qiskit.exceptions.QiskitIndexError está obsoleta y se eliminará en una futura versión. Esta excepción no estaba siendo usada activamente por nada en Qiskit, si la estabas usando puedes crear una clase de excepción personalizada para reemplazarla.
  • Los kwargs epsilon y factr para el qiskit.algorithms.optimizers.L_BFGS_B y factr de la clase P_BFGS están obsoletos y se eliminarán en una futura versión. Por favor, utilice eps karg en lugar de epsilon. El factr kwarg se sustituye por ftol. La relación entre ambos es ftol = factr * numpy.finfo(float).eps. Este cambio se ha realizado para ser coherente con el uso del método 'L-BFGS-B' de las funciones scipy.optimize.minimize . Consulte la documentación de : scipy.optimize.minimize(method='L-BFGS-B') para obtener más información sobre cómo se utilizan estos nuevos parámetros.
  • La interfaz de proveedores heredada, que consistía en las clases abstractas qiskit.providers.BaseBackend, qiskit.providers.BaseJob, y qiskit.providers.BaseProvider , ha quedado obsoleta y se eliminará en una futura versión. En su lugar, debe utilizar la interfaz versionada, cuyas versiones de clases abstractas actuales son qiskit.providers.BackendV1, qiskit.providers.JobV1y qiskit.providers.ProviderV1. Los objetos de V1 son en su mayoría compatibles con versiones anteriores para facilitar la migración de la interfaz heredada a la versionada. Sin embargo, es de esperar que las futuras versiones de las interfaces abstractas diverjan más. Puede consultar la qiskit.providers para más detalles de alto nivel sobre la interfaz versionada.
  • El kwarg condition al constructor DAGDepNode junto con el atributo condition correspondiente del constructor DAGDepNode han quedado obsoletos y se eliminarán en una futura versión. En cambio, puede acceder a condition de un DAGDepNode si el nodo es de tipo op, utilizando DAGDepNode.op.condition.
  • El atributo condition de la clase DAGNode ha quedado obsoleto y se eliminará en una futura versión. En cambio, puede acceder a condition de un objeto DAGNode si el nodo es de tipo op, utilizando DAGNode.op.condition.
  • La sintaxis del generador de impulsos (qiskit.pulse.builder.build()) qiskit.pulse.builder.inline() está obsoleta y se eliminará en una futura versión. En lugar de utilizar este contexto, puede simplemente eliminar los contextos de alineación dentro del contexto en línea.
  • La sintaxis del generador de impulsos (qiskit.pulse.builder.build()) qiskit.pulse.builder.pad() está obsoleta y se eliminará en una futura versión. Esto se hizo porque el ScheduleBlock ahora devuelto por el constructor de pulsos no soporta el método .insert (y no hay sintaxis de inserción en el constructor). Ya no es necesario utilizar marcadores de posición para bloquear la inserción de otras instrucciones.

Corrección de errores

  • En OneQubitEulerDecomposer y TwoQubitBasisDecomposer para la síntesis de puertas de uno y dos qubits se han mejorado para ajustar las tolerancias, mejorar la repetibilidad y la simplificación, y corregir varios errores de seguimiento de fase global.

  • Se ha corregido un problema en la asignación del atributo name al atributo Gate generada por múltiples llamadas al método inverse`() . Antes de esta corrección, cuando se llamaba a inverse`() , se añadía incondicionalmente _dg en cada llamada a la función inversa. Esto se ha corregido para que en una segunda llamada de inverse`() el sufijo _dg sea eliminado.

  • Fija las condiciones de comprobación de trivialidad de CZGate, CRZGate, CU1Gate y MCU1Gate en el HoareOptimizer pasar. Anteriormente, en algunos casos el optimizador eliminaba estas puertas rompiendo la equivalencia semántica de la transformación.

  • Se ha corregido un problema al convertir un ListOp objeto de PauliSumOp objetos utilizando PauliExpectation o AerPauliExpectation. Anteriormente, aparecía una advertencia sobre la conversión a una representación de Pauli, que es potencialmente costosa. Esto se ha solucionado convirtiendo internamente el archivo ListOp a un SummedOp de los objetos PauliOp ahora crea un objeto PauliSumOp que es más eficiente. Corregido #6159

  • Se ha solucionado un problema con la clase NLocal en el módulo qiskit.circuit.library que no lanzaba correctamente una excepción en la inicialización del objeto si se utilizaba un tipo no válido para el kwarg reps , lo que provocaba posteriormente un error de ejecución inesperado. Ahora se generará correctamente un TypeError si el kwarg reps no es un valor int . Corregido #6515

  • Se ha solucionado un problema por el que la clase TwoLocal en el módulo qiskit.circuit.library no aceptaba los tipos enteros de numpy (por ejemplo, numpy.int32, numpy.int64, etc) como entrada válida para el kwarg entanglement . Corregido #6455

  • Al cargar un archivo o cadena OpenQASM2 con los constructores from_qasm_file() o from_qasm_str() para la clase QuantumCircuit clase, si el circuito OpenQASM2 contiene una instrucción con el nombre delay ésta será mapeada a una qiskit.circuit.Delay instrucción. Por ejemplo:

    from qiskit import QuantumCircuit
    
    qasm = """OPENQASM 2.0;
    include "qelib1.inc";
    opaque delay(time) q;
    qreg q[1];
    delay(172) q[0];
    u3(0.1,0.2,0.3) q[0];
    """
    circuit = QuantumCircuit.from_qasm_str(qasm)
    circuit.draw()

    Corregido #6510

  • Se ha solucionado un problema con la adición entre PauliSumOp que tenían ParameterExpression coeficientes. Anteriormente, esto provocaba una excepción en QiskitError porque la adición de la etiqueta ParameterExpression no se gestionaba correctamente. Esto se ha corregido para que se pueda realizar la adición entre PauliSumOp objetos con ParameterExpression coeficientes.

  • Se ha corregido un problema con la inicialización de la clase AmplificationProblem clase El kwarg de is_good_state era un campo obligatorio, pero se trataba incorrectamente como opcional (y se documentaba como tal). Esto se ha corregido y actualizado para que, a menos que la entrada oracle sea un objeto PhaseOracle (que proporciona su propio método de evaluación) el campo es obligatorio y generará un TypeError cuando se construya sin is_good_state.

  • Se ha corregido un problema por el que, al añadir un control a un ControlledGate con controles abiertos desactivaba los controles abiertos internos. Correcciones #5857

  • Se ha solucionado un problema con el método convert() de la clase PauliExpectation cuando se llamaba a un operador que no era Hermitiano devolvía un resultado incorrecto. Corregido #6307

  • Se ha corregido un problema con la función qiskit.pulse.transforms.inline_subroutines() que anteriormente no eliminaba correctamente todos los componentes anidados cuando se invocaba en programaciones anidadas. Corregido #6321

  • Se ha corregido un problema al pasar una llamada parcialmente vinculada creada con la función functools.partial() de la biblioteca estándar Python como kwarg schedule al método add() de la clase InstructionScheduleMap que anteriormente provocaba un error. Corregido #6278

  • Se ha solucionado un problema con el PiecewiseChebyshev cuando se establecía el valor breakpoints a None en un objeto existente se trataba incorrectamente como un punto de interrupción. Esto se ha corregido para que cuando se establezca en None se vuelva al comportamiento por defecto de aproximación sobre el intervalo completo. Corregido #6198

  • Se ha solucionado un problema con el método num_connected_components() método de QuantumCircuit que devolvía el número incorrecto de componentes cuando el circuito contenía dos o más puertas condicionadas a registros clásicos. Corregido #6477

  • Se ha corregido un problema con el módulo qiskit.opflow.expectations por el que los coeficientes de una función de estado no se multiplicaban correctamente. También se han corregido los cálculos de Gradientes y QFIs cuando se utiliza la función PauliExpectation o AerPauliExpectation clases. Por ejemplo, anteriormente:

    from qiskit.opflow import StateFn, I, One
    
    exp = ~StateFn(I) @ (2 * One)

    evaluado a 2 para AerPauliExpectation y a 4 para otros convertidores de expectativas. Dado que ~StateFn(I) @ (2 * One) es una notación abreviada de ~(2 * One) @ I @ (2 * One), se devuelve el coeficiente ahora correcto de 4 para todos los convertidores de expectativas. Corregido #6497

  • Se ha corregido el error que provocaba el fallo de to_circuit() cuando PauliOp tenía una fase. Al mismo tiempo, se hizo más eficiente el uso de PauliGate.

  • Se ha solucionado un problema por el que la salida QASM generada por el qasm() de QuantumCircuit para puertas compuestas como MCXGate y sus variantes ( MCXGrayCode, MCXRecursivey MCXVChain) sería incorrecto. Ahora bien, si a Gate en el circuito no está presente en qelib1.inc, su definición se añade a la cadena QASM de salida. Corregido #4943 y #3945

  • Se ha solucionado un problema con la función circuit_drawer() y el método draw() de QuantumCircuit. Cuando se utilizan los modos de salida mpl o latex , con el kwarg cregbundle ajustado a False y el kwarg reverse_bits ajustado a True, los bits de los registros clásicos se muestran en el mismo orden que cuando reverse_bits estaba ajustado a False.

  • Se ha corregido un problema al utilizar la instrucción qiskit.extensions.Initialize que no establecía correctamente la fase global de la definición sintetizada cuando se construía. Corregido #5320

  • Se ha corregido un problema por el que el orden de bits en qiskit.circuit.library.PhaseOracle.evaluate_bitstring() no coincidía con el orden de la cadena de bits medida. Esta corrección también afecta a la ejecución de la clase de algoritmo Grover si el oráculo se especifica como PhaseOracleque ahora identificará correctamente la cadena de bits correcta. Corregido #6314

  • Corrige un error en Optimize1qGatesDecomposition() que provocaba que algunas secuencias cortas de puertas no se reescribieran por error.

  • Solucionado un problema en el método qiskit.opflow.gradients.Gradient.gradient_wrapper() con el cálculo del gradiente. Anteriormente, si el operador no era diagonal se obtenía un resultado incorrecto en algunas situaciones. Esto se ha solucionado utilizando un convertidor de expectativas para garantizar que el resultado sea siempre correcto.

  • Se ha solucionado un problema con la función circuit_drawer() y el método draw() de QuantumCircuit con todos los modos de salida en los que, en algunas circunstancias, renderizaba incorrectamente una instrucción personalizada que incluía bits clásicos. Corregidos #3201, #3202 y #6178

  • Se ha corregido un problema en circuit_drawer() y el método draw() de la clase QuantumCircuit cuando se utilizaba el modo de salida mpl , las Compuertas-Z controladas se dibujaban incorrectamente como asimétricas. Corregido #5981

  • Se ha solucionado un problema con el pase del transpilador de OptimizeSwapBeforeMeasure por el que en algunas situaciones un SwapGate que contenía una condición clásica se eliminaba. Corregido #6192

  • Se ha corregido un problema con la fase de la clase qiskit.opflow.gradients.QFI cuando qfi_method está en lin_comb_full , lo que provocaba que se evaluara el observable incorrecto.

  • Se ha corregido un problema con la clase VQE cuando se ejecutaba con la clase de algoritmo L_BFGS_B o P_BFGS y se utilizan gradientes, el gradiente se pasaba incorrectamente como una matriz numpy en lugar de la lista esperada de flotantes, lo que provocaba un error. Esto se ha resuelto para que pueda utilizar degradados con VQE y los botones L_BFGS_B o P_BFGS optimizadores.

Otras notas

  • Se ha anulado la eliminación del método parameters() para la clase Instruction . Este método se suprimió originalmente en 0.17.0, pero sigue siendo necesario para varias aplicaciones, como la realización de experimentos de calibración. Este método seguirá siendo compatible y no se suprimirá.

Aer 0.8.2

No cambia

Ignis 0.6.0

No cambia

Aqua 0.9.4

No cambia

IBM Proveedor Q 0.15.0

Nuevas funciones

  • Añadir soporte para el nuevo método qiskit.providers.ibmq.runtime.RuntimeJob.error_message() que devolverá una cadena representando la razón si el trabajo falló.

  • El parámetro de entrada del método qiskit.providers.ibmq.runtime.IBMRuntimeService.run() ahora se puede especificar como una instancia de qiskit.providers.ibmq.runtime.ParameterNamespace que admite funciones de autocompletado. Puede utilizar qiskit.providers.ibmq.runtime.RuntimeProgram.parameters() para recuperar una instancia de ParameterNamespace .

    Por ejemplo:

    from qiskit import IBMQ
    
    provider = IBMQ.load_account()
    
    # Set the "sample-program" program parameters.
    params = provider.runtime.program(program_id="sample-program").parameters()
    params.iterations = 2
    
    # Configure backend options
    options = {'backend_name': 'ibmq_qasm_simulator'}
    
    # Execute the circuit using the "circuit-runner" program.
    job = provider.runtime.run(program_id="sample-program",
                               options=options,
                               inputs=params)
  • El usuario puede ahora establecer la visibilidad (privada/pública) de un programa Qiskit Runtime utilizando qiskit.providers.ibmq.runtime.IBMRuntimeService.set_program_visibility().

  • Se ha añadido un parámetro booleano opcional pending a qiskit.providers.ibmq.runtime.IBMRuntimeService.jobs() que permite filtrar los trabajos por su estado. Si no se especifica pendiente, se devuelven todos los trabajos. Si pendiente es True, se devuelven los trabajos "QUEUED" y "RUNNING". Si pendiente está en False, se devuelven los trabajos 'DONE', 'ERROR' y 'CANCELADO'.

  • Añade soporte para la bandera use_measure_esp en el método qiskit.providers.ibmq.IBMQBackend.run() . Si True, el backend utilizará la lectura ESP para todas las mediciones que son la instrucción terminal en ese qubit. Si se utiliza y el backend no admite la lectura ESP, se produce un error.

Notas de actualización

  • qiskit.providers.ibmq.runtime.RuntimeProgram.parameters() es ahora un método que devuelve una instancia de qiskit.providers.ibmq.runtime.ParameterNamespace , que puede utilizar para rellenar los valores de los parámetros del programa en tiempo de ejecución y pasarlos a qiskit.providers.ibmq.runtime.IBMRuntimeService.run().
  • La bandera open_pulse en la configuración del backend ya no indica si un backend soporta el control a nivel de pulso. Como resultado, qiskit.providers.ibmq.IBMQBackend.configuration() puede devolver una PulseBackendConfiguration aunque su bandera open_pulse sea False.
  • El nivel de trabajo compartido ya no es compatible debido a su baja adopción y la interfaz correspondiente se eliminará en una futura versión. Esto significa que ya no debe pasar share\level al crear un trabajo ni utilizar el método qiskit.providers.ibmq.job.IBMQJob.share_level() para obtener el nivel de share de un trabajo.

Notas sobre características en desuso

  • La instrucción id ha quedado obsoleta en los backends de hardware IBM. En su lugar, utilice la instrucción delay que implementa retardos de longitud variable, especificados en unidades de dt. Cuando se ejecute un circuito que contenga una instrucción id , aparecerá una advertencia al enviar el trabajo y cualquier instrucción id del trabajo se sustituirá automáticamente por su instrucción equivalente delay .
¿Le ha resultado útil esta página?
Informe de un error, de una errata o solicite contenido en GitHub.