Transpiler를 위한 양자 컴퓨터 표현하기
패키지 버전
이 페이지의 코드는 다음 요구 사항을 사용하여 개발되었습니다. 이 버전 이상을 사용하는 것을 권장합니다.
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
추상 Circuit을 특정 QPU(양자 처리 장치)에서 실행할 수 있는 ISA Circuit으로 변환하려면, Transpiler가 QPU에 대한 특정 정보를 필요로 합니다. 이 정보는 두 곳에서 찾을 수 있습니다: 작업을 제출할 BackendV2(또는 레거시 BackendV1) 객체와 Backend의 Target 속성입니다.
Target은 기기의 모든 관련 제약 조건, 즉 기본 기저 Gate, Qubit 연결성, 펄스 또는 타이밍 정보 등을 포함합니다.Backend는 기본적으로Target을 보유하며,InstructionScheduleMap과 같은 추가 정보를 포함하고, 양자 Circuit 작업 제출을 위한 인터페이스를 제공합니다.
또한 특정 사용 사례가 있거나 이 정보가 Transpiler가 더 최적화된 Circuit을 생성하는 데 도움이 된다고 판단되는 경우, Transpiler가 사용할 정보를 명시적으로 제공할 수도 있습니다.
Transpiler가 특정 하드웨어에 가장 적합한 Circuit을 얼마나 정밀하게 생성하는지는 Target 또는 Backend가 제약 조건에 대해 얼마나 많은 정보를 보유하고 있는지에 달려 있습니다.
기본 트랜스파일 알고리즘 중 다수가 확률론적이기 때문에, 더 나은 Circuit이 발견된다는 보장은 없습니다.
이 페이지에서는 QPU 정보를 Transpiler에 전달하는 여러 예제를 살펴봐요. 이 예제들은 FakeSherbrooke 모의 Backend의 Target을 사용합니다.
기본 구성
Transpiler를 가장 간단하게 사용하는 방법은 Backend 또는 Target을 제공하여 모든 QPU 정보를 제공하는 것입니다. Transpiler가 어떻게 작동하는지 더 잘 이해하려면, 아래와 같이 Circuit을 구성하고 다양한 정보로 트랜스파일해 보세요.
필요한 라이브러리를 가져오고 QPU를 인스턴스화합니다:
추상 Circuit을 특정 프로세서에서 실행할 수 있는 ISA Circuit으로 변환하기 위해, Transpiler는 프로세서에 대한 특정 정보를 필요로 합니다. 일반적으로 이 정보는 Transpiler에 제공되는 Backend 또는 Target에 저장되며, 추가 정보는 필요하지 않습니다. 그러나 특정 사용 사례가 있거나 이 정보가 Transpiler가 더 최적화된 Circuit을 생성하는 데 도움이 된다고 판단되는 경우, Transpiler가 사용할 정보를 명시적으로 제공할 수도 있습니다.
이 항목에서는 Transpiler에 정보를 전달하는 여러 예제를 살펴봐요. 이 예제들은 FakeSherbrooke 모의 Backend의 Target을 사용합니다.
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
backend = FakeSherbrooke()
target = backend.target
예제 Circuit은 Qiskit의 Circuit 라이브러리에서 efficient_su2의 인스턴스를 사용합니다.
from qiskit.circuit.library import efficient_su2
qc = efficient_su2(12, entanglement="circular", reps=1)
qc.draw("mpl")
이 예제는 기본 설정을 사용하여 backend의 target으로 트랜스파일합니다. 이 Target은 Circuit을 Backend에서 실행할 수 있는 형태로 변환하는 데 필요한 모든 정보를 제공합니다.
from qiskit.transpiler import generate_preset_pass_manager
pass_manager = generate_preset_pass_manager(
optimization_level=1, target=target, seed_transpiler=12345
)
qc_t_target = pass_manager.run(qc)
qc_t_target.draw("mpl", idle_wires=False, fold=-1)
이 예제 는 이 항목의 이후 섹션에서 커플링 맵과 기저 Gate가 최적의 Circuit 구성을 위해 Transpiler에 전달해야 할 필수 정보임을 설명하는 데 사용됩니다. QPU는 일반적으로 타이밍 및 스케줄링과 같이 전달되지 않은 다른 정보에 대해 기본 설정을 선택할 수 있습니다.
커플링 맵
커플링 맵은 어떤 Qubit들이 연결되어 있고 따라서 두 Qubit Gate를 가지는지를 보여주는 그래프입니다. 때로는 이 그래프가 방향성을 가지며, 이는 두 Qubit Gate가 한 방향으로만 적용될 수 있음을 의미합니다. 그러나 Transpiler는 추가적인 단일 Qubit Gate를 추가하여 Gate의 방향을 항상 반전시킬 수 있습니다. 추상 양자 Circuit은 SWAP Gate를 도입하여 양자 정보를 이동시킴으로써, 연결성이 제한되어 있더라도 항상 이 그래프에서 표현될 수 있습니다.
추상 Circuit의 Qubit을 _가상 Qubit_이라고 하며, 커플링 맵의 Qubit을 _물리적 Qubit_이라고 합니다. Transpiler는 가상 Qubit과 물리적 Qubit 사이의 매핑을 제공합니다. 트랜스파일의 첫 번째 단계 중 하나인 레이아웃 단계에서 이 매핑을 수행합니다.
라우팅 단계는 실제 Qubit을 선택하는 레이아웃 단계와 얽혀 있지만, 이 항목에서는 기본적으로 단순화를 위해 별개의 단계로 다룹니다. 라우팅과 레이아웃의 조합을 _Qubit 매핑_이라고 합니다. 이러한 단계에 대한 자세한 내용은 Transpiler 단계 항목에서 확인하세요.
coupling_map 키워드 인수를 전달하여 Transpiler에 미치는 영향을 확인해 보세요:
coupling_map = target.build_coupling_map()
pass_manager = generate_preset_pass_manager(
optimization_level=0, coupling_map=coupling_map, seed_transpiler=12345
)
qc_t_cm_lv0 = pass_manager.run(qc)
qc_t_cm_lv0.draw("mpl", idle_wires=False, fold=-1)
위에서 보이듯이, 여러 SWAP Gate가 삽입되었습니다(각각 세 개의 CX Gate로 구성됨). 이는 현재 장치에서 많은 오류를 유발할 것입니다. 실제 Qubit 토폴로지에서 어떤 Qubit이 선택되었는지 확인하려면, Qiskit 시각화에서 plot_circuit_layout을 사용하세요:
from qiskit.visualization import plot_circuit_layout
plot_circuit_layout(qc_t_cm_lv0, backend, view="physical")
이는 가상 Qubit 0-11이 물리적 Qubit 0-11의 라인에 단순하게 매핑되었음을 보여줍니다. 라우팅이 필요한 경우 VF2Layout을 사용하는 기본값(optimization_level=1)으로 돌아가겠습니다.
pass_manager = generate_preset_pass_manager(
optimization_level=1, coupling_map=coupling_map, seed_transpiler=12345
)
qc_t_cm_lv1 = pass_manager.run(qc)
qc_t_cm_lv1.draw("mpl", idle_wires=False, fold=-1)
이제 SWAP Gate가 삽입되지 않았으며, 선택된 물리적 Qubit은 target 클래스를 사용할 때와 동일합니다.
from qiskit.visualization import plot_circuit_layout
plot_circuit_layout(qc_t_cm_lv1, backend, view="physical")