RelabelModes
class RelabelModes(permutation=None, *, solver=None, **kwargs)
Bases: GenericPass[DAGCircuit, DAGCircuit]
Uma etapa de transpilagem para renomear os modos fermiónicos.
Essa etapa reordena os modos fermiónicos de um circuito. A reordenação é descrita por uma lista permutation , interpretada como um mapeamento do índice do modo original para o novo : o modo original i é colocado no novo índice permutation[i] no circuito renomeado. Por exemplo, permutation = [0, 2, 4, 1, 3, 5] coloca o modo original 1 no novo índice 2, o modo original 2 no novo índice 4e assim por diante. Por se tratar de uma permutação, cada índice deve aparecer exatamente uma vez.
Pós-processamento
A reclassificação reordena os modos fermiónicos, o que, por sua vez, influencia o mapeamento de férmions para qubits escolhido por uma etapa posterior da síntese (e, portanto, a profundidade do circuito que pode ser alcançada). Como a ordem dos modos muda, qualquer sequência de bits amostrada do circuito final é expressa na nova ordem dos modos e deve ser remapeada para a ordem original antes de poder ser interpretada. A reetiquetagem que foi efetivamente aplicada está registrada em um campo permutation dos FermionicDAGCircuitresultados retornados metadata.
Sempre leia a reetiquetagem a partir dos metadados do circuito, e não a partir de permutation. Quando se utiliza a otimização automática (ou seja, permutation (é None), a permutação aplicada só está disponível a partir dos metadados; e mesmo quando permutation foi fornecida explicitamente, garante-se que os metadados reflitam o que a passagem realizou.
Observe que o campo de metadados permutation só está presente quando a passagem realmente reclassificou o circuito. Quando a etapa não produz nenhum efeito — por exemplo, quando a otimização automática não pode ser executada porque solver falta uma pyomo dependência opcional ou um —, o circuito retornado permanece inalterado e não contém metadados permutation ; portanto, acesse-o com cautela (por exemplo, qcirc.metadata.get("permutation")).
Conceitualmente, ao reverter a reclassificação, atribui-se a cada modo original o m valor que foi medido para o novo modo permutation[m]. Na prática, isso se complica pelo fato de que os modos FermionicRegister e os bits clássicos do Qiskit são executados em ordem oposta (little-endian); assim, a agregação no espaço de modos se transforma em uma negação de índice (~idx) seguida por uma inversão final ([::-1]) nas cadeias de bits de contagem.
O exemplo abaixo reclassifica um sistema de seis modos, passando de uma ordenação de spins em blocos ([u0, u1, u2, d0, d1, d2]) para uma intercalada ([u0, d0, u1, d1, u2, d2]), um recurso comum para reduzir a profundidade de implementação, e, em seguida, desfaz a reclassificação nas contagens amostradas:
>>> from qiskit.passmanager import MultiStagePassManager
>>> from qiskit.providers.basic_provider import BasicSimulator
>>> from qiskit_fermions.circuit import FermionicCircuit
>>> from qiskit_fermions.circuit.library import InitializeModes
>>> from qiskit_fermions.transpiler import FermionicCircuitToDAG, QuantumDAGToCircuit
>>> from qiskit_fermions.transpiler.passes import (
... F2QSynthesis, F2QSynthesisPluginManager, RelabelModes, TrivialF2QLayout,
... )
>>>
>>> # blocked occupation: spin-up orbitals 0 and 1 and spin-down orbital 0 are occupied
>>> circ = FermionicCircuit(6)
>>> circ.append(InitializeModes([1, 1, 0, 1, 0, 0]), circ.modes)
>>>
>>> synth_plugins = F2QSynthesisPluginManager()
>>> synth = F2QSynthesis()
>>> synth.methods["InitializeModes"] = synth_plugins.method("InitializeModes", "TrivialOccupation")()
>>>
>>> # map blocked mode order onto the interleaved one
>>> relabel = RelabelModes(permutation=[0, 2, 4, 1, 3, 5])
>>>
>>> pm = MultiStagePassManager(
... init=FermionicCircuitToDAG(),
... optimization=relabel,
... layout=TrivialF2QLayout(),
... synthesis=synth,
... output=QuantumDAGToCircuit(),
... )
>>>
>>> qcirc = pm.run(circ)
>>> qcirc.measure_all()
>>>
>>> bit_permutation = qcirc.metadata.get("permutation")
>>> print(bit_permutation)
[0, 2, 4, 1, 3, 5]
>>>
>>> res = BasicSimulator().run(qcirc, shots=1).result()
>>> counts = res.get_counts()
>>> print(counts) # measured in the interleaved ordering
{'000111': 1}
>>>
>>> # undo the relabeling to recover the counts in the original blocked ordering
>>> post_processed = {
... "".join(bitstring[~idx] for idx in bit_permutation)[::-1]: count
... for bitstring, count in counts.items()
... }
>>> print(post_processed) # recovered in the original blocked ordering
{'001011': 1}
A inicialização desta etapa do transpiler pode ser feita com os argumentos listados a seguir.
Parâmetros
- permutation (list[int] | None) – a permutação de índices utilizada para renumerar os índices dos modos fermiónicos. Quando isso ocorrer
None, uma permutação será determinada automaticamente com base embuild_excitation_span_minimization_model(). Veja tambémpermutationpara obter mais detalhes. - solver (pyomo.opt.SolverFactory | None) – a instância do solucionador de problemas de otimização utilizada para resolver o problema
build_excitation_span_minimization_model(). Quando isso ocorreNone, nãopermutationé possível determinar automaticamente nenhum valor. Veja tambémsolverpara mais detalhes. - kwargs – quaisquer argumentos-chave adicionais serão repassados para
build_excitation_span_minimization_model().
Atributos
permutation
A permutação de índices utilizada para renumerar os índices dos modos fermiónicos.
Isso pode ser um list[int], que mapeia o índice do modo original i para o índice do novo modo permutation[i] (consulte a documentação da classe para obter mais detalhes). Seu comprimento deve corresponder ao número de modos fermiónicos do circuito que está sendo transpilado, e cada índice deve aparecer exatamente uma vez. Esse cenário exige, portanto, que a etapa do transpiler seja adaptada de forma bastante específica ao circuito do usuário.
Ou pode ser que None, nesse caso, a função build_excitation_span_minimization_model() seja usada para definir um problema de otimização que busca minimizar a amplitude de todas as excitações fermiónicas que ocorrem. Nesse caso, a permutação aplicada só está disponível nos metadados do circuito transpilado (consulte a descrição da classe).
O uso desse modelo de otimização é implementado apenas para portas de evolução temporal que contenham uma instância FermionOperator .
solver
A instância do solucionador de problemas de otimização para encontrar automaticamente permutation.
Quando permutation é None, o problema de otimização definido por build_excitation_span_minimization_model() é utilizado para encontrar automaticamente uma boa permutação dos índices de modo. Nesse caso, o usuário deve fornecer um otimizador para resolver esse modelo.
Métodos
find_permutation
find_permutation(dag)
Encontra um índice de modo quando permutation este não for especificado pelo usuário.
Essa função só é chamada quando não permutation for especificado pelo usuário (ou seja, quando for None). Nesse caso, ele faz o seguinte:
- Certifique-se de que a dependência opcional do pyomo esteja instalada. Caso contrário, nenhuma otimização poderá ser realizada e essa etapa do transpilador não terá efeito.
- certifique-se de que a
solveresteja especificada. Caso contrário, nenhuma otimização poderá ser realizada e essa etapa do transpilador não terá efeito. - reunir todas as excitações fermiónicas de quaisquer portas
Evolutionque contenham uma instânciaFermionOperator. - construir o problema de otimização usando
build_excitation_span_minimization_model(), encaminhando quaisquer argumentos de palavra-chave adicionais (kwargs) de quando essa passagem do transpiler foi construída. - resolva o problema de otimização usando
solvere extraia a permutação final.
Parâmetros
dag (FermionicDAGCircuit) – o circuito a ser transpilado.
Retorna
A permutação a ser utilizada. Nesse caso None, essa etapa do transpiler não terá efeito.
Aumentos
NotImplementedError – ao encontrar um gate Evolution que contenha um operador que não seja uma instância FermionOperator .
Tipo de retorno
tupla [ lista [ int ] | None, pyomo.opt.results.results_.SolverResults | None]
run
run(dag)
Executa essa etapa de transpilagem.
Parâmetros
dag (DAGCircuit) – o circuito de entrada com instruções baseadas em férmions. Somente DAGOpNode FermionicGate instâncias como essas são op suportadas.
Retorna
O circuito de saída que ainda está atuando sobre um registro fermiónico.
Aumentos
NotImplementedError – quando o circuito de entrada fornecido possui mais de um registro.
Tipo de retorno
Métodos herdados
execute
execute(passmanager_ir, state, callback=None)
Executar tarefa de otimização para o IR do Qiskit de entrada.
Parâmetros
- passmanager_ir (IR) – Qiskit IR para otimização.
- state (PassManagerState) – Estado associado à execução do fluxo de trabalho pelo próprio gerenciador de passagens.
- callback (Callable[[Task, IR_OUT, PropertySet, float, int], None] | None) – Uma função de retorno de chamada que é chamada a cada execução da tarefa de otimização.
Retorna
IR do Qiskit otimizado e situação atual do fluxo de trabalho.
Tipo de retorno
tupla [ IR_OUT, PassManagerState ]
name
update_status
update_status(state, run_state)
Atualizar o status do fluxo de trabalho.
Parâmetros
- state (PassManagerState) – Passe o estado do gerenciador para atualização.
- run_state (RunState) – Status de conclusão da tarefa atual.
Retorna
Atualizou o estado do gerenciador de passes.
Tipo de retorno