Mudanças de recursos do Qiskit 1.0
Este guia descreve os caminhos de migração para as mudanças de recursos mais importantes do Qiskit 1.0, organizadas por módulo. Use o índice do lado direito para navegar até o módulo de seu interesse.
Ferramenta de migração do Qiskit 1.0
Para facilitar o processo de migração, você pode usar a ferramenta
flake8-qiskit-migration
para detectar caminhos de importação removidos no seu código e sugerir alternativas.
- Executar com pipx
- Executar com venv
Se você tiver o pipx instalado, basta executar
o seguinte comando.
pipx run flake8-qiskit-migration <path-to-source-directory>
Isso instalará o pacote em um ambiente virtual temporário e o executará no seu código.
Se você não quiser usar pipx, pode criar manualmente um novo
ambiente para a ferramenta. Essa abordagem também permite usar
o nbqa para verificar exemplos de código em
notebooks Jupyter. Exclua o ambiente quando terminar.
# 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 ferramenta detecta apenas caminhos de importaç ão removidos. Ela não detecta o uso de
métodos removidos (como QuantumCircuit.qasm) ou argumentos. Também não consegue rastrear
atribuições como qk = qiskit, embora consiga lidar com aliases como
import qiskit as qk.
Para mais informações, consulte o repositório do projeto.
Instâncias e funções globais
Aer
O objeto qiskit.Aer não está disponível no Qiskit 1.0. Em vez disso, use o
mesmo objeto do namespace qiskit_aer, que é um substituto direto.
Para instalar o qiskit_aer, execute:
pip install qiskit-aer
BasicAer
O objeto qiskit.BasicAer não está disponível no Qiskit 1.0. Consulte a
seção de migração do basicaer para
obter opções de migração.
execute
A função qiskit.execute não está disponível no Qiskit 1.0. Essa
função servia como um wrapper de alto nível em torno das funções
transpile e
run do Qiskit.
Em vez de qiskit.execute, use a função
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)
Alternativamente, o primitivo Sampler
é semanticamente equivalente à função qiskit.execute removida.
A classe
BackendSampler é um
wrapper genérico para backends que não suportam primitivos:
from qiskit.primitives import BackendSampler
sampler = BackendSampler(backend)
job = sampler.run(circuit)
qiskit.circuit
QuantumCircuit.qasm
O método QuantumCircuit.qasm foi removido. Em vez disso, use
qasm2.dump ou
qasm2.dumps.
Para saída formatada com Pygments, consulte o pacote independente
openqasm-pygments,
pois qasm2.dump e qasm2.dumps não fornecem saída colorida pelo 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 do QuantumCircuit
Os seguintes métodos de Gate foram removidos em favor de métodos mais consolidados que adicionam os mesmos gates:
| Removido | 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 |
Os seguintes métodos do Circuit foram removidos. Em vez disso, esses gates podem ser
aplicados a um Circuit com QuantumCircuit.append.
| Removido | 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 exemplo, para um 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
Os seguintes métodos do QuantumCircuit também foram removidos:
| Removido | Alternativa |
|---|---|
QuantumCircuit.bind_parameters | QuantumCircuit.assign_parameters |
QuantumCircuit.snapshot | instruções de salvamento do qiskit-aer |
qiskit.converters
A função qiskit.converters.ast_to_dag foi removida do Qiskit. Ela convertia a
árvore de sintaxe abstrata gerada pelo parser legado do OpenQASM 2 em um
DAGCircuit. Como o parser legado do
OpenQASM 2 foi removido (consulte qiskit.qasm), essa
função não tem mais propósito. Em vez disso, analise seus arquivos OpenQASM 2 em um
QuantumCircuit usando os métodos construtores
QuantumCircuit.from_qasm_file
ou
QuantumCircuit.from_qasm_str
(ou o módulo qiskit.qasm2), e então
converta esse QuantumCircuit em um
DAGCircuit com
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
O módulo qiskit.extensions não está mais disponível. A maioria dos seus objetos foi
integrada à biblioteca de circuits
(qiskit.circuit.library). Para migrar para o
novo local, basta substituir qiskit.extensions por qiskit.circuit.library
no caminho de importação do objeto. Trata-se de um substituto direto.
# Previous
from qiskit.extensions import DiagonalGate
# Current alternative
from qiskit.circuit.library import DiagonalGate
As classes movidas para qiskit.circuit.library são:
DiagonalGateHamiltonianGateInitializeIsometryqiskit.circuit.library.generalized_gates.mcg_up_diag.MCGupDiagUCGateUCPauliRotGateUCRXGateUCRYGateUCRZGateUnitaryGate
As seguintes classes foram removidas do código base, pois suas
funções eram redundantes ou ligadas ao módulo extensions:
| Removido | Alternativa |
|---|---|
SingleQubitUnitary | qiskit.circuit.library.UnitaryGate |
Snapshot | Use as instruções de salvamento do qiskit-aer |
ExtensionError | Uma classe de erro relevante |
qiskit.primitives
A mudança mais notável no módulo qiskit.primitives é a
introdução da nova interface V2 dos primitivos. Esta seção mostra como migrar seu
fluxo de trabalho dos primitivos V1 para os primitivos V2, bem como as poucas mudanças que ocorreram
nas entradas aceitas pela interface V1.
A partir da versão 1.0, vamos nos referir à interface de primitivos pré-1.0 como "primitivos V1".
Migrar de V1 para V2
A distinção formal entre as APIs dos primitivos V1 e V2 são as classes base das quais
as implementações de primitivos herdam. Para fazer a transição para as novas classes base, você pode manter
o caminho de importação original de qiskit.primitives:
| Migrar de | Substituir por |
|---|---|
BaseEstimator | BaseEstimatorV2 |
BaseSampler | BaseSamplerV2 |
Os nomes das implementações centrais do Qiskit dos primitivos V2 (aquelas importáveis de qiskit.primitives)
foram modificados para esclarecer seu propósito como implementações que podem ser executadas localmente
com um backend simulador de statevector. Os novos nomes não incluem o sufixo -V2.
| Migrar de | Substituir por |
|---|---|
qiskit.primitives.Estimator | qiskit.primitives.StatevectorEstimator |
qiskit.primitives.Sampler | qiskit.primitives.StatevectorSampler |
Há algumas diferenças conceituais a considerar ao migrar de V1 para V2.
Essas diferenças são ditadas pela classe base, mas são mostradas nos exemplos a seguir usando as implementações de statevector
encontradas em qiskit.primitives:
Para os exemplos a seguir, assuma as seguintes importações e inicializações 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 e Estimator: Os novos primitivos V2 foram projetados para aceitar entradas vetorizadas, onde um único Circuit pode ser agrupado com especificações de valores em array. Ou seja, um Circuit pode ser executado para arrays denconjuntos de parâmetros,nobserváveis, ou ambos (no caso do estimador). Cada grupo é chamado de primitive unified bloc (pub), e pode ser representado como uma tupla:(1 x circuit, [n x observables], [n x parameters]). A interface V1 não permitia a mesma flexibilidade. Em vez disso, o número de circuits de entrada tinha que corresponder ao número de observáveis e conjuntos de parâmetros, como mostrado nos exemplos a seguir (selecione uma aba para ver cada exemplo):
- 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
Os primitivos V2 aceitam múltiplos PUBs como entradas, e cada pub recebe seu próprio resultado. Isso permite que você execute diferentes Circuits com várias combinações de parâmetros/observáveis, o que nem sempre era possível na interface 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: O Sampler V2 agora retorna amostras de resultados de medição na forma de bitstrings ou contagens, em vez das distribuições de quase-probabilidade da interface V1. As bitstrings mostram os resultados das medições, preservando a ordem de execução em que foram medidas. Os objetos de resultado do Sampler V2 organizam os dados em termos dos nomes de registros clássicos dos circuits de entrada, para compatibilidade com 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 1Nome padrão do registro clássicoNo Circuit acima, observe que o nome do registro clássico é padronizado como
"meas". Esse nome será usado posteriormente para acessar as bitstrings de medição.# 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 e Estimator: O overhead de amostragem, comumente exposto pelas implementações V1 pela opção de execuçãoshots, agora é um argumento do métodorun()dos primitivos que pode ser especificado no nível do PUB. As classes base V2 expõem os argumentos em formatos diferentes da API V1:-
BaseSamplerV2.runexpõe um argumentoshots(semelhante ao fluxo de trabalho 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.runintroduz um argumentoprecisionque especifica as barras de erro que a implementação do primitivo deve almejar para estimativas 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)
-
Atualizações na interface V1
-
A conversão implícita de um
BaseOperatordenso para umSparsePauliOpnos argumentos de observáveis doEstimatornão é mais permitida. Você deve converter explicitamente para umSparsePauliOpusandoSparsePauliOp.from_operator(operator)em vez disso. -
O uso de um
PauliListnos argumentos de observáveis do Estimator não é mais permitido. Em vez disso, você deve converter explicitamente o argumento usandoSparsePauliOp(pauli_list)primeiro.
qiskit.providers
basicaer
A maior parte da funcionalidade do módulo qiskit.providers.basicaer foi
substituída pelo novo módulo
qiskit.providers.basic_provider,
exceto pelas classes UnitarySimulatorPy e StatevectorSimulatorPy,
que foram removidas; suas funcionalidades já estavam contidas no
módulo quantum_info.
A migração para os novos caminhos é simples. Você pode substituir a maioria das
classes em qiskit.providers.basicaer pelo seu equivalente em
qiskit.providers.basic_provider
(substituto direto). Observe que as seguintes classes têm
novos caminhos e nomes:
| Removido | Alternativa |
|---|---|
qiskit.providers.basicaer | qiskit.providers.basic_provider |
BasicAerProvider | BasicProvider |
BasicAerJob | BasicProviderJob |
QasmSimulatorPy | BasicSimulator |
Fique atento a quaisquer instâncias globais ao migrar para o novo módulo. Não existe substituto para
a instância global BasicAer que poderia ser importada diretamente como qiskit.BasicAer. Isso significa que
from qiskit import BasicProvider não é mais uma importação válida.
Em vez disso, a classe provider deve ser importada do seu submódulo e instanciada pelo usuário:
# 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")
Os simuladores unitary e statevector podem ser substituídos por
diferentes classes de quantum_info. Isso não é um
substituto direto, mas as mudanças são mínimas. Veja os seguintes exemplos de migração:
| Removido | Alternativa |
|---|---|
UnitarySimulatorPy | quantum_info.Operator |
StatevectorSimulatorPy | quantum_info.Statevector |
Os exemplos a seguir mostram os caminhos de migração dos simuladores do basicaer.
- Simulador de statevector
- Simulador unitário
- 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
A maioria dos componentes voltados ao usuário do
qiskit.providers.fake_provider foi
migrada para o pacote Python qiskit-ibm-runtime. Isso inclui as
classes fake provider, todos os fake backends específicos de dispositivos (como
FakeVigo, FakeNairobiV2 e FakeSherbrooke) e as classes base
de fake backends. Clique nas abas a seguir para ver as classes afetadas.
- Fake Backends
- Fake Providers
- Qualquer classe em
qiskit.providers.fake_provider.backends fake_provider.fake_backend.FakeBackendfake_provider.fake_backend.FakeBackendV2
fake_provider.FakeProviderfake_provider.FakeProviderForBackendV2fake_provider.FakeProviderFactory
Para migrar para o novo caminho:
-
Instale
qiskit-ibm-runtime0.17.1ou posterior:pip install 'qiskit-ibm-runtime>=0.17.1' -
Substitua as instâncias de
qiskit.providers.fake_providerno seu código porqiskit_ibm_runtime.fake_provider. Por exemplo:# 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()
As classes base de fake backends também foram migradas, mas possuem algumas diferenças no caminho de importação:
| Removido | 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 |
Se você depende de fake backends para testes unitários de uma biblioteca downstream e tem conflitos com a
dependência qiskit-ibm-runtime, você também pode encontrar novas alternativas de fake backends genéricos nativos do Qiskit.
Estes incluem as seguintes classes BackendV1 (substitutos diretos):
qiskit.providers.fake_provider.Fake5QV1qiskit.providers.fake_provider.Fake20QV1qiskit.providers.fake_provider.Fake7QPulseV1qiskit.providers.fake_provider.Fake27QPulseV1qiskit.providers.fake_provider.Fake127QPulseV1
Esta é uma classe configurável que retorna instâncias BackendV2:
fake_provider (backends especiais de teste)
As classes de fake backend para fins especiais de teste em
qiskit.providers.fake_provider
não foram migradas para qiskit_ibm_runtime.fake_provider. O caminho de migração
recomendado é usar a nova classe
GenericBackendV2
para configurar um backend com propriedades semelhantes ou para construir um target
personalizado.
| Removido | 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 |
Exemplo: Migrar para a nova classe
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.
Outras dicas de migração
-
Importar de
qiskit.providers.aernão é mais possível. Em vez disso, importe deqiskit_aer, que é um substituto direto. Para instalarqiskit_aer, execute:pip install qiskit-aer -
O suporte para executar jobs de pulse em backends do
qiskit.providers.fake_providerfoi removido no Qiskit 1.0. Isso se deve ao fato de o Qiskit Aer ter removido sua funcionalidade de simulação para tais jobs. Para cargas de trabalho de simulação hamiltoniana de baixo nível, considere usar uma biblioteca especializada como o Qiskit Dynamics.
qiskit.pulse
ParametricPulse
A classe base qiskit.pulse.library.parametric_pulses.ParametricPulse e a
biblioteca de pulsos foram substituídas por
qiskit.pulse.SymbolicPulse
e a biblioteca de pulsos correspondente. O SymbolicPulse suporta
serialização 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)
| Removido | 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 |
Amplitude com valor complexo
A amplitude de pulso com valor complexo (amp) é substituída por um duo (amp,
angle). Essa representação é mais intuitiva, especialmente para algumas
tarefas de calibração, como a calibração 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})
Injeção de operações de gates de Circuit
A injeção de operações de gates de Circuit no contexto do pulse builder por meio de
qiskit.pulse.builder.call não é mais possível.
Essa remoção afeta argumentos de entrada do tipo QuantumCircuit, bem como as
seguintes funções:
qiskit.pulse.builder.call_gateqiskit.pulse.builder.cxqiskit.pulse.builder.u1qiskit.pulse.builder.u2qiskit.pulse.builder.u3qiskit.pulse.builder.x
Se você ainda quiser injetar schedules calibrados pelo backend, use o seguinte padrão em vez de chamar 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)
Da mesma forma, um QuantumCircuit pode
ser injetado no contexto do builder transpilando e agendando manualmente o
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)
Recomendamos escrever um programa de pulso mínimo com o builder e anexá-lo ao
QuantumCircuit por meio do método
QuantumCircuit.add_calibration
como microcode de uma instrução de gate, em vez de escrever todo o
programa com o modelo de pulso.
builder.build
Os seguintes argumentos em qiskit.pulse.builder.build foram removidos sem
alternativa.
default_transpiler_settingsdefault_circuit_scheduler_settings
Essas funções também foram removidas:
qiskit.pulse.builder.active_transpiler_settingsqiskit.pulse.builder.active_circuit_scheduler_settingsqiskit.pulse.builder.transpiler_settingsqiskit.pulse.builder.circuit_scheduler_settings
Isso se deve ao fato de que não é mais possível injetar objetos Circuit no contexto do builder (veja Injeção de operações de gates de Circuit ); essas configurações eram para converter objetos injetados em representações de pulso.
library
A biblioteca de pulsos discretos foi removida do código base. Isso inclui:
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
Em vez disso, use o
qiskit.pulse.SymbolicPulse correspondente,
com
SymbolicPulse.get_waveform().
Por exemplo, em vez de pulse.gaussian(100,0.5,10), use
pulse.Gaussian(100,0.5,10).get_waveform(). Observe que a fase tanto do
Sawtooth quanto do
Square é definida de tal forma
que uma fase de 2\\pi desloca um ciclo completo, ao contrário da contraparte discreta.
Observe também que amplitudes complexas não são mais suportadas na
biblioteca de pulsos simbólicos; use float, amp e angle em vez disso.
ScalableSymbolicPulse
Não é mais possível carregar objetos qiskit.pulse.ScalableSymbolicPulse da biblioteca
com um parâmetro amp complexo de arquivos qpy da versão 5 ou anterior
(Qiskit Terra < 0.23.0). Nenhuma ação de migração é necessária, pois o amp complexo será
convertido automaticamente para float (amp, angle).
Essa mudança se aplica a estes pulsos:
qiskit.qasm
O módulo legado do parser do OpenQASM 2, anteriormente em qiskit.qasm, foi
substituído pelo módulo qiskit.qasm2, que
fornece um parser mais rápido e preciso para o OpenQASM 2. Os métodos de alto nível do
QuantumCircuit
from_qasm_file()
e
from_qasm_str()
permanecem os mesmos, mas usarão o novo parser internamente. No entanto, a interface
pública do módulo qasm2 não é a mesma. Enquanto o módulo qiskit.qasm
fornecia uma interface para uma árvore de sintaxe abstrata retornada pela biblioteca de parser ply,
o qiskit.qasm2 não expõe a AST nem quaisquer detalhes de implementação de nível mais baixo
sobre o parser. Em vez disso, recebe entrada OpenQASM 2 e
produz um objeto QuantumCircuit.
Por exemplo, se você estava executando algo assim anteriormente:
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)
Substitua pelo seguinte:
import qiskit.qasm2
qasm_circ = qiskit.qasm2.load("myfile.qasm")
qiskit.quantum_info
O módulo qiskit.quantum_info.synthesis foi migrado para vários
locais no código base, principalmente qiskit.synthesis.
| Removido | 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 |
Essa mudança não afetou o caminho de importação usual do Quaternion, mas você não pode mais acessá-lo
por meio de qiskit.quantum_info.synthesis.
Por fim, cnot_rxx_decompose foi removido.
qiskit.test
O módulo qiskit.test não é mais um módulo público. Nunca foi destinado a ser público,
nem a ser usado fora do conjunto de testes do Qiskit. Toda a funcionalidade era específica do Qiskit e nenhuma
alternativa é fornecida; se você precisava de funcionalidade similar, deve incluí-la nos seus próprios
frameworks de teste.
qiskit.tools
O módulo qiskit.tools foi removido no Qiskit 1.0. A maior parte dessa funcionalidade foi
substituída por funcionalidade similar em outros pacotes ou removida sem alternativa.
A principal exceção é a função qiskit.tools.parallel_map(), que foi realocada para
o módulo qiskit.utils. Ela pode ser usada
a partir desse novo local. Por exemplo:
Se você estava executando anteriormente:
# Previous
from qiskit.tools import parallel_map
parallel_map(func, input)
# Current
from qiskit.utils import parallel_map
parallel_map(func, input)
jupyter
O submódulo qiskit.tools.jupyter foi removido porque a funcionalidade
deste módulo está vinculada ao pacote legado qiskit-ibmq-provider, que não é mais
suportado. Ele também suportava apenas BackendV1 e não a interface mais recente
BackendV2.
monitor
O submódulo qiskit.tools.monitor foi removido pois estava vinculado ao
pacote legado qiskit-ibmq-provider, que não é mais suportado (ele também
suportava apenas a interface BackendV1 e não a mais recente
BackendV2). Não existe
nenhuma alternativa fornecida para esta funcionalidade.
visualization
O submódulo qiskit.tools.visualization foi removido. Este módulo era um
redirecionamento legado da localização original do módulo de visualização do Qiskit e
foi movido para qiskit.visualization no Qiskit
0.8.0. Se você ainda estiver usando esse caminho, atualize suas importações de
qiskit.tools.visualization para
qiskit.visualization.
# Previous
from qiskit.tools.visualization import plot_histogram
plot_histogram(counts)
# Current
from qiskit.visualization import plot_histogram
plot_histogram(counts)
events
O módulo qiskit.tools.events e o utilitário progressbar() que ele expunha
foram removidos. A funcionalidade deste módulo não era muito utilizada e é
melhor coberta por pacotes dedicados como o
tqdm.
qiskit.transpiler
synthesis
Os itens no módulo qiskit.transpiler.synthesis foram migrados para novos locais:
| Removido | Alternativa |
|---|---|
qiskit.transpiler.synthesis.aqc (exceto 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
O passo do Transpiler NoiseAdaptiveLayout foi substituído por
VF2Layout e
VF2PostLayout,
que definem um layout com base nas características de ruído reportadas de um
backend. Tanto o passo quanto o plugin de estágio de layout "noise_adaptive" correspondente
foram removidos do Qiskit.
O passo do Transpiler CrosstalkAdaptiveSchedule foi removido do
código base. Esse passo não era mais utilizável porque sua operação interna
dependia de propriedades personalizadas definidas no payload BackendProperties de
uma instância BackendV1. Como nenhum backend define esses campos, o passo
foi removido.
passmanager
Os métodos append das classes
ConditionalController,
FlowControllerLinear e
DoWhileController
foram removidos. Em vez disso, todas as tarefas devem ser fornecidas quando os objetos
controller são construídos.
qiskit.utils
As seguintes ferramentas em qiskit.utils foram removidas sem substituição:
qiskit.utils.arithmeticqiskit.utils.circuit_utilsqiskit.utils.entangler_mapqiskit.utils.name_unnamed_args
Essas funções eram usadas exclusivamente nos módulos qiskit.algorithms e
qiskit.opflow, que também foram removidos.
qiskit.visualization
O módulo qiskit.visualization.qcstyle foi removido. Use
qiskit.visualization.circuit.qcstyle como substituto direto.