QPanda3
Supported by OriginQ
载入中...
搜索中...
未找到
量子线路编译

上一章: 噪声

下一章: 量子中间编译


Transpiler 模块教程

本教程提供了 Transpiler 模块的功能概览,其中包括生成线路拓扑、编译量子程序以及分解量子线路。这些操作对于优化和调整量子算法以适应特定的硬件架构至关重要。

概述

Transpiler 模块旨在帮助量子程序做好执行准备,包括生成拓扑结构、编译程序以适应特定架构,并将线路分解为更简单的组件。

函数与类

Transpiler 类

Transpiler 类用于将量子程序编译为符合特定拓扑结构和优化级别的版本。其提供了一个构造函数用于初始化一个新的 Transpiler 类实例。以下是 Transpiler 的构造示例:

transpile 方法

transpile 接口用于通过多个编译过程(passes)将量子程序(QProg)编译到指定的后端拓扑上。此过程通常包括以下步骤:

  • 优化量子线路:通过不同的优化策略减少量子门的数量和复杂度,从而提高量子程序的执行效率。
  • 映射到指定拓扑:根据目标量子计算机的拓扑,将逻辑量子比特映射到实际物理量子比特。该步骤考虑量子计算机的连通性限制,以确保量子门的物理可行性。
  • 量子门转换:将量子子程序中的高级量子门转换为目标硬件支持的低级量子门。这可能涉及对某些门的分解,以适应目标硬件的能力。
注解
  • 芯片拓扑边(Chip Topology edges):如果 chip_topology_edges 为空,编译过程中将跳过初始映射和路由流程,这可能会影响最终线路的优化和性能。因此,在使用时应提供有效的芯片拓扑信息。
  • 优化级别
    • 0:不进行优化。
    • 1:应用基本优化,包括简单的双量子逻辑门抵消和单量子逻辑门合并。
    • 2:执行高级优化,包括矩阵优化、双量子逻辑门抵消和单量子逻辑门合并。

以下是使用 Transpiler 类编译量子线路的示例:

运行结果如下所示:

prog:
┌─┐ ┌──┐ ┌─┐
q_0: |0>─┤H├ ┤RX├ ───*── ──── ───*── ───────┤M├ ───────
└─┘ └──┘ ┌──┴─┐ ┌──┐ ┌──┴─┐ └╥┘ ┌─┐
q_1: |0>──── ──── ┤CNOT├ ┤U1├ ┤CNOT├ ───*────╫─ ─┤M├───
└────┘ └──┘ └────┘ ┌──┴─┐ ║ └╥┘┌─┐
q_2: |0>──── ──── ────── ──── ────── ┤CNOT├──╫─ ──╫─┤M├
└────┘ ║ ║ └╥┘
c : / ═════════════════════════════════════╩════╩══╩═
0 1 2
Transpiler lavel 0:
┌──┐ ┌──┐ ┌──┐ ┌─┐ >
q_0: |0>─┤RY├ ┤RX├ ┤RX├ ──*─ ──── ──── ──── ──── ──── ──── ──── ──*─ ─────┤M├ ──── ──── ──── ──────── >
├──┤ ├──┤ ├──┤ ┌─┴┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌─┴┐ ┌──┐ └╥┘ ┌──┐ ┌──┐ ┌─┐ >
q_1: |0>─┤RZ├ ┤RX├ ┤RZ├ ┤CZ├ ┤RZ├ ┤RX├ ┤RZ├ ┤RZ├ ┤RZ├ ┤RX├ ┤RZ├ ┤CZ├ ┤RZ├──╫─ ┤RX├ ┤RZ├ ──*─ ─────┤M├ >
├──┤ ├──┤ ├──┤ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ ║ └──┘ └──┘ ┌─┴┐ ┌──┐ └╥┘ >
q_2: |0>─┤RZ├ ┤RX├ ┤RZ├ ──── ──── ──── ──── ──── ──── ──── ──── ──── ──────╫─ ──── ──── ┤CZ├ ┤RZ├──╫─ >
└──┘ └──┘ └──┘ ║ └──┘ └──┘ ║ >
c : / ═══════════════════════════════════════════════════════════════════╩═══════════════════════╩═
0 1
q_0: |0>──── ──── ────
q_1: |0>──── ──── ────
┌──┐ ┌──┐ ┌─┐
q_2: |0>┤RX├ ┤RZ├ ─┤M├
└──┘ └──┘ └╥┘
c : / ════════════╩═
2
Transpiler lavel 1:
┌──┐ ┌──┐ ┌──┐ ┌─┐ >
q_0: |0>─┤RZ├ ┤RX├ ┤RZ├ ──*─ ──── ──── ──── ──── ──── ──── ──── ──*─ ─────┤M├ ──── ──── ──── ──────── >
├──┤ ├──┤ ├──┤ ┌─┴┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌─┴┐ ┌──┐ └╥┘ ┌──┐ ┌──┐ ┌─┐ >
q_1: |0>─┤RZ├ ┤RX├ ┤RZ├ ┤CZ├ ┤RZ├ ┤RX├ ┤RZ├ ┤RZ├ ┤RZ├ ┤RX├ ┤RZ├ ┤CZ├ ┤RZ├──╫─ ┤RX├ ┤RZ├ ──*─ ─────┤M├ >
├──┤ ├──┤ ├──┤ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ ║ └──┘ └──┘ ┌─┴┐ ┌──┐ └╥┘ >
q_2: |0>─┤RZ├ ┤RX├ ┤RZ├ ──── ──── ──── ──── ──── ──── ──── ──── ──── ──────╫─ ──── ──── ┤CZ├ ┤RZ├──╫─ >
└──┘ └──┘ └──┘ ║ └──┘ └──┘ ║ >
c : / ═══════════════════════════════════════════════════════════════════╩═══════════════════════╩═
0 1
q_0: |0>──── ──── ────
q_1: |0>──── ──── ────
┌──┐ ┌──┐ ┌─┐
q_2: |0>┤RX├ ┤RZ├ ─┤M├
└──┘ └──┘ └╥┘
c : / ════════════╩═
2
Transpiler lavel 2:
┌──┐ ┌──┐ ┌──┐ ┌─┐ >
q_0: |0>─┤RZ├ ┤RX├ ┤RZ├ ──*─ ──── ──── ──── ──── ──── ──── ──── ──*─ ─────┤M├ ──── ──── ──── ──────── >
├──┤ ├──┤ ├──┤ ┌─┴┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌─┴┐ ┌──┐ └╥┘ ┌──┐ ┌──┐ ┌─┐ >
q_1: |0>─┤RZ├ ┤RX├ ┤RZ├ ┤CZ├ ┤RZ├ ┤RX├ ┤RZ├ ┤RZ├ ┤RZ├ ┤RX├ ┤RZ├ ┤CZ├ ┤RZ├──╫─ ┤RX├ ┤RZ├ ──*─ ─────┤M├ >
├──┤ ├──┤ ├──┤ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ ║ └──┘ └──┘ ┌─┴┐ ┌──┐ └╥┘ >
q_2: |0>─┤RZ├ ┤RX├ ┤RZ├ ──── ──── ──── ──── ──── ──── ──── ──── ──── ──────╫─ ──── ──── ┤CZ├ ┤RZ├──╫─ >
└──┘ └──┘ └──┘ ║ └──┘ └──┘ ║ >
c : / ═══════════════════════════════════════════════════════════════════╩═══════════════════════╩═
0 1
q_0: |0>──── ──── ────
q_1: |0>──── ──── ────
┌──┐ ┌──┐ ┌─┐
q_2: |0>┤RX├ ┤RZ├ ─┤M├
└──┘ └──┘ └╥┘
c : / ════════════╩═
2

如果 chip_topology_edges 参数未提供,则路由(Routing)操作将被跳过。如果 basic_gates参数未提供,则转化(Translation)操作将被跳过。

运行结果如下所示:

no chip_topology_edges prog:
┌──┐ ┌──┐ ┌──┐ ┌─┐ >
q_0: |0>─┤RZ├ ┤RX├ ┤RZ├ ──*─ ──── ──── ──── ──── ──── ──── ──── ──*─ ─────┤M├ ──── ──── ──── ──────── >
├──┤ ├──┤ ├──┤ ┌─┴┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌─┴┐ ┌──┐ └╥┘ ┌──┐ ┌──┐ ┌─┐ >
q_1: |0>─┤RZ├ ┤RX├ ┤RZ├ ┤CZ├ ┤RZ├ ┤RX├ ┤RZ├ ┤RZ├ ┤RZ├ ┤RX├ ┤RZ├ ┤CZ├ ┤RZ├──╫─ ┤RX├ ┤RZ├ ──*─ ─────┤M├ >
├──┤ ├──┤ ├──┤ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ ║ └──┘ └──┘ ┌─┴┐ ┌──┐ └╥┘ >
q_2: |0>─┤RZ├ ┤RX├ ┤RZ├ ──── ──── ──── ──── ──── ──── ──── ──── ──── ──────╫─ ──── ──── ┤CZ├ ┤RZ├──╫─ >
└──┘ └──┘ └──┘ ║ └──┘ └──┘ ║ >
c : / ═══════════════════════════════════════════════════════════════════╩═══════════════════════╩═
0 1
q_0: |0>──── ──── ────
q_1: |0>──── ──── ────
┌──┐ ┌──┐ ┌─┐
q_2: |0>┤RX├ ┤RZ├ ─┤M├
└──┘ └──┘ └╥┘
c : / ════════════╩═
2

如果提供了 init_mappings 参数,则会基于 init_mappings 进行路由。

运行结果如下所示:

init_mapping prog:
┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌─┐
q_0: |0>─┤RZ├ ┤RX├ ┤RZ├ ──── ──── ──── ──── ──── ──── ──── ──── ──── ──── ──── ──── ┤CZ├ ┤RZ├ ┤RX├ ┤RZ├ ─┤M├
├──┤ ├──┤ ├──┤ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ └─┬┘ └┬─┤ └──┘ └──┘ └╥┘
q_1: |0>─┤RZ├ ┤RX├ ┤RZ├ ┤CZ├ ┤RZ├ ┤RX├ ┤RZ├ ┤RZ├ ┤RZ├ ┤RX├ ┤RZ├ ┤CZ├ ┤RZ├ ┤RX├ ┤RZ├ ──*─ ─┤M├ ──── ──── ──╫─
├──┤ ├──┤ ├──┤ └─┬┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └─┬┘ └┬─┤ └──┘ └──┘ └╥┘ ║
q_2: |0>─┤RZ├ ┤RX├ ┤RZ├ ──*─ ──── ──── ──── ──── ──── ──── ──── ──*─ ─┤M├ ──── ──── ──── ──╫─ ──── ──── ──╫─
└──┘ └──┘ └──┘ └╥┘ ║ ║
c : / ═══════════════════════════════════════════════════════════════╩═══════════════════╩══════════════╩═
0 1 2

transpile 方法重载

transpile 接口有一个重载函数,该函数用于将量子程序转换为适合特定量子芯片后端的格式,并根据指定的优化级别进行优化。

参数说明如下:

  • prog : 需要转换的量子程序。
  • backend : 量子芯片的后端配置。该参数定义了芯片的拓扑结构、支持的门操作等信息。
  • init_mapping : 初始映射,从虚拟量子比特到物理量子比特的映射关系。默认为空映射。
  • optimization_level : 优化级别,指定转换过程中应用的优化策略。默认值为 2。

这个接口可以配合to_instructionrun_instruction使用,将一个量子程序编译到云平台的指定芯片上,转成指令文件,运行到芯片上。 以下是一个完整流程的示例代码:

from pyqpanda3.intermediate_compiler import convert_originir_file_to_qprog, convert_originir_string_to_qprog
from pyqpanda3.qcloud.qcloud import ChipBackend
from pyqpanda3.qcloud import QCloudService, LogOutput, QCloudOptions
from pyqpanda3.transpilation import Transpiler
from pyqpanda3.core import *
api_key = "" # 换成自己的key
def run_instruction_test(prog_1: QProg):
# 获取服务
service = QCloudService(api_key)
# 获取指定芯片
backend_wukong = service.backend("72")
chip_info = backend_wukong.chip_info()
# 获取芯片后端
backend: ChipBackend = chip_info.get_chip_backend()
# 根据芯片信息编译
transpiler = Transpiler()
prog_2 = transpiler.transpile(prog_1, backend, {}, 2)
# 转成芯片指令
use_pattern = False
ins = prog_2.to_instruction(backend, 1, use_pattern)
# 运行到芯片上
options = QCloudOptions()
options.set_mapping(False)
options.set_amend(False)
job = backend_wukong.run_instruction([ins], 1000, options)
result = job.result()
print(result.get_probs_list())
# 测试函数
if __name__ == "__main__":
ir = """
QINIT 8
CREG 8
H q[0]
H q[1]
H q[2]
H q[3]
H q[4]
H q[5]
CNOT q[0],q[4]
RZ q[4],(0.93926449)
CNOT q[0],q[4]
CNOT q[0],q[5]
RZ q[5],(0.42459902)
CNOT q[0],q[5]
CNOT q[1],q[4]
RZ q[4],(0.88779795)
CNOT q[1],q[4]
CNOT q[1],q[5]
RZ q[5],(0.46319893)
CNOT q[1],q[5]
CNOT q[2],q[5]
RZ q[5],(1.132264)
CNOT q[2],q[5]
CNOT q[3],q[5]
RZ q[5],(0.86206467)
CNOT q[3],q[5]
RX q[0],(2.3543679)
RX q[1],(2.3543679)
RX q[2],(2.3543679)
RX q[3],(2.3543679)
RX q[4],(2.3543679)
RX q[5],(2.3543679)
MEASURE q[0],c[0]
MEASURE q[1],c[1]
MEASURE q[2],c[2]
MEASURE q[3],c[3]
MEASURE q[4],c[4]
MEASURE q[5],c[5]
"""
prog_1 = convert_originir_string_to_qprog(ir)
run_instruction_test(prog_1)
定义 __init__.py:1
定义 qcloud.pyi:1
定义 __init__.py:1

运行结果如下:

[{'0x0': 0.077, '0x1': 0.007, '0x10': 0.032, '0x11': 0.005, '0x12': 0.043, '0x13': 0.006,
'0x14': 0.009, '0x15': 0.002, '0x16': 0.018, '0x17': 0.005, '0x18': 0.022, '0x19': 0.002,
'0x1a': 0.018, '0x1b': 0.005, '0x1c': 0.018, '0x1d': 0.002, '0x1e': 0.025, '0x1f': 0.003,
'0x2': 0.084, '0x20': 0.036, '0x21': 0.004, '0x22': 0.039, '0x23': 0.003, '0x24': 0.013,
'0x26': 0.011, '0x27': 0.006, '0x28': 0.03, '0x29': 0.004, '0x2a': 0.024, '0x2b': 0.002,
'0x2c': 0.016, '0x2d': 0.006, '0x2e': 0.029, '0x2f': 0.006, '0x3': 0.018, '0x30': 0.014,
'0x31': 0.003, '0x32': 0.019, '0x33': 0.005, '0x34': 0.006, '0x35': 0.002, '0x36': 0.009,
'0x37': 0.002, '0x38': 0.009, '0x39': 0.002, '0x3a': 0.012, '0x3b': 0.001, '0x3c': 0.008,
'0x3d': 0.001, '0x3e': 0.016, '0x3f': 0.001, '0x4': 0.023, '0x5': 0.002, '0x6': 0.03,
'0x7': 0.012, '0x8': 0.042, '0x9': 0.008, '0xa': 0.042, '0xb': 0.004, '0xc': 0.038,
'0xd': 0.005, '0xe': 0.046, '0xf': 0.008}]

生成拓扑

generate_topology 用于基于特定参数生成量子线路的拓扑结构。

分解

decompose 函数可用于将量子程序和线路分解为其基本组成部分。如果 basic_gates参数未提供,则转化(Translation)操作将被跳过。以下是 decompose 函数的使用示例:

运行结果如下所示:

decomposed prog:
┌──┐ ┌──┐ ┌──┐ ┌─┐ >
q_0: |0>─┤RY├ ┤RX├ ┤RX├ ──*─ ──── ──── ──── ──── ──── ──── ──── ──*─ ─────┤M├ ──── ──── ──── ──────── >
├──┤ ├──┤ ├──┤ ┌─┴┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌─┴┐ ┌──┐ └╥┘ ┌──┐ ┌──┐ ┌─┐ >
q_1: |0>─┤RZ├ ┤RX├ ┤RZ├ ┤CZ├ ┤RZ├ ┤RX├ ┤RZ├ ┤RZ├ ┤RZ├ ┤RX├ ┤RZ├ ┤CZ├ ┤RZ├──╫─ ┤RX├ ┤RZ├ ──*─ ─────┤M├ >
├──┤ ├──┤ ├──┤ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ ║ └──┘ └──┘ ┌─┴┐ ┌──┐ └╥┘ >
q_2: |0>─┤RZ├ ┤RX├ ┤RZ├ ──── ──── ──── ──── ──── ──── ──── ──── ──── ──────╫─ ──── ──── ┤CZ├ ┤RZ├──╫─ >
└──┘ └──┘ └──┘ ║ └──┘ └──┘ ║ >
c : / ═══════════════════════════════════════════════════════════════════╩═══════════════════════╩═
0 1
q_0: |0>──── ──── ────
q_1: |0>──── ──── ────
┌──┐ ┌──┐ ┌─┐
q_2: |0>┤RX├ ┤RZ├ ─┤M├
└──┘ └──┘ └╥┘
c : / ════════════╩═
2

在 V0.2.0 版本以后,也可以使用 decompose 接口来分解矩阵,使用示例如下: