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_mitgationpara el constructorQuantumInstanceconstructor ahora se puede establecer en la claseTensoredMeasFitterde qiskit-ignis además deCompleteMeasFitterque ya era compatible. Si utilizaTensoredMeasFittertambién podrá establecer el nuevo kwargmit_patternpara especificar los qubits en los que utilizarTensoredMeasFitter. Puede consultar la documentación demit_patternen la documentación deTensoredMeasFitterpara conocer el formato esperado. -
Los métodos de descomposición para puertas de un solo qubit, especificados mediante el kwarg
basis, enOneQubitEulerDecomposerse ha ampliado para incluir ahora también la base'ZSXX', para hacer uso de la puerta directa así como de la puerta . -
Añadidos dos nuevos pases
AlignMeasuresyValidatePulseGatesal móduloqiskit.transpiler.passesmó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 pasoAlignMeasurespass se utiliza para ajustar los retardos en un circuito programado para garantizar que cualquier instrucciónMeasuredel circuito esté alineada dadas las restricciones del backend. El pasoValidatePulseGatespass se utiliza para comprobar si alguna puerta de impulsos personalizados (puertas que tienen una definición de impulsos personalizados en el atributocalibrationsde un objetoQuantumCircuit) son válidas dada una restricción de alineación para el backend de destino.En la página
preset_passmangersutilizada por la funcióntranspile()estos pases se activan automáticamente si la restricción de alineación, ya sea a través del kwarg dedicadotiming_constraintsentranspile()o tiene un atributotiming_constraintsen el objetoBackendConfigurationdel 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.BIPMappingque 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_mapmá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étodoScheduleyScheduleBlock. 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ónjob_monitor()función. Este kwarg permite cambiar los caracteres de retorno de carro utilizados en la salida dejob_monitor. El kwarg deline_disciplineaparece por defecto en'\r', que es lo que se utilizaba antes. -
La clase abstracta
Pulse(que es la clase padre de clases comoWaveform,ConstantyGaussiantiene ahora un nuevo kwarg en el constructor,limit_amplitude, que puede establecerse enFalsepara desactivar el límite de amplitud previamente codificado en1. 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óduloqiskit.quantum_infomódulo. Esta clase se utiliza para representar eficientemente una lista dePaulioperadores. Esta nueva clase hereda de la misma clase padre que la ya existentePauliTable(y por lo tanto se puede utilizar mayoritariamente de forma intercambiable), sin embargo difiere de laPauliTableporque la claseqiskit.quantum_info.PauliListpuede gestionar las fases de Z4. -
Añadido un nuevo pase de transpilador,
RemoveBarriersaqiskit.transpiler.passes. Este pase se utiliza para eliminar todas las barreras de un circuito. -
Añade una nueva clase de optimizador
SciPyOptimizeral móduloqiskit.algorithms.optimizersmódulo. Esta clase es una simple clase de envoltura de la funciónscipy.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 conscipy.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
HoareOptimizerpass se ha mejorado de modo que ahora puede sustituir a aControlledGateen un circuito con la puerta base si todos los qubits de control están en el estado . -
Añadidos dos nuevos métodos
is_successor()yis_predecessor()a la claseDAGCircuitclase. Estas funciones se utilizan para comprobar si un nodo es sucesor o predecesor de otro nodo de la tablaDAGCircuit. -
Se ha añadido un nuevo pase de transpilador
RZXCalibrationBuilderNoEchose ha añadido al móduloqiskit.transpiler.passesmódulo. Este paso es similar al existenteRZXCalibrationBuilderen que crea calibraciones para unRZXGate(theta), sin embargoRZXCalibrationBuilderNoEcholo 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. ElRZXCalibrationBuilderNoEchopass sólo admite la dirección nativa de hardware de la direcciónCXGate. -
Se ha añadido un nuevo kwarg,
wrap, alcompose()método deQuantumCircuit. Esto permite elegir si los circuitos compuestos deben envolverse en una instrucción o no. Por defecto esFalse, 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 clasePulseBackendConfigurationclase. Este atributo representa los canales de control en un backend como un mapeo de qubits a una lista deControlChannelobjetos. -
Se ha añadido un nuevo kwarg,
epsilon, al constructor de la claseIsometryy al método correspondienteQuantumCircuitcorrespondienteisometry(). Este kwarg permite establecer opcionalmente la tolerancia épsilon utilizada por una puertaIsometry. 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,
DynamicalDecouplingaqiskit.transpiler.passespara 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
QuantumCircuitmétodoqasm()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óduloqiskit.circuit.librarymó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 claseUCCSDen el módulochemistryde Qiskit Nature o la claseQAOAAnsatzclase -
Una nueva clase de backend falso está disponible en
qiskit.test.mockpara el backendibmq_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 claseSchedulese ha añadido un nuevo método para la clase Este método se utiliza para devolver los componentes del horario hijo del objetoSchedulecomo 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óduloqiskit.algorithms.optimizersmó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 ejemploVQE. Para obtener una descripción detallada y ejemplos sobre cómo utilizar esta clase, consulte la documentación de la claseGradientDescentdocumentación de la clase. -
Se ha añadido una nueva clase de optimizador
QNSPSAse ha añadido al móduloqiskit.algorithms.optimizersmó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 claseQNSPSAdocumentación de la clase. -
Se ha añadido un nuevo kwarg,
second_order, al constructor de la claseSPSAen el móduloqiskit.algorithms.optimizersmódulo. Si se configura enTrue, 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 claseSPSAdocumentación de la clase. -
Cuando se utiliza el modo de salida
latexolatex_sourcedecircuit_drawer()o el mododraw()deQuantumCircuitel kwargstylepuede utilizarse ahora igual que con el formato de salidampl. Sin embargo, a diferencia del modo de salidampl, sólo se utilizará el campodisplaytextcuando se utilicen los modos de salidalatexolatex_source(porque ninguno de los dos admite color). -
Cuando se utilizan los métodos de salida
mplolatexpara la funcióncircuit_drawer()o la funcióndraw()deQuantumCircuitahora puede utilizar el formato de modo matemático para el texto y establecer el formato de color (sólompl) estableciendo el kwargstylecomo 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,
CDKMRippleCarryAdderClassicalAdderyDraperQFTAdderal móduloqiskit.circuit.librarymó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 y en qubits, las tres nuevas clases realizan la operación:
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
RGQFTMultiplieryHRSCumulativeMultiplieral móduloqiskit.circuit.librarymódulo. Estas clases se utilizan para realizar la multiplicación clásica de dos registros qubit de igual tamaño. Para dos registros y en qubits, las dos nuevas clases realizan la operación
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
Delayahora puede aceptar una claseParameterExpressionoParameterpara el kwargdurationen su constructor y para su atributodurationatributo.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
TwoQubitBasisDecomposerclase 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 deTwoQubitBasisDecomposerpara 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
UnitarySynthesissituado enqiskit.transpiler.passesse ha actualizado para permitir la descomposición óptima del pulso. Esto se hace principalmente con el argumento de la palabra clavepulse_optimizeque 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 kwargpulse_optimizeen el constructor de la claseTwoQubitBasisDecomposerde 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. SiNoneypulse_optimizesonFalseoNone, utilice"unitary". Si None y pulse_optimize esTrue, 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ésCXGateduraciones 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 argumentobasisOneQubitEulerDecomposerclase. -
Se ha añadido un nuevo método,
get_instructions()a la claseQuantumCircuitclase. Este método se utiliza para devolver todos losInstructionobjetos del circuito que tengan unnameque coincide con el argumentonameproporcionado junto con sus listas asociadasqargsycargsdeQubityClbitasociados. -
Se ha añadido un nuevo extra opcional
allal 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
ProbDistributionyQuasiDistributionpara 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
settingsa la clase base abstractaOptimizerclase base abstracta en la que se basan todas las clases optimizadoras delqiskit.algorithms.optimizersdel 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
settingstambié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óduloqiskit.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 = mpla la seccióndefaultdel archivosettings.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 entornoQISKIT_SETTINGSsi 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óduloqiskit.quantum_infomó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 kwargsortde la funciónqiskit.visualization.plot_histogram()función. Cuandosortse 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 aparallel_map()comotranspile()yassemble()) en Python 3.9 conQISKIT_PARALLELestablecido 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 siQISKIT_PARALLELse 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_PARALLELen entornos Python 3.9 ha cambiado aFalse, 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 entornoQISKIT_PARALLELenTRUE. -
Las clases backend falsas existentes en
qiskit.test.mockahora implementan estrictamente la interfazBackendV1interfaz. Esto significa que si estuviera construyendo manualmenteQasmQobjoPulseQobjpara utilizarlo con el métodorun()ya no funcionará. El métodorun()sólo aceptaQuantumCircuitoScheduleobjetos 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 conQasmQobjoPulseQobjse 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 interfazBackendV1y no se añadirán nuevas clases de backend heredadas para los nuevos backends falsos. -
Al crear un
Paulicon una etiqueta de cadena no válida, se produce un errorQiskitError. Se trata de un cambio con respecto a versiones anteriores, en las que se producía un mensajeAttributeErrorsi 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 unAttributeErrorgenérico. -
La representación del programa de salida del generador de impulsos (
qiskit.pulse.builder.build()) ha cambiado deSchedulea aScheduleBlock. 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 deqiskit.algorithms. -
El extra opcional
full-featured-simulatorsque anteriormente podía utilizarse para instalarqiskit-aercon algo comopip install qiskit-terra[full-featured-simulators]ha sido eliminado del paquete qiskit-terra. Si esto se estaba utilizando para instalarqiskit-aerconqiskit-terraen su lugar debe confiar en el metapaquete qiskit o simplemente instalar qiskit-terra y qiskit-aer junto conpip 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
ParameteryParameterExpressionobjetos. -
Todas las clases de circuito de la biblioteca, es decir, todas las
QuantumCircuitderivadas enqiskit.circuit.libraryestán ahora envueltas en unInstruction(oGatesi son unitarias). Por ejemplo, importando y dibujando elQFTcircuito: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 circuitoEste cambio se hizo principalmente por coherencia, ya que antes de esta versión algunas clases de circuito en
qiskit.circuit.libraryestaban antes envueltas en unInstructionoGatepero no todas.
Notas sobre características en desuso
- La clase
qiskit.exceptions.QiskitIndexErrorestá 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
epsilonyfactrpara elqiskit.algorithms.optimizers.L_BFGS_Byfactrde la claseP_BFGSestán obsoletos y se eliminarán en una futura versión. Por favor, utiliceepskarg en lugar deepsilon. Elfactrkwarg se sustituye porftol. La relación entre ambos esftol = factr * numpy.finfo(float).eps. Este cambio se ha realizado para ser coherente con el uso del método'L-BFGS-B'de las funcionesscipy.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, yqiskit.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 sonqiskit.providers.BackendV1,qiskit.providers.JobV1yqiskit.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 laqiskit.providerspara más detalles de alto nivel sobre la interfaz versionada. - El kwarg
conditional constructorDAGDepNodejunto con el atributoconditioncorrespondiente del constructorDAGDepNodehan quedado obsoletos y se eliminarán en una futura versión. En cambio, puede acceder aconditionde unDAGDepNodesi el nodo es de tipoop, utilizandoDAGDepNode.op.condition. - El atributo
conditionde la claseDAGNodeha quedado obsoleto y se eliminará en una futura versión. En cambio, puede acceder aconditionde un objetoDAGNodesi el nodo es de tipoop, utilizandoDAGNode.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 elScheduleBlockahora 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
OneQubitEulerDecomposeryTwoQubitBasisDecomposerpara 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
nameal atributoGategenerada por múltiples llamadas al métodoinverse`(). Antes de esta corrección, cuando se llamaba ainverse`(), se añadía incondicionalmente_dgen cada llamada a la función inversa. Esto se ha corregido para que en una segunda llamada deinverse`()el sufijo_dgsea eliminado. -
Fija las condiciones de comprobación de trivialidad de
CZGate,CRZGate,CU1GateyMCU1Gateen elHoareOptimizerpasar. 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
ListOpobjeto dePauliSumOpobjetos utilizandoPauliExpectationoAerPauliExpectation. 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 archivoListOpa unSummedOpde los objetosPauliOpahora crea un objetoPauliSumOpque es más eficiente. Corregido #6159 -
Se ha solucionado un problema con la clase
NLocalen el móduloqiskit.circuit.libraryque no lanzaba correctamente una excepción en la inicialización del objeto si se utilizaba un tipo no válido para el kwargreps, lo que provocaba posteriormente un error de ejecución inesperado. Ahora se generará correctamente unTypeErrorsi el kwargrepsno es un valorint. Corregido #6515 -
Se ha solucionado un problema por el que la clase
TwoLocalen el móduloqiskit.circuit.libraryno aceptaba los tipos enteros de numpy (por ejemplo,numpy.int32,numpy.int64, etc) como entrada válida para el kwargentanglement. Corregido #6455 -
Al cargar un archivo o cadena OpenQASM2 con los constructores
from_qasm_file()ofrom_qasm_str()para la claseQuantumCircuitclase, si el circuito OpenQASM2 contiene una instrucción con el nombredelayésta será mapeada a unaqiskit.circuit.Delayinstrucció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
PauliSumOpque teníanParameterExpressioncoeficientes. Anteriormente, esto provocaba una excepción enQiskitErrorporque la adición de la etiquetaParameterExpressionno se gestionaba correctamente. Esto se ha corregido para que se pueda realizar la adición entrePauliSumOpobjetos conParameterExpressioncoeficientes. -
Se ha corregido un problema con la inicialización de la clase
AmplificationProblemclase El kwarg deis_good_stateera 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 entradaoraclesea un objetoPhaseOracle(que proporciona su propio método de evaluación) el campo es obligatorio y generará unTypeErrorcuando se construya sinis_good_state. -
Se ha corregido un problema por el que, al añadir un control a un
ControlledGatecon controles abiertos desactivaba los controles abiertos internos. Correcciones #5857 -
Se ha solucionado un problema con el método
convert()de la clasePauliExpectationcuando 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 kwargscheduleal métodoadd()de la claseInstructionScheduleMapque anteriormente provocaba un error. Corregido #6278 -
Se ha solucionado un problema con el
PiecewiseChebyshevcuando se establecía el valorbreakpointsaNoneen un objeto existente se trataba incorrectamente como un punto de interrupción. Esto se ha corregido para que cuando se establezca enNonese 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 deQuantumCircuitque 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.expectationspor 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ónPauliExpectationoAerPauliExpectationclases. Por ejemplo, anteriormente:from qiskit.opflow import StateFn, I, One exp = ~StateFn(I) @ (2 * One)evaluado a
2paraAerPauliExpectationy a4para 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 de4para todos los convertidores de expectativas. Corregido #6497 -
Se ha corregido el error que provocaba el fallo de
to_circuit()cuandoPauliOptenía una fase. Al mismo tiempo, se hizo más eficiente el uso dePauliGate. -
Se ha solucionado un problema por el que la salida QASM generada por el
qasm()deQuantumCircuitpara puertas compuestas comoMCXGatey sus variantes (MCXGrayCode,MCXRecursiveyMCXVChain) sería incorrecto. Ahora bien, si aGateen el circuito no está presente enqelib1.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étododraw()deQuantumCircuit. Cuando se utilizan los modos de salidamplolatex, con el kwargcregbundleajustado aFalsey el kwargreverse_bitsajustado aTrue, los bits de los registros clásicos se muestran en el mismo orden que cuandoreverse_bitsestaba ajustado aFalse. -
Se ha corregido un problema al utilizar la instrucción
qiskit.extensions.Initializeque 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 algoritmoGroversi el oráculo se especifica comoPhaseOracleque 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étododraw()deQuantumCircuitcon 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étododraw()de la claseQuantumCircuitcuando se utilizaba el modo de salidampl, las Compuertas-Z controladas se dibujaban incorrectamente como asimétricas. Corregido #5981 -
Se ha solucionado un problema con el pase del transpilador de
OptimizeSwapBeforeMeasurepor el que en algunas situaciones unSwapGateque 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.QFIcuandoqfi_methodestá enlin_comb_full, lo que provocaba que se evaluara el observable incorrecto. -
Se ha corregido un problema con la clase
VQEcuando se ejecutaba con la clase de algoritmoL_BFGS_BoP_BFGSy 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 conVQEy los botonesL_BFGS_BoP_BFGSoptimizadores.
Otras notas
- Se ha anulado la eliminación del método
parameters()para la claseInstruction. 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 deqiskit.providers.ibmq.runtime.ParameterNamespaceque admite funciones de autocompletado. Puede utilizarqiskit.providers.ibmq.runtime.RuntimeProgram.parameters()para recuperar una instancia deParameterNamespace.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_espen el métodoqiskit.providers.ibmq.IBMQBackend.run(). SiTrue, 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 deqiskit.providers.ibmq.runtime.ParameterNamespace, que puede utilizar para rellenar los valores de los parámetros del programa en tiempo de ejecución y pasarlos aqiskit.providers.ibmq.runtime.IBMRuntimeService.run().- La bandera
open_pulseen 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 unaPulseBackendConfigurationaunque su banderaopen_pulseseaFalse. - 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
idha quedado obsoleta en los backends de hardware IBM. En su lugar, utilice la instruccióndelayque implementa retardos de longitud variable, especificados en unidades dedt. Cuando se ejecute un circuito que contenga una instrucciónid, aparecerá una advertencia al enviar el trabajo y cualquier instruccióniddel trabajo se sustituirá automáticamente por su instrucción equivalentedelay.