Skip to main content
IBM Quantum Platform

Notas de la versión de Qiskit SDK 2.1


2.1.2

Preludio

Qiskit 2.1.2 es un pequeño parche que corrige varios errores encontrados en la serie 2.1.

Corrección de errores

  • En Qiskit 2.1.0 el VF2PostLayout transpiler pass se añadió a la etapa optimization del gestor de pases predefinidos cuando optimization_level=3. Sin embargo, la salida del paso nunca se aplicó al circuito. Esta versión elimina el pase de la etapa optimization del gestor de pases predefinidos para ahorrar costes de ejecución. En Qiskit 2.2.0 el pase formará parte de la etapa optimization y la salida se aplicará si el pase encuentra un diseño mejor.

  • Se ha solucionado un problema en el VF2Layout donde incluso con un conjunto de semillas fijo la salida del pase era potencialmente no determinista; específicamente si el circuito de entrada tenía qubits activos que sólo contenían operaciones de qubit único. Corregido #14729

  • Se ha corregido un error en PassManager.run() por el que no se invocaba la función callback cuando se ejecutaba con varios circuitos. Ahora la llamada de retorno se activa correctamente para cada pasada en cada circuito, incluso en ejecución paralela.

  • Los pases de transpilador integrados que establecen la propiedad final_layout ahora gestionarán correctamente la actualización de este campo si ya estaba establecido. Esto puede observarse como el método TranspileLayout.routing_permutation devuelve ahora una permutación correcta después de ejecutar más de una pasada que establece final_layout.

    Esto no afectó a las llamadas normales a transpile() o generate_preset_pass_manager() usando los plugins incorporados de Qiskit; ningún pipeline construido de esta forma intentaría establecer final_layout más de una vez.

  • Se ha corregido un error en Target.instruction_supported() por el que se omitía la comprobación del orden de los qubits de la instrucción cuando se llamaba al método con argumentos operation_name y parameters que coincidían con una instrucción existente.

  • Se ha corregido un error de corrección al exportar circuitos con instrucciones de retardo utilizando ps unidades a QASM3.

  • Corregido un caso extremo en la visualización del QFT circuito. Anteriormente, cuando se llamaba a QFT.inverse() y se modificaban los atributos del circuito QFT, el nombre del QFT aparecía como "IQFT_dg". Esto era incorrecto, y ahora muestra correctamente "IQFT". Corregido #14758.

  • Se ha corregido una fuga de memoria en la coordinación del uso de qk_circuit_get_instruction y qk_circuit_instruction_clear.

  • Aclarado el mensaje de error para versiones no válidas especificadas en qpy.dump() para que sea más fácil actuar en consecuencia.

  • Se ha corregido un problema con la función generate_preset_pass_manager() por el que ignoraba incorrectamente los datos de restricciones de temporización contenidos en un objeto Target cuando el argumento backend no estaba definido. Corregido #14329

  • Se ha corregido un error en SparsePauliOp.simplify() por el que el método eliminaba los términos de Pauli basándose en las magnitudes de sus coeficientes antes de combinar los duplicados. Esto provocaba un comportamiento incorrecto en dos casos extremos clave:

    1. Cuando varios términos de Pauli idénticos tenían coeficientes pequeños que individualmente estaban por debajo del umbral de simplificación pero cuya suma superaba el umbral, esos términos se eliminaban incorrectamente.
    2. Cuando múltiples términos de Pauli idénticos tenían coeficientes por encima del umbral pero sumados a casi cero, se mantenían incorrectamente.

    Ver #14194 para más detalles.


2.1.1

Preludio

Qiskit 2.1.1 es un pequeño parche que corrige varios errores encontrados en la serie 2.1.

Corrección de errores

  • Se ha corregido un error en la DAGOpNode comprobación de igualdad, por el que la comparación de dos DAGOpNode que contienen una instrucción BoxOp instrucción. Anteriormente, el atributo BoxOp.unit no se tenía en cuenta como parte de la comprobación de igualdad, lo que podía dar lugar a que dos nodos desiguales se evaluaran como iguales.

  • Corregido el aviso de obsoleto para Python 3.9 para que se identifique correctamente como causado por código de usuario al importar Qiskit. Anteriormente, no se identificaba como causado por código de usuario, y esto significaba que los filtros de advertencia predeterminados de Python no mostraban la advertencia al usuario.

  • Se ha corregido el comportamiento del argumento max_trials para VF2Layout cuando se establece en None o en un número negativo. El pase estaba documentado como limitando la búsqueda a basarse en el tamaño del circuito o del objetivo si la opción se establecía en None, y como aceptando valores negativos para especificar una búsqueda sin límites. Sin embargo, en 2.1.0 este comportamiento se modificó incorrectamente de modo que None ejecutaba una búsqueda no limitada y el uso de un número negativo provocaba un error. Estos descuidos se han corregido para que el pase se comporte según lo documentado y sea coherente con las versiones anteriores.

  • Solucionado un problema en los plugins de síntesis de alto nivel MCXSynthesis1DirtyKG24 y MCXSynthesis2DirtyKG24 para MCXGatedonde los plugins no consideraban los qubits auxiliares limpios disponibles como qubits auxiliares sucios disponibles. En particular, el complemento MCXSynthesis2DirtyKG24 no se aplicaba cuando se disponía de un qubits auxiliar limpio y otro sucio.

  • Se ha corregido una regresión de rendimiento al construir incrementalmente ParameterExpression combinando un gran número de subexpresiones. Corregido #14653


2.1.0

Preludio

La versión de Qiskit v2.1 introduce varias mejoras importantes en áreas clave como la API de C, las capacidades del transpilador y la usabilidad de los circuitos cuánticos. Además, incluye muchas mejoras generales y correcciones de errores. Entre las principales destacan:

  • Extensiones de la API de C: Basándose en el trabajo iniciado en la versión anterior, Qiskit v2.1 añade soporte para crear e interactuar con circuitos cuánticos a través de funciones de la API de C, soportando la adición de puertas estándar, instrucciones estándar y puertas unitarias. En esta versión también se ha añadido un conjunto de funciones C para construir y manipular un objeto Target como preparación para soportar un flujo de trabajo de transpilación completo basado en la API de C en la próxima versión. Además, QkComplex64 se define ahora como una estructura, sirviendo como una representación independiente del compilador para números complejos cuando se trabaja con la API C de Qiskit. También se ha actualizado el archivo de cabecera de la API de C para que, en general, sea compatible para su uso nativo en C++.
  • Soporte del conjunto de bases Clifford+T: Ahora es posible transpilar circuitos para un objetivo con puertas Clifford+T. Si el conjunto de bases consiste sólo en puertas Clifford+T, Qiskit se asegura de que los pases apropiados para manejar estas puertas se añadan a los gestores de pases predefinidos. Este es un paso inicial hacia el apoyo a la transpilación para backends tolerantes a fallos.
  • Mejoras para BoxOp: Esta versión añade la posibilidad de adjuntar anotaciones personalizadas a BoxOp instrucciones, apoyando aún más el concepto de declaraciones de caja de OpenQASM 3 en Qiskit. También incluye la serialización de anotaciones en los formatos QASM y QPY. Además, se ha añadido soporte para utilizar duraciones de estiramiento en las cajas.
  • Python 3.9 obsoleto: Python 3.9 es obsoleto a partir de Qiskit v2.1 y ya no será compatible con Qiskit v2.3.

Para más detalles sobre lo anterior y mucho más, consulte las notas de la versión que figuran a continuación y visite la documentación actualizada.

Características de la API C

  • La API C de Qiskit ( qiskit.h ) soporta ahora la construcción e interacción con Circuitos Cuánticos. La API C de circuitos se centra en el tipo opaco QkCircuit que representa el circuito. El tipo QkCircuit permite construir un circuito con cualquier elemento de circuito definido de forma nativa en el modelo de datos interno Rust de Qiskit para QuantumCircuit. Actualmente incluye puertas estándar, Measure, Delay, Reset, Barriery UnitaryGate. Las capacidades de los circuitos C API se ampliarán en futuras versiones a medida que se añada más del modelo de datos Qiskit de forma nativa al modelo de datos interno de Rust, lo que permitirá utilizarlo en la C API.

    Por ejemplo, puedes utilizar la API de C para construir un estado GHZ de 1000 qubits:

    #include <qiskit.h>
    
    int main() {
        // Create an empty circuit with 1000 qubits and 1000 clbits
        QkCircuit *qc = qk_circuit_new(1000, 1000);
    
        // Add a Hadamard Gate on Qubit 0
        uint32_t one_qubit[1] = {0,};
        qk_circuit_gate(qc, QkGate_H, one_qubit, NULL); // The NULL pointer is for the parameter array.
                                                        // Since Hadamard doesn't have parameters it
                                                        // is never accessed.
    
        // Add the CX Gates:
        uint32_t qubits[2] = {0, 0};
        uint32_t num_qubits = qk_circuit_num_qubits(qc);
        for (int i = 1; i<num_qubits; i++) {
            qubits[1] = i;
            qk_circuit_gate(qc, QkGate_CX, qubits, NULL);
        }
    
        // Add the measurements:
        uint32_t num_clbits = qk_circuit_num_clbits(qc);
    
        for (uint32_t i = 0; i<num_clbits; i++) {
            qk_circuit_measure(qc, i, i);
        }
        qk_circuit_free(qc);
        return 0;
    }
  • La API C de Qiskit ( qiskit.h ) ahora soporta la construcción de un Target para representar un objetivo de transpilación. Por ejemplo:

    #include <qiskit.h>
    #include <math.h>
    
    int main() {
        // Create a Target with 3 qubits
        QkTarget *target = qk_target_new(3);
    
        // Create a Target Entry for a CX Gate
        QkTargetEntry *cx_entry = qk_target_entry_new(QkGate_CX);
        // Define properties for CX between qubits (0, 1) with a duration of 1.93e-9 sec and error rate 3.17e-10.
        uint32_t qargs[2] = {0, 1};
        qk_target_entry_add_property(cx_entry, qargs, 2, 1.93e-9, 3.17e-10);
        // Define properties for cx between qubits (1, 0) with a duration of 1.27e-9 sec and no error.
        uint32_t rev_qargs[2] = {1, 2};
        qk_target_entry_add_property(cx_entry, rev_qargs, 2, 1.27e-9, NAN);
        // Add the cx entry to the target.
        QkExitCode result_cx = qk_target_add_instruction(target, cx_entry);
        // Add global ideal Y gate entry to the target
        QkExitCode result_y = qk_target_add_instruction(target, qk_target_entry_new(QkGate_Y));
        // Create a Target entry for a Measurement with increasing duration and error as the qubit indices increase
        QkTargetEntry *measure = qk_target_entry_new_measure();
        for (uint32_t i = 0; i< qk_target_num_qubits(target); i++) {
            uint32_t q[1] = {i};
            qk_target_entry_add_property(measure, q, 1, 1e-6 * (i + 1), 1e-3 * (i + 1));
        }
        QkExitCode result_measure = qk_target_add_instruction(target, measure);
        return 0;
    }
    
  • Añadido soporte para consultar la información de la versión de Qiskit desde la API de C utilizando las siguientes macros:

    • QISKIT_VERSION_MAJOR contiene el número de versión principal.
    • QISKIT_VERSION_MINOR contiene el número de versión menor.
    • QISKIT_VERSION_PATCH contiene el número de versión del parche.
    • QISKIT_VERSION : Contiene una representación numérica de la información de la versión, que puede utilizarse para comparaciones.
    • QISKIT_VERSION_NUMERIC(M,m,p) : Una macro de tipo función que devuelve la versión " M.m.p " como valor numérico, que puede utilizarse para comparaciones.

    Por ejemplo, para comprobar si la versión actual es al menos 2.1.0, puede utilizar:

    if (QISKIT_VERSION >= QISKIT_VERSION_NUMERIC(2, 1, 0)) {
        // Code for version 2.1.0 or later
    }
  • Habilitada la compatibilidad C++ para la API C. La cabecera generada permite ahora llamar directamente a objetos y funciones desde C++. Por ejemplo, un observable de 100 qubits con el término XYZ en los 3 primeros qubits puede construirse como

    #include <iostream>
    #include <complex>
    #include <vector>
    #include <qiskit.h>
    
    int main() {
        uint32_t num_qubits = 100;
    
        // Use smart pointer with custom deleter to manage QkObs memory
        QkObs *obs = qk_obs_zero(num_qubits);
    
        // Construct the observable term
        std::complex<double> coeff_complex = 2.0;
        QkComplex64 coeff = qk_complex64_from_native(coeff_complex);
        std::vector<QkBitTerm> bit_terms = {QkBitTerm_X, QkBitTerm_Y, QkBitTerm_Z};
        std::vector<uint32_t> indices = {0, 1, 2};
    
        QkObsTerm term {
            .coeff      = coeff,
            .len        = bit_terms.size(),
            .bit_terms  = bit_terms.data(),
            .indices    = indices.data(),
            .num_qubits = num_qubits
        };
    
        qk_obs_add_term(obs.get(), &term);
    
        // Print observable properties
        std::cout << "num_qubits: " << qk_obs_num_qubits(obs) << "\n";
        std::cout << "num_terms: "  << qk_obs_num_terms(obs)  << "\n";
    
        qk_obs_free(obs);
        return 0;
    }

Características de los circuitos

  • Se ha añadido una función random_circuit_from_graph() que genera un circuito aleatorio que induce el mismo grafo de interacción que el especificado por interaction_graph.

    La probabilidad de extraer aleatoriamente una arista del grafo de interacción como una puerta de dos qubits puede ser establecida por el usuario en el atributo de peso de una arista en el grafo de interacción de entrada. Si el usuario no fija la probabilidad, cada arista se dibuja uniformemente. Es decir, cada puerta de dos qubits representada por una arista en el grafo de interacción tiene la misma probabilidad de ser añadida al circuito aleatorio. Si sólo se establece un subconjunto de probabilidades de arista, aparecerá ValueError .

    En este ejemplo, cp_map es una lista de aristas con pesos arbitrarios.

    from qiskit.circuit.random.utils import random_circuit_from_graph
    import rustworkx as rx
    pydi_graph = rx.PyDiGraph()
    n_q = 5
    cp_map = [(0, 1, 0.18), (1, 2, 0.15), (2, 3, 0.15), (3, 4, 0.22)]
    pydi_graph.extend_from_weighted_edge_list(cp_map)
    # cp_map can be passed in directly as interaction_graph
    qc = random_circuit_from_graph(interaction_graph = pydi_graph,
      min_2q_gate_per_edge = 1,
      max_operands = 2,
      measure = True,
      conditional = True,
      reset = True,
      seed = 0,
      insert_1q_oper = True,
      prob_conditional = 0.21,
      prob_reset = 0.1)
    qc.draw(output='mpl')
    _images/release_notes-1.png
  • Se ha añadido un nuevo QuantumCircuit método QuantumCircuit.has_control_flow_op() para comprobar si un QuantumCircuit contiene alguna operación de flujo de control.

  • Un nuevo módulo qiskit.circuit.annotation y objeto principal Annotation se han añadido.

    Las anotaciones son una forma de etiquetar instrucciones (actualmente sólo BoxOp) con datos locales, personalizados por el usuario. Estos datos están destinados a ser consumidos por pases de transpilador personalizados. Las anotaciones proporcionan una forma de adjuntar datos a instrucciones específicas, en lugar de utilizar el objeto global-context PropertySet durante la compilación.

    Todos los objetos Annotation objetos tienen un campo namespace . Esta clave de cadena se utiliza para búsquedas, para que los consumidores puedan saber si manejan una anotación en particular o no. Actualmente no existen métodos para consultar la semántica abstracta de una Annotation pero se espera que se amplíen en el futuro.

    Consulte qiskit.circuit.annotation para una discusión completa de las capacidades y casos de uso.

  • BoxOp (creadas por QuantumCircuit.box()) se pueden anotar con instancias Annotation personalizadas. La igualdad de dos casillas depende de que las anotaciones sean iguales.

    Normalmente, esto se consigue pasando una lista de anotaciones como único argumento posicional cuando se utiliza QuantumCircuit.box() en forma de gestor de contexto:

    from qiskit.circuit import annotation, QuantumCircuit
    
    class MyAnnotation(annotation.Annotation):
        namespace = "my.annotation"
    
        def __eq__(self, other):
            return isinstance(other, MyAnnotation)
    
    qc = QuantumCircuit()
    with qc.box([MyAnnotation()]):
        pass
  • El método UnitaryGate.control() utiliza ahora internamente qs_decomposition() en lugar de Isometry para la descomposición utilizada para definir el control UnitaryGate. Este cambio reduce el número de CXGate utilizados en el definition para el ControlledGate en aproximadamente 2x.

  • Mejorada la síntesis de un multi-controlado U1Gatepara que no crezca exponencialmente con el número de controles.

  • El atributo BoxOp.duration ahora puede ser un expr.Expr nodo de tipo Durationigual que Delay.duration. Esto incluye también el apoyo Stretch durante la duración de un BoxOp.

Características primitivas

OpenQASM Características

  • qasm3.dump() y qasm3.dumps() tienen un nuevo argumento annotation_handlers , que se utiliza para proporcionar instancias de annotation.OpenQASM3Serializer al proceso de exportación de OpenQASM 3, que puede serializar objetos personalizados Annotation a OpenQASM 3.

  • Cuando se instala qiskit_qasm3_import>=0.6.0 , qasm3.load() y qasm3.loads() tienen un nuevo argumento annotation_handlers , que se utiliza para proporcionar instancias de annotation.OpenQASM3Serializer al proceso de importación de OpenQASM 3, que puede deserializar objetos personalizados Annotation de OpenQASM 3. Este soporte se limita actualmente a las declaraciones box , ya que es el único lugar donde Qiskit puede representar anotaciones en su modelo de datos.

Características de QPY

  • Añadida una nueva versión 15 del formato QPY que incluye soporte para los nuevos Annotation objetos, con soporte de serializadores y deserializadores externos. El formato permite que dichos serializadores sean de estado, y se asignan lugares seguros en el formato binario para los objetos de estado personalizados y las representaciones de anotación personalizadas.

  • qpy.dump() y qpy.load() ahora tienen un argumento opcional annotation_factories , que se utiliza para proporcionar funciones constructoras de annotation.QPYSerializer objetos para manejar Annotation subclases. Estos deben ser suministrados por el usuario, de forma similar a metadata_serializer, ya que en general, Qiskit no puede conocer todos los posibles objetos definidos externamente Annotation definidos externamente.

  • Se ha añadido una nueva función get_qpy_version() al módulo qpy módulo. Esta función inspeccionará un archivo QPY y recuperará la versión de formato QPY utilizada en la carga útil. La versión se devuelve como un número entero, que puede utilizarse con fines de registro o depuración. ver #14201.

Características de la información cuántica

  • Se añade una nueva clase, PauliLindbladMapque es una parametrización basada en Pauli de un subconjunto de mapas lineales de operadores multi-qubit, utilizados en aplicaciones de aprendizaje de ruido. Se espera que esta clase constituya la espina dorsal de algoritmos mejorados de aprendizaje del ruido y proporcione un control mejor y más eficaz de los modelos de ruido en futuras versiones de Qiskit.

  • Introdujo el QubitSparsePauli y QubitSparsePauliList que representan los mismos conceptos que Pauli y PauliList respectivamente, pero sólo almacenan términos no identitarios, de forma análoga a SparseObservable. Estas clases están pensadas principalmente para ser utilizadas con el nuevo PauliLindbladMap.

Características de síntesis

  • Se ha añadido un nuevo algoritmo de síntesis para HalfAdderGate que no requiere qubits auxiliares y tiene mejor recuento de CX en comparación con adder_qft_d00():

  • Añadidas nuevas descomposiciones para MCXGate utilizar ancillae limpia, mejorando la profundidad del circuito y la eficiencia:

    Ejemplo de uso:

    from qiskit.synthesis.multi_controlled import synth_mcx_1_clean_kg24
    
    n_ctrls = 10
    qc = synth_mcx_1_clean_kg24(n_ctrls)
    qc.draw()
  • Se ha mejorado la síntesis de puertas CZGate se ha mejorado para reducir el número de compuertas sintetizadas; en algunos casos es posible una reducción de hasta el 99%. Esto se logró aprovechando la síntesis mejorada en torno a la MCXGate con una síntesis CZGate también la síntesis.

  • Mejorado el plugin por defecto para sintetizar AnnotatedOperation objetos. La mejora es especialmente útil al crear y transpilar circuitos controlados con puertas controladas en su interior. Por ejemplo:

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import CXGate
    from qiskit.compiler import transpile
    
    inner = QuantumCircuit(5)
    inner.append(CXGate().control(3, annotated=True), [0, 1, 2, 3, 4])
    controlled_inner_gate = inner.to_gate().control(2, annotated=True)
    qc = QuantumCircuit(15)
    qc.append(controlled_inner_gate, [0, 1, 2, 3, 4, 5, 6])
    qct = transpile(qc, basis_gates=["cx", "u"])

    Este código crea un circuito cuántico qc que contiene un circuito cuántico de 2 controles con una puerta CX de 3 controles en su interior. Con esta mejora, el número de puertas CX en el circuito transpilado se reduce de 378 a 30. Tenga en cuenta que al especificar annotated=True al definir la lógica de control, las puertas controladas se crean como operaciones anotadas. Esto evita la síntesis ansiosa, permite al transpilador detectar que controlled_inner_gate es equivalente a una X-gate controlada por 6, y elegir el mejor método de síntesis disponible para X-gates multicontroladas, en particular utilizando los qubits ancilla disponibles.

  • La función adder_qft_d00()utilizada para sintetizar ModularAdderGate y HalfAdderGate acepta ahora un parámetro adicional annotated. Si True, la puerta-QFT inversa dentro de los sumadores se implementa como una operación anotada, lo que permite al transpilador aplicar optimizaciones adicionales.

  • La descomposición cuántica de Shannon (qs_decomposition()) incluye ahora una optimización que reduce el CXGate en el caso de que el unitario de entrada sea un unitario controlado.

  • La función de síntesis synth_mcx_1_clean_b95() produce ahora un circuito con menos puertas CX.

  • La clase SolovayKitaevDecomposition tiene ahora argumentos adicionales en el inicializador, que permiten construirla directamente a partir de un conjunto de basis_gates y un depth para las aproximaciones básicas.

  • Se ha añadido SolovayKitaevDecomposition.save_basic_approximations() para guardar el conjunto de aproximaciones básicas que utiliza la clase en un formato binario. Este cambio, en combinación con los nuevos argumentos del inicializador, permite a los usuarios omitir el uso explícito de generate_basic_approximations() y confiar únicamente en SolovayKitaevDecomposition.

Características del transpilador

  • La función generate_preset_pass_manager() genera ahora un gestor de pases especial cuando el conjunto de bases está formado sólo por puertas Clifford+T. Formalmente, un conjunto de bases Clifford+T debe contener sólo puertas Clifford, junto con TGate, TdgGateo ambas. La lista completa de puertas Clifford compatibles puede obtenerse utilizando get_clifford_gate_names().

    Por ejemplo:

    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
    from qiskit.quantum_info import get_clifford_gate_names
    
    basis_gates = get_clifford_gate_names() + ["t", "tdg"]
    pm = generate_preset_pass_manager(basis_gates=basis_gates)
    
    qc = QuantumCircuit(1)
    qc.rx(0.8, 0)
    qct = pm.run(qc)
    print(qct.count_ops())

    Resultaría con:

    OrderedDict([('h', 10210), ('t', 4508), ('tdg', 4503), ('sdg', 943), ('s', 941)])

    Anteriormente, el gestor de pases generado no podía manejar el ejemplo anterior porque no podía descomponer puertas de rotación de un solo qubit UGate en puertas Clifford+T. Sin embargo, el nuevo gestor de pases utiliza la descomposición Solovay-Kitaev para aproximar puertas de rotación de un solo qubit utilizando las puertas H, T y Tdg , y llama al pase BasisTranslator para traducir las puertas al conjunto de bases objetivo. El nuevo gestor de pases también tiene otros cambios para permitir una traducción más eficiente a puertas Clifford+T.

    Es importante señalar que el conjunto de puertas base Clifford+T especificado debe ser universal, o de lo contrario la transpilación podría no tener éxito. Aunque el conjunto de puertas ["h", "t", "tdg"] o incluso ["h", "t"] es suficiente para la universalidad, se recomienda añadir más puertas Clifford al conjunto si es posible, ya que de lo contrario la traducción podría ser menos eficiente. Por ejemplo, si no se incluye la puerta S, las puertas S podrían descomponerse en pares de puertas T (es decir, las puertas Clifford podrían descomponerse en puertas no Clifford, lo que podría no ser el comportamiento deseado).

    A continuación se muestra un ejemplo ligeramente mayor:

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import QFTGate
    from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
    
    qc = QuantumCircuit(4)
    qc.append(QFTGate(4), [0, 1, 2, 3])
    
    basis_gates = ["cx", "s", "sdg", "h", "t", "tdg"]
    pm = generate_preset_pass_manager(basis_gates=basis_gates, optimization_level=2)
    
    qc = QuantumCircuit(4)
    qc.append(QFTGate(4), [0, 1, 2, 3])
    
    qct = pm.run(qc)
    print(qct.count_ops())

    Resultaría con:

    OrderedDict([('h', 96510), ('tdg', 42396), ('t', 42389), ('s', 8240), ('sdg', 8235), ('cx', 12)])
  • Añadido un nuevo plugin de síntesis de alto nivel HalfAdderSynthesisR25 para sintetizar un HalfAdderGate. El nuevo plugin se basa en adder_ripple_r25().

    La página HalfAdderSynthesisDefault también se ha actualizado para seguir la siguiente secuencia de sintetizadores de medio sumador: "HalfAdder.ripple_r25" cuando hay 3\leq 3 qubits, "HalfAdder.ripple_c04" cuando se dispone de un qubit auxiliar, y "HalfAdder.ripple_r25" en todos los casos restantes.

  • Añadidos múltiples plugins de síntesis de alto nivel para sintetizar un MCXGate:

    La clase MCXSynthesisDefault también se ha actualizado para que ejecute la siguiente secuencia de métodos de síntesis MCX hasta que el primero tenga éxito: : "mcx.2_clean_kg24", "mcx.1_clean_kg24", "mcx.n_clean_m15", "mcx.n_dirty_i15"`, ``"mcx.2_dirty_kg24", "mcx.1_dirty_kg24", "mcx.1_clean_b95", "mcx.noaux_v24". Los métodos se ordenan de forma que se apliquen primero los de mejor calidad.

  • VF2PostLayout se ha añadido al final de la etapa de optimización por defecto cuando se utiliza el nivel de optimización 3.

  • Se ha añadido un nuevo OptimizeCliffordT que combina pares de puertas T consecutivas en puertas S y pares de puertas Td consecutivas en puertas Sd. Esta optimización es especialmente eficaz para reducir el número de T tras la descomposición Solovay-Kitaev, que produce múltiples puertas T o Tdg consecutivas. Por ejemplo:

    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler.passes import SolovayKitaev, OptimizeCliffordT
    
    qc = QuantumCircuit(1)
    qc.rx(0.8, 0)
    
    # Run Solovay-Kitaev pass on qc
    transpiled = SolovayKitaev()(qc)
    print(transpiled.count_ops().get("t", 0) + transpiled.count_ops().get("tdg", 0))
    # Should print 12779
    
    # Run Clifford+T optimization
    optimized = OptimizeCliffordT()(transpiled)
    print(optimized.count_ops().get("t", 0) + optimized.count_ops().get("tdg", 0))
    # Should print 9011
  • Se ha añadido el ContextAwareDynamicalDecoupling que implementa un desacoplamiento dinámico contextual basado en secuencias Walsh-Hadamard. Las secuencias de retardo insertadas serán mutuamente ortogonales a las secuencias en qubits vecinos, y tendrán en cuenta los espectadores de control/objetivo de las puertas CX y ECR. Consulte arXiv:2403.06852 para más información.

    Ejemplo:

    from qiskit.circuit.library import QFT
    from qiskit.transpiler import PassManager, CouplingMap
    from qiskit.transpiler.passes import ALAPScheduleAnalysis, ContextAwareDynamicalDecoupling
    from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
    from qiskit.providers.fake_provider import GenericBackendV2
    
    num_qubits = 10
    circuit = QFT(num_qubits)
    circuit.measure_all()
    
    target = GenericBackendV2(
        100,
        basis_gates=["id", "rz", "sx", "x", "ecr"],
        coupling_map=CouplingMap.from_grid(10, 10)
    ).target
    
    pm = generate_preset_pass_manager(optimization_level=2, target=target)
    dd = PassManager([
        ALAPScheduleAnalysis(target=target),
        ContextAwareDynamicalDecoupling(target=target),
    ])
    
    transpiled = pm.run(circuit)
    with_dd = dd.run(transpiled)
    
    with_dd.draw("mpl", idle_wires=False)
    _images/release_notes-2.png
  • Se han añadido los siguientes atributos a la clase DAGCircuit para poder consultar el número de variables de estiramiento: num_stretches, num_captured_stretches y num_declared_stretches.

  • Añadido un nuevo plugin de síntesis unitaria CliffordUnitarySynthesis que intenta sintetizar una puerta unitaria dada comprobando si puede ser representada por un Clifford, en cuyo caso devuelve un circuito que implementa este unitario y consiste sólo en puertas Clifford.

    El complemento es invocado por el UnitarySynthesis transpiler pass cuando el parámetro method se establece en "clifford".

    Además, el parámetro plugin_config de UnitarySynthesis se puede utilizar para pasar los siguientes parámetros específicos del plugin:

    • min_qubits: el número mínimo de qubits a considerar (el valor por defecto es 1).
    • max_qubits: el número máximo de qubits a considerar (el valor por defecto es 3).

    Por ejemplo:

    import math
    
    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import UnitaryGate
    from qiskit.quantum_info import Operator
    from qiskit.transpiler.passes import UnitarySynthesis
    
    # clifford unitary over 2 qubits
    c2 = QuantumCircuit(2)
    c2.h(0)
    c2.rz(math.pi / 4, 1)
    c2.rz(math.pi / 4, 1)
    c2.sdg(1)
    uc2 = UnitaryGate(Operator(c2).data)
    
    # non-clifford unitary over 2 qubits
    n2 = QuantumCircuit(2)
    n2.h(0)
    n2.rz(math.pi / 4, 1)
    n2.sdg(1)
    un2 = UnitaryGate(Operator(n2).data)
    
    # quantum circuit with two unitary gates
    qc = QuantumCircuit(3)
    qc.append(uc2, [2, 1])
    qc.append(un2, [0, 2])
    
    transpiled = UnitarySynthesis(method="clifford")(qc)
    transpiled.draw("mpl")
    _images/release_notes-3.png

    Ejecutando el código anterior se resintetiza la primera puerta unitaria en puertas Clifford, mientras que la segunda puerta permanece inalterada.

    Si modificamos el ejemplo anterior de la siguiente manera

    config = {"min_qubits": 3}
    transpiled = UnitarySynthesis(method="clifford", plugin_config=config)(qc)

    entonces ambas puertas unitarias permanecen inalteradas.

Funciones de visualización

  • Se han introducido estilos personalizados para la función dag_drawer() función. Esto permite pasar un diccionario al parámetro style con atributos personalizados que cambian el estilo del DAG que devuelve la función. Por ejemplo:

    from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
    from qiskit.converters import circuit_to_dag
    from qiskit.visualization import dag_drawer
    
    q = QuantumRegister(3, 'q')
    c = ClassicalRegister(3, 'c')
    circ = QuantumCircuit(q, c)
    circ.h(q[0])
    circ.cx(q[0], q[1])
    circ.measure(q[0], c[0])
    circ.rz(0.5, q[1]).c_if(c, 2)
    
    dag = circuit_to_dag(circ)
    
    style = {
        "inputnodecolor": "pink",
        "outputnodecolor": "lightblue",
        "opnodecolor": "red",
    }
    
    dag_drawer(dag, style=style)

Notas de actualización

  • La biblioteca python-dateutil ya no es una dependencia de Qiskit. Desde que Qiskit v2.0 nada en la librería estaba usando el python-dateutil y Qiskit ya no dependía de la librería. Esta versión lo elimina de la lista de dependencias, por lo que no se instala automáticamente como requisito previo para utilizar Qiskit. Si usted estaba confiando en Qiskit para instalar dateutil para usted como una dependencia que ahora tendrá que asegurarse de que está instalando manualmente (que es la mejor práctica para las dependencias directas).

  • sympy ya no es un requisito para instalar Qiskit. Tras la migración a un motor simbólico basado en Rust para la clase ParameterExpression los usos de SymPy quedan aislados a algunas utilidades de visualización, el TemplateOptimization transpiler pass, ParameterExpression.sympify() (que es explícitamente para SymPy interoperabilidad) y SparsePauliOp.simplify() si se utilizan coeficientes parametrizados. Esta funcionalidad no es la más utilizada por lo que SymPy se trata ahora como una dependencia opcional y esas funciones lanzarán una MissingOptionalLibraryError excepción si se utilizan y SymPy no está instalado.

  • Se ha eliminado la dependencia de symengine que se utilizaba para construir ParameterExpression se ha eliminado. Ha sido sustituido por un motor simbólico interno y ya no es necesario para las funciones básicas de Qiskit. La única excepción es que symengine se incluyó en los formatos QPY 10, 11 y 12, por lo que sigue siendo necesario si está deserializando esos formatos. La dependencia de symengine para qpy.load() se ha hecho explícitamente opcional en 2.0.0, pero si antes confiabas en que symengine se instalara por defecto para esta funcionalidad, ahora tendrás que instalarlo manualmente para cargar la carga útil. Si estuviera utilizando ParameterExpression.sympify() para obtener un objeto de expresión symengine de un archivo ParameterExpression que ahora devolverá una expresión sympy . Si necesitas usar esto con symengine puedes aprovechar symengine.sympify para convertir la expresión sympy en una de symengine.

Notas sobre la actualización de circuitos

  • El atributo definition del atributo HalfAdderGate se ha cambiado para utilizar internamente adder_ripple_r25() para generar la definición de la puerta para un circuito más eficiente sin qubits auxiliares. Si por alguna razón se desea la definición antigua, se puede utilizar directamente la función adder_qft_d00() que generará un circuito equivalente al que definition en versiones anteriores.

  • El circuito devuelto por la función excitation_preserving() y la clase ExcitationPreserving se construyen ahora con un único circuito XXPlusYYGate. Esto supone un cambio con respecto a versiones anteriores en las que se utilizaba un RXXGate seguido de un RYYGate. Esta nueva construcción del circuito es equivalente pero utiliza menos puertas que son todas de excitación preservando por definición más simple.

  • Los definition atributos de varias puertas estándar se han actualizado de acuerdo con los siguientes principios:

    • Cuando está disponible, se prefiere una definición que utilice puertas Clifford a las definiciones que incluyan puertas que no sean Clifford.
    • Cuando está disponible, se prefiere una definición que utilice puertas Clifford+T a una que utilice una puerta UGate.
    • El uso de PhaseGate es preferible a U1Gate.
    • El uso de UGate es preferible a `U2Gate y `U3Gate.

    Lo más importante es que se mantiene la siguiente invariante: ampliando recursivamente las definiciones de las puertas, cualquier puerta puede expresarse utilizando únicamente la base ["cx", "u"] . Las definiciones de todas las puertas estándar son equivalentes, por lo que no cambia la semántica detrás de las puertas, sólo la construcción exacta del circuito devuelto para algunas puertas ya no es exactamente la misma. Este cambio era necesario para apoyar la transpilación Clifford+T.

  • Qiskit utiliza ahora su propia biblioteca de expresiones simbólicas basada en Rust para implementar las funciones internas de ParameterExpression y Parameter. Dado que se trata de una nueva implementación del motor matemático simbólico central utilizado para ParameterExpression puede haber pequeñas diferencias en el comportamiento exacto de algunas funciones. Siempre debería producir resultados equivalentes para la API documentada. Por favor, abra una incidencia si encuentra algún problema de corrección.

Notas sobre la actualización de la API C

  • La forma en que se exponen los números complejos en la API C de Qiskit ha cambiado. Anteriormente, QkComplex64 era un typedef dependiente del compilador que permitía pasar tipos complejos nativos por puntero a la API de Qiskit (por ejemplo como double complex*). Aunque resultaba cómodo, este enfoque se basaba implícitamente en suposiciones sobre la disposición de la memoria que no están estrictamente garantizadas.

    Qiskit v2.1 ahora expone QkComplex64 { double re; double im; } como una estructura, para asegurar que la disposición de la memoria es siempre compatible y para una mayor compatibilidad con el compilador. Para mayor comodidad, se proporcionan convertidores dependientes del compilador qk_complex64_from_native y qk_complex64_to_native , que permiten traducir del struct a un número complejo nativo. Tenga en cuenta que sólo funcionan en plataformas compatibles con double complex o para compiladores MSVC que utilicen _Dcomplex.

    Por ejemplo:

    #include <qiskit.h>
    #include <math.h>
    #include <stdio.h>
    #include <complex.h>
    
    int main(int argc, char *argv[]) {
        // platform-independent constructions:
        QkComplex64 coeff = {5.0, 3.0};
    
        // ... or using converter
        // double complex native = 5.0 + I * 3; // uses C11 standard, does not work on MSVC
        // QkComplex64 coeff = qk_complex64_from_native(&native);  // convert from native
    
        uint32_t num_qubits = 100;
        QkObs *obs = qk_obs_zero(num_qubits);
        QkBitTerm bit_terms[3] = {QkBitTerm_X, QkBitTerm_Y, QkBitTerm_Z};
        uint32_t indices[3] = {0, 1, 2};
        QkObsTerm term = {coeff, 3, bit_terms, indices, num_qubits};
        qk_obs_add_term(obs, &term);
        printf("num_qubits: %u\n", qk_obs_num_qubits(obs));
        printf("num_terms: %lu\n", qk_obs_num_terms(obs));
    
        qk_obs_free(obs);
        return 0;
    }

Notas sobre la actualización de QPY

  • La versión QPY por defecto emitida por qpy.dump() se ha cambiado a la última versión 15 de QPY. Si por alguna razón necesita generar una versión de formato anterior, puede utilizar el argumento version en qpy.dump() para especificar una versión más antigua a generar.

Notas sobre la actualización de Synthesis

  • El formato de serialización para las aproximaciones básicas en los algoritmos Solovay-Kitaev se ha cambiado de .npy a otro formato binario, basado en serde y bincode de Rust. Todas las rutinas que cargan aproximaciones básicas (como generate_basic_approximations(), SolovayKitaevDecomposition.load_basic_approximations() o el inicializador de SolovayKitaev) siguen soportando la carga del formato heredado. Sin embargo, cualquier archivo nuevo se almacenará en el nuevo formato. Si confiabas en el formato antiguo, baja Qiskit a < 2.2 y guarda los archivos necesarios.

  • Los valores por defecto para SolovayKitaev (y clases afines) han aumentado a depth=12 y reps=5. Esto se debe a que la implementación subyacente está ahora en Rust, lo que nos permite aumentar la precisión por defecto, sin dejar de ser significativamente más rápido que la versión anterior Python.

Notas sobre la actualización del transpilador

  • Los plugins de diseño incorporados para los gestores de pases actuales ya no contendrán su componente principal (por ejemplo, una SabreLayout para la etapa "sable ") si no se proporcionan restricciones de acoplamiento. Anteriormente, los plugins construían instancias inválidas de sus pases de diseño, bajo la suposición de que una lógica separada evitaría que los pases se ejecutaran y lanzaran excepciones.

    Esto no debería tener ningún efecto significativo en el uso de los gestores de pases predefinidos o los plugins, ya que nunca fue válido llamar a los pases en un estado no válido.

Notas sobre características en desuso

  • El soporte para ejecutar Qiskit con Python 3.9 ha sido obsoleto y será eliminado en la versión de Qiskit v2.3. La versión 2.3.0 es la primera versión después de que Python 3.9 llegue al final de su vida útil y deje de recibir soporte [1]. Esto significa que a partir de la versión 2.3.0 deberá actualizar la versión Python que esté utilizando a Python 3.9 o superior.

    [1] https://devguide.python.org/versions/

Circuitos obsoletos

Corrección de errores

  • Se ha corregido un error en la función dag_drawer() y en el método DAGCircuit.draw() donde al establecer el argumento de la palabra clave style=plain no se mostraban las etiquetas de circuito para los nodos del DAG en la visualización.

  • Se ha corregido un error en el método QuantumCircuit.assign_parameters() por el que los parámetros que no se utilizaban en el circuito y se pasaban como cadenas no se ignoraban cuando se establecía el argumento strict=False . Consulte el problema nº 13933 para obtener más información.

  • Se han corregido casos extremos en la configuración de Makefile para Windows, en los que la variable de entorno predefinida OS no coincidía con la salida del comando uname -s .

  • Se ha corregido el atributo name del archivo OrGateque anteriormente se establecía incorrectamente a la cadena "and" en lugar del valor esperado "or" que ahora se devuelve. Este valor incorrecto "and" entraba en conflicto con el AndGate.name y podría haber dado lugar a varios problemas relacionados con el uso de Orgate y su diferenciación de un archivo AndGate.

  • Se ha corregido un error en la función qpy.load() por el que podía fallar la deserialización de circuitos cuyos parámetros habían sido reasignados a parámetros con los mismos nombres. Corregido #13720, #13720, y #13720.

  • Se ha corregido el GenericBackendV2 para incluir ahora BoxOp como un tipo de instrucción soportado en el GenericBackendV2.target cuando el argumento de palabra clave control_flow=True se establece en el constructor.

  • Cuando se sintetiza una MCXGate puerta con 3 controles, la función de síntesis synth_mcx_n_dirty_i15() requería un qubit auxiliar, lo que producía un circuito con 5 qubits (3 de control, 1 objetivo y 1 auxiliar). Sin embargo, el algoritmo de síntesis real no hace uso de este qubit auxiliar. Ahora se ha corregido este comportamiento: el circuito sintetizado tiene más de 4 qubits (3 de control y 1 de destino), lo que permite aplicar la función de síntesis en un número ligeramente mayor de casos.

  • En QuantumCircuit.draw() y circuit_drawer() mostrará ahora las instrucciones BoxOp en un QuantumCircuit en el mismo corte vertical si los tramos verticales no se solapan ahora se renderizan en el mismo corte vertical, siempre que sea posible.

  • Se ha corregido el QuantumCircuit.draw() método y circuit_drawer() función en el modo "mpl" para insertar menos espacio extraño dentro del borde izquierdo al dibujar BoxOp instancias en un QuantumCircuit.

Otras notas

  • Se ha añadido un nuevo objetivo de dependencia adicional opcional qpy-compat. Este objetivo debe utilizarse si planea cargar qpy archivos con formatos QPY antiguos. El objetivo instala requisitos adicionales utilizados para cargar archivos QPY utilizando versiones de formato < 13. If you are only using newer QPY format versions you do no need to install this. The qpy.dump() only generates QPY > =13 esto sólo es necesario para cargar archivos generados con versiones antiguas (anteriores a 2.0.0 ) de Qiskit Puede instalar esta nueva variante opcional con pip install qiskit[qpy-compat].

  • Los pesos relativos de los componentes "básico" y "anticipado" del SabreSwap y SabreLayout se han modificado cuando el seguimiento de conjunto ampliado está activo (como siempre en SabreLayouty por defecto en SabreSwap). El componente heurístico relativo a la distancia entre qubits en una puerta individual de la capa frontal ya no se debilita proporcionalmente al número de puertas de la capa frontal; este comportamiento fue una elección histórica, pero en circuitos de gran tamaño, tiene el efecto accidental de hacer que la capa frontal sea casi ignorada, lo que es desastroso para la eficiencia.

    Las mejoras de enrutamiento resultantes deberían ser más notables en los circuitos que con frecuencia pueden estratificarse en capas de más de 20 puertas paralelas de dos qubits.

¿Le ha resultado útil esta página?
Informe de un error, de una errata o solicite contenido en GitHub.