在 SDK 中建構電路 - Amazon Braket

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

在 SDK 中建構電路

本節提供定義電路、檢視可用閘極、延伸電路以及檢視每個裝置支援的閘極的範例。它還包含有關如何手動分配qubits,指示編譯器完全按照定義運行電路,以及使用噪聲模擬器構建嘈雜的電路的說明。

您還可以在 Braket 的脈衝級別上工作,用於具有某些 QPU 的各種門。如需詳細資訊,請參閱 Amazon Braket 上的脈衝控制

門和電路

量子閘和電路是在Amazon布拉克特 Python SDK 的braket.circuits類別中定義的。從 SDK 中,您可以通過調Circuit()用實例化新的電路對象。

範例:定義電路

此範例從定義四個樣本電路開始 qubits (標籤為、、和q3) q0 q1q2,該電路由標準的單量子位元 Hadamard 閘和雙量子位元 CNT 閘極組成。您可以透過呼叫print函式來視覺化此電路,如下列範例所示。

# import the circuit module from braket.circuits import Circuit # define circuit with 4 qubits my_circuit = Circuit().h(range(4)).cnot(control=0, target=2).cnot(control=1, target=3) print(my_circuit)
T : |0| 1 | q0 : -H-C--- | q1 : -H-|-C- | | q2 : -H-X-|- | q3 : -H---X- T : |0| 1 |

範例:定義參數化電路

在此示例中,我們定義了一個具有依賴於自由參數的門的電路。我們可以指定這些參數的值來創建一個新的電路,或者在提交電路時,在某些設備上作為量子任務運行。

from braket.circuits import Circuit, FreeParameter #define a FreeParameter to represent the angle of a gate alpha = FreeParameter("alpha") #define a circuit with three qubits my_circuit = Circuit().h(range(3)).cnot(control=0, target=2).rx(0, alpha).rx(1, alpha) print(my_circuit)

您可以通過提供單個float(這是所有空閒參數將採用的值)或將每個參數值指定給電路的關鍵字參數來創建一個新的非參數化電路,如下所示。

my_fixed_circuit = my_circuit(1.2) my_fixed_circuit = my_circuit(alpha=1.2)

請注意,my_circuit未經修改,因此您可以使用它來實例化許多具有固定參數值的新電路。

範例:修改電路中的灌嘴

以下範例定義了具有使用控制和功率修改器的閘極的電路。您可以使用這些修改來建立新灌嘴,例如受控灌Ry嘴。

from braket.circuits import Circuit # Create a bell circuit with a controlled x gate my_circuit = Circuit().h(0).x(control=0, target=1) # Add a multi-controlled Ry gate of angle .13 my_circuit.ry(angle=.13, target=2, control=(0, 1)) # Add a 1/5 root of X gate my_circuit.x(0, power=1/5) print(my_circuit)

門修飾符僅在本地模擬器上受支持。

範例:查看所有可用的灌嘴

下面的例子顯示了如何查看 Amazon Braket 中所有可用的灌嘴。

from braket.circuits import Gate # print all available gates in Amazon Braket gate_set = [attr for attr in dir(Gate) if attr[0].isupper()] print(gate_set)

此代碼的輸出列出了所有門。

['CCNot', 'CNot', 'CPhaseShift', 'CPhaseShift00', 'CPhaseShift01', 'CPhaseShift10', 'CSwap', 'CV', 'CY', 'CZ', 'ECR', 'GPi', 'GPi2', 'H', 'I', 'ISwap', 'MS', 'PSwap', 'PhaseShift', 'PulseGate', 'Rx', 'Ry', 'Rz', 'S', 'Si', 'Swap', 'T', 'Ti', 'Unitary', 'V', 'Vi', 'X', 'XX', 'XY', 'Y', 'YY', 'Z', 'ZZ']

這些閘門中的任何一個都可以通過調用該類型電路的方法來附加到電路中。例如,您可以打電話給circ.h(0)第一個 Hadamard 門添加。qubit

注意

將現地附加灌嘴,下面的範例將上一個範例中列示的所有灌嘴加入至同一電路。

circ = Circuit() # toffoli gate with q0, q1 the control qubits and q2 the target. circ.ccnot(0, 1, 2) # cnot gate circ.cnot(0, 1) # controlled-phase gate that phases the |11> state, cphaseshift(phi) = diag((1,1,1,exp(1j*phi))), where phi=0.15 in the examples below circ.cphaseshift(0, 1, 0.15) # controlled-phase gate that phases the |00> state, cphaseshift00(phi) = diag([exp(1j*phi),1,1,1]) circ.cphaseshift00(0, 1, 0.15) # controlled-phase gate that phases the |01> state, cphaseshift01(phi) = diag([1,exp(1j*phi),1,1]) circ.cphaseshift01(0, 1, 0.15) # controlled-phase gate that phases the |10> state, cphaseshift10(phi) = diag([1,1,exp(1j*phi),1]) circ.cphaseshift10(0, 1, 0.15) # controlled swap gate circ.cswap(0, 1, 2) # swap gate circ.swap(0,1) # phaseshift(phi)= diag([1,exp(1j*phi)]) circ.phaseshift(0,0.15) # controlled Y gate circ.cy(0, 1) # controlled phase gate circ.cz(0, 1) # Echoed cross-resonance gate applied to q0, q1 circ = Circuit().ecr(0,1) # X rotation with angle 0.15 circ.rx(0, 0.15) # Y rotation with angle 0.15 circ.ry(0, 0.15) # Z rotation with angle 0.15 circ.rz(0, 0.15) # Hadamard gates applied to q0, q1, q2 circ.h(range(3)) # identity gates applied to q0, q1, q2 circ.i([0, 1, 2]) # iswap gate, iswap = [[1,0,0,0],[0,0,1j,0],[0,1j,0,0],[0,0,0,1]] circ.iswap(0, 1) # pswap gate, PSWAP(phi) = [[1,0,0,0],[0,0,exp(1j*phi),0],[0,exp(1j*phi),0,0],[0,0,0,1]] circ.pswap(0, 1, 0.15) # X gate applied to q1, q2 circ.x([1, 2]) # Y gate applied to q1, q2 circ.y([1, 2]) # Z gate applied to q1, q2 circ.z([1, 2]) # S gate applied to q0, q1, q2 circ.s([0, 1, 2]) # conjugate transpose of S gate applied to q0, q1 circ.si([0, 1]) # T gate applied to q0, q1 circ.t([0, 1]) # conjugate transpose of T gate applied to q0, q1 circ.ti([0, 1]) # square root of not gate applied to q0, q1, q2 circ.v([0, 1, 2]) # conjugate transpose of square root of not gate applied to q0, q1, q2 circ.vi([0, 1, 2]) # exp(-iXX theta/2) circ.xx(0, 1, 0.15) # exp(i(XX+YY) theta/4), where theta=0.15 in the examples below circ.xy(0, 1, 0.15) # exp(-iYY theta/2) circ.yy(0, 1, 0.15) # exp(-iZZ theta/2) circ.zz(0, 1, 0.15) # IonQ native gate GPi with angle 0.15 applied to q0 circ.gpi(0, 0.15) # IonQ native gate GPi2 with angle 0.15 applied to q0 circ.gpi2(0, 0.15) # IonQ native gate MS with angles 0.15, 0.15, 0.15 applied to q0, q1 circ.ms(0, 1, 0.15, 0.15, 0.15)

除了預先定義的灌嘴組之外,您還可以將自定義的單一灌嘴套用至電路。這些可以是單量子位門(如下面的源代碼所示)或應用於參數qubits定義的多量子位門。targets

import numpy as np # apply a general unitary my_unitary = np.array([[0, 1],[1, 0]]) circ.unitary(matrix=my_unitary, targets=[0])

範例:延伸既有電路

您可以透過加入指示來延伸既有電路。A Instruction 是一個量子指令,描述量子任務在量子設備上執行。 Instruction運算子Gate僅包括類型的物件。

# import the Gate and Instruction modules from braket.circuits import Gate, Instruction # add instructions directly. circ = Circuit([Instruction(Gate.H(), 4), Instruction(Gate.CNot(), [4, 5])]) # or with add_instruction/add functions instr = Instruction(Gate.CNot(), [0, 1]) circ.add_instruction(instr) circ.add(instr) # specify where the circuit is appended circ.add_instruction(instr, target=[3, 4]) circ.add_instruction(instr, target_mapping={0: 3, 1: 4}) # print the instructions print(circ.instructions) # if there are multiple instructions, you can print them in a for loop for instr in circ.instructions: print(instr) # instructions can be copied new_instr = instr.copy() # appoint the instruction to target new_instr = instr.copy(target=[5]) new_instr = instr.copy(target_mapping={0: 5})

範例:檢視每個裝置支援的閘門

模擬器支持 Braket SDK 中的所有門,但 QPU 設備支持較小的子集。您可以在設備屬性中找到設備的支持門。以下是 iONQ 裝置的範例:

# import the device module from braket.aws import AwsDevice device = AwsDevice("arn:aws:braket:us-east-1::device/qpu/ionq/Harmony") # get device name device_name = device.name # show supportedQuantumOperations (supported gates for a device) device_operations = device.properties.dict()['action']['braket.ir.openqasm.program']['supportedOperations'] print('Quantum Gates supported by {}:\n {}'.format(device_name, device_operations))
Quantum Gates supported by the Harmony device: ['x', 'y', 'z', 'rx', 'ry', 'rz', 'h', 'cnot', 's', 'si', 't', 'ti', 'v', 'vi', 'xx', 'yy', 'zz', 'swap', 'i']

支援的閘可能需要先編譯成原生閘,才能在量子硬體上執行。當您提交電路時,AmazonBraket 會自動執行此編譯。

範例:以程式設計方式擷取裝置支援的原生閘門的擬真度

您可以在 Braket 主控台的「裝置」頁面上檢視擬真度資訊。有時,以編程方式訪問相同的信息是有幫助的。下面的代碼演示了如何提取一個 QPU 的兩個qubit門之間的兩個門保真度。

# import the device module from braket.aws import AwsDevice device = AwsDevice("arn:aws:braket:us-west-1::device/qpu/rigetti/Aspen-M-3") #specify the qubits a=10 b=113 print(f"Fidelity of the XY gate between qubits {a} and {b}: ", device.properties.provider.specs["2Q"][f"{a}-{b}"]["fXY"])

局部測量

按照前面的例子,我們已經測量了量子電路中的所有量子比特。但是,可以測量單個量子位或量子位的子集。

範例:測量量子位元的子集

在此示例中,我們通過在電路末端添加帶有目標量子位的measure指令來演示局部測量。

# Use the local state vector simulator device = LocalSimulator() # Define an example bell circuit and measure qubit 0 circuit = Circuit().h(0).cnot(0, 1).measure(0) # Run the circuit task = device.run(circuit, shots=10) # Get the results result = task.result() # Print the circuit and measured qubits print(circuit) print() print("Measured qubits: ", result.measured_qubits)

手動qubit配置

當您從量子電腦上執行量子電路時Rigetti,您可以選擇性地使用手動qubit配置來控制用於演算法的哪qubits些電路。Amazon Braket 主控台Amazon Braket 開發套件可協助您檢查所選量子處理單元 (QPU) 裝置的最新校準資料,以便您選擇最qubits適合實驗的項目。

手動qubit配置可讓您更精確地執行電路,並調查個別qubit屬性。研究人員和高級用戶根據最新的設備校準數據優化其電路設計,並可以獲得更準確的結果。

下面的例子演示了如何qubits明確分配。

circ = Circuit().h(0).cnot(0, 7) # Indices of actual qubits in the QPU my_task = device.run(circ, s3_location, shots=100, disable_qubit_rewiring=True)

如需詳細資訊,請參閱本筆記本上 GitHub或更具體的 Amazon Braket 範例:在 QPU 裝置上配置量子位元

注意

編OQC譯器不支援設定disable_qubit_rewiring=True。將此旗標設定為會True產生下列錯誤:An error occurred (ValidationException) when calling the CreateQuantumTask operation: Device arn:aws:braket:eu-west-2::device/qpu/oqc/Lucy does not support disabled qubit rewiring

逐字编译

當您從Rigetti、、或 Oxford Quantum Circuits (OQC) 在量子電腦上執行量子電路時IonQ,您可以指示編譯器完全按照定義執行電路,而無需進行任何修改。使用逐字編譯,您可以指定按照指定的方式精確保留整個電路(由RigettiIonQ、和支持OQC),或者僅保留其中的特定部分(Rigetti僅受支持)。在開發硬體基準測試或錯誤緩解通訊協定的演算法時,您需要選擇精確指定您在硬體上執行的閘道和電路配置。逐字彙編可讓您直接控制編譯程序,方法是關閉某些最佳化步驟,從而確保您的電路完全按照設計執行。

、和 Oxford Quantum Circuits (OQC) 裝置目前支援逐字編譯 RigettiIonQ,且需要使用原生閘門。使用逐字編譯時,建議檢查設備的拓撲結構,以確保在連接時調用門,qubits並且電路使用硬件上支持的本機門。下列範例會示範如何以程式設計方式存取裝置支援的原生閘道清單。

device.properties.paradigm.nativeGateSet

對於Rigetti,必須通過設置與逐字編譯一起使disableQubitRewiring=True用來關閉qubit重新佈線。如果disableQubitRewiring=False在編譯中使用逐字框時設置,則量子電路驗證失敗並且不運行。

如果針對電路啟用逐字編譯,並在不支援該電路的 QPU 上執行,則會產生錯誤,指出不受支援的作業造成工作失敗。隨著越來越多的量子硬體本身支援編譯器函數,因此此功能將擴充以包含這些裝置。支持逐字編譯的設備在使用以下代碼查詢時將其包含為支持的操作。

from braket.aws import AwsDevice from braket.device_schema.device_action_properties import DeviceActionType device = AwsDevice("arn:aws:braket:us-west-1::device/qpu/rigetti/Aspen-M-3") device.properties.action[DeviceActionType.OPENQASM].supportedPragmas

使用逐字編譯沒有相關的額外費用。依據 Amazon Braket 定價頁面上指定的目前費率,繼續向您收取在 Braket QPU 裝置、筆記型電腦執行個體和隨需模擬器上執行的量子任務費用。如需詳細資訊,請參閱逐字編譯範例筆記本。

注意

如果您使用 OpenQASM 為OQC和IonQ設備編寫電路,並且希望將電路直接映射到物理量子位,則需要使用,#pragma braket verbatim因為 OpenQASM 完全忽略了該disableQubitRewiring標誌。

噪音模擬

要實例化本地噪聲模擬器,您可以按如下方式更改後端。

device = LocalSimulator(backend="braket_dm")

您可以通過兩種方式構建嘈雜的電路:

  1. 從下往上構建嘈雜的電路。

  2. 採取現有的無噪音電路,並在整個過程中注入噪音。

下面的例子顯示了使用具有去極化噪聲和自定義 Kraus 通道的簡單電路的方法。

# Bottom up approach # apply depolarizing noise to qubit 0 with probability of 0.1 circ = Circuit().x(0).x(1).depolarizing(0, probability=0.1) # create an arbitrary 2-qubit Kraus channel E0 = scipy.stats.unitary_group.rvs(4) * np.sqrt(0.8) E1 = scipy.stats.unitary_group.rvs(4) * np.sqrt(0.2) K = [E0, E1] # apply a two-qubit Kraus channel to qubits 0 and 2 circ = circ.kraus([0,2], K)
# Inject noise approach # define phase damping noise noise = Noise.PhaseDamping(gamma=0.1) # the noise channel is applied to all the X gates in the circuit circ = Circuit().x(0).y(1).cnot(0,2).x(1).z(2) circ_noise = circ.copy() circ_noise.apply_gate_noise(noise, target_gates = Gate.X)

執行電路與以前相同的使用者體驗,如下列兩個範例所示。

範例 1

task = device.run(circ, s3_location)

範例 2

task = device.run(circ_noise, s3_location)

有關更多示例,請參閱 Braket 入門噪聲模擬器示例