Skip to main content
IBM Quantum Platform

MultiStagePassManager

class qiskit.passmanager.MultiStagePassManager(**stages)

GitHub

ベース: Generic[IR, IR_OUT]

複数のIRをサポートするステージド・パスマネージャー。

このパスマネージャは、入力プログラムに対して、名前が付けられた各ステージを順次実行します。 ステージは、 Task、その反復可能オブジェクト、または として定義することができます BasePassManager。 a がステージとして設定 BasePassManager された場合、そこに含まれるタスクのみが実行され、その a および _passmanager_frontend b メソッド _passmanager_backend で定義された入力および出力の変換は適用されません。

ステージでは、以下のことが可能です:

  • Task[IR, IR]IRを保持する。たとえば、次のように BasePassManager[IR] 設定された場合、または、あるいは
  • Task[IR1, IR2]IRを下げる。例えば、次のように。

各段の出力IRが次の段の入力IRと一致するように、互換性のある方法で各段を設定するのは、ユーザーの責任です。 ステージ名と実行順序は、パスマネージャーの構築時に設定されます。 ステージの実装は、対応するオブジェクト属性に新しい実装を割り当てることで変更できます。

メソッド run() にコールバックが指定される場合、そのコールバックは、パスマネージャ内のタスクによって出力されるあらゆる型のIR入力を処理できる必要があります。

コールバックは、以下のシグネチャで呼び出されます:

def callback(
    task: Task,  # the executed task
    passmanager_ir: Any,  # the IR after the task execution
    property_set: PropertySet,  # the property set after execution
    running_time: float,  # the time the task ran
    count: int  # the number of executed tasks so far
):
    ...

すべての引数はキーワード引数として渡されます。

注

object Task はタスクのインターフェースを定義しますが、カスタムパスは基底クラスからのみ派生させる必要があります GenericPass。 このベース Task は内部インターフェースであり、今後のQiskitのリリースでは、利用可能な型に対してさらに制限が設けられる可能性があります Task。

ワークフローの一例は次のとおりです:

from qiskit.circuit import QuantumCircuit
from qiskit.dagcircuit import DAGCircuit
from qiskit.passmanager import GenericPass, MultiStagePassManager
from qiskit.transpiler import generate_preset_pass_manager, Target, CouplingMap

class CustomPauliIR:
    # A custom IR of global Pauli strings
    def __init__(self, num_qubits):
        self.num_qubits = num_qubits
        self.paulis = []

    def apply(self, pauli: str):
        assert len(pauli) == self.num_qubits
        self.paulis.append(pauli)

class CustomPauliOptimization(GenericPass[CustomPauliIR, CustomPauliIR]):
    # A pass run on the custom Pauli IR
    def run(self, passmanager_ir: CustomPauliIR) -> CustomPauliIR:
        to_remove = []
        for i, pauli in enumerate(passmanager_ir.paulis):
            if all(p == "I" for p in pauli):
                to_remove.append(i)

        for i in reversed(to_remove):
            del passmanager_ir.paulis[i]

        return passmanager_ir

class PauliToDAG(GenericPass[CustomPauliIR, DAGCircuit]):
    # A pass converting CustomPauliIR to DAGCircuit
    def run(self, passmanager_ir: CustomPauliIR) -> DAGCircuit:
        circuit = QuantumCircuit(passmanager_ir.num_qubits)
        for pauli in passmanager_ir.paulis:
            circuit.pauli(pauli, circuit.qubits)
        return circuit.to_dag()

def callback(task, passmanager_ir, property_set, running_time, count):
    if isinstance(passmanager_ir, CustomPauliIR):
        print("PauliIR:", task.__class__.__name__, passmanager_ir.paulis)
    else:
        print("DAGCircuit:", task.__class__.__name__, passmanager_ir.count_ops())

target = Target.from_configuration(
    basis_gates=["u", "cx"], coupling_map=CouplingMap.from_line(3)
)
multi_pm = MultiStagePassManager(
    pauli_opt=CustomPauliOptimization(),
    pauli_to_dag=PauliToDAG(),
    dag_opt=generate_preset_pass_manager(target=target),
)

program = CustomPauliIR(3)
program.apply("XYZ")
program.apply("III")
program.apply("ZZI")

out = multi_pm.run(program, callback=callback)
print(out.count_ops())

このクラスは、両者とも段階的な実行モデルを採用しているという点で、…と StagedPassManager 関連しています。 StagedPassManagerただし、この関数はIRとしてのみを許可 DAGCircuit し、入力および出力レベルでからへの QuantumCircuit 暗黙の変換を持ち、書き込み可能な暗黙 pre_* のおよび post_* ステージフックを備えています。

の処理ロジックは StagedPassManager 、おおむね次のように表されます:

from qiskit.circuit import QuantumCircuit
from qiskit.dagcircuit import DAGCircuit
from qiskit.passmanager import GenericPass, MultiStagePassManager
from qiskit.transpiler import TranspileLayout

class CircuitToDAG(GenericPass[QuantumCircuit, DAGCircuit]):
    def run(self, passmanager_ir: QuantumCircuit) -> DAGCircuit:
        self.property_set["original_qubit_indices"] = {
            bit: i for i, bit in enumerate(passmanager_ir.qubits)
        }
        self.property_set["num_input_qubits"] = passmanager_ir.num_qubits
        return passmanager_ir.to_dag()

class DAGToCircuit(GenericPass[DAGCircuit, QuantumCircuit]):
    def run(self, passmanager_ir: DAGCircuit) -> QuantumCircuit:
        qc = passmanager_ir.to_circuit(copy_operations=False)
        qc._layout = TranspileLayout.from_property_set(passmanager_ir, self.property_set)
        return qc

multi_pm = MultiStagePassManager(
    input=CircuitToDAG(),
    # ... stages of StagedPassManager ...
    output=DAGToCircuit()
)

input_circuit = QuantumCircuit(1)
output_circuit = multi_pm.run(input_circuit)
警告

FlowControllerLinear 現在の実行モデルでは、タスクを実行するために、パスを線形化しています。 この基礎となるモデルは変更される可能性があるため、この前提に基づいて構築を行うのは安全ではありません。 ただし、このクラスのパブリックインターフェースは安定しています。

パラメーター

stages (BasePassManager[Any] | Task[Any, Any] | Iterable[Task[Any, Any]]) –

パス管理者としての役割。 これらは指定された順序で実行され、互換性のあるIRを持つ必要があります。

ステージ名はコンストラクタによって固定されます。後から新しいステージを追加することはできませんが、各ステージの属性に再代入を行うことで、その実装を置き換えることは可能です。


属性

stages

芸名。 これらは不変です。

ステージ自体は、そのステージと同じ名前の属性に値を書き込むことで変更できます。


方法

run

run(in_programs, callback=None, *, property_set=None)

GitHub

一連の入力プログラムに対して、パスマネージャを実行します。

パラメーター

  • in_programs (IR | list[IR] | tuple[IR]) – パスマネージャーを実行するプログラム。
  • callback (Callable[[Task, Any, PropertySet, float, int], None] | None) – 個々のタスクごとに渡されるコールバック。
  • property_set (PropertySet | None) – パスマネージャーに渡すように設定されたオプションのプロパティ。 指定された場合、これはその場で変更されます。 これは、プログラム内で複数回使用することはできません。

戻り値

出力されるプログラム。

戻りの型

IR_OUT | Iterable [ IR_OUT ]

to_flow_controller

to_flow_controller()

GitHub

この多段式パスマネージャーを、線形フローコントローラに変換してください。

この変換により、このパスマネージャーが Task[IR, IR_OUT] に正規化され、 自体やその他の実行フロー MultiStagePassManager 内にネストできるようになります。

戻りの型

Flow[* ControllerLinearIR*、 IR_OUT]

このページは役に立ちましたか?
バグや誤字の報告、またはコンテンツの要求はGitHubで行ってください。