注釈

当ページは tutorials/circuits_advanced/4_transpiler_passes_and_passmanager.ipynb から生成されました。

トランスパイラー パスとパス マネージャー

はじめに

Qiskit Terra の中核コンポーネントはトランスパイラーで、モジュール性と拡張性のために設計されています。目的は新しい回路の変換(トランスパイラー パス ** と呼んでいます) を簡単に書けるようにし、他の既存のパスと組み合わせられるようにすることです。これらのパスを連鎖させ、どの順番で適用するかは、最終的な結果に大きな影響を与えます。このパイプラインは **パスマネージャー により決定されます。パスマネージャーは、パスをスケジューリングし、共有スペースによるパス間の相互通信を行えるようにしています。このようにトランスパイラーは、量子回路の積極的な最適化の研究のために、ドアを開放しています。

このノートブックでは、ビルドインされたパスを調べ、パスマネージャの利用法を確認し、簡単なトランスパイラパスを開発します。そのために、最初に有向非巡回グラフ(Directed Acyclic Graph、DAG)の形で、Qiskitにおける量子回路の内部表現を紹介します。次に、入力回路を接続性の制限された量子デバイスと互換性を持つように変換する、単純な swap mapper パスを示します。

*始める前に*: DAGプロットルーチンの pydot ライブラリと graphviz ライブラリをインストールする必要があります。 Anaconda Python を使用している場合は、conda コマンドを使用して両方をインストールできます。 システムのネイティブ Python インタプリタを使用する場合は、pip コマンドを使用して pydot をインストールし、システムのネイティブ パッケージ マネージャー (例.yum, apt, dnf, brew など) を使用して graphviz をインストールします。

[1]:
%matplotlib inline
from qiskit import QuantumCircuit
from qiskit.compiler import transpile
from qiskit.transpiler import PassManager

パスマネージャーオブジェクト

必要なパスのセットが指定できます。

[2]:
circ = QuantumCircuit(3)
circ.ccx(0, 1, 2)
circ.draw(output='mpl')
[2]:
../../_images/tutorials_circuits_advanced_4_transpiler_passes_and_passmanager_5_0.png
[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]:
../../_images/tutorials_circuits_advanced_4_transpiler_passes_and_passmanager_6_0.png

Qiskit のトランスパイラーパスは、すべて 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']

同じパスの異なる実装

同じジョブをこなすパスがあっても、その方法は様々です。例えば、 TrivialLayoutDenseLayout および NoiseAdaptiveLayout は、すべてレイアウト(物理量子ビットへの仮想量子ビットのバインド)の選択ですが、それぞれ異なるアルゴリズムや目的を使います。同様に、 BasicSwapLookaheadSwap および StochasticSwap は結合マップに適合するように swap を挿入して回路を作成します。トランスパイラーのモジュール性により、各パスをプラグアンドプレイで置き換えられます。

以下では、swap パスを全て同じ回路、線形鎖トポロジーに適合するように変換しているもの、に適用したものを示しています。パフォーマンスに違いが見られ、明らかに StochasticSwap がベストです。しかしながら、入力回路によって違いが現れるでしょう。

[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]:
../../_images/tutorials_circuits_advanced_4_transpiler_passes_and_passmanager_11_0.png
[7]:
basic_circ.draw(output='mpl')
[7]:
../../_images/tutorials_circuits_advanced_4_transpiler_passes_and_passmanager_12_0.png
[8]:
lookahead_circ.draw(output='mpl')
[8]:
../../_images/tutorials_circuits_advanced_4_transpiler_passes_and_passmanager_13_0.png
[9]:
stochastic_circ.draw(output='mpl')
[9]:
../../_images/tutorials_circuits_advanced_4_transpiler_passes_and_passmanager_14_0.png

プリセット パスマネージャ

Qiskit には既定のパスマネージャを用意しており、異なるパスのパイプラインを通じて達成される様々な最適化レベルに対応しています。現時点で optimization_level は 0 から 3 までサポートされており、一番大きな数字はより最適化されますが、一方で時間を消費します。トランスパイルされる回路とターゲットとなるバックエンドに非常に依存するので、最適なパスマネージャの選択は試行錯誤を繰り返します。

ここでは、異なるレベルの結果を状態合成 (state synthesis) 回路で見てみたいと思います。4つの量子ビットを任意の状態で初期化し、これを実現する回路を最適化します。

  • optimization_level=0 : 明示的な最適化をせず回路をバックエンドにマップします(どの最適化でもマッパーが実施する項目を除く)。

  • optimization_level=1 : 回路をマップしますが、隣接するゲートをつぶすといった軽量の最適化を実施します。

  • optimization_level=2 : 中程度の最適化で、ノイズに適応したレイアウト、ゲートの交換関係に基づくゲートキャンセル処理が含まれます。

  • optimization_level=3 : 重量な最適化で、前までのステップに加え、回路にある2量子ビットの再合成 (resynthesis) を実施します。

[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: ──────────────────────────────────────────────────────────────────────────────
«                                                                                   

では、これを異なる最適化レベルで20量子ビットの Tokyo デバイスにマップします。

[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

DAGの紹介

Qiskit では、回路の表現として有向非巡回グラフ( Directed Acyclic Graph - DAG) を内部的に使用しています。純粋なゲートのリスト(つまり netlist ) に比べてこの表現の利点は、操作間の情報のフローが明示的になり、回路のセマンティックを変更することなくパスが変換の決定をするのにより容易である点です。

簡単な回路を構築して、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]:
../../_images/tutorials_circuits_advanced_4_transpiler_passes_and_passmanager_25_0.png

DAGには、3種類のグラフノードがあります:qubit/clbit インプットノード(緑)、操作ノード(青)、及びアウトプットノード(赤) です。各エッジはノード間のデータの流れ(もしくは依存性) を示しています。

[17]:
from qiskit.converters import circuit_to_dag
from qiskit.tools.visualization import dag_drawer
dag = circuit_to_dag(circ)
dag_drawer(dag)
[17]:
../../_images/tutorials_circuits_advanced_4_transpiler_passes_and_passmanager_27_0.png

従って、トランスパイラーのパスを実装するということは、Qiskit の DAGCircuit API を利用して分析し、回路を変換するということを意味します。幾つかの例を見てみましょう。

a. DAG中の全ての操作ノードを取得します:

[18]:
dag.op_nodes()
[18]:
[<qiskit.dagcircuit.dagnode.DAGNode at 0x7f1eebb870b0>,
 <qiskit.dagcircuit.dagnode.DAGNode at 0x7f1eebb87820>,
 <qiskit.dagcircuit.dagnode.DAGNode at 0x7f1eebb87eb0>,
 <qiskit.dagcircuit.dagnode.DAGNode at 0x7f1eebb876d0>]

各ノードは DAGNode クラスのインスタンスです。2つ目の操作ノードに含まれる情報を確認しましょう。

[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.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. 後ろに操作を追加します:

[20]:
from qiskit.circuit.library import HGate
dag.apply_operation_back(HGate(), qargs=[q[0]])
dag_drawer(dag)
[20]:
../../_images/tutorials_circuits_advanced_4_transpiler_passes_and_passmanager_34_0.png

c. 前に操作を追加します:

[21]:
from qiskit.circuit.library import CCXGate
dag.apply_operation_front(CCXGate(), qargs=[q[0], q[1], q[2]], cargs=[])
dag_drawer(dag)
[21]:
../../_images/tutorials_circuits_advanced_4_transpiler_passes_and_passmanager_36_0.png

d. ノードをサブ回路で置き換えます:

[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]:
../../_images/tutorials_circuits_advanced_4_transpiler_passes_and_passmanager_38_0.png

最後に、全ての変換が完了した後に、通常の QuantumCircuit オブジェクトに戻すことができます。これがトランスパイラーは実施していることです! 回路を受け取り、DAG 形式で操作し、変換した回路を出力します。

[23]:
from qiskit.converters import dag_to_circuit
circuit = dag_to_circuit(dag)
circuit.draw(output='mpl')
[23]:
../../_images/tutorials_circuits_advanced_4_transpiler_passes_and_passmanager_40_0.png

BasicMapper パスを実装してみる

DAG について理解できたので、トランスパイラーパスを書いてみましょう。ここでは、限られた量子ビット接続でのデバイスに対して任意の回路をマッピングする基本的なパスを実装します。これを BasicMapper と呼ぶことにします。このパスは、Qiskit Terra に含まれています。

トランスパイラーパスを作成する時に最初にやらなければいけないことは、パスクラスを TransformationPassAnalysisPass のどちらから派生させるかを決定することです。Transformationパス は回路を修正しますが、Analysisパス は回路の情報を収集する(のちに別のパスで利用される) のみです。次に、メインタスクとなる run(dag) メソッドを実装します。最後に、 qiskit.transpiler.passes モジュールの内部に登録させます。

このパスは以下のように機能します:DAG をレイヤー毎に横断します(各レイヤーは独立した量子ビットに作用しない操作のグループで、理論的にはレイヤーに存在する操作は独立して実行できます)。各操作に対して、既にカップリングマップの制約に適合していない場合には、パスは swap パスを特定し、2つの量子ビットが近くなるように swap を追加していきます。

詳細はコード中のコメントを参照してください。

[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

このパスを小さな回路例で試してみましょう。

[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>

我々の新しいパスを含むパスマネージャーを構築します。上記の回路例をこのパスマネージャに渡し、変換された新しい回路を受け取ります。

[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]:
../../_images/tutorials_circuits_advanced_4_transpiler_passes_and_passmanager_48_0.png
[28]:
out_circ.draw(output='mpl')
[28]:
../../_images/tutorials_circuits_advanced_4_transpiler_passes_and_passmanager_49_0.png

このパスはデバイスのカップリングマップに適合するように、全ての2量子ビットの相互作用が出来るように swap を追加しているだけであるという点に着目してください。このパスは相互作用の方向やデバイスがサポートするネイティブゲートについては考慮していません。これは Qiskitのトランスパイラーの設計思想です。全てのパスは小さく、よく定義されたアクションを持ち、積極的な回路の最適化は複数のパスを組み合わせるパスマネージャーによって達成されます。

トランスパイラーロギング

トランスパイラーが実装する内部操作の複雑性のため、問題をデバッグしたり呼び出した時にトランスバイラー内部で何が行われているかを理解したい局面が発生するでしょう。これを達成するために、通常の操作の一部としてトランスパイラーはログメッセージを出力します。ロギングには、Python の標準ライブラリの logging モジュールを利用してログメッセージを出しています。Python の標準ロギングを使用しているので、Qiskit-Terra のロギングを他のアプリケーションやライブラリと組みわせることが出来るようになります。

Python のロギングについての情報は、 公式ドキュメント 、及びリンク先のチュートリアルと cookbook を参照してください。

<b>Note:</b> Most of the <code>logging</code> module functions used in this section adjust global settings. If you run commands in this section it might effect the output from other cells if they are run in a different order.

Python ロギング標準ライブラリの設定

デフォルトでは Python 標準ロギングは、 WARNINGERRORCRITICAL ログレベルでのみログメッセージを出力します。トランスパイラーではこれらのログレベルを利用しておらず(全ては情報のみ) ログを吐きませんので、ロギングを設定する必要があります。

最も簡単な方法は次を実行することです:

[29]:
import logging

logging.basicConfig(level='DEBUG')

basicConfig() 関数 (ドキュメントは以下を参照してください: https://docs.python.org/3/library/logging.html#logging.basicConfig) ルートハンドラーとフォーマッタを設定します。ここでは ログレベルlevel kwarg で設定しています。特例のレベルに設定するとより高位のレベルも含まれます。例えば、 INFO に設定すると、 INFO レベルだけではなく、 WARNINGERROR 、 及び CRITICAL ログレベルも含まれます。

このノートブックの Python 環境ではトランスパイラーを実行した時に stderr にログメッセージを出力するように設定されています。例えば:

<b>Note:</b> <code>basicConfig()</code> will only work when called the first time it's called. It detects if a root handler and formatter have already been setup (either by using an earlier <code>basicConfig()</code> call or otherwise) and does nothing if they have. Further adjustments will have to by interacting with the handler directly.
[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)

ここではっきりわかるように、transpile() を呼び出すと2種類のログメッセージを出力されるようになりました。1つ目は INFO ログレベルで、パスマネージャーからのものです。これらは、実行された各パスとその所要時間を示しています。2番目は DEBUG レベルであり、StochasticSwapパスからのもので、そのパスの内部操作を記述しています。パスの操作における問題をデバッグするのに役立ちます。

トランスパイラーのログレベルを調整する

Qiskit トランスパイラーは、 logging.getLogger('qiskit.transpiler') で利用されているように、 単一のネームスペース qiskit.transpiler を利用しています。これによりトランスパイラー単独のログレベルを調整することが簡単に出来ます。例えば、INFO レベル以上のログメッセージだけを確認したい場合は、次のように実行できます:

[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)

平行実行を扱うためのログ設定

複数の回路をトランスパイルする時にはデフォルトではこれらの回路は平行でトランスパイルされます。ログレベルを設定してこれを実行し、出力を理解できるようにするには追加のステップが必要です。

単にロギングを設定して 複数の回路に対して transpile() を渡しただけでは、解読が難しい結果になるでしょう。例えば:

[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)

結果から確認出来るように3つの回路が一緒にトランスパイルされているログメッセージを取得しています。どのパスがどの回路のトランスパイルの一部なのかを知る手段がありません。幸いなことに、Python ロギングではこの状況を扱う手段を提供しています。簡単な方法は、ログフォーマッタ を変更して追加情報を含めるようにし、どのプロセスからログメッセージが出ているかを関連づけることです。

[33]:
formatter = logging.Formatter('%(name)s - %(processName)-10s - %(levelname)s: %(message)s')
handler = logging.getLogger().handlers[0]
handler.setFormatter(formatter)

次に、 transpile() 呼び出しを再実行し新しいログフォーマッタを確認します。

[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)

ログメッセージのフォーマットが変更され、各トランスパイラープロセスのプロセス名が含まれるようになり、どのログメッセージが進行しているかが明確になりました。

設定には多くの異なるオプションがあります。この例ではかなり限られています。より多くの例とオプションについてはドキュメントを参照し、あなたの特別なユースケースと好みに応じてより洗練されたユースケースをビルド出来るようにしてください。

[35]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright

Version Information

Qiskit SoftwareVersion
Qiskit0.20.0
Terra0.15.1
Aer0.6.1
Ignis0.4.0
Aqua0.7.5
IBM Q Provider0.8.0
System information
Python3.8.5 | packaged by conda-forge | (default, Jul 31 2020, 02:39:48) [GCC 7.5.0]
OSLinux
CPUs4
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.

[ ]: