

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 OpenQASM 3.0 运行您的电路
<a name="braket-openqasm"></a>

 Amazon Braket 现在支持适用于基于门的量子设备和模拟器的 [OpenQASM 3.0](https://openqasm.com/)。本用户指南提供了有关 Braket 支持的 OpenQASM 3.0 子集的信息。Braket 客户现在可以选择使用 [SDK](braket-constructing-circuit.md) 提交 Braket 电路，也可以使用 [Amazon Braket API](https://docs.aws.amazon.com/braket/latest/APIReference/Welcome.html) 和 [Amazon Braket Python SDK](https://github.com/aws/amazon-braket-sdk-python) 直接向所有基于门的设备提供 OpenQASM 3.0 字符型。

本指南中的主题将引导您了解如何完成以下量子任务的各种示例。
+  [在不同的 Braket 设备上创建和提交 OpenQASM 量子任务](braket-openqasm-create-submit-task.md) 
+  [访问受支持的操作和结果类型](braket-openqasm-device-support.md#braket-openqasm-supported-operations-results-result-types) 
+  [使用 OpenQASM 模拟噪声](braket-openqasm-noise-simulation.md) 
+  [在 OpenQASM 中使用逐字记录编译](braket-openqasm-verbatim-compilation.md) 
+  [排查 OpenQASM 问题](https://docs.aws.amazon.com/braket/latest/developerguide/braket-troubleshooting-openqasm.html) 

本指南还介绍了某些硬件特有的功能，这些功能可以通过 Braket 上的 OpenQASM 3.0 实现，并提供了更多资源的链接。

**Topics**
+ [什么是 OpenQASM 3.0？](#braket-openqasm-what-is)
+ [何时使用 OpenQASM 3.0](#braket-openqasm-when-to-use)
+ [OpenQASM 3.0 的工作方式](#braket-openqasm-how-it-works)
+ [先决条件](#braket-openqasm-prerequisites)
+ [Braket 支持哪些 OpenQASM 功能？](braket-openqasm-supported-features.md)
+ [创建并提交示例 OpenQASM 3.0 量子任务](braket-openqasm-create-submit-task.md)
+ [在不同的 Braket 设备上支持 OpenQASM](braket-openqasm-device-support.md)
+ [使用 OpenQASM 3.0 模拟噪声](braket-openqasm-noise-simulation.md)
+ [Qubit 使用 OpenQASM 3.0 重新布线](braket-openqasm-rewire-qubits.md)
+ [使用 OpenQASM 3.0 进行逐字记录编译](braket-openqasm-verbatim-compilation.md)
+ [Braket 控制台](#braket-openqasm-braket-console)
+ [其他资源](#braket-openqasm-more-resources)
+ [使用 OpenQASM 3.0 计算梯度](braket-openqasm-computing-gradients.md)
+ [使用 OpenQASM 3.0 测量特定的量子比特](braket-openqasm-measure-qubits.md)

## 什么是 OpenQASM 3.0？
<a name="braket-openqasm-what-is"></a>

开放量子汇编语言（OpenQASM）是量子指令的[中间表示形式](https://en.wikipedia.org/wiki/Intermediate_representation)。OpenQASM 是一个开源框架，广泛用于规范基于门的设备的量子程序。使用 OpenQASM，用户可以对构成量子计算基块的量子门和测量操作进行编程。许多量子编程库都使用先前版本的 OpenQASM (2.0) 来描述基本程序。

新版本的 OpenQASM (3.0) 扩展了之前的版本，增加了更多功能，如脉冲电平控制、门定时和经典控制流，以弥合最终用户界面和硬件描述语言之间的差距。当前版本 3.0 的详细信息和规格可在 GitHub [OpenQasm 3.x](https://github.com/openqasm/openqasm) 实时规格中找到。OpenQasm 的未来发展由 OpenQasm 3.0 [技术指导委员会管理，该委员会](https://aws.amazon.com/blogs/quantum-computing/aws-joins-the-openqasm-3-0-technical-steering-committee/)与 IBM、微软和因斯布鲁克大学一起 AWS 是该委员会的成员。

## 何时使用 OpenQASM 3.0
<a name="braket-openqasm-when-to-use"></a>

OpenQASM 提供了一个富有表现力的框架，可通过非特定架构的低级控件来指定量子程序，因而非常适合作为多个基于门的设备的表示形式。Braket 对 OpenQASM 的支持进一步推动了其作为开发基于门的量子算法的一致方法的采用，从而减少了用户在多个框架中学习和维护库的需求。

如果您在 OpenQASM 3.0 中已有程序库，则可以对其进行调整，使其与 Braket 配合使用，而不必完全重写这些电路。研究人员和开发人员还应受益于越来越多的支持 OpenQASM 算法开发的可用第三方库。

## OpenQASM 3.0 的工作方式
<a name="braket-openqasm-how-it-works"></a>

Braket 对 OpenQASM 3.0 的支持提供了与当前中间表示法相同的功能。这意味着，您今天在硬件设备和使用 Braket 的按需模拟器上能做的任何事情，都可以使用 Braket API 在 OpenQASM 上处理。您可以通过直接向所有基于门的设备提供 OpenQASM 字符串来运行 OpenQASM 3.0 程序，其方式类似于当前向 Braket 上的设备提供电路。Braket 用户还可以集成支持 OpenQASM 3.0 的第三方库。本指南的其他部分详细介绍了如何开发用于 Braket 的 OpenQASM 表示形式。

## 先决条件
<a name="braket-openqasm-prerequisites"></a>

要在 Amazon Braket 上使用 OpenQASM 3.0，您必须拥有 [Amazon Braket Python 架构](https://github.com/aws/amazon-braket-schemas-python)的 1.8.0 版本和 [Amazon Braket Python SDK](https://github.com/aws/amazon-braket-sdk-python) 的 1.17.0 版本或更高版本。

如果您是首次接触 Amazon Braket 的用户，则需要启用 Amazon Braket。有关说明，请参阅[启用 Amazon Braket](https://docs.aws.amazon.com/braket/latest/developerguide/braket-enable-overview.html)。

# Braket 支持哪些 OpenQASM 功能？
<a name="braket-openqasm-supported-features"></a>

下节列出了 Braket 支持的 OpenQASM 3.0 数据类型、语句和编译指令。

**Topics**
+ [受支持的 OpenQASM 数据类型](#braket-openqasm-supported-features-datatypes)
+ [受支持的 OpenQASM 语句](#braket-openqasm-supported-features-statements)
+ [Braket OpenQASM 编译指示](#braket-openqasm-supported-features-pragmas)
+ [本地模拟器上对 OpenQASM 的高级功能支持](#braket-openqasm-supported-features-advanced-feature-local-simulator)
+ [支持的操作和语法 OpenPulse](#braket-openpulse-supported-operations-grammar)

## 受支持的 OpenQASM 数据类型
<a name="braket-openqasm-supported-features-datatypes"></a>

Amazon Braket 支持以下 OpenQASM 数据类型：
+ 非负整数用于（虚拟和物理）量子比特索引：
  +  `cnot q[0], q[1];` 
  +  `h $0;` 
+ 浮点数或常数可用于门旋转角度：
  +  `rx(-0.314) $0;` 
  +  `rx(pi/4) $0;` 

**注意**  
pi 是 OpenQASM 中的内置常量，不能用作参数名称。
+ 在用于定义一般哈密特量可观测值的结果类型编译指示和单一编译指示中，允许使用复数数组（虚数部分使用 OpenQASM `im` 表示法）：
  +  `#pragma braket unitary [[0, -1im], [1im, 0]] q[0]` 
  +  `#pragma braket result expectation hermitian([[0, -1im], [1im, 0]]) q[0]` 

## 受支持的 OpenQASM 语句
<a name="braket-openqasm-supported-features-statements"></a>

Amazon Braket 支持以下 OpenQASM 语句。
+  `Header: OPENQASM 3;` 
+ 经典位声明：
  +  `bit b1;` (equivalently, `creg b1;`)
  +  `bit[10] b2;` (equivalently, `creg b2[10];`)
+ 量子比特声明：
  +  `qubit b1;` (equivalently, `qreg b1;`)
  +  `qubit[10] b2;` (equivalently, `qreg b2[10];`)
+ 在数组内建立索引：`q[0]`
+ 输入：`input float alpha;`
+ 物理 qubits 的规格：`$0`
+ 设备上受支持的门和操作：
  +  `h $0;` 
  +  `iswap q[0], q[1];` 

**注意**  
设备支持的门可以在 OpenQASM 操作的设备属性中找到；使用这些门不需要任何门定义。
+ 逐字记录表声明。目前，我们不支持方框持续时间表示法。原生门和物理 qubits 必须放在逐字记录框中。

```
#pragma braket verbatim
box{
    rx(0.314) $0;
}
```
+ 在 qubits 或整个 qubit 寄存器上进行测量和测量分配。
  +  `measure $0;` 
  +  `measure q;` 
  +  `measure q[0];` 
  +  `b = measure q;` 
  +  `measure q → b;` 
+ Barrier 语句通过防止跨屏障边界的门重新排序和优化，提供对电路编译和执行的明确控制。它们还在执行期间强制执行严格的时间顺序，确保屏障之前的所有操作在后续操作开始之前完成。
  +  `barrier;` 
  +  `barrier q[0], q[1];` 
  +  `barrier $3, $6;` 

## Braket OpenQASM 编译指示
<a name="braket-openqasm-supported-features-pragmas"></a>

Amazon Braket 支持下列 OpenQASM 编译指示说明。
+ 噪声编译指示
  +  `#pragma braket noise bit_flip(0.2) q[0]` 
  +  `#pragma braket noise phase_flip(0.1) q[0]` 
  +  `#pragma braket noise pauli_channel` 
+ 逐字编译指示
  +  `#pragma braket verbatim` 
+ 结果类型编译指示
  + 基数不变结果类型：
    + 状态向量：`#pragma braket result state_vector`
    + 密度矩阵：`#pragma braket result density_matrix`
  + 梯度计算编译指示：
    + 伴随渐变：`#pragma braket result adjoint_gradient expectation(2.2 * x[0] @ x[1]) all`
  + Z 基准结果类型：
    + 振幅：`#pragma braket result amplitude "01"`
    + 概率：`#pragma braket result probability q[0], q[1]`
  + 基础轮换结果类型
    + 期望：`#pragma braket result expectation x(q[0]) @ y([q1])`
    + 方差：`#pragma braket result variance hermitian([[0, -1im], [1im, 0]]) $0`
    + 示例：`#pragma braket result sample h($1)`

**注意**  
由于 OpenQASM 3.0 向后兼容 OpenQASM 2.0，因而使用 2.0 编写的程序可以在 Braket 上运行。但是，Braket 支持的 OpenQASM 3.0 功能确实存在一些细微的语法差异，如 `qreg` vs `creg` 和 `qubit` vs `bit`。测量句法也有差异，需要用正确的语法来支持这些语法。

## 本地模拟器上对 OpenQASM 的高级功能支持
<a name="braket-openqasm-supported-features-advanced-feature-local-simulator"></a>

`LocalSimulator` 支持高级 OpenQASM 功能，这些功能不是作为 Braket 的 QPU 模拟器或按需模拟器的一部分提供的。在 `LocalSimulator` 中，仅支持下列功能：
+ 门修改器
+ OpenQASM 内置门
+ 经典变量
+ 经典运算
+ 定制门
+ 经典控制
+ QASM 文件
+ 子程序

有关每项高级功能的示例，请参阅此[样本 Notebook。](https://github.com/aws/amazon-braket-examples/blob/main/examples/braket_features/Simulating_Advanced_OpenQASM_Programs_with_the_Local_Simulator.ipynb)有关完整的 OpenQASM 规范，请访问 [OpenQASM 网站](https://openqasm.com/language/index.html)。

## 支持的操作和语法 OpenPulse
<a name="braket-openpulse-supported-operations-grammar"></a>

 **支持 OpenPulse 的数据类型** 

Cal 块：

```
cal {
    ...
}
```

Defcal 块：

```
// 1 qubit
defcal x $0 {
...
}

// 1 qubit w. input parameters as constants
defcal my_rx(pi) $0 {
...
}

// 1 qubit w. input parameters as free parameters
defcal my_rz(angle theta) $0 {
...
}

// 2 qubit (above gate args are also valid)
defcal cz $1, $0 {
...
}
```

帧:

```
frame my_frame = newframe(port_0, 4.5e9, 0.0);
```

波形：

```
// prebuilt
waveform my_waveform_1 = constant(1e-6, 1.0);

//arbitrary
waveform my_waveform_2 = {0.1 + 0.1im, 0.1 + 0.1im, 0.1, 0.1};
```

 **自定义门校准示例：**

```
cal {
    waveform wf1 = constant(1e-6, 0.25);
}

defcal my_x $0 {
   play(wf1, q0_rf_frame);
}

defcal my_cz $1, $0 {
    barrier q0_q1_cz_frame, q0_rf_frame;
    play(q0_q1_cz_frame, wf1);
    delay[300ns] q0_rf_frame
    shift_phase(q0_rf_frame, 4.366186381749424);
    delay[300ns] q0_rf_frame;
    shift_phase(q0_rf_frame.phase, 5.916747563126659);
    barrier q0_q1_cz_frame, q0_rf_frame;
    shift_phase(q0_q1_cz_frame, 2.183093190874712);
}

bit[2] ro;
my_x $0;
my_cz $1,$0;
c[0] = measure $0;
```

 **任意脉冲示例：**

```
bit[2] ro;
cal {
    waveform wf1 = {0.1 + 0.1im, 0.1 + 0.1im, 0.1, 0.1};
    barrier q0_drive, q0_q1_cross_resonance;
    play(q0_q1_cross_resonance, wf1);
    delay[300ns] q0_drive;
    shift_phase(q0_drive, 4.366186381749424);
    delay[300dt] q0_drive;
   barrier q0_drive, q0_q1_cross_resonance;
   play(q0_q1_cross_resonance, wf1);
    ro[0] = capture_v0(r0_measure);
    ro[1] = capture_v0(r1_measure);
}
```

# 创建并提交示例 OpenQASM 3.0 量子任务
<a name="braket-openqasm-create-submit-task"></a>

你可以使用 Amazon Braket Python SDK、Boto3 或，向亚马逊 Braket AWS CLI 设备提交 OpenQasm 3.0 量子任务。

**Topics**
+ [一个 OpenQASM 3.0 程序示例](#braket-openqasm-example-program)
+ [使用 Python SDK 创建 OpenQASM 3.0 量子任务](#braket-openqasm-create-tasks-with-python-sdk)
+ [使用 Boto3 创建 OpenQASM 3.0 量子任务](#braket-openqasm-create-tasks-with-boto3)
+ [使用创建 OpenQasm 3.0 任务 AWS CLI](#braket-openqasm-create-tasks-with-aws-cli)

## 一个 OpenQASM 3.0 程序示例
<a name="braket-openqasm-example-program"></a>

要创建 OpenQASM 3.0 任务，您可以从一个基本的 OpenQASM 3.0 程序 (ghz.qasm) 开始，该程序准备 [GHZ](https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state) 状态，如以下示例所示。

```
// ghz.qasm
// Prepare a GHZ state
OPENQASM 3;

qubit[3] q;
bit[3] c;

h q[0];
cnot q[0], q[1];
cnot q[1], q[2];

c = measure q;
```

## 使用 Python SDK 创建 OpenQASM 3.0 量子任务
<a name="braket-openqasm-create-tasks-with-python-sdk"></a>

您可以使用以下代码及 [Amazon Braket Python SDK](https://github.com/aws/amazon-braket-sdk-python) 将此程序提交到 Amazon Braket 设备。请务必将 Amazon S3 存储桶位置“amzn-s3-demo-bucket”替换为您自己的 Amazon S3 存储桶名称。

```
with open("ghz.qasm", "r") as ghz:
    ghz_qasm_string = ghz.read()

# Import the device module
from braket.aws import AwsDevice
# Choose the Rigetti device
device = AwsDevice("arn:aws:braket:us-west-1::device/qpu/rigetti/Ankaa-3")
from braket.ir.openqasm import Program

program = Program(source=ghz_qasm_string)
my_task = device.run(program)

# Specify an optional s3 bucket location and number of shots
s3_location = ("amzn-s3-demo-bucket", "openqasm-tasks")
my_task = device.run(
    program,
    s3_location,
    shots=100,
)
```

## 使用 Boto3 创建 OpenQASM 3.0 量子任务
<a name="braket-openqasm-create-tasks-with-boto3"></a>

您还可以使用 [AWS 适用于 Braket 的 Python SDK（Boto3）](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/braket.html)，利用 OpenQASM 3.0 字符串创建量子任务，如以下示例所示。以下代码片段引用了 ghz.qasm，它准备了 [GHZ](https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state) 状态，如上所示。

```
import boto3
import json

my_bucket = "amzn-s3-demo-bucket"
s3_prefix = "openqasm-tasks"

with open("ghz.qasm") as f:
    source = f.read()

action = {
    "braketSchemaHeader": {
        "name": "braket.ir.openqasm.program",
        "version": "1"
    },
    "source": source
}
device_parameters = {}
device_arn = "arn:aws:braket:us-west-1::device/qpu/rigetti/Ankaa-3"
shots = 100

braket_client = boto3.client('braket', region_name='us-west-1')
rsp = braket_client.create_quantum_task(
    action=json.dumps(
        action
    ),
    deviceParameters=json.dumps(
        device_parameters
    ),
    deviceArn=device_arn,
    shots=shots,
    outputS3Bucket=my_bucket,
    outputS3KeyPrefix=s3_prefix,
)
```

## 使用创建 OpenQasm 3.0 任务 AWS CLI
<a name="braket-openqasm-create-tasks-with-aws-cli"></a>

[AWS Command Line Interface （CLI）](https://aws.amazon.com/cli/)也可用于提交 OpenQASM 3.0 程序，如以下示例所示。

```
aws braket create-quantum-task \
    --region "us-west-1" \
    --device-arn "arn:aws:braket:us-west-1::device/qpu/rigetti/Ankaa-3" \
    --shots 100 \
    --output-s3-bucket "amzn-s3-demo-bucket" \
    --output-s3-key-prefix "openqasm-tasks" \
    --action '{
        "braketSchemaHeader": {
            "name": "braket.ir.openqasm.program",
            "version": "1"
        },
        "source": $(cat ghz.qasm)
    }'
```

# 在不同的 Braket 设备上支持 OpenQASM
<a name="braket-openqasm-device-support"></a>

对于支持 OpenQASM 3.0 的设备，`action` 字段支持通过 `GetDevice` 响应执行新操作，如下列 Rigetti 和 IonQ 设备示例所示。

```
//OpenQASM as available with the Rigetti device capabilities
{
    "braketSchemaHeader": {
        "name": "braket.device_schema.rigetti.rigetti_device_capabilities",
        "version": "1"
    },
    "service": {...},
    "action": {
        "braket.ir.jaqcd.program": {...},
        "braket.ir.openqasm.program": {
            "actionType": "braket.ir.openqasm.program",
            "version": [
                "1"
            ],
            ….
        }
    }
}

//OpenQASM as available with the IonQ device capabilities
{
    "braketSchemaHeader": {
        "name": "braket.device_schema.ionq.ionq_device_capabilities",
        "version": "1"
    },
    "service": {...},
    "action": {
        "braket.ir.jaqcd.program": {...},
        "braket.ir.openqasm.program": {
            "actionType": "braket.ir.openqasm.program",
            "version": [
                "1"
            ],
            ….
        }
    }
}
```

对于支持脉冲控制的设备，`pulse` 字段显示在 `GetDevice` 响应中。以下示例显示了 Rigetti 设备的 `pulse` 字段。

```
// Rigetti
{
  "pulse": {
    "braketSchemaHeader": {
      "name": "braket.device_schema.pulse.pulse_device_action_properties",
      "version": "1"
    },
    "supportedQhpTemplateWaveforms": {
      "constant": {
        "functionName": "constant",
        "arguments": [
          {
            "name": "length",
            "type": "float",
            "optional": false
          },
          {
            "name": "iq",
            "type": "complex",
            "optional": false
          }
        ]
      },
      ...
    },
    "ports": {
      "q0_ff": {
        "portId": "q0_ff",
        "direction": "tx",
        "portType": "ff",
        "dt": 1e-9,
        "centerFrequencies": [
          375000000
        ]
      },
      ...
    },
    "supportedFunctions": {
      "shift_phase": {
        "functionName": "shift_phase",
        "arguments": [
          {
            "name": "frame",
            "type": "frame",
            "optional": false
          },
          {
            "name": "phase",
            "type": "float",
            "optional": false
          }
        ]
      },
     ...
    },
    "frames": {
      "q0_q1_cphase_frame": {
        "frameId": "q0_q1_cphase_frame",
        "portId": "q0_ff",
        "frequency": 462475694.24460185,
        "centerFrequency": 375000000,
        "phase": 0,
        "associatedGate": "cphase",
        "qubitMappings": [
          0,
          1
        ]
      },
      ...
    },
    "supportsLocalPulseElements": false,
    "supportsDynamicFrames": false,
    "supportsNonNativeGatesWithPulses": false,
    "validationParameters": {
      "MAX_SCALE": 4,
      "MAX_AMPLITUDE": 1,
      "PERMITTED_FREQUENCY_DIFFERENCE": 400000000
    }
  }
}
```

前面的字段详细说明了以下内容：

 **端口：**

描述了在 QPU 上声明的预制外部 (`extern`) 设备端口以及给定端口的相关属性。此结构中列出的所有端口都预先声明为用户提交的 `OpenQASM 3.0` 程序中的有效标识符。端口的其他属性包括：
+ 端口 ID (portId)
  + 在 OpenQASM 3.0 中声明为标识符的端口名称。
+ 方向 (direction)
  + 端口的方向。驱动端口传输脉冲（“tx”方向），而测量端口接收脉冲（“rx”方向）。
+ 端口类型 (portType)
  + 此端口负责的操作类型（例如，驱动、捕获或 ff - fast-flux）。
+ Dt (dt)
  + 表示给定端口上的单个采样时间步长，以秒为单位。
+ 量子比特映射 (qubitMappings)
  + 与给定端口关联的量子比特。
+ 中心频率 (centerFrequencies)
  + 端口上所有预先声明或用户定义的帧的相关中心频率列表。有关更多信息，请参阅“帧”。
+ QHP 特定属性 () qhpSpecificProperties
  + 一张可选地图，详细介绍有关 QHP 特定端口的现有属性。

 **帧：**

描述了在 QPU 上声明的预制外部帧以及与这些帧相关的属性。此结构中列出的所有帧都预先声明为用户提交的 `OpenQASM 3.0` 程序中的有效标识符。帧的其他属性包括：
+ 帧编号 (frameId)
  + 在 OpenQASM 3.0 中声明为标识符的帧名称。
+ 端口 ID (portId)
  + 帧的关联硬件端口。
+ 频率 (frequency)
  + 帧的默认初始频率。
+ 中心频率 (centerFrequency)
  + 帧频率带宽的中心。通常，只能将帧调整到中心频率周围的特定带宽。因此，频率调整应保持在中心频率的给定增量之内。您可以在验证参数中找到带宽值。
+ 阶段 (phase)
  + 帧的默认初始阶段。
+ 关联门 (associatedGate)
  + 与给定帧关联的门。
+ 量子比特映射 (qubitMappings)
  + 与给定帧关联的量子比特。
+ QHP 特定属性 () qhpSpecificProperties
  + 一张可选地图，详细说明有关 QHP 特定帧的现有属性。

 **SupportsDynamicFrames:** 

描述了帧是否可以通过 OpenPulse `newframe` 函数在 `cal` 或 `defcal` 块中声明。如果该值为 false，则只能在程序中使用帧结构中列出的帧。

 **SupportedFunctions:** 

除了给定函数的关联参数、参数类型和返回类型之外，还描述了设备支持的 OpenPulse 函数。要查看使用这些OpenPulse函数的示例，请参阅[OpenPulse规范](https://openqasm.com/language/openpulse.html)。目前，Braket 支持：
+ shift\$1phase
  + 按指定值移动帧的相位
+ set\$1phase
  + 将帧的相位设置为指定值
+ swap\$1phases
  + 在两帧之间交换相位。
+ shift\$1frequency
  + 按指定值移动帧的频率
+ set\$1frequency
  + 将帧频设置为指定值
+ play
  + 安排波形
+ capture\$1v0
  + 将捕获帧上的值返回到位寄存器

 **SupportedQhpTemplateWaveforms:** 

描述了设备上可用的预先构造的波形函数以及相关的参数和类型。默认情况下，Braket Pulse 在所有设备上提供预先构造的波形例程，它们是：

 ***Constant*** 

![\[显示参数为 t、tau 和 iq 的常数函数的数学表达式，其中：输出始终等于 iq。\]](http://docs.aws.amazon.com/zh_cn/braket/latest/developerguide/images/ConstantFunction.png)


 `τ` 是波形长度，`iq` 是一个复数。

```
def constant(length, iq)
```

 ***Gaussian*** 

![\[显示参数为 t、tau、sigma、A=1 和 zae=0 的高斯函数的数学方程。\]](http://docs.aws.amazon.com/zh_cn/braket/latest/developerguide/images/GaussianFunction.png)


 `τ` 是波形长度，`σ` 是高斯宽度，`A` 是振幅。如果将 `ZaE` 设置为 `True`，则对 Gaussian 进行偏移和重新缩放，使其在波形的开头和结尾处都等于零，且最大达到 `A`。

```
def gaussian(length, sigma, amplitude=1, zero_at_edges=False)
```

 ***DRAG Gaussian*** 

![\[参数为 t、tau、sigma、beta、A=1 和 zae=0 的阻力高斯分布的数学方程。\]](http://docs.aws.amazon.com/zh_cn/braket/latest/developerguide/images/DRAGGaussianFunction.png)


 `τ` 是波形长度，`σ` 是高斯宽度，`β` 是自由参数，`A` 是振幅。如果将 `ZaE` 设置为 `True`，则对绝热门导数去除（DRAG）Gaussian 进行偏移和重新缩放，使其在波形的开头和结尾处都等于零，实数部分最大达到 `A`。有关阻力波形的更多信息，请参阅论文 [Simple Pulses for Elimination of Leakage in Weakly Nonlinear Qubits](https://doi.org/10.1103/PhysRevLett.103.110501)。

```
def drag_gaussian(length, sigma, beta, amplitude=1, zero_at_edges=False)
```

 ***Erf Square*** 

![\[Erf Square 分布的数学方程，含参数 t、长度、宽度、sigma、A=1 和 zae=0。\]](http://docs.aws.amazon.com/zh_cn/braket/latest/developerguide/images/ErfSquareFunction.PNG)


其中：`L` 是长度，`W` 是波形宽度，`σ` 定义了边缘上升和下降的速度，`t1​=(L−W)/2` 和 `t22=(L+W)/2`，`A` 是振幅。如果将 `ZaE` 设置为 `True`，则对 Gaussian 进行偏移和重新缩放，使其在波形的开头和结尾处都等于零，且最大达到 `A`。以下方程是波形的重新缩放版本。

![\[参数为 zae=1 的重新缩放的 Erf Square 分布数学方程。\]](http://docs.aws.amazon.com/zh_cn/braket/latest/developerguide/images/RescaledErfSquareFunction.PNG)


其中：`a=erf(W/2σ)` 且 `b=erf(-t1​/σ)/2+erf(t2​/σ)/2`。

```
def erf_square(length, width, sigma, amplitude=1, zero_at_edges=False)
```

 **SupportsLocalPulseElements:** 

描述了脉冲元素（如端口、帧和波形）是否可以在 `defcal` 块中进行本地定义。如果值为 `false`，则必须以 `cal` 块形式定义元素。

 **SupportsNonNativeGatesWithPulses:** 

描述了我们是否可以将非原生门与脉冲程序结合使用。例如，如果不先通过 `defcal` 为所使用的量子比特定义门，就不能像程序中的 `H` 门一样使用非原生门。您可以在“设备功能”下方找到原生门 `nativeGateSet` 键列表。

 **ValidationParameters:** 

描述了脉冲元件验证边界，包括：
+ （任意及预先构造的）波形的最大扩展/最大振幅值
+ 所提供中心频率的最大频率带宽（单位为赫兹）
+  length/duration 以秒为单位的最小脉冲
+ 以秒为单位的最 length/duration 大脉冲

## OpenQASM 支持的操作、结果和结果类型
<a name="braket-openqasm-supported-operations-results-result-types"></a>

要了解每台设备支持哪些 OpenQASM 3.0 功能，可以参考设备功能输出 `action` 字段中的 `braket.ir.openqasm.program` 键。例如，以下是 Braket 状态向量模拟器 SV1 支持的操作和结果类型。

```
...
  "action": {
    "braket.ir.jaqcd.program": {
      ...
    },
 "braket.ir.openqasm.program": {
      "version": [
        "1.0"
      ],
      "actionType": "braket.ir.openqasm.program",
      "supportedOperations": [
        "ccnot",
        "cnot",
        "cphaseshift",
        "cphaseshift00",
        "cphaseshift01",
        "cphaseshift10",
        "cswap",
        "cy",
        "cz",
        "h",
        "i",
        "iswap",
        "pswap",
        "phaseshift",
        "rx",
        "ry",
        "rz",
        "s",
        "si",
        "swap",
        "t",
        "ti",
        "v",
        "vi",
        "x",
        "xx",
        "xy",
        "y",
        "yy",
        "z",
        "zz"
      ],
      "supportedPragmas": [
        "braket_unitary_matrix"
      ],
      "forbiddenPragmas": [],
      "maximumQubitArrays": 1,
      "maximumClassicalArrays": 1,
      "forbiddenArrayOperations": [
        "concatenation",
        "negativeIndex",
        "range",
        "rangeWithStep",
        "slicing",
        "selection"
      ],
      "requiresAllQubitsMeasurement": true,
      "supportsPhysicalQubits": false,
      "requiresContiguousQubitIndices": true,
      "disabledQubitRewiringSupported": false,
      "supportedResultTypes": [
        {
          "name": "Sample",
          "observables": [
            "x",
            "y",
            "z",
            "h",
            "i",
            "hermitian"
          ],
          "minShots": 1,
          "maxShots": 100000
        },
        {
          "name": "Expectation",
          "observables": [
            "x",
            "y",
            "z",
            "h",
            "i",
            "hermitian"
          ],
          "minShots": 0,
          "maxShots": 100000
        },
        {
          "name": "Variance",
          "observables": [
            "x",
            "y",
            "z",
            "h",
            "i",
            "hermitian"
          ],
          "minShots": 0,
          "maxShots": 100000
        },
        {
          "name": "Probability",
          "minShots": 1,
          "maxShots": 100000
        },
        {
          "name": "Amplitude",
          "minShots": 0,
          "maxShots": 0
        }
        {
          "name": "AdjointGradient",
          "minShots": 0,
          "maxShots": 0
        }
      ]
    }
  },
...
```

# 使用 OpenQASM 3.0 模拟噪声
<a name="braket-openqasm-noise-simulation"></a>

要使用 Open 模拟噪声QASM3，可以使用 *pragma* 指令添加噪音运算符。例如，要模拟之前提供的 [GHZ 程序](braket-openqasm-create-submit-task.md#braket-openqasm-example-program)的噪声版本，您可以提交以下 OpenQASM 程序。

```
// ghz.qasm
// Prepare a GHZ state
OPENQASM 3;

qubit[3] q;
bit[3] c;

h q[0];
#pragma braket noise depolarizing(0.75) q[0] cnot q[0], q[1];
#pragma braket noise depolarizing(0.75) q[0]
#pragma braket noise depolarizing(0.75) q[1] cnot q[1], q[2];
#pragma braket noise depolarizing(0.75) q[0]
#pragma braket noise depolarizing(0.75) q[1]

c = measure q;
```

以下列表给出了所有受支持的编译指示噪声运算符的规格。

```
#pragma braket noise bit_flip(<float in [0,1/2]>) <qubit>
#pragma braket noise phase_flip(<float in [0,1/2]>) <qubit>
#pragma braket noise pauli_channel(<float>, <float>, <float>)  <qubit>
#pragma braket noise depolarizing(<float in [0,3/4]>) <qubit>
#pragma braket noise two_qubit_depolarizing(<float in [0,15/16]>) <qubit>, <qubit>
#pragma braket noise two_qubit_dephasing(<float in [0,3/4]>) <qubit>, <qubit>
#pragma braket noise amplitude_damping(<float in [0,1]>) <qubit>
#pragma braket noise generalized_amplitude_damping(<float in [0,1]> <float in [0,1]>)  <qubit>
#pragma braket noise phase_damping(<float in [0,1]>) <qubit>
#pragma braket noise kraus([[<complex m0_00>, ], ...], [[<complex m1_00>, ], ...], ...) <qubit>[, <qubit>]     // maximum of 2 qubits and maximum of 4 matrices for 1 qubit, 16 for 2
```

## Kraus 运算符
<a name="braket-openqasm-kraus-operator"></a>

要生成 Kraus 运算符，可以遍历矩阵列表，将矩阵的每个元素打印为复杂表达式。

使用克劳斯运算符时，请记住以下几点：
+ qubits 的数量不得超过 2。[架构中的当前定义](https://github.com/aws/amazon-braket-sdk-python/blob/0d28a8fa89263daf5d88bc706e79200d8dc091a8/src/braket/circuits/noises.py#L811-L814))设定了此限制。
+ 参数列表的长度必须是 8 的倍数。这意味着它必须仅由 2x2 矩阵组成。
+ 总长度不超过 22\$1num\$1qubits 矩阵。这意味着，1 个 qubit 有 4 个矩阵，2 个 qubits 有 16 个矩阵。
+ 所有提供的矩阵均为[完全正迹线保持(CPTP）](https://github.com/aws/amazon-braket-sdk-python/blob/0d28a8fa89263daf5d88bc706e79200d8dc091a8/src/braket/circuits/quantum_operator_helpers.py#L94-L108)。
+ Kraus 运算符及其转置共轭的乘积需要相加得出一个单位矩阵。

# Qubit 使用 OpenQASM 3.0 重新布线
<a name="braket-openqasm-rewire-qubits"></a>

[Amazon Braket Rigetti 支持设备上的 OpenQASM 中的物理 qubit 符号（要了解更多信息，请参阅本](https://github.com/openqasm/openqasm/blob/main/source/language/types.rst)页面）。在将物理 qubits 与[原生重新布线策略](https://pyquil-docs.rigetti.com/en/v2.28.1/compiler.html#naive)配合使用时，请确保 qubits 已连接到所选设备上。或者，如果改用 qubit 寄存器，则默认情况下，Rigetti 设备上会启用部分重新布线策略。

```
// ghz.qasm
// Prepare a GHZ state
OPENQASM 3;

h $0;
cnot $0, $1;
cnot $1, $2;

measure $0;
measure $1;
measure $2;
```

# 使用 OpenQASM 3.0 进行逐字记录编译
<a name="braket-openqasm-verbatim-compilation"></a>

当您在 Rigetti 和 IonQ 等供应商提供的量子计算机上运行量子电路时，您可以指示编译器完全按照定义运行您的电路，而无需做出任何修改。此功能称为*逐字记录编译*。使用Rigetti设备，您可以精确地指定要保留的内容——要么是整个电路，要么仅保留其中的特定部分。如果仅保留电路的特定部分，需要在保留区域内使用原生门。目前，IonQ 仅支持整个电路的逐字记录编译，因此电路中的每条指令都需要放在逐字记录框中。

使用 OpenQASM，您可以围绕代码框明确指定逐字记录编译指示，然后该代码保持不变，不会被硬件的低级编译例程优化。以下代码示例演示了如何使用 `#pragma braket verbatim` 指令实现这一点。

```
OPENQASM 3;

bit[2] c;

#pragma braket verbatim
box{
    rx(0.314159) $0;
    rz(0.628318) $0, $1;
    cz $0, $1;
}

c[0] = measure $0;
c[1] = measure $1;
```

有关逐字编译过程的更多详细信息，包括示例和最佳实践，请参阅 github 存储库中提供的 [Verbatim 编译](https://github.com/aws/amazon-braket-examples/blob/main/examples/braket_features/Verbatim_Compilation.ipynb)示例笔记本。 amazon-braket-examples

## Braket 控制台
<a name="braket-openqasm-braket-console"></a>

OpenQASM 3.0 任务可用，可在 Amazon Braket 控制台中进行管理。在控制台上，您在 OpenQASM 3.0 中提交量子任务的体验与提交现有量子任务的体验相同。

## 其他资源
<a name="braket-openqasm-more-resources"></a>

OpenQASM 在所有 Amazon Braket 区域中都可用。

[有关在 Amazon Braket 上开始使用 OpenQasm 的笔记本示例，请参阅 Braket 教程。 GitHub](https://github.com/aws/amazon-braket-examples/blob/main/examples/braket_features/Getting_Started_with_OpenQASM_on_Braket.ipynb)

# 使用 OpenQASM 3.0 计算梯度
<a name="braket-openqasm-computing-gradients"></a>

在 `shots=0`（精确）模式下运行时，Amazon Braket 支持在按需模拟器和本地模拟器上计算梯度。通过使用伴随微分法，可以实现这一点。要指定所计算的梯度，可以提供相应的编译指示，如以下示例中的代码所示。

```
OPENQASM 3.0;
input float alpha;

bit[2] b;
qubit[2] q;

h q[0];
h q[1];
rx(alpha) q[0];
rx(alpha) q[1];
b[0] = measure q[0];
b[1] = measure q[1];

#pragma braket result adjoint_gradient h(q[0]) @ i(q[1]) alpha
```

您不必明确列出所有单独的参数，可以在编译指示中指定 `all` 关键字。这样可以计算出所列的所有参数的梯度，当 `input` 参数数量非常大时，这可能是一个方便的选择。在这种情况下，编译指示与以下示例中的代码类似。

```
#pragma braket result adjoint_gradient h(q[0]) @ i(q[1]) all
```

Amazon Braket 的 OpenQASM 3.0 实现支持所有可观察类型，包括单个运算符、张量乘积、哈密特量可观测值和 `Sum` 可观测值。计算梯度时要使用的特定运算符必须封装在 `expectation()` 函数中，而且必须明确指定可观测值的每一项所作用的量子比特。

# 使用 OpenQASM 3.0 测量特定的量子比特
<a name="braket-openqasm-measure-qubits"></a>

Amazon Braket 提供的局部状态向量模拟器和局部密度矩阵模拟器支持提交可以选择性测量电路量子比特子集的 OpenQASM 程序。这种能力通常被称为部分测量，可以更有针对性、更高效地进行量子计算。例如，在以下代码片段中，您可以创建一个双量子比特电路，并选择仅测量第一个量子比特，而不测量第二个量子比特。

```
partial_measure_qasm = """
OPENQASM 3.0;
bit[1] b;
qubit[2] q;
h q[0];
cnot q[0], q[1];
b[0] = measure q[0];
"""
```

在该例中，我们有一个包含两个量子比特的量子电路，`q[0]` 和 `q[1]`，但是我们只对测量第一个量子比特的状态感兴趣。这是通过直线 `b[0] = measure q[0]` 来实现的，它测量的是 quit[0] 的状态并将结果存储在经典位 b[0] 中。要运行此部分测量场景，我们可以在 Amazon Braket 提供的本地状态向量模拟器上运行以下代码。

```
from braket.devices import LocalSimulator

local_sim = LocalSimulator()
partial_measure_local_sim_task = local_sim.run(OpenQASMProgram(source=partial_measure_qasm), shots = 10)
partial_measure_local_sim_result = partial_measure_local_sim_task.result()
print(partial_measure_local_sim_result.measurement_counts)
print("Measured qubits: ", partial_measure_local_sim_result.measured_qubits)
```

您可以通过检查设备动作属性中的 `requiresAllQubitsMeasurement` 字段来检查设备是否支持部分测量；如果是 `False`，则支持部分测量。

```
from braket.devices import Devices
            
AwsDevice(Devices.Rigetti.Ankaa3).properties.action['braket.ir.openqasm.program'].requiresAllQubitsMeasurement
```

这里，`requiresAllQubitsMeasurement` 是 `False`，这表明并非所有量子比特都必须进行测量。