Notas de la versión de Qiskit 0.14
0.14.0
Terra 0.11.0
Preludio
La versión 0.11.0 incluye varias novedades y correcciones de errores. El mayor cambio de esta versión es la incorporación del programador de impulsos. Esto permite a los usuarios definir su programa cuántico como QuantumCircuit y, a continuación, asignarlo a las instrucciones de impulso subyacentes que controlarán el hardware cuántico para implementar el circuito.
Nuevas funciones
-
Añadidos 5 nuevos comandos para recuperar fácilmente datos específicos del usuario de
BackendProperties:gate_property,gate_error,gate_length,qubit_property,t1,t2,readout_erroryfrequency. Devuelven los valores específicos de las propiedades del backend. Por ejemplo:from qiskit.test.mock import FakeOurense backend = FakeOurense() properties = backend.properties() gate_property = properties.gate_property('u1') gate_error = properties.gate_error('u1', 0) gate_length = properties.gate_length('u1', 0) qubit_0_property = properties.qubit_property(0) t1_time_0 = properties.t1(0) t2_time_0 = properties.t2(0) readout_error_0 = properties.readout_error(0) frequency_0 = properties.frequency(0) -
Añadido el método
Instruction.is_parameterized()para comprobar si un objeto de instrucción está parametrizado. Este método devuelveTruesi y sólo si la instrucción tiene un objetoParameterExpressionoParametercomo uno de sus parámetros. -
Se ha añadido un nuevo pase de análisis
Layout2qDistance. Esta pasada permite "puntuar" una selección de trazado, una vez que se ha configuradoproperty_set['layout']. La puntuación será la suma de las distancias de cada puerta de dos qubits del circuito, cuando no estén directamente conectadas. Esta puntuación no tiene en cuenta la dirección en el mapa de acoplamiento. Cuanto más bajo sea el número, mejor será la selección del diseño.Por ejemplo, considere un mapa de acoplamiento lineal
[0]--[2]--[1]y el siguiente circuito:qr = QuantumRegister(2, 'qr') circuit = QuantumCircuit(qr) circuit.cx(qr[0], qr[1])Si el diseño es
{qr[0]:0, qr[1]:1},Layout2qDistancefijaráproperty_set['layout_score'] = 1. Si la disposición es{qr[0]:0, qr[1]:2}, el resultado esproperty_set['layout_score'] = 0. Cuanto menor sea la puntuación, mejor. -
Se ha añadido
qiskit.QuantumCircuit.cnotcomo alias del métodocxdeQuantumCircuit. Los nombrescnotycxse utilizan a menudo indistintamente ahora el método cx puede ser llamado con cualquiera de los dos nombres. -
Se ha añadido
qiskit.QuantumCircuit.toffolicomo alias del métodoccxdeQuantumCircuit. Los nombrestoffoliyccxse utilizan a menudo indistintamente ahora el método ccx puede ser llamado con cualquiera de los dos nombres. -
Se ha añadido
qiskit.QuantumCircuit.fredkincomo alias del métodocswapdeQuantumCircuit. Los nombresfredkinycswapse utilizan a menudo indistintamente ahora el método cswap se puede llamar con cualquier nombre. -
El modo de salida
latexparaqiskit.visualization.circuit_drawer()y el métodoqiskit.circuit.QuantumCircuit.draw()tiene ahora un modo para pasar el látex crudo de las etiquetas de las puertas y los parámetros. La sintaxis para hacer esto refleja la sintaxis del modo mathtext de matplotlib. Cualquier parte de una cadena de etiquetas entre un par de caracteres '$' se tratará como látex sin procesar y se pasará directamente al látex de salida generado. Esto puede aprovecharse para añadir un formato más avanzado a los diagramas de circuito generados con el cajón de látex.Antes de esta versión, todas las etiquetas de las puertas pasaban por una conversión utf8 -> látex para asegurarse de que el látex de salida compilaría la cadena como se esperaba. Esto sigue siendo lo que ocurre para todas las partes de una etiqueta fuera del par '$'. Además, si desea utilizar un signo de dólar en la etiqueta, asegúrese de escaparlo en la cadena de caracteres de la etiqueta (es decir,
'\$').Puede combinar este paso con la conversión utf8 -> latex para crear la etiqueta exacta que desee, por ejemplo:
from qiskit import circuit circ = circuit.QuantumCircuit(2) circ.h([0, 1]) circ.append(circuit.Gate(name='α_gate', num_qubits=1, params=[0]), [0]) circ.append(circuit.Gate(name='α_gate$_2$', num_qubits=1, params=[0]), [1]) circ.append(circuit.Gate(name='\$α\$_gate', num_qubits=1, params=[0]), [1]) circ.draw(output='latex')mostrará la etiqueta de la primera puerta personalizada como
α_gate, la segunda seráα_gatecon un subíndice 2, y la etiqueta de la última puerta personalizada será$α$_gate. -
Añadir la clase
ControlledGatepara representar compuertas controladas. Las instancias de puerta controlada se crean con el métodocontrol(n)de los objetosGatedondenrepresenta el número de controles. Los qubits de control van antes que los qubits controlados en la nueva puerta. Por ejemplo:from qiskit import QuantumCircuit from qiskit.extensions import HGate hgate = HGate() circ = QuantumCircuit(4) circ.append(hgate.control(3), [0, 1, 2, 3]) print(circ)genera:
q_0: |0>──■── │ q_1: |0>──■── │ q_2: |0>──■── ┌─┴─┐ q_3: |0>┤ H ├ └───┘ -
Los valores permitidos de los parámetros y campos de
meas_levelahora pueden ser un miembro de la clase IntEnumqiskit.qobj.utils.MeasLevel. Se puede utilizar cuando se llama aexecute(o en cualquier otro lugar donde se especifiquemeas_level) con un experimento de pulso. Por ejemplo:from qiskit import QuantumCircuit, transpile, schedule, execute from qiskit.test.mock import FakeOpenPulse2Q from qiskit.qobj.utils import MeasLevel, MeasReturnType backend = FakeOpenPulse2Q() qc = QuantumCircuit(2, 2) qc.h(0) qc.cx(0,1) qc_transpiled = transpile(qc, backend) sched = schedule(qc_transpiled, backend) execute(sched, backend, meas_level=MeasLevel.CLASSIFIED)En el ejemplo anterior,
meas_level=MeasLevel.CLASSIFIEDymeas_level=2pueden utilizarse indistintamente. -
Se incluye un nuevo selector de diseño basado en la resolución de restricciones. CSPLayout modela el problema de encontrar un diseño como un problema de restricciones y utiliza el backtracking recursivo para resolverlo.
cmap16 = CouplingMap(FakeRueschlikon().configuration().coupling_map) qr = QuantumRegister(5, 'q') circuit = QuantumCircuit(qr) circuit.cx(qr[0], qr[1]) circuit.cx(qr[0], qr[2]) circuit.cx(qr[0], qr[3]) pm = PassManager(CSPLayout(cmap16)) circuit_after = pm.run(circuit) print(pm.property_set['layout'])Layout({ 1: Qubit(QuantumRegister(5, 'q'), 1), 2: Qubit(QuantumRegister(5, 'q'), 0), 3: Qubit(QuantumRegister(5, 'q'), 3), 4: Qubit(QuantumRegister(5, 'q'), 4), 15: Qubit(QuantumRegister(5, 'q'), 2) })El parámetro
CSPLayout(...,strict_direction=True)es más restrictivo pero garantizará que no sea necesario ejecutarCXDirectiondespués.pm = PassManager(CSPLayout(cmap16, strict_direction=True)) circuit_after = pm.run(circuit) print(pm.property_set['layout'])Layout({ 8: Qubit(QuantumRegister(5, 'q'), 4), 11: Qubit(QuantumRegister(5, 'q'), 3), 5: Qubit(QuantumRegister(5, 'q'), 1), 6: Qubit(QuantumRegister(5, 'q'), 0), 7: Qubit(QuantumRegister(5, 'q'), 2) })Si el sistema de restricciones no es solucionable, la propiedad de diseño no se establece.
circuit.cx(qr[0], qr[4]) pm = PassManager(CSPLayout(cmap16)) circuit_after = pm.run(circuit) print(pm.property_set['layout'])None -
PulseBackendConfiguration (al que se accede normalmente como backend.configuration ()) se ha ampliado con métodos útiles para explorar sus datos y la funcionalidad que existe en PulseChannelSpec. PulseChannelSpec quedará obsoleto en el futuro. Por ejemplo:
backend = provider.get_backend(backend_name) config = backend.configuration() q0_drive = config.drive(0) # or, DriveChannel(0) q0_meas = config.measure(0) # MeasureChannel(0) q0_acquire = config.acquire(0) # AcquireChannel(0) config.hamiltonian # Returns a dictionary with hamiltonian info config.sample_rate() # New method which returns 1 / dt -
PulseDefaults(al que se accede normalmente comobackend.defaults()) tiene un atributo,circuit_instruction_mapque tiene los métodos de CmdDef. El nuevo circuit_instruction\map es un objetoInstructionScheduleMapcon tres nuevas funciones además de las que tenía CmdDef :- qubit_instructions(qubits) devuelve las operaciones definidas para los qubits
- assert_has(instruction, qubits) produce un error si la op no está definida
- remove(instrucción, qubits) como pop, pero no requiere parámetros
Existen algunas diferencias con el CmdDef:
__init__no recibe argumentoscmdsycmd_qubitsquedan obsoletos y se sustituyen porinstructionsyqubits_with_instruction
Ejemplo:
backend = provider.get_backend(backend_name) inst_map = backend.defaults().circuit_instruction_map qubit = inst_map.qubits_with_instruction('u3')[0] x_gate = inst_map.get('u3', qubit, P0=np.pi, P1=0, P2=np.pi) pulse_schedule = x_gate(DriveChannel(qubit)) -
Se ha añadido a la función
qiskit.visualization.pulse_drawer()y al métodoqiskit.pulse.Schedule.draw()un nuevo parámetro kwarg,show_framechange_channels, para deshabilitar opcionalmente la visualización de canales con sólo instrucciones de cambio de marco en visualizaciones de pulsos. Cuando este nuevo kwarg se establece enFalsela visualización de la programación de pulsos de salida no incluirá ningún canal que sólo incluya cambios de trama.Por ejemplo:
from qiskit.pulse import * from qiskit.pulse import library as pulse_lib gp0 = pulse_lib.gaussian(duration=20, amp=1.0, sigma=1.0) sched = Schedule() channel_a = DriveChannel(0) channel_b = DriveChannel(1) sched += Play(gp0, channel_a) sched = sched.insert(60, ShiftPhase(-1.57, channel_a)) sched = sched.insert(30, ShiftPhase(-1.50, channel_b)) sched = sched.insert(70, ShiftPhase(1.50, channel_b)) sched.draw(show_framechange_channels=False) -
Se añade una nueva función de utilidad
qiskit.result.marginal_counts()que permite marginar los recuentos sobre algunos índices de interés. Esto es útil cuando se miden más qubits de los necesarios, y se desea obtener los recuentos de observación sólo para algún subconjunto de ellos. -
Cuando se invoca
passmanager.run(...)con más de un circuito, la transpilación de estos circuitos se ejecutará en paralelo. -
PassManagers ahora se puede cortar para crear un nuevo PassManager que contenga un subconjunto de pases utilizando el operador de corchetes. Esto permite ejecutar o dibujar una parte de la PassManager para facilitar las pruebas y la visualización. Por ejemplo, intentemos dibujar las 3 primeras pasadas de un PassManager pm, o ejecutar sólo la segunda pasada en nuestro circuito:
pm[0:4].draw() circuit2 = pm[1].run(circuit)También ahora, PassManagers puede crearse añadiendo dos PassManagers o añadiendo directamente un pase/lista de pases a un PassManager.
pm = pm1[0] + pm2[1:3] pm += [setLayout, unroller] -
Se ha añadido a Qiskit un módulo básico
scheduler. El programador programa una entrada transpiladaQuantumCircuiten un pulsoSchedule. El planificador acepta como entrada unScheduley, o bien un pulsoBackend, o bien unCmdDefque relaciona objetos de circuitoInstructionen qubits específicos con pulsos Planificaciones y unmeas_mapque determina qué mediciones deben ocurrir juntas.Ejemplo de programación:
from qiskit import QuantumCircuit, transpile, schedule from qiskit.test.mock import FakeOpenPulse2Q backend = FakeOpenPulse2Q() qc = QuantumCircuit(2, 2) qc.h(0) qc.cx(0,1) qc_transpiled = transpile(qc, backend) schedule(qc_transpiled, backend)El programador admite actualmente dos políticas de programación, as_late_as_possible (
alap) y as_soon_as_possible (asap), que programan respectivamente las instrucciones de impulso para que se produzcan lo más tarde posible o lo más pronto posible a través de los qubits de un circuito. La política de programación puede seleccionarse con el argumento de entradamethod, por ejemplo:schedule(qc_transpiled, backend, method='alap')Es fácil utilizar un impulso
Scheduledentro de unQuantumCircuitasignándolo a una instrucción de circuito personalizada, como una puerta que puede utilizarse en unQuantumCircuit. Para ello, en primer lugar, defina la puerta personalizada y, a continuación, añada una entrada enCmdDefpara la puerta, para cada qubit al que se aplicará la puerta. La puerta puede utilizarse enQuantumCircuit. En el momento de la programación, la puerta se asignará al programa de impulsos subyacente. El uso de esta técnica permite una fácil integración con módulos qiskit preexistentes como Ignis.Por ejemplo:
from qiskit import pulse, circuit, schedule from qiskit.pulse import pulse_lib custom_cmd_def = pulse.CmdDef() # create custom gate custom_gate = circuit.Gate(name='custom_gate', num_qubits=1, params=[]) # define schedule for custom gate custom_schedule = pulse.Schedule() custom_schedule += pulse_lib.gaussian(20, 1.0, 10)(pulse.DriveChannel) # add schedule to custom gate with same name custom_cmd_def.add('custom_gate', (0,), custom_schedule) # use custom gate in a circuit custom_qc = circuit.QuantumCircuit(1) custom_qc.append(custom_gate, qargs=[0]) # schedule the custom gate schedule(custom_qc, cmd_def=custom_cmd_def, meas_map=[[0]])
Problemas conocidos
- La función para transpilar en paralelo cuando se invoca
passmanager.run(...)con más de un circuito no es compatible con Windows. Véase el nº 2988 para más detalles.
Notas de actualización
- La clase
qiskit.pulse.channels.SystemTopologyse utilizó como clase auxiliar dePulseChannelSpec. Se ha eliminado con la desaparición dePulseChannelSpecy los cambios enBackendConfigurationlo hacen innecesario. - Se ha eliminado la representación de qubits y bits clásicos como tupla, que estaba obsoleta en la versión 0.9. El uso de los objetos
QubityClbites la nueva forma de representar los qubits y los bits clásicos. - Se ha eliminado la representación anteriormente obsoleta del conjunto de bases como cadena única. Una lista de cadenas es la nueva forma preferida.
- El método
BaseModel.as_dict, que estaba obsoleto en la versión 0.9, se ha eliminado en favor del métodoBaseModel.to_dict. - En PulseDefaults (al que se accede normalmente como backend.defaults ()),
qubit_freq_estymeas_freq_estse devuelven ahora en Hz en lugar de GHz. Esto significa que los nuevos valores de retorno son 1e9 * su valor anterior. - se añadió eneldo como requisito. Esto es necesario para poder ejecutar
passmanager.run()en paralelo para más de un circuito. - La anteriormente obsoleta puerta
UBase, que fue obsoleta en la versión 0.9, ha sido eliminada. En su lugar debe utilizarse la puertaU3Gate. - La anteriormente obsoleta puerta
CXBase, que fue obsoleta en la versión 0.9, ha sido eliminada. En su lugar debe utilizarse la puertaCnotGate. - La instrucción
snapshotse utiliza para convertir implícitamente el parámetrolabelen cadena. Esa conversión se ha eliminado y se produce un error si no se proporciona una cadena. - La anteriormente obsoleta puerta
U0Gate, que fue obsoleta en la versión 0.9, ha sido eliminada. La puertaIdGatedebería utilizarse en su lugar para insertar retardos.
Notas sobre características en desuso
-
La clase
qiskit.pulse.CmdDefha quedado obsoleta. En su lugar, debe utilizar la direcciónqiskit.pulse.InstructionScheduleMap. Se puede acceder al objetoInstructionScheduleMappara un sistema activado por impulsos enbackend.defaults().instruction_schedules. -
PulseChannelSpecestá en desuso. UtiliceBackendConfigurationen su lugar. A la configuración del backend se accede normalmente comobackend.configuration(). El config se ha ampliado con la mayor parte de la funcionalidad de PulseChannelSpec, con algunas modificaciones como sigue, donde 0 es un índice de qubit ejemplar:pulse_spec.drives[0] -> config.drive(0) pulse_spec.measures[0] -> config.measure(0) pulse_spec.acquires[0] -> config.acquire(0) pulse_spec.controls[0] -> config.control(0)Ahora, si se intenta obtener un canal para un qubit que no existe para el dispositivo, se emitirá un mensaje
BackendConfigurationErrorcon una explicación útil.Los métodos
memoryslotsyregisterslotsde PulseChannelSpec no se han migrado a la configuración del backend. Estos recursos clásicos no están limitados por la configuración física de un sistema backend. Instálelos directamente:pulse_spec.memoryslots[0] -> MemorySlot(0) pulse_spec.registerslots[0] -> RegisterSlot(0)El método
qubitsno se migra a la configuración del backend. El resultado dequbitspuede construirse así:[q for q in range(backend.configuration().n_qubits)] -
Qubitenpulse.channelsha quedado obsoleto. No deben utilizarse. Es posible obtener mapeados de qubits del canal <=> a través de BackendConfiguration (o backend.configuration ()). -
La función
qiskit.visualization.circuit_drawer.qx_color_scheme()ha quedado obsoleta. Esta función ya no se utiliza internamente y no refleja el estilo actual de IBM QX. Si estaba utilizando esta función para generar un diccionario de estilo localmente, debe guardar la salida de la misma y utilizar ese diccionario directamente. -
La Excepción
TranspilerAccessErrorha quedado obsoleta. En su lugar, puede utilizarse una función alternativaTranspilerErrorpara proporcionar la misma funcionalidad. Esta función alternativa proporciona exactamente la misma funcionalidad pero con mayor generalidad. -
Los buffers en Pulse están obsoletos. Si se proporciona un búfer distinto de cero, se emitirá una advertencia con un recordatorio para utilizar un Retraso en su lugar. Otras opciones incluirían añadir muestras a una instrucción de pulso que son ( 0.+0.j ) o establecer el tiempo de inicio del siguiente pulso en
schedule.duration + buffer. -
Pasar los tipos
sympy.Basic,sympy.Exprysympy.Matrixcomo parámetros de instrucción está obsoleto y se eliminará en una futura versión. Tendrás que convertir la entrada a uno de los tipos admitidos, que son:intfloatcomplexstrnp.ndarray
Corrección de errores
- Los pases Collect2qBlocks y CommutationAnalysis del transpilador no habían podido procesar circuitos que contenían puertas parametrizadas, lo que impedía transpilar circuitos parametrizados en el nivel de optimización 2 o superior. Estos pases se han corregido para tratar las puertas parametrizadas como opacas.
- La función align_measures tenía un problema por el que los pulsos de estímulo Measure no se alineaban correctamente con los pulsos Acquire, lo que provocaba un error. Esto se ha solucionado.
- Se ha eliminado el uso de
numpy.random.seedpara que las llamadas a las funciones qiskit no afecten a los resultados de futuras llamadas anumpy.random - Corregida la condición de carrera que se producía en el monitor de trabajos cuando
job.queue_position()devolvíaNone.Nonees una devolución válida dejob.queue_position(). - El soporte de backend para
memory=Trueahora se comprueba cuando se pasa ese kwarg.QiskitErrorresultados si no es compatible. - Al transpilar sin mapa de acoplamiento, no se comprobaba la cantidad de qubits del circuito a transpilar. Ahora el proceso de transpilación comprueba que el backend tiene suficientes qubits para asignar el circuito.
Otras notas
- La función
qiskit.result.marginal_counts()sustituye a una función de utilidad similar en qiskit-ignisqiskit.ignis.verification.tomography.marginal_counts(), que quedará obsoleta en una futura versión de qiskit-ignis. - Se han eliminado todos los tipos de salida de parámetros sympy (o han quedado obsoletos, según se indique) de qiskit-terra. Esto incluye parámetros de tipo sympy en objetos
QuantumCircuit, nodos qasm ast u objetosQobj.
Aer 0.3
Sin cambios
Ignis 0.2
Sin cambios
Aqua 0.6
Sin cambios
IBM Proveedor Q 0.4
Preludio
La versión 0.4.0 es la primera que utiliza todas las funciones de la nueva API IBM Q. En particular, se ha renovado la clase IBMQJob para poder recuperar más información de IBM Q, y se ha añadido una clase Job Manager para permitir un uso de mayor nivel y más fluido de trabajos grandes o complejos. Si aún no se ha actualizado desde la versión anterior IBM Q Experience o QConsole, asegúrese de volver a consultar las notas de la versión de IBM Q Provider 0.3 (Qiskit 0.11 ) para obtener más detalles sobre cómo realizar la transición. Las cuentas heredadas dejarán de ser compatibles a partir de esta versión.
Nuevas funciones
Modificaciones del puesto de trabajo
La clase IBMQJob ha sido revisada, y ahora se asemeja más al contenido de un trabajo remoto junto con nuevas características:
- Ahora puede asignar un nombre a un trabajo, especificando
IBMQBackend.run(..., job_name='...')al enviar un trabajo. Este nombre se puede recuperar a través deIBMQJob.name()y se puede utilizar para filtrar. - Ahora los trabajos pueden compartirse con otros usuarios a distintos niveles (global, por hub, grupo o proyecto) mediante un parámetro opcional
job_share_levelal enviar el trabajo. IBMQJobtienen ahora más atributos, que reflejan el contenido de los trabajos remotos de IBM Q. Esto implica que los nuevos atributos introducidos por la API IBM Q estarán automática e inmediatamente disponibles para su uso (por ejemplo,job.new_api_attribute). Los nuevos atributos se promoverán a métodos cuando se consideren estables (por ejemplo,job.name())..error_message()devuelve más información sobre por qué ha fallado un trabajo..queue_position()acepta un parámetrorefreshpara forzar una actualización..result()acepta un parámetro opcionalpartial, para devolver resultados parciales, si los hubiera, de trabajos que hayan fallado. Tenga en cuenta que los métodos deResult, comoget_counts(), lanzarán una excepción si se aplican a experimentos que han fallado.
Tenga en cuenta que los cambios incluyen algunas modificaciones de bajo nivel de la clase. Si creabas las instancias manualmente, tenlo en cuenta:
- la firma del constructor ha cambiado para tener en cuenta las nuevas características.
- el método
.submit()ya no se puede llamar directamente, y se espera que los trabajos se envíen a través deIBMQBackend.run()síncrono o a través del gestor de trabajos.
Gestor de trabajos
Se ha introducido un nuevo gestor de trabajos (IBMQJobManager), como mecanismo de nivel superior para gestionar trabajos compuestos por múltiples circuitos o programaciones de impulsos. El gestor de trabajos pretende ofrecer una interfaz transparente, dividiendo de forma inteligente la entrada en unidades de trabajo eficientes y aprovechando al máximo los distintos componentes. Se ampliará en las próximas versiones y se convertirá en el punto de entrada recomendado para la presentación de trabajos.
Su método .run() recibe una lista de circuitos o programaciones de impulsos, y devuelve un ManagedJobSet instance, que puede utilizarse para realizar un seguimiento de los estados y resultados de estos trabajos. Por ejemplo:
from qiskit.providers.ibmq.managed import IBMQJobManager
from qiskit.circuit.random import random_circuit
from qiskit import IBMQ
from qiskit.compiler import transpile
provider = IBMQ.load_account()
backend = provider.backends.ibmq_ourense
circs = []
for _ in range(1000000):
circs.append(random_circuit(2, 2))
transpile(circs, backend=backend)
# Farm out the jobs.
jm = IBMQJobManager()
job_set = jm.run(circs, backend=backend, name='foo')
job_set.statuses() # Gives a list of job statuses
job_set.report() # Prints detailed job information
results = job_set.results()
counts = results.get_counts(5) # Returns data for experiment 5provider.backends modificaciones
El miembro provider.backends , que antes era una función que devolvía una lista de backends, ha pasado a ser un servicio. Esto implica que puede utilizarse tanto de la forma anterior, como método .backends() , como atributo .backends con capacidades ampliadas:
-
contiene los backends existentes de ese proveedor como atributos, que pueden utilizarse para el autocompletado. Por ejemplo:
my_backend = provider.get_backend('ibmq_qasm_simulator')es equivalente a:
my_backend = provider.backends.ibmq_qasm_simulator -
los métodos
provider.backends.jobs()yprovider.backends.retrieve_job()pueden utilizarse para recuperar trabajos de todo el proveedor.
Otros cambios
- La función
backend.properties()acepta ahora un parámetro opcionaldatetime. Si se especifica, la función devuelve las propiedades backend más cercanas, pero más antiguas, al filtro datetime especificado. - Algunos mensajes de
warningsse han reducido alogger.warning.