Skip to main content
IBM Quantum Platform

MultiStagePassManager

class qiskit.passmanager.MultiStagePassManager(**stages)

GitHub

베이스: Generic[IR, IR_OUT]

여러 IR을 지원하는 단계별 패스 관리자.

이 패스 관리자는 입력 프로그램에 대해 순차적이고 이름이 지정된 단계들을 실행합니다. 스테이지는 Task, 그 반복 가능한 객체, 또는 로 정의될 수 있다 BasePassManager. a가 스테이지로 설정된 BasePassManager 경우, a에 포함된 작업만 실행되며, a의 및 _passmanager_frontend 메서드로 _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 는 작업 인터페이스를 정의하는 반면, 사용자 정의 패스는 반드시 base class에서 파생되어야 합니다 GenericPass. Task base는 내부 인터페이스이며, 향후 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에서 버그, 오타를 보고하거나 컨텐츠를 요청하십시오.