Nota
Esta página foi gerada, a partir de tutorials/circuits_advanced/04_transpiler_passes_and_passmanager.ipynb.
Transpilador de passes e gerenciador de passes¶
Introdução¶
Um componente central do Qiskit Terra é o transpilador, que é projetado para modularidade e extensibilidade. O objetivo é ser capaz de escrever, facilmente, novas transformações de circuito (conhecidas como transpiler passes) e combiná-las com outros passes existentes. Quais passes são encadeados em conjunto e, em que ordem, tem um grande efeito sobre o resultado final. Este pipeline é determinado por um gerenciador de passe, que planeja os passes e, também, permite que os passes se comuniquem, entre si, fornecendo um espaço compartilhado. Desta forma, o transpilador abre a porta para pesquisa, em otimização agressiva de circuitos quânticos.
Neste notebook, olhamos para os passes embutidos, como usar o gerenciador de passes e desenvolver um simples transpilador de passe personalizado. Para fazer o último, precisamos, primeiramente, introduzir a representação interna dos circuitos quânticos em Qiskit, na forma de um Gráfico Acíclico Direcionado, ou DAG. Em seguida, ilustramos um simples mapeador de passe de troca, que transforma um circuito de entrada, para ser compatível com um dispositivo quântico de conectividade limitada.
Antes de começar: Talvez você precise instalar a biblioteca pydot
e a biblioteca graphviz
para as rotinas de plot de DAG. Se você estiver usando Anaconda Python, você pode instalar ambos com o comando conda
. Se você usa o interpretador nativo de Python do seu sistema, instale o pydot
usando o comando pip
e instale o graphviz
usando o gerenciador de pacotes nativo do seu sistema (por exemplo, yum
, apt
, dnf
, brew
, etc.).
[1]:
from qiskit import QuantumCircuit
from qiskit.compiler import transpile
from qiskit.transpiler import PassManager
Objeto gerenciador de passes¶
Permite que você especifique o conjunto de passes desejados.
[2]:
circ = QuantumCircuit(3)
circ.ccx(0, 1, 2)
circ.draw(output='mpl')
[2]:

[3]:
from qiskit.transpiler.passes import Unroller
pass_ = Unroller(['u1', 'u2', 'u3', 'cx'])
pm = PassManager(pass_)
new_circ = pm.run(circ)
new_circ.draw(output='mpl')
[3]:

Todos os passes de transpilador do Qiskit são acessíveis, a partir de qiskit.transpiler.passes
.
[4]:
from qiskit.transpiler import passes
[pass_ for pass_ in dir(passes) if pass_[0].isupper()]
[4]:
['ApplyLayout',
'BarrierBeforeFinalMeasurements',
'BasicSwap',
'BasisTranslator',
'CSPLayout',
'CXCancellation',
'CXDirection',
'CheckCXDirection',
'CheckMap',
'Collect2qBlocks',
'CommutationAnalysis',
'CommutativeCancellation',
'ConsolidateBlocks',
'CountOps',
'CountOpsLongestPath',
'CrosstalkAdaptiveSchedule',
'DAGFixedPoint',
'DAGLongestPath',
'Decompose',
'DenseLayout',
'Depth',
'EnlargeWithAncilla',
'FixedPoint',
'FullAncillaAllocation',
'HoareOptimizer',
'Layout2qDistance',
'LayoutTransformation',
'LookaheadSwap',
'MergeAdjacentBarriers',
'NoiseAdaptiveLayout',
'NumTensorFactors',
'Optimize1qGates',
'OptimizeSwapBeforeMeasure',
'RemoveDiagonalGatesBeforeMeasure',
'RemoveFinalMeasurements',
'RemoveResetInZeroState',
'ResourceEstimation',
'SabreLayout',
'SabreSwap',
'SetLayout',
'Size',
'StochasticSwap',
'TrivialLayout',
'UnitarySynthesis',
'Unroll3qOrMore',
'UnrollCustomDefinitions',
'Unroller',
'Width']
Diferentes variações do mesmo passe¶
Pode haver passes que façam o mesmo trabalho, mas de maneiras diferentes. Por exemplo, o TrivialLayout
, DenseLayout
e NoiseAdaptiveLayout
todos escolhem um layout (ligação de qubits virtuais para qubits físicos), mas usam algoritmos e objetivos diferentes. Da mesma forma, o BasicSwap
, LookaheadSwap
e StochasticSwap
todos fazem a inserção de swaps para tornar o circuito compatível com o mapa de acoplamento. A modularidade do transpilador permite reposicionamentos de plug-and-play para cada passe.
Abaixo, mostramos todos os passes de troca aplicados para o mesmo circuito para transformá-lo, para combinar com uma topologia de cadeia linear. Você pode ver diferenças de desempenho, em que o StochasticSwap
é, claramente, o melhor. No entanto, isto pode variar, dependendo do circuito de entrada.
[5]:
from qiskit.transpiler import CouplingMap, Layout
from qiskit.transpiler.passes import BasicSwap, LookaheadSwap, StochasticSwap
coupling = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6]]
circuit = QuantumCircuit(7)
circuit.h(3)
circuit.cx(0, 6)
circuit.cx(6, 0)
circuit.cx(0, 1)
circuit.cx(3, 1)
circuit.cx(3, 0)
coupling_map = CouplingMap(couplinglist=coupling)
bs = BasicSwap(coupling_map=coupling_map)
pass_manager = PassManager(bs)
basic_circ = pass_manager.run(circuit)
ls = LookaheadSwap(coupling_map=coupling_map)
pass_manager = PassManager(ls)
lookahead_circ = pass_manager.run(circuit)
ss = StochasticSwap(coupling_map=coupling_map)
pass_manager = PassManager(ss)
stochastic_circ = pass_manager.run(circuit)
[6]:
circuit.draw(output='mpl')
[6]:

[7]:
basic_circ.draw(output='mpl')
[7]:

[8]:
lookahead_circ.draw(output='mpl')
[8]:

[9]:
stochastic_circ.draw(output='mpl')
[9]:

Gerenciador de passes predefinidos¶
O Qiskit vem com vários gerenciadores de passe pré-definidos, correspondentes a vários níveis de otimização alcançados, através de diferentes condutas de passes. Atualmente, otimization_level
0 até 3 são suportados; quanto maior o número, mais otimizado ele é, à custa de mais tempo. Escolher um bom gestor de passe, pode ser uma tarefa de tentativa e erro, já que depende muito do circuito, que está sendo transpilado e do backend de destino.
Aqui, ilustramos os diferentes níveis, olhando para um circuito de síntese de estado. Inicializamos quatro qubits em um estado arbitrário e, em seguida, tentamos otimizar o circuito, que realiza isto.
optimization_level=0
: somente mapeia o circuito para o processo interno, sem nenhuma otimização explícita (exceto, quaisquer otimizações feitas pelo mapeador).optimization_level=1
: mapeia o circuito, mas também realiza otimizações leves, colapsando portas adjacentes.optimization_level=2
: otimizações médias, incluindo um layout adaptável ao ruído e um procedimento de cancelamento de portas, a partir de relações de comutação das portas.optimization_level=3
: otimização pesada, que, além das etapas anteriores, faz a resíntese de blocos de portas de dois qubits no circuito.
[10]:
import math
from qiskit.test.mock import FakeTokyo
backend = FakeTokyo() # mimics the tokyo device in terms of coupling map and basis gates
[11]:
qc = QuantumCircuit(10)
random_state = [
1 / math.sqrt(4) * complex(0, 1),
1 / math.sqrt(8) * complex(1, 0),
0,
0,
0,
0,
0,
0,
1 / math.sqrt(8) * complex(1, 0),
1 / math.sqrt(8) * complex(0, 1),
0,
0,
0,
0,
1 / math.sqrt(4) * complex(1, 0),
1 / math.sqrt(8) * complex(1, 0)]
qc.initialize(random_state, range(4))
qc.draw()
[11]:
» q_0: » » q_1: » » q_2: » » q_3: » » q_4: » » q_5: » » q_6: » » q_7: » » q_8: » » q_9: » » « ┌────────────────────────────────────────────────────────────────────────────┐ «q_0: ┤0 ├ « │ │ «q_1: ┤1 ├ « │ initialize(0.5j,0.35355,0,0,0,0,0,0,0.35355,0.35355j,0,0,0,0,0.5,0.35355) │ «q_2: ┤2 ├ « │ │ «q_3: ┤3 ├ « └────────────────────────────────────────────────────────────────────────────┘ «q_4: ────────────────────────────────────────────────────────────────────────────── « «q_5: ────────────────────────────────────────────────────────────────────────────── « «q_6: ────────────────────────────────────────────────────────────────────────────── « «q_7: ────────────────────────────────────────────────────────────────────────────── « «q_8: ────────────────────────────────────────────────────────────────────────────── « «q_9: ────────────────────────────────────────────────────────────────────────────── «
Agora, mapeie isto para o servidor de 20-qubit chamado Tokyo, com um nível de otimização diferente:
[12]:
optimized_0 = transpile(qc, backend=backend, seed_transpiler=11, optimization_level=0)
print('gates = ', optimized_0.count_ops())
print('depth = ', optimized_0.depth())
gates = OrderedDict([('cx', 55), ('u3', 15), ('u1', 15), ('reset', 4)])
depth = 69
[13]:
optimized_1 = transpile(qc, backend=backend, seed_transpiler=11, optimization_level=1)
print('gates = ', optimized_1.count_ops())
print('depth = ', optimized_1.depth())
gates = OrderedDict([('cx', 55), ('u3', 15), ('u1', 6)])
depth = 59
[14]:
optimized_2 = transpile(qc, backend=backend, seed_transpiler=11, optimization_level=2)
print('gates = ', optimized_2.count_ops())
print('depth = ', optimized_2.depth())
gates = OrderedDict([('cx', 45), ('u3', 15), ('u1', 6)])
depth = 55
[15]:
optimized_3 = transpile(qc, backend=backend, seed_transpiler=11, optimization_level=3)
print('gates = ', optimized_3.count_ops())
print('depth = ', optimized_3.depth())
gates = OrderedDict([('cx', 20), ('u3', 15), ('u1', 6)])
depth = 38
Apresentando o DAG¶
No Qiskit, representamos circuitos, internamente, usando um Gráfico Acíclico Direcionado (DAG). A vantagem desta representação sobre uma lista pura de portões (ou seja, netlist) é que, o fluxo de informações, entre as operações, são explícitas, tornando mais fácil para os passes tomarem decisões de transformação, sem alterar a semântica do circuito.
Vamos começar pela construção de um circuito simples e examinando seu DAG.
[16]:
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
from qiskit.dagcircuit import DAGCircuit
q = QuantumRegister(3, 'q')
c = ClassicalRegister(3, 'c')
circ = QuantumCircuit(q, c)
circ.h(q[0])
circ.cx(q[0], q[1])
circ.measure(q[0], c[0])
circ.rz(0.5, q[1]).c_if(c, 2)
circ.draw(output='mpl')
[16]:

No DAG, existem três tipos de vértices do gráfico: vértices de entrada do qubit/clbit (verde), vértices de operação (azul) e vértices de saída (vermelho). Cada aresta indica fluxo de dados (ou dependência) entre dois vértices.
[17]:
from qiskit.converters import circuit_to_dag
from qiskit.tools.visualization import dag_drawer
dag = circuit_to_dag(circ)
dag_drawer(dag)
[17]:

Por isto, escrever um passe de transpilador, significa utilizar a API DAGCircuit do Qiskit, para analisar ou transformar o circuito. Vamos ver alguns exemplos disto.
a. Obter todos os nós de operações no DAG:
[18]:
dag.op_nodes()
[18]:
[<qiskit.dagcircuit.dagnode.DAGOpNode at 0x7f1eebb870b0>,
<qiskit.dagcircuit.dagnode.DAGOpNode at 0x7f1eebb87820>,
<qiskit.dagcircuit.dagnode.DAGOpNode at 0x7f1eebb87eb0>,
<qiskit.dagcircuit.dagnode.DAGOpNode at 0x7f1eebb876d0>]
Each node is an instance of the DAGOpNode
class. Let’s examine the information stored in the second op node.
[19]:
node = dag.op_nodes()[3]
print("node name: ", node.name)
print("node op: ", node.op)
print("node qargs: ", node.qargs)
print("node cargs: ", node.cargs)
print("node condition: ", node.op.condition)
node name: rz
node op: <qiskit.circuit.library.standard_gates.rz.RZGate object at 0x7f1eec144e20>
node qargs: [Qubit(QuantumRegister(3, 'q'), 1)]
node cargs: []
node condition: (ClassicalRegister(3, 'c'), 2)
b. Adicione um operador para a parte de trás:
[20]:
from qiskit.circuit.library import HGate
dag.apply_operation_back(HGate(), qargs=[q[0]])
dag_drawer(dag)
[20]:

c. Adicione um operador para a parte da frente:
[21]:
from qiskit.circuit.library import CCXGate
dag.apply_operation_front(CCXGate(), qargs=[q[0], q[1], q[2]], cargs=[])
dag_drawer(dag)
[21]:

d. Substituir um nó com um subcircuito:
[22]:
from qiskit.circuit.library import CHGate, U2Gate, CXGate
mini_dag = DAGCircuit()
p = QuantumRegister(2, "p")
mini_dag.add_qreg(p)
mini_dag.apply_operation_back(CHGate(), qargs=[p[1], p[0]])
mini_dag.apply_operation_back(U2Gate(0.1, 0.2), qargs=[p[1]])
# substitute the cx node with the above mini-dag
cx_node = dag.op_nodes(op=CXGate).pop()
dag.substitute_node_with_dag(node=cx_node, input_dag=mini_dag, wires=[p[0], p[1]])
dag_drawer(dag)
[22]:

Por fim, após todas as transformações serem completadas, podemos converter, de volta, para um objeto QuantumCircuit regular. Isto é o que o transpilador faz! Ele recebe um circuito, opera nele na forma DAG e fornece, como resultado, um circuito transformado.
[23]:
from qiskit.converters import dag_to_circuit
circuit = dag_to_circuit(dag)
circuit.draw(output='mpl')
[23]:

Implementando um passe BasicMapper¶
Agora que estamos familiarizados com o DAG, vamos usá-lo para escrever um passe de transpilador. Aqui, implementamos um passe básico, para mapeamento de um circuito arbitrário para um dispositivo com conectividade de qubit limitado. Chamamos isto de BasicMapper. Este passe está incluído no Qiskit Terra também.
A primeira coisa a fazer, ao escrever um passe de transpilador, é decidir se a classe pass deriva de um TransformationPass
ou AnalysisPass
. Passes de transformação modificam o circuito, enquanto passes de análise, apenas coletam informações sobre um circuito (para ser usado por outros passes). Em seguida, o método run (dag)
é implementado, fazendo a tarefa principal. Por fim, o passe é registrado, dentro do módulo qiskit.transpiler.passes
.
Este passe funciona da seguinte forma: ele atravessa a DAG camada-por-camada (cada camada é um grupo de operações, que não atua em qubits independentes, portanto, em teoria, todas as operações em uma camada podem ser feitas de forma independente). Para cada operação, se ela já não atende às restrições de mapa de acoplamento, o passe identifica um caminho de troca e insere swaps para trazer os dois qubits próximos uns dos outros.
Siga os comentários no código para mais detalhes.
[24]:
from copy import copy
from qiskit.transpiler.basepasses import TransformationPass
from qiskit.transpiler import Layout
from qiskit.circuit.library import SwapGate
class BasicSwap(TransformationPass):
"""Maps (with minimum effort) a DAGCircuit onto a `coupling_map` adding swap gates."""
def __init__(self,
coupling_map,
initial_layout=None):
"""Maps a DAGCircuit onto a `coupling_map` using swap gates.
Args:
coupling_map (CouplingMap): Directed graph represented a coupling map.
initial_layout (Layout): initial layout of qubits in mapping
"""
super().__init__()
self.coupling_map = coupling_map
self.initial_layout = initial_layout
def run(self, dag):
"""Runs the BasicSwap pass on `dag`.
Args:
dag (DAGCircuit): DAG to map.
Returns:
DAGCircuit: A mapped DAG.
Raises:
TranspilerError: if the coupling map or the layout are not
compatible with the DAG.
"""
new_dag = DAGCircuit()
for qreg in dag.qregs.values():
new_dag.add_qreg(qreg)
for creg in dag.cregs.values():
new_dag.add_creg(creg)
if self.initial_layout is None:
if self.property_set["layout"]:
self.initial_layout = self.property_set["layout"]
else:
self.initial_layout = Layout.generate_trivial_layout(*dag.qregs.values())
if len(dag.qubits) != len(self.initial_layout):
raise TranspilerError('The layout does not match the amount of qubits in the DAG')
if len(self.coupling_map.physical_qubits) != len(self.initial_layout):
raise TranspilerError(
"Mappers require to have the layout to be the same size as the coupling map")
canonical_register = dag.qregs['q']
trivial_layout = Layout.generate_trivial_layout(canonical_register)
current_layout = trivial_layout.copy()
for layer in dag.serial_layers():
subdag = layer['graph']
for gate in subdag.two_qubit_ops():
physical_q0 = current_layout[gate.qargs[0]]
physical_q1 = current_layout[gate.qargs[1]]
if self.coupling_map.distance(physical_q0, physical_q1) != 1:
# Insert a new layer with the SWAP(s).
swap_layer = DAGCircuit()
swap_layer.add_qreg(canonical_register)
path = self.coupling_map.shortest_undirected_path(physical_q0, physical_q1)
for swap in range(len(path) - 2):
connected_wire_1 = path[swap]
connected_wire_2 = path[swap + 1]
qubit_1 = current_layout[connected_wire_1]
qubit_2 = current_layout[connected_wire_2]
# create the swap operation
swap_layer.apply_operation_back(SwapGate(),
qargs=[qubit_1, qubit_2],
cargs=[])
# layer insertion
order = current_layout.reorder_bits(new_dag.qubits)
new_dag.compose(swap_layer, qubits=order)
# update current_layout
for swap in range(len(path) - 2):
current_layout.swap(path[swap], path[swap + 1])
order = current_layout.reorder_bits(new_dag.qubits)
new_dag.compose(subdag, qubits=order)
return new_dag
Vamos testar este passe em um pequeno circuito de exemplo.
[25]:
q = QuantumRegister(7, 'q')
in_circ = QuantumCircuit(q)
in_circ.h(q[0])
in_circ.cx(q[0], q[4])
in_circ.cx(q[2], q[3])
in_circ.cx(q[6], q[1])
in_circ.cx(q[5], q[0])
in_circ.rz(0.1, q[2])
in_circ.cx(q[5], q[0])
[25]:
<qiskit.circuit.instructionset.InstructionSet at 0x7f1f5e2747c0>
Agora, construímos um gerenciador de passes, que contém nosso novo passe. Passamos o circuito de exemplo, acima, para este gerenciador de passes e obtemos um novo circuito transformado.
[26]:
from qiskit.transpiler import PassManager
from qiskit.transpiler import CouplingMap
from qiskit import BasicAer
pm = PassManager()
coupling = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6]]
coupling_map = CouplingMap(couplinglist=coupling)
pm.append([BasicSwap(coupling_map)])
out_circ = pm.run(in_circ)
<ipython-input-24-6348c3c81f5c>:50: DeprecationWarning: dag.qubits() and dag.clbits() are no longer methods. Use dag.qubits and dag.clbits properties instead.
if len(dag.qubits()) != len(self.initial_layout):
[27]:
in_circ.draw(output='mpl')
[27]:

[28]:
out_circ.draw(output='mpl')
[28]:

Note que este passe, só insere as trocas necessárias para fazer com que cada interação de dois qubit esteja em conformidade com o mapa de acoplamento do dispositivo. Ele não se preocupa, por exemplo, com a direção de interações, ou com o conjunto de portões nativos suportado pelo dispositivo. Trata-se de uma filosofia de design do transpilador do Qiskit: cada passe executa uma ação pequena, bem definida, e a otimização agressiva do circuito é obtida pelo gerenciador de passes através da combinação de múltiplos passes.
Registro do Transpilador¶
Devido à complexidade das operações internas, que o transpilador está realizando, é provável que você acabe em uma situação em que gostaria de depurar um problema ou, apenas, entender mais do que está acontecendo dentro do transpilador, quando você o chama. Para facilitar isto, o transpilador emite mensagens de log como parte de sua operação normal. Este registro usa o módulo logging
da biblioteca padrão do Python para emitir as mensagens de log. O registro padrão do Python foi usado, porque permite que o registro do Qiskit-Terra se integre, de uma maneira padrão com outros aplicativos e bibliotecas.
Para uma introdução mais completa, aos logs do Python, consulte a documentação oficial e os tutoriais e cookbooks, mencionados lá.
Nota: a maioria das funções do módulo de registro utilizado nesta seção ajusta as configurações globais. Se você executar comandos nesta seção ele pode efetivar a saída de outras células se elas forem executadas em uma ordem diferente.
Configurando o Registro de Biblioteca Padrão Python¶
Por padrão, os registros de log do Python imprimem apenas mensagens de log nos níveis WARNING
, ERROR
ou CRITICAL
. Uma vez que nenhum dos logs emitidos pelo transpilador usam estes níveis de log (todos eles são informativos), você precisa configurar o logging.
A maneira mais simples de fazer isto é apenas executar:
[29]:
import logging
logging.basicConfig(level='DEBUG')
A função basicConfig()
(veja os docs aqui: https://docs.python.org/3/library/logging.html#logging.basicConfig) configura um manipulador de raiz e formatador. Também especificamos o nível de log <https://docs.python.org/3/library/logging.html#levels> __ para exibir com o level
kwarg. Fixá-lo em um nível, também, incluirá níveis mais altos. Por exemplo, se configurar para 'INFO'
, além do nível INFO
, este incluirá, também, os níveis de log WARNING
, ERROR
, e CRITICAL
.
Agora, o ambiente python neste notebook está configurado para emitir mensagens de log para stderr, quando você executar o transpilador. Por exemplo:
Nota: basicConfig() só funcionará quando chamado a primeira vez que for chamado. Ele detecta se um manipulador de root e formatador já foram configurados (seja usando uma chamada basicConfig() anterior ou de outra forma) e não faz nada se eles tiverem feito. Mais ajustes terão que interagir com o manipulador diretamente.
[30]:
from qiskit.test.mock import FakeTenerife
log_circ = QuantumCircuit(2, 2)
log_circ.h(0)
log_circ.h(1)
log_circ.h(1)
log_circ.x(1)
log_circ.cx(0, 1)
log_circ.measure([0,1], [0,1])
backend = FakeTenerife()
transpile(log_circ, backend);
INFO:qiskit.transpiler.runningpassmanager:Pass: SetLayout - 0.00477 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: TrivialLayout - 0.04864 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Layout2qDistance - 0.45657 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: FullAncillaAllocation - 0.08535 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: EnlargeWithAncilla - 0.08416 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: ApplyLayout - 0.64754 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Unroll3qOrMore - 0.05555 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CheckMap - 0.05698 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: UnrollCustomDefinitions - 0.08774 (ms)
INFO:qiskit.transpiler.passes.basis.basis_translator:Begin BasisTranslator from source basis {('measure', 1), ('x', 1), ('h', 1), ('cx', 2)} to target basis {'cx', 'barrier', 'id', 'reset', 'u3', 'u1', 'measure', 'u2', 'snapshot'}.
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Begining basis search from frozenset({('measure', 1), ('x', 1), ('h', 1), ('cx', 2)}) to frozenset({'reset', 'cx', 'u3', 'barrier', 'u1', 'measure', 'id', 'u2', 'snapshot'}).
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Inspecting basis frozenset({('measure', 1), ('x', 1), ('h', 1), ('cx', 2)}).
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Inspecting basis frozenset({('measure', 1), ('h', 1), ('cx', 2), ('u3', 1)}).
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Transformation path:
DEBUG:qiskit.transpiler.passes.basis.basis_translator:x/1 => []
┌─────────────┐
q_0: ┤ U3(pi,0,pi) ├
└─────────────┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:h/1 => []
┌──────────┐
q_0: ┤ U2(0,pi) ├
└──────────┘
INFO:qiskit.transpiler.passes.basis.basis_translator:Basis translation path search completed in 0.010s.
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Composing transform step: x/1 [] =>
┌─────────────┐
q_0: ┤ U3(pi,0,pi) ├
└─────────────┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Updating transform for mapped instr ('x', 1) x, [] from
┌───┐
q293_0: ┤ x ├
└───┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Updated transform for mapped instr ('x', 1) x, [] to
┌─────────────┐
q293_0: ┤ U3(pi,0,pi) ├
└─────────────┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Composing transform step: h/1 [] =>
┌──────────┐
q_0: ┤ U2(0,pi) ├
└──────────┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Updating transform for mapped instr ('h', 1) h, [] from
┌───┐
q294_0: ┤ h ├
└───┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Updated transform for mapped instr ('h', 1) h, [] to
┌──────────┐
q294_0: ┤ U2(0,pi) ├
└──────────┘
INFO:qiskit.transpiler.passes.basis.basis_translator:Basis translation paths composed in 0.020s.
INFO:qiskit.transpiler.passes.basis.basis_translator:Basis translation instructions replaced in 0.000s.
INFO:qiskit.transpiler.runningpassmanager:Pass: BasisTranslator - 36.93509 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CheckCXDirection - 0.09489 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CXDirection - 0.78416 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: RemoveResetInZeroState - 0.03719 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Depth - 0.05436 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: FixedPoint - 0.03481 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Optimize1qGates - 1.50800 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CXCancellation - 0.08798 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Depth - 0.03672 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: FixedPoint - 0.01812 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Optimize1qGates - 0.23603 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CXCancellation - 0.06080 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Depth - 0.02980 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: FixedPoint - 0.01717 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Optimize1qGates - 0.23818 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CXCancellation - 0.07939 (ms)
INFO:qiskit.compiler.transpile:Total Transpile Time - 75.43111 (ms)
Como você pode ver claramente aqui, ao chamar transpile()
, ele agora imprime 2 tipos de mensagens de log. O primeiro está no nível de log INFO
e vem do gerenciador de passes. Eles indicam cada passe que foi executado e quanto tempo isto levou. A segunda está no nível DEBUG
e vem do passe StochasticSwap descrevendo o funcionamento interno deste passe. É útil para depurar problemas na operação do passe.
Ajustando o nível do log para o transpiler¶
O transpilador qiskit usa um único namespace qiskit.transpiler
, como usado por logging.getLogger('qiskit.transpiler')
. Isso faz com que seja muito fácil ajustar o nível de log apenas para o transpiler. Por exemplo, se você deseja ver mensagens de log no nível INFO ou mais detalhadas você pode executar:
[31]:
logging.getLogger('qiskit.transpiler').setLevel('INFO')
transpile(log_circ, backend);
INFO:qiskit.transpiler.runningpassmanager:Pass: SetLayout - 0.00572 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: TrivialLayout - 0.04363 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Layout2qDistance - 0.42200 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: FullAncillaAllocation - 0.06890 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: EnlargeWithAncilla - 0.08631 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: ApplyLayout - 0.56601 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Unroll3qOrMore - 0.02265 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CheckMap - 0.04959 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: UnrollCustomDefinitions - 0.04530 (ms)
INFO:qiskit.transpiler.passes.basis.basis_translator:Begin BasisTranslator from source basis {('measure', 1), ('x', 1), ('h', 1), ('cx', 2)} to target basis {'cx', 'barrier', 'id', 'reset', 'u3', 'u1', 'measure', 'u2', 'snapshot'}.
INFO:qiskit.transpiler.passes.basis.basis_translator:Basis translation path search completed in 0.001s.
INFO:qiskit.transpiler.passes.basis.basis_translator:Basis translation paths composed in 0.001s.
INFO:qiskit.transpiler.passes.basis.basis_translator:Basis translation instructions replaced in 0.000s.
INFO:qiskit.transpiler.runningpassmanager:Pass: BasisTranslator - 4.98986 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CheckCXDirection - 0.07892 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CXDirection - 0.71764 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: RemoveResetInZeroState - 0.02217 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Depth - 0.04625 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: FixedPoint - 0.01764 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Optimize1qGates - 2.09403 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CXCancellation - 0.07653 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Depth - 0.02766 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: FixedPoint - 0.01836 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Optimize1qGates - 0.25296 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CXCancellation - 0.06986 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Depth - 0.02646 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: FixedPoint - 0.01407 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Optimize1qGates - 0.23460 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CXCancellation - 0.05984 (ms)
INFO:qiskit.compiler.transpile:Total Transpile Time - 38.27548 (ms)
Configurando o log para trabalhar com execução paralela¶
Ao executar o transpilador com vários circuitos, por padrão, estes circuitos são transpilados em paralelo. Se você deseja fazer isto com o registro de log ativado e ser capaz de entender a saída, algumas etapas adicionais são necessárias.
Se você quiser apenas ativar o registro como acima e depois chamar transpile()
para múltiplos circuitos, você obterá resultados que são difíceis de decifrar. Por exemplo:
[32]:
# Change log level back to DEBUG
logging.getLogger('qiskit.transpiler').setLevel('DEBUG')
# Transpile multiple circuits
circuits = [log_circ, log_circ]
transpile(circuits, backend);
INFO:qiskit.transpiler.runningpassmanager:Pass: SetLayout - 0.01788 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: TrivialLayout - 0.14687 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: SetLayout - 0.01669 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Layout2qDistance - 0.79012 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: TrivialLayout - 0.17047 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Layout2qDistance - 0.97585 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: FullAncillaAllocation - 0.22602 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: EnlargeWithAncilla - 0.09418 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: FullAncillaAllocation - 0.25630 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: EnlargeWithAncilla - 0.10729 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: ApplyLayout - 0.69308 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: ApplyLayout - 0.62561 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Unroll3qOrMore - 0.02956 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Unroll3qOrMore - 0.02003 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CheckMap - 0.05436 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CheckMap - 0.04601 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: UnrollCustomDefinitions - 0.19526 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: UnrollCustomDefinitions - 0.13828 (ms)
INFO:qiskit.transpiler.passes.basis.basis_translator:Begin BasisTranslator from source basis {('measure', 1), ('x', 1), ('h', 1), ('cx', 2)} to target basis {'cx', 'barrier', 'id', 'reset', 'u3', 'u1', 'measure', 'u2', 'snapshot'}.
INFO:qiskit.transpiler.passes.basis.basis_translator:Begin BasisTranslator from source basis {('measure', 1), ('x', 1), ('h', 1), ('cx', 2)} to target basis {'cx', 'barrier', 'id', 'reset', 'u3', 'u1', 'measure', 'u2', 'snapshot'}.
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Begining basis search from frozenset({('measure', 1), ('x', 1), ('h', 1), ('cx', 2)}) to frozenset({'reset', 'cx', 'u3', 'barrier', 'u1', 'measure', 'id', 'u2', 'snapshot'}).
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Inspecting basis frozenset({('measure', 1), ('x', 1), ('h', 1), ('cx', 2)}).
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Begining basis search from frozenset({('measure', 1), ('x', 1), ('h', 1), ('cx', 2)}) to frozenset({'reset', 'cx', 'u3', 'barrier', 'u1', 'measure', 'id', 'u2', 'snapshot'}).
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Inspecting basis frozenset({('measure', 1), ('h', 1), ('cx', 2), ('u3', 1)}).
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Inspecting basis frozenset({('measure', 1), ('x', 1), ('h', 1), ('cx', 2)}).
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Transformation path:
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Inspecting basis frozenset({('measure', 1), ('h', 1), ('cx', 2), ('u3', 1)}).
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Transformation path:
DEBUG:qiskit.transpiler.passes.basis.basis_translator:x/1 => []
┌─────────────┐
q_0: ┤ U3(pi,0,pi) ├
└─────────────┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:x/1 => []
┌─────────────┐
q_0: ┤ U3(pi,0,pi) ├
└─────────────┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:h/1 => []
┌──────────┐
q_0: ┤ U2(0,pi) ├
└──────────┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:h/1 => []
┌──────────┐
q_0: ┤ U2(0,pi) ├
└──────────┘
INFO:qiskit.transpiler.passes.basis.basis_translator:Basis translation path search completed in 0.015s.
INFO:qiskit.transpiler.passes.basis.basis_translator:Basis translation path search completed in 0.019s.
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Composing transform step: x/1 [] =>
┌─────────────┐
q_0: ┤ U3(pi,0,pi) ├
└─────────────┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Composing transform step: x/1 [] =>
┌─────────────┐
q_0: ┤ U3(pi,0,pi) ├
└─────────────┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Updating transform for mapped instr ('x', 1) x, [] from
┌───┐
q303_0: ┤ x ├
└───┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Updated transform for mapped instr ('x', 1) x, [] to
┌─────────────┐
q303_0: ┤ U3(pi,0,pi) ├
└─────────────┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Composing transform step: h/1 [] =>
┌──────────┐
q_0: ┤ U2(0,pi) ├
└──────────┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Updating transform for mapped instr ('x', 1) x, [] from
┌───┐
q303_0: ┤ x ├
└───┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Updating transform for mapped instr ('h', 1) h, [] from
┌───┐
q304_0: ┤ h ├
└───┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Updated transform for mapped instr ('x', 1) x, [] to
┌─────────────┐
q303_0: ┤ U3(pi,0,pi) ├
└─────────────┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Updated transform for mapped instr ('h', 1) h, [] to
┌──────────┐
q304_0: ┤ U2(0,pi) ├
└──────────┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Composing transform step: h/1 [] =>
┌──────────┐
q_0: ┤ U2(0,pi) ├
└──────────┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Updating transform for mapped instr ('h', 1) h, [] from
┌───┐
q304_0: ┤ h ├
└───┘
DEBUG:qiskit.transpiler.passes.basis.basis_translator:Updated transform for mapped instr ('h', 1) h, [] to
┌──────────┐
q304_0: ┤ U2(0,pi) ├
└──────────┘
INFO:qiskit.transpiler.passes.basis.basis_translator:Basis translation paths composed in 0.025s.
INFO:qiskit.transpiler.passes.basis.basis_translator:Basis translation instructions replaced in 0.000s.
INFO:qiskit.transpiler.passes.basis.basis_translator:Basis translation paths composed in 0.026s.
INFO:qiskit.transpiler.runningpassmanager:Pass: BasisTranslator - 49.03197 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CheckCXDirection - 0.13423 (ms)
INFO:qiskit.transpiler.passes.basis.basis_translator:Basis translation instructions replaced in 0.000s.
INFO:qiskit.transpiler.runningpassmanager:Pass: BasisTranslator - 54.11601 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CXDirection - 0.91052 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: RemoveResetInZeroState - 0.04077 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CheckCXDirection - 0.15759 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CXDirection - 0.79799 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Depth - 0.11158 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: FixedPoint - 0.04745 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: RemoveResetInZeroState - 0.04077 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Optimize1qGates - 1.99819 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CXCancellation - 0.08464 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Depth - 0.04339 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Depth - 0.10943 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: FixedPoint - 0.03314 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: FixedPoint - 0.03242 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Optimize1qGates - 0.21958 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CXCancellation - 0.07629 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Depth - 0.02503 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Optimize1qGates - 2.43950 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: FixedPoint - 0.01597 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CXCancellation - 0.12016 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Optimize1qGates - 0.17095 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CXCancellation - 0.05364 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Depth - 0.03505 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: FixedPoint - 0.01788 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Optimize1qGates - 0.18024 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CXCancellation - 0.07749 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Depth - 0.03338 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: FixedPoint - 0.01717 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: Optimize1qGates - 0.15736 (ms)
INFO:qiskit.transpiler.runningpassmanager:Pass: CXCancellation - 0.07129 (ms)
INFO:qiskit.compiler.transpile:Total Transpile Time - 195.16397 (ms)
Como você pode ver aqui, recebemos mensagens de log de todos os 3 circuitos, sendo transpilados juntos. Não há como saber qual passagem faz parte de qual transpilação do circuito. Por sorte, o registro de log do Python fornece ferramentas para lidar com isto. O mais simples é, apenas alterar o log formatter,de modo que inclua informações adicionais, para que possamos associar uma mensagem de log, com o processo de que ela veio.
[33]:
formatter = logging.Formatter('%(name)s - %(processName)-10s - %(levelname)s: %(message)s')
handler = logging.getLogger().handlers[0]
handler.setFormatter(formatter)
Em seguida, reexecute a chamada transpile()
e veja o novo formatador de log.
[34]:
transpile(circuits, backend);
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: SetLayout - 0.01597 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: TrivialLayout - 0.17691 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: SetLayout - 0.01693 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: Layout2qDistance - 1.08218 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: TrivialLayout - 0.11516 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: Layout2qDistance - 0.69022 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: FullAncillaAllocation - 0.16642 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: EnlargeWithAncilla - 0.09775 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: FullAncillaAllocation - 0.31352 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: EnlargeWithAncilla - 0.15903 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: ApplyLayout - 0.44227 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: Unroll3qOrMore - 0.02933 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: CheckMap - 0.05007 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: ApplyLayout - 0.67401 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: UnrollCustomDefinitions - 0.12970 (ms)
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-5 - INFO: Begin BasisTranslator from source basis {('measure', 1), ('x', 1), ('h', 1), ('cx', 2)} to target basis {'cx', 'barrier', 'id', 'reset', 'u3', 'u1', 'measure', 'u2', 'snapshot'}.
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: Unroll3qOrMore - 0.02599 (ms)
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-5 - DEBUG: Begining basis search from frozenset({('measure', 1), ('x', 1), ('h', 1), ('cx', 2)}) to frozenset({'reset', 'cx', 'u3', 'barrier', 'u1', 'measure', 'id', 'u2', 'snapshot'}).
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: CheckMap - 0.04196 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: UnrollCustomDefinitions - 0.20337 (ms)
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-6 - INFO: Begin BasisTranslator from source basis {('measure', 1), ('x', 1), ('h', 1), ('cx', 2)} to target basis {'cx', 'barrier', 'id', 'reset', 'u3', 'u1', 'measure', 'u2', 'snapshot'}.
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-5 - DEBUG: Inspecting basis frozenset({('measure', 1), ('x', 1), ('h', 1), ('cx', 2)}).
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-6 - DEBUG: Begining basis search from frozenset({('measure', 1), ('x', 1), ('h', 1), ('cx', 2)}) to frozenset({'reset', 'cx', 'u3', 'barrier', 'u1', 'measure', 'id', 'u2', 'snapshot'}).
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-5 - DEBUG: Inspecting basis frozenset({('measure', 1), ('h', 1), ('cx', 2), ('u3', 1)}).
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-6 - DEBUG: Inspecting basis frozenset({('measure', 1), ('x', 1), ('h', 1), ('cx', 2)}).
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-6 - DEBUG: Inspecting basis frozenset({('measure', 1), ('h', 1), ('cx', 2), ('u3', 1)}).
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-5 - DEBUG: Transformation path:
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-6 - DEBUG: Transformation path:
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-5 - DEBUG: x/1 => []
┌─────────────┐
q_0: ┤ U3(pi,0,pi) ├
└─────────────┘
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-6 - DEBUG: x/1 => []
┌─────────────┐
q_0: ┤ U3(pi,0,pi) ├
└─────────────┘
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-5 - DEBUG: h/1 => []
┌──────────┐
q_0: ┤ U2(0,pi) ├
└──────────┘
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-6 - DEBUG: h/1 => []
┌──────────┐
q_0: ┤ U2(0,pi) ├
└──────────┘
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-5 - INFO: Basis translation path search completed in 0.018s.
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-6 - INFO: Basis translation path search completed in 0.014s.
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-6 - DEBUG: Composing transform step: x/1 [] =>
┌─────────────┐
q_0: ┤ U3(pi,0,pi) ├
└─────────────┘
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-5 - DEBUG: Composing transform step: x/1 [] =>
┌─────────────┐
q_0: ┤ U3(pi,0,pi) ├
└─────────────┘
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-5 - DEBUG: Updating transform for mapped instr ('x', 1) x, [] from
┌───┐
q303_0: ┤ x ├
└───┘
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-6 - DEBUG: Updating transform for mapped instr ('x', 1) x, [] from
┌───┐
q303_0: ┤ x ├
└───┘
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-5 - DEBUG: Updated transform for mapped instr ('x', 1) x, [] to
┌─────────────┐
q303_0: ┤ U3(pi,0,pi) ├
└─────────────┘
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-6 - DEBUG: Updated transform for mapped instr ('x', 1) x, [] to
┌─────────────┐
q303_0: ┤ U3(pi,0,pi) ├
└─────────────┘
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-5 - DEBUG: Composing transform step: h/1 [] =>
┌──────────┐
q_0: ┤ U2(0,pi) ├
└──────────┘
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-6 - DEBUG: Composing transform step: h/1 [] =>
┌──────────┐
q_0: ┤ U2(0,pi) ├
└──────────┘
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-5 - DEBUG: Updating transform for mapped instr ('h', 1) h, [] from
┌───┐
q304_0: ┤ h ├
└───┘
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-6 - DEBUG: Updating transform for mapped instr ('h', 1) h, [] from
┌───┐
q304_0: ┤ h ├
└───┘
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-5 - DEBUG: Updated transform for mapped instr ('h', 1) h, [] to
┌──────────┐
q304_0: ┤ U2(0,pi) ├
└──────────┘
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-6 - DEBUG: Updated transform for mapped instr ('h', 1) h, [] to
┌──────────┐
q304_0: ┤ U2(0,pi) ├
└──────────┘
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-6 - INFO: Basis translation paths composed in 0.020s.
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-5 - INFO: Basis translation paths composed in 0.020s.
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-5 - INFO: Basis translation instructions replaced in 0.000s.
qiskit.transpiler.passes.basis.basis_translator - ForkProcess-6 - INFO: Basis translation instructions replaced in 0.000s.
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: BasisTranslator - 40.80915 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: BasisTranslator - 45.52960 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: CheckCXDirection - 0.11969 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: CheckCXDirection - 0.13542 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: CXDirection - 0.81277 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: CXDirection - 0.93150 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: RemoveResetInZeroState - 0.03934 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: RemoveResetInZeroState - 0.04005 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: Depth - 0.12755 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: Depth - 0.09656 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: FixedPoint - 0.03791 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: FixedPoint - 0.04053 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: Optimize1qGates - 2.46310 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: CXCancellation - 0.13208 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: Depth - 0.03552 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: FixedPoint - 0.02217 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: Optimize1qGates - 2.03133 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: CXCancellation - 0.14567 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: Optimize1qGates - 0.18024 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: CXCancellation - 0.07057 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: Depth - 0.04125 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: FixedPoint - 0.02265 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: Depth - 0.03672 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: Optimize1qGates - 0.31304 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: FixedPoint - 0.01884 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-6 - INFO: Pass: CXCancellation - 0.06986 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: Optimize1qGates - 0.17571 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: CXCancellation - 0.19479 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: Depth - 0.04315 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: FixedPoint - 0.02480 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: Optimize1qGates - 0.43654 (ms)
qiskit.transpiler.runningpassmanager - ForkProcess-5 - INFO: Pass: CXCancellation - 0.05555 (ms)
qiskit.compiler.transpile - MainProcess - INFO: Total Transpile Time - 172.73402 (ms)
Agora, o formato para as mensagens de log foi alterado e ele inclui um nome de processo para cada um dos processos de transpilação, para que fique claro, quais mensagens de log são relacionadas.
Existem muitas opções diferentes, para como você pode configurar, este exemplo é bem limitado. Consulte a documentação para obter mais exemplos e opções para construir casos de uso mais sofisticados, que se adequam ao seu caso de uso ou preferências específicas.
[35]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
Version Information
Qiskit Software | Version |
---|---|
Qiskit | 0.20.0 |
Terra | 0.15.1 |
Aer | 0.6.1 |
Ignis | 0.4.0 |
Aqua | 0.7.5 |
IBM Q Provider | 0.8.0 |
System information | |
Python | 3.8.5 | packaged by conda-forge | (default, Jul 31 2020, 02:39:48) [GCC 7.5.0] |
OS | Linux |
CPUs | 4 |
Memory (Gb) | 30.82091522216797 |
Tue Sep 08 13:39:41 2020 EDT |
This code is a part of Qiskit
© Copyright IBM 2017, 2020.
This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.
[ ]: