Cambios de características en Qiskit 1.0
Esta guía describe los caminos de migración para los cambios de características más importantes en Qiskit 1.0, organizados por módulo. Usa la tabla de contenidos del lado derecho para navegar al módulo que te interesa.
Herramienta de migración de Qiskit 1.0
Para facilitar el proceso de migración, puedes usar la herramienta
flake8-qiskit-migration
para detectar rutas de importación eliminadas en tu código y sugerir alternativas.
- Ejecutar con pipx
- Ejecutar con venv
Si tienes pipx instalado, simplemente ejecuta
el siguiente comando.
pipx run flake8-qiskit-migration <path-to-source-directory>
Esto instalará el paquete en un entorno virtual temporal y lo ejecutará sobre tu código.
Si no quieres usar pipx, puedes crear manualmente un nuevo
entorno para la herramienta. Este enfoque también te permite usar
nbqa para revisar ejemplos de código en
notebooks de Jupyter. Elimina el entorno cuando termines.
# Make new environment and install
python -m venv .flake8-qiskit-migration-venv
source .flake8-qiskit-migration-venv/bin/activate
pip install flake8-qiskit-migration
# Run plugin on Python code
flake8 --select QKT100 <path-to-source-directory> # e.g. `src/`
# (Optional) run plugin on notebooks
pip install nbqa
nbqa flake8 ./**/*.ipynb --select QKT100
# Deactivate and delete environment
deactivate
rm -r .flake8-qiskit-migration-venv
Esta herramienta solo detecta rutas de importación eliminadas. No detecta el uso de métodos
eliminados (como QuantumCircuit.qasm) ni de argumentos. Tampoco puede rastrear
asignaciones como qk = qiskit, aunque sí puede manejar alias como
import qiskit as qk.
Para más información, consulta el repositorio del proyecto.
Instancias y funciones globales
Aer
El objeto qiskit.Aer no está disponible en Qiskit 1.0. En su lugar, usa el
mismo objeto del espacio de nombres qiskit_aer, que es un reemplazo directo.
Para instalar qiskit_aer, ejecuta:
pip install qiskit-aer
BasicAer
El objeto qiskit.BasicAer no está disponible en Qiskit 1.0. Consulta la
sección de migración de basicaer para
ver las opciones de migración.
execute
La función qiskit.execute no está disponible en Qiskit 1.0. Esta
función servía como un envoltorio de alto nivel alrededor de las funciones
transpile y
run de Qiskit.
En lugar de qiskit.execute, usa la función
transpile seguida de
backend.run().
# Legacy path
from qiskit import execute
job = execute(circuit, backend)
# New path
from qiskit import transpile
new_circuit = transpile(circuit, backend)
job = backend.run(new_circuit)
Como alternativa, el primitivo Sampler
es semánticamente equivalente a la función qiskit.execute eliminada. La clase
BackendSampler es un
envoltorio genérico para backends que no admiten primitivos:
from qiskit.primitives import BackendSampler
sampler = BackendSampler(backend)
job = sampler.run(circuit)
qiskit.circuit
QuantumCircuit.qasm
El método QuantumCircuit.qasm ha sido eliminado. En su lugar, usa
qasm2.dump o
qasm2.dumps.
Para salida formateada con Pygments, consulta el paquete independiente
openqasm-pygments,
ya que qasm2.dump y qasm2.dumps no proporcionan salida coloreada con Pygments.
from qiskit import QuantumCircuit
qc = QuantumCircuit(1)
# Old
qasm_str = qc.qasm()
# Alternative
from qiskit.qasm2 import dumps
qasm_str = dumps(qc)
# Alternative: Write to file
from qiskit.qasm2 import dump
with open("my_file.qasm", "w") as f:
dump(qc, f)
Gates de QuantumCircuit
Los siguientes métodos de Gate han sido eliminados en favor de métodos más consolidados que agregan los mismos gates:
| Eliminado | Alternativa |
|---|---|
QuantumCircuit.cnot | QuantumCircuit.cx |
QuantumCircuit.toffoli | QuantumCircuit.ccx |
QuantumCircuit.fredkin | QuantumCircuit.cswap |
QuantumCircuit.mct | QuantumCircuit.mcx |
QuantumCircuit.i | QuantumCircuit.id |
QuantumCircuit.squ | QuantumCircuit.unitary |
Los siguientes métodos de Circuit también han sido eliminados. En su lugar, estos gates se pueden
aplicar a un Circuit con QuantumCircuit.append.
| Eliminado | Alternativa (append) |
|---|---|
QuantumCircuit.diagonal | DiagonalGate |
QuantumCircuit.hamiltonian | HamiltonianGate |
QuantumCircuit.isometry | Isometry |
QuantumCircuit.iso | Isometry |
QuantumCircuit.uc | UCGate |
QuantumCircuit.ucrx | UCRXGate |
QuantumCircuit.ucry | UCRYGate |
QuantumCircuit.ucrz | UCRZGate |
Por ejemplo, para un DiagonalGate:
from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import DiagonalGate # new location in the circuit library
circuit = QuantumCircuit(2)
circuit.h([0, 1]) # some initial state
gate = DiagonalGate([1, -1, -1, 1])
qubits = [0, 1] # qubit indices on which to apply the gate
circuit.append(gate, qubits) # apply the gate
Los siguientes métodos de QuantumCircuit también han sido eliminados:
| Eliminado | Alternativa |
|---|---|
QuantumCircuit.bind_parameters | QuantumCircuit.assign_parameters |
QuantumCircuit.snapshot | Las instrucciones de guardado de qiskit-aer |
qiskit.converters
La función qiskit.converters.ast_to_dag ha sido eliminada de Qiskit. Convertía el
árbol de sintaxis abstracta generado por el parser heredado de OpenQASM 2 a un
DAGCircuit. Dado que el parser
heredado de OpenQASM 2 ha sido eliminado (ver qiskit.qasm), esta
función ya no tiene propósito. En su lugar, parsea tus archivos OpenQASM 2 en
un QuantumCircuit usando los métodos constructores
QuantumCircuit.from_qasm_file
o
QuantumCircuit.from_qasm_str
(o el módulo qiskit.qasm2), y luego
convierte ese QuantumCircuit en un
DAGCircuit con
circuit_to_dag.
# Previous
from qiskit.converters import ast_to_dag
from qiskit.qasm import Qasm
dag = ast_to_dag(Qasm(filename="myfile.qasm").parse())
# Current alternative
import qiskit.qasm2
from qiskit.converters import circuit_to_dag
dag = circuit_to_dag(qiskit.qasm2.load("myfile.qasm"))
qiskit.extensions
El módulo qiskit.extensions ya no está disponible. La mayoría de sus objetos han sido
integrados en la biblioteca de circuitos
(qiskit.circuit.library). Para migrar a la
nueva ubicación, simplemente reemplaza qiskit.extensions con qiskit.circuit.library
en la ruta de importación del objeto. Es un reemplazo directo.
# Previous
from qiskit.extensions import DiagonalGate
# Current alternative
from qiskit.circuit.library import DiagonalGate
Las clases trasladadas a qiskit.circuit.library son:
DiagonalGateHamiltonianGateInitializeIsometryqiskit.circuit.library.generalized_gates.mcg_up_diag.MCGupDiagUCGateUCPauliRotGateUCRXGateUCRYGateUCRZGateUnitaryGate
Las siguientes clases han sido eliminadas del código base, ya que sus
funciones eran redundantes o estaban vinculadas al módulo extensions:
| Eliminado | Alternativa |
|---|---|
SingleQubitUnitary | qiskit.circuit.library.UnitaryGate |
Snapshot | Usa las instrucciones de guardado de qiskit-aer |
ExtensionError | Una clase de error pertinente |
qiskit.primitives
El cambio más notable en el módulo qiskit.primitives es la
introducción de la nueva interfaz de primitivos V2. Esta sección muestra cómo migrar tu
flujo de trabajo de primitivos V1 a primitivos V2, así como los pocos cambios que han tenido lugar
en las entradas aceptadas por la interfaz V1.
A partir de la versión 1.0, nos referiremos a la interfaz de primitivos anterior a la 1.0 como "primitivos V1".
Migrar de V1 a V2
La distinción formal entre las APIs de primitivos V1 y V2 son las clases base de las que
heredan las implementaciones de primitivos. Para hacer la transición a las nuevas clases base, puedes mantener
la ruta de importación original desde qiskit.primitives:
| Migrar de | Reemplazar con |
|---|---|
BaseEstimator | BaseEstimatorV2 |
BaseSampler | BaseSamplerV2 |
Los nombres de las implementaciones principales de Qiskit de los primitivos V2 (las que se pueden importar desde qiskit.primitives),
han sido modificados para clarificar su propósito como implementaciones que se pueden ejecutar localmente
con un backend simulador de vector de estado. Los nuevos nombres no incluyen el sufijo -V2.
| Migrar de | Reemplazar con |
|---|---|
qiskit.primitives.Estimator | qiskit.primitives.StatevectorEstimator |
qiskit.primitives.Sampler | qiskit.primitives.StatevectorSampler |
Hay algunas diferencias conceptuales a tener en cuenta al migrar de V1 a V2.
Estas diferencias las dicta la clase base, pero se muestran en los siguientes ejemplos usando las implementaciones
de vector de estado encontradas en qiskit.primitives:
Para los siguientes ejemplos, asume las siguientes importaciones e inicializaciones de primitivos:
from qiskit.primitives import (
Sampler,
StatevectorSampler,
Estimator,
StatevectorEstimator,
)
estimator_v1 = Estimator()
sampler_v1 = Sampler()
estimator_v2 = StatevectorEstimator()
sampler_v2 = StatevectorSampler()
# define circuits, observables and parameter values
Sampler y Estimator: Los nuevos primitivos V2 están diseñados para aceptar entradas vectorizadas, donde un único Circuit puede agruparse con especificaciones de valor de array. Es decir, un Circuit puede ejecutarse para arrays denconjuntos de parámetros,nobservables, o ambos (en el caso del estimator). Cada grupo se llama bloque primitivo unificado (pub), y puede representarse como una tupla:(1 x circuit, [n x observables], [n x parameters]). La interfaz V1 no permitía la misma flexibilidad. En cambio, el número de circuits de entrada tenía que coincidir con el número de observables y conjuntos de parámetros, como se muestra en los siguientes ejemplos (selecciona una pestaña para ver cada ejemplo):
- Estimator, 1 circuit, 4 observables
- Sampler, 1 circuit, 3 parameter sets
- Estimator, 1 circuit, 4 observables, 2 parameter sets
# executing 1 circuit with 4 observables using Estimator V1
job = estimator_v1.run([circuit] * 4, [obs1, obs2, obs3, obs4])
evs = job.result().values
# executing 1 circuit with 4 observables using Estimator V2
job = estimator_v2.run([(circuit, [obs1, obs2, obs3, obs4])])
evs = job.result()[0].data.evs
# executing 1 circuit with 3 parameter sets using Sampler V1
job = sampler_v1.run([circuit] * 3, [vals1, vals2, vals3])
dists = job.result().quasi_dists
# executing 1 circuit with 3 parameter sets using Sampler V2
job = sampler_v2.run([(circuit, [vals1, vals2, vals3])])
counts = job.result()[0].data.meas.get_counts()
# executing 1 circuit with 4 observables and 2 parameter sets using Estimator V1
job = estimator_v1.run([circuit] * 8, [obs1, obs2, obs3, obs4] * 2, [vals1, vals2] * 4)
evs = job.result().values
# executing 1 circuit with 4 observables and 2 parameter sets using Estimator V2
job = estimator_v2.run([(circuit, [[obs1, obs2, obs3, obs4]], [[vals1], [vals2]])])
evs = job.result()[0].data.evs
Los primitivos V2 aceptan múltiples PUBs como entradas, y cada pub obtiene su propio resultado. Esto te permite ejecutar distintos circuits con varias combinaciones de parámetros/observables, lo que no siempre era posible en la interfaz V1:
- Sampler, 2 circuits, 1 parameter set
- Estimator, 2 circuits, 2 different observables
# executing 2 circuits with 1 parameter set using Sampler V1
job = sampler_v1.run([circuit1, circuit2], [vals1] * 2)
dists = job.result().quasi_dists
# executing 2 circuits with 1 parameter set using Sampler V2
job = sampler_v2.run([(circuit1, vals1), (circuit2, vals1)])
counts1 = job.result()[0].data.meas.get_counts() # result for pub 1 (circuit 1)
counts2 = job.result()[1].data.meas.get_counts() # result for pub 2 (circuit 2)
# executing 2 circuits with 2 different observables using Estimator V1
job = estimator_v1.run([circuit1, circuit2] , [obs1, obs2])
evs = job.result().values
# executing 2 circuits with 2 different observables using Estimator V2
job = estimator_v2.run([(circuit1, obs1), (circuit2, obs2)])
evs1 = job.result()[0].data.evs # result for pub 1 (circuit 1)
evs2 = job.result()[1].data.evs # result for pub 2 (circuit 2)
-
Sampler: El Sampler V2 ahora devuelve muestras de resultados de medición en forma de cadenas de bits o conteos, en lugar de las distribuciones de cuasi-probabilidad de la interfaz V1. Las cadenas de bits muestran los resultados de medición, preservando el orden de los disparos en que fueron medidos. Los objetos de resultado del Sampler V2 organizan los datos en función de los nombres de registros clásicos de sus circuits de entrada, para compatibilidad con circuits dinámicos.
# Define quantum circuit with 2 qubits
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()
circuit.draw()┌───┐ ░ ┌─┐
q_0: ┤ H ├──■───░─┤M├───
└───┘┌─┴─┐ ░ └╥┘┌─┐
q_1: ─────┤ X ├─░──╫─┤M├
└───┘ ░ ║ └╥┘
meas: 2/══════════════╩══╩═
0 1Nombre predeterminado del registro clásicoEn el circuit anterior, observa que el nombre del registro clásico es por defecto
"meas". Este nombre se usará más adelante para acceder a las cadenas de bits de medición.# Run using V1 sampler
result = sampler_v1.run(circuit).result()
quasi_dist = result.quasi_dists[0]
print(f"The quasi-probability distribution is: {quasi_dist}")The quasi-probability distribution is: {0: 0.5, 3: 0.5}# Run using V2 sampler
result = sampler_v2.run([circuit]).result()
# Access result data for pub 0
data_pub = result[0].data
# Access bitstrings for the classical register "meas"
bitstrings = data_pub.meas.get_bitstrings()
print(f"The number of bitstrings is: {len(bitstrings)}")
# Get counts for the classical register "meas"
counts = data_pub.meas.get_counts()
print(f"The counts are: {counts}")The number of bitstrings is: 1024
The counts are: {'00': 523, '11': 501} -
Sampler y Estimator: La sobrecarga de muestreo, comúnmente expuesta por las implementaciones V1 a través de la opción de ejecuciónshots, ahora es un argumento del métodorun()de los primitivos que se puede especificar a nivel de PUB. Las clases base V2 exponen los argumentos en formatos distintos a los de la API V1:-
BaseSamplerV2.runexpone un argumentoshots(similar al flujo de trabajo anterior):# Sample two circuits at 128 shots each.
sampler_v2.run([circuit1, circuit2], shots=128)
# Sample two circuits at different amounts of shots. The "None"s are necessary
# as placeholders
# for the lack of parameter values in this example.
sampler_v2.run([(circuit1, None, 123), (circuit2, None, 456)]) -
EstimatorV2.runintroduce un argumentoprecisionque especifica las barras de error que la implementación del primitivo debe alcanzar en las estimaciones de valores esperados:# Estimate expectation values for two PUBs, both with 0.05 precision.
estimator_v2.run([(circuit1, obs_array1), (circuit2, obs_array_2)], precision=0.05)
-
Actualizaciones en la interfaz V1
-
Ya no se permite la conversión implícita de un
BaseOperatordenso a unSparsePauliOpen los argumentos de observable deEstimator. Debes convertir explícitamente aSparsePauliOpusandoSparsePauliOp.from_operator(operator)en su lugar. -
Ya no se permite usar una
PauliListen los argumentos de observable de Estimator. En su lugar, debes convertir explícitamente el argumento usandoSparsePauliOp(pauli_list)primero.
qiskit.providers
basicaer
La mayor parte de la funcionalidad del módulo qiskit.providers.basicaer ha sido
reemplazada por el nuevo módulo
qiskit.providers.basic_provider,
excepto las clases UnitarySimulatorPy y StatevectorSimulatorPy,
que han sido eliminadas; su funcionalidad ya estaba contenida en
el módulo quantum_info.
La migración a las nuevas rutas es directa. Puedes reemplazar la mayoría de las
clases en qiskit.providers.basicaer con su contraparte de
qiskit.providers.basic_provider
(reemplazo directo). Ten en cuenta que las siguientes clases tienen
nuevas rutas y nombres:
| Eliminado | Alternativa |
|---|---|
qiskit.providers.basicaer | qiskit.providers.basic_provider |
BasicAerProvider | BasicProvider |
BasicAerJob | BasicProviderJob |
QasmSimulatorPy | BasicSimulator |
Ten cuidado con cualquier instancia global al migrar al nuevo módulo. No existe reemplazo para
la instancia global BasicAer que se pudiera importar directamente como qiskit.BasicAer. Esto significa que
from qiskit import BasicProvider ya no es una importación válida.
En cambio, la clase del proveedor debe importarse desde su submódulo e instanciarse por el usuario:
# Previous
from qiskit import BasicAer
backend = BasicAer.get_backend("backend_name")
# Current
from qiskit.providers.basic_provider import BasicProvider
backend = BasicProvider().get_backend("backend_name")
Los simuladores unitario y de vector de estado pueden reemplazarse con
distintas clases de quantum_info. No es un
reemplazo directo, pero los cambios son mínimos. Consulta los siguientes ejemplos
de migración:
| Eliminado | Alternativa |
|---|---|
UnitarySimulatorPy | quantum_info.Operator |
StatevectorSimulatorPy | quantum_info.Statevector |
Los siguientes ejemplos muestran las rutas de migración de los simuladores de basicaer.
- Simulador de vector de estado
- Simulador unitario
- Simulador QASM
from qiskit import QuantumCircuit
qc = QuantumCircuit(3)
qc.h(0)
qc.h(1)
qc.cx(1, 2)
qc.measure_all()
# Previous
from qiskit import BasicAer
backend = BasicAer.get_backend("statevector_simulator")
statevector = backend.run(qc).result().get_statevector()
# Current
qc.remove_final_measurements() # no measurements allowed
from qiskit.quantum_info import Statevector
statevector = Statevector(qc)
from qiskit import QuantumCircuit
qc = QuantumCircuit(3)
qc.h(0)
qc.h(1)
qc.cx(1, 2)
qc.measure_all()
# Previous
from qiskit import BasicAer
backend = BasicAer.get_backend("unitary_simulator")
result = backend.run(qc).result()
# Current
qc.remove_final_measurements() # no measurements allowed
from qiskit.quantum_info import Operator
result = Operator(qc).data
from qiskit import QuantumCircuit
qc = QuantumCircuit(3)
qc.h(0)
qc.h(1)
qc.cx(1, 2)
qc.measure_all()
# Previous
from qiskit import BasicAer
backend = BasicAer.get_backend("qasm_simulator")
result = backend.run(qc).result()
# One current option
from qiskit.providers.basic_provider import BasicProvider
backend = BasicProvider().get_backend("basic_simulator")
result = backend.run(qc).result()
# Another current option is to specify it directly
from qiskit.providers.basic_provider import BasicSimulator
backend = BasicSimulator()
result = backend.run(qc).result()
fake_provider
La mayoría de los componentes de cara al usuario de
qiskit.providers.fake_provider han sido
migrados al paquete Python qiskit-ibm-runtime. Esto incluye las
clases de proveedor falso, todos los backends falsos específicos de dispositivo (como
FakeVigo, FakeNairobiV2 y FakeSherbrooke), y las clases
base de backends falsos. Haz clic en las siguientes pestañas para ver las clases afectadas.
- Backends falsos
- Proveedores falsos
- Cualquier clase en
qiskit.providers.fake_provider.backends fake_provider.fake_backend.FakeBackendfake_provider.fake_backend.FakeBackendV2
fake_provider.FakeProviderfake_provider.FakeProviderForBackendV2fake_provider.FakeProviderFactory
Para migrar a la nueva ruta:
-
Instala
qiskit-ibm-runtime0.17.1o posterior:pip install 'qiskit-ibm-runtime>=0.17.1' -
Reemplaza las instancias de
qiskit.providers.fake_provideren tu código conqiskit_ibm_runtime.fake_provider. Por ejemplo:# Old
from qiskit.providers.fake_provider import FakeProvider
backend1 = FakeProvider().get_backend("fake_ourense")
from qiskit.providers.fake_provider import FakeSherbrooke
backend2 = FakeSherbrooke()
# Alternative
from qiskit_ibm_runtime.fake_provider import FakeProvider
backend1 = FakeProvider().get_backend("fake_ourense")
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
backend2 = FakeSherbrooke()
Las clases base de backends falsos también han sido migradas, pero tienen algunas diferencias en la ruta de importación:
| Eliminado | Alternativa |
|---|---|
qiskit.providers.fake_provider.FakeQasmBackend | qiskit_ibm_runtime.fake_provider.fake_qasm_backend.FakeQasmBackend |
qiskit.providers.fake_provider.FakePulseBackend | qiskit_ibm_runtime.fake_provider.fake_pulse_backend.FakePulseBackend |
Si dependes de backends falsos para pruebas unitarias en una biblioteca downstream y tienes conflictos con la
dependencia de qiskit-ibm-runtime, también puedes encontrar nuevas alternativas de backends falsos genéricos nativos de Qiskit.
Estas incluyen las siguientes clases BackendV1 (reemplazos directos):
qiskit.providers.fake_provider.Fake5QV1qiskit.providers.fake_provider.Fake20QV1qiskit.providers.fake_provider.Fake7QPulseV1qiskit.providers.fake_provider.Fake27QPulseV1qiskit.providers.fake_provider.Fake127QPulseV1
Esta es una clase configurable que devuelve instancias de BackendV2:
fake_provider (backends especiales para pruebas)
Las clases de backend falso para propósitos especiales de prueba en
qiskit.providers.fake_provider no han sido
migradas a qiskit_ibm_runtime.fake_provider. La ruta de migración
recomendada es usar la nueva clase
GenericBackendV2
para configurar un backend con propiedades similares o para construir un
target personalizado.
| Eliminado | Alternativa |
|---|---|
fake_provider.FakeBackendV2 | fake_provider.GenericBackendV2 |
fake_provider.FakeBackend5QV2 | fake_provider.GenericBackendV2 |
fake_provider.FakeBackendV2LegacyQubitProps | fake_provider.GenericBackendV2 |
fake_provider.FakeBackendSimple | fake_provider.GenericBackendV2 |
fake_provider.ConfigurableFakeBackend | fake_provider.GenericBackendV2 |
Ejemplo: Migrar a la nueva clase
GenericBackendV2:
# Legacy path
from qiskit.providers.fake_provider import FakeBackend5QV2
backend = FakeBackend5QV2()
# New path
from qiskit.providers.fake_provider import GenericBackendV2
backend = GenericBackendV2(num_qubits=5)
# Note that this class generates a 5q backend with generic
# properties that serves the same purpose as FakeBackend5QV2
# but will not be identical.
Otros consejos de migración
-
Ya no es posible importar desde
qiskit.providers.aer. En cambio, importa desdeqiskit_aer, que es un reemplazo directo. Para instalarqiskit_aer, ejecuta:pip install qiskit-aer -
En Qiskit 1.0 se ha eliminado el soporte para ejecutar trabajos de pulso en backends de
qiskit.providers.fake_provider. Esto se debe a que Qiskit Aer eliminó su funcionalidad de simulación para este tipo de trabajos. Para cargas de trabajo de simulación hamiltoniana de bajo nivel, considera usar una biblioteca especializada como Qiskit Dynamics.
qiskit.pulse
ParametricPulse
La clase base qiskit.pulse.library.parametric_pulses.ParametricPulse y
la biblioteca de pulsos han sido reemplazadas por
qiskit.pulse.SymbolicPulse
y la biblioteca de pulsos correspondiente. SymbolicPulse admite la
serialización QPY:
from qiskit import pulse, qpy
with pulse.build() as schedule:
pulse.play(pulse.Gaussian(100, 0.1, 25), pulse.DriveChannel(0))
with open('schedule.qpy', 'wb') as fd:
qpy.dump(schedule, fd)
| Eliminado | Alternativa |
|---|---|
pulse.library.parametric_pulses.ParametricPulse | qiskit.pulse.SymbolicPulse |
pulse.library.parametric_pulses.Constant | pulse.library.symbolic_pulses.Constant |
pulse.library.parametric_pulses.Drag | pulse.library.symbolic_pulses.Drag |
pulse.library.parametric_pulses.Gaussian | pulse.library.symbolic_pulses.Gaussian |
qiskit.pulse.library.parametric_pulses.GaussianSquare | pulse.library.symbolic_pulses.GaussianSquare |
Amplitud de valor complejo
La amplitud de pulso de valor complejo (amp) es reemplazada por el par (amp,
angle). Esta representación es más intuitiva, especialmente para algunas
tareas de calibración como la calibración de ángulo:
from qiskit import pulse
from qiskit.circuit import Parameter
from math import pi
with pulse.build() as schedule:
angle = Parameter("θ")
pulse.play(pulse.Gaussian(100, 0.1, 25, angle=angle), pulse.DriveChannel(0))
schedule.assign_parameters({angle: pi})
Inyección de operaciones de Gate de Circuit
Ya no es posible inyectar operaciones de Gate de Circuit en el contexto del
constructor de pulsos a través de
qiskit.pulse.builder.call.
Esta eliminación afecta a los argumentos de entrada de tipo QuantumCircuit, así como a las
siguientes funciones:
qiskit.pulse.builder.call_gateqiskit.pulse.builder.cxqiskit.pulse.builder.u1qiskit.pulse.builder.u2qiskit.pulse.builder.u3qiskit.pulse.builder.x
Si aún quieres inyectar schedules calibrados por el backend, usa el siguiente patrón en lugar de llamar comandos de gate.
from qiskit.providers.fake_provider import GenericBackendV2
from qiskit import pulse
backend = GenericBackendV2(num_qubits=5)
sched = backend.target["x"][(qubit,)].calibration
with pulse.build() as only_pulse_scheds:
pulse.call(sched)
De manera similar, un QuantumCircuit puede
inyectarse en el contexto del constructor transpilando y programando manualmente el
objeto.
from math import pi
from qiskit.compiler import schedule, transpile
qc = QuantumCircuit(2)
qc.rz(pi / 2, 0)
qc.sx(0)
qc.rz(pi / 2, 0)
qc.cx(0, 1)
qc_t = transpile(qc, backend)
sched = schedule(qc_t, backend)
with pulse.build() as only_pulse_scheds:
pulse.call(sched)
Te recomendamos escribir un programa de pulso mínimo con el constructor y adjuntarlo al
QuantumCircuit a través del método
QuantumCircuit.add_calibration
como microcódigo de una instrucción de gate, en lugar de escribir el programa completo
con el modelo de pulso.
builder.build
Los siguientes argumentos de qiskit.pulse.builder.build han sido eliminados
sin alternativa.
default_transpiler_settingsdefault_circuit_scheduler_settings
Estas funciones también han sido eliminadas:
qiskit.pulse.builder.active_transpiler_settingsqiskit.pulse.builder.active_circuit_scheduler_settingsqiskit.pulse.builder.transpiler_settingsqiskit.pulse.builder.circuit_scheduler_settings
Esto se debe a que ya no es posible inyectar objetos de circuito en el contexto del builder (consulta Inyectar operaciones de puertas de circuito); estos ajustes servían para convertir los objetos inyectados en representaciones de pulso.
library
La biblioteca de pulsos discretos ha sido eliminada del código base. Esto incluye:
qiskit.pulse.library.constantqiskit.pulse.library.zeroqiskit.pulse.library.squareqiskit.pulse.library.sawtoothqiskit.pulse.library.triangleqiskit.pulse.library.cosqiskit.pulse.library.sinqiskit.pulse.library.gaussianqiskit.pulse.library.gaussian_derivqiskit.pulse.library.sechqiskit.pulse.library.sech_derivqiskit.pulse.library.gaussian_squareqiskit.pulse.library.drag
En su lugar, usa el
qiskit.pulse.SymbolicPulse
correspondiente con
SymbolicPulse.get_waveform().
Por ejemplo, en lugar de pulse.gaussian(100,0.5,10), usa
pulse.Gaussian(100,0.5,10).get_waveform(). Ten en cuenta que la fase tanto de
Sawtooth como de
Square se define de modo que
una fase de 2\\pi desplaza un ciclo completo, al contrario que su equivalente discreto.
Ten en cuenta también que las amplitudes complejas ya no están soportadas en la
biblioteca de pulsos simbólicos; usa float, amp y angle en su lugar.
ScalableSymbolicPulse
Ya no es posible cargar objetos qiskit.pulse.ScalableSymbolicPulse de la
biblioteca con un parámetro amp complejo de archivos qpy de la versión 5 o
anteriores (Qiskit Terra < 0.23.0). No se requiere ninguna acción de migración,
ya que el amp complejo se convertirá automáticamente a float (amp, angle).
Este cambio afecta a los siguientes pulsos:
qiskit.qasm
El módulo heredado del analizador de OpenQASM 2 que estaba en qiskit.qasm ha
sido reemplazado por el módulo qiskit.qasm2, que
proporciona un analizador más rápido y preciso para OpenQASM 2. Los métodos de
alto nivel de QuantumCircuit
from_qasm_file()
y
from_qasm_str()
siguen siendo los mismos, pero internamente utilizarán el nuevo analizador. Sin embargo,
la interfaz pública del módulo qasm2 no es la misma. Mientras que el módulo
qiskit.qasm proporcionaba una interfaz a un árbol de sintaxis abstracta devuelto
por la biblioteca de análisis ply, qiskit.qasm2 no expone el AST ni ningún
detalle de implementación de bajo nivel sobre el analizador. En su lugar, toma
entradas en OpenQASM 2 y devuelve un objeto
QuantumCircuit.
Por ejemplo, si anteriormente ejecutabas algo como esto:
import qiskit.qasm
from qiskit.converters import ast_to_dag, dag_to_circuit
ast = qiskit.qasm.Qasm(filename="myfile.qasm").parse()
dag = ast_to_dag(ast)
qasm_circ = dag_to_circuit(dag)
Reemplázalo con lo siguiente:
import qiskit.qasm2
qasm_circ = qiskit.qasm2.load("myfile.qasm")
qiskit.quantum_info
El módulo qiskit.quantum_info.synthesis ha sido migrado a varios lugares del
código base, principalmente a qiskit.synthesis.
| Eliminado | Alternativa |
|---|---|
OneQubitEulerDecomposer | qiskit.synthesis.one_qubit.OneQubitEulerDecomposer |
TwoQubitBasisDecomposer | qiskit.synthesis.two_qubits.TwoQubitBasisDecomposer |
XXDecomposer | qiskit.synthesis.two_qubits.XXDecomposer |
two_qubit_cnot_decompose | qiskit.synthesis.two_qubits.two_qubit_cnot_decompose |
Quaternion | qiskit.quantum_info.Quaternion |
Este cambio no afectó a la ruta de importación habitual de Quaternion, pero ya
no puedes acceder a él a través de qiskit.quantum_info.synthesis.
Por último, cnot_rxx_decompose ha sido eliminado.
qiskit.test
El módulo qiskit.test ya no es un módulo público. Nunca estuvo pensado para ser
público ni para usarse fuera del conjunto de pruebas de Qiskit. Toda la
funcionalidad era específica de Qiskit y no se proporciona ninguna alternativa;
si necesitas una funcionalidad similar, deberías incluirla en tus propios marcos
de pruebas.
qiskit.tools
El módulo qiskit.tools fue eliminado en Qiskit 1.0. La mayor parte de esta
funcionalidad fue reemplazada por funcionalidad equivalente en otros paquetes o
eliminada sin alternativa. La principal excepción es la función
qiskit.tools.parallel_map(), que ha sido trasladada al módulo
qiskit.utils. Puedes
usarla desde esta nueva ubicación. Por ejemplo:
Si anteriormente ejecutabas:
# Previous
from qiskit.tools import parallel_map
parallel_map(func, input)
# Current
from qiskit.utils import parallel_map
parallel_map(func, input)
jupyter
El submódulo qiskit.tools.jupyter ha sido eliminado porque la funcionalidad de
este módulo estaba vinculada al paquete heredado qiskit-ibmq-provider, que ya
no cuenta con soporte. Además, solo era compatible con BackendV1 y no con la
interfaz más reciente
BackendV2.
monitor
El submódulo qiskit.tools.monitor ha sido eliminado porque estaba vinculado al
paquete heredado qiskit-ibmq-provider, que ya no cuenta con soporte (tampoco
era compatible con la interfaz BackendV1, solo con la más reciente
BackendV2). No se
proporciona ninguna alternativa para esta funcionalidad.
visualization
El submódulo qiskit.tools.visualization ha sido eliminado. Este módulo era una
redirección heredada desde la ubicación original del módulo de visualización de
Qiskit, que fue trasladado a
qiskit.visualization en Qiskit
0.8.0. Si todavía usas esta ruta, actualiza tus importaciones de
qiskit.tools.visualization a
qiskit.visualization.
# Previous
from qiskit.tools.visualization import plot_histogram
plot_histogram(counts)
# Current
from qiskit.visualization import plot_histogram
plot_histogram(counts)
events
El módulo qiskit.tools.events y la utilidad progressbar() que exponía han
sido eliminados. La funcionalidad de este módulo no era ampliamente utilizada y
está mejor cubierta por paquetes dedicados como
tqdm.
qiskit.transpiler
synthesis
Los elementos del módulo qiskit.transpiler.synthesis han sido migrados a nuevas ubicaciones:
| Eliminado | Alternativa |
|---|---|
qiskit.transpiler.synthesis.aqc (excepto AQCSynthesisPlugin) | qiskit.synthesis.unitary.aqc |
qiskit.transpiler.synthesis.graysynth | qiskit.synthesis.synth_cnot_phase_aam |
qiskit.transpiler.synthesis.cnot_synth | qiskit.synthesis.synth_cnot_count_full_pmh |
passes
El pase de Transpiler NoiseAdaptiveLayout ha sido reemplazado por
VF2Layout y
VF2PostLayout,
que establecen un layout basado en las características de ruido reportadas por un
backend. Tanto el pase como el plugin de etapa de layout "noise_adaptive"
correspondiente han sido eliminados de Qiskit.
El pase de Transpiler CrosstalkAdaptiveSchedule ha sido eliminado del código
base. Este pase ya no era utilizable porque su operación interna dependía de
propiedades personalizadas configuradas en el payload BackendProperties de una
instancia BackendV1. Como ningún backend establece estos campos, el pase ha
sido eliminado.
passmanager
Los métodos append de las clases
ConditionalController,
FlowControllerLinear y
DoWhileController
han sido eliminados. En su lugar, todas las tareas deben proporcionarse al
construir los objetos del controlador.
qiskit.utils
Las siguientes herramientas de qiskit.utils han sido eliminadas sin reemplazo:
qiskit.utils.arithmeticqiskit.utils.circuit_utilsqiskit.utils.entangler_mapqiskit.utils.name_unnamed_args
Estas funciones se usaban exclusivamente en los módulos qiskit.algorithms y
qiskit.opflow, que también han sido eliminados.
qiskit.visualization
El módulo qiskit.visualization.qcstyle ha sido eliminado. Usa
qiskit.visualization.circuit.qcstyle como reemplazo directo.