本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
在 中建構電路 SDK
本節提供定義電路、檢視可用閘道、延伸電路和檢視每個裝置支援之閘道的範例。它也包含如何手動配置的指示 qubits,指示編譯器完全依照定義執行您的電路,並使用雜訊模擬器建置吵雜的電路。
您也可以在 Braket 中的脈衝層級使用特定 處理各種閘道QPUs。如需詳細資訊,請參閱 Amazon Braket 上的脈衝控制。
閘道和電路
Quantum 閘道和電路是在 Amazon Braket Python 的braket.circuits
Circuit()
。
範例:定義電路
此範例從定義四個範例電路開始 qubits (已標記 q0
、q2
、 q1
和 q3
) 由標準、單qubit Hadamard 閘道和雙qubit CNOT閘道組成。您可以透過呼叫 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 煞車。
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)
除了預先定義的閘道集之外,您也可以將自行定義的單一閘道套用至電路。這些可以是單一 qubit 閘道 (如下列原始碼所示) 或套用至 的多 qubit 閘道 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])
範例:擴展現有電路
您可以新增指示來擴展現有的電路。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/Aria-1") # 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 Aria-1 device: ['x', 'y', 'z', 'rx', 'ry', 'rz', 'h', 'cnot', 's', 'si', 't', 'ti', 'v', 'vi', 'xx', 'yy', 'zz', 'swap']
支援的閘道可能需要編譯為原生閘道,才能在量子硬體上執行。當您提交電路時,Amazon Braket 會自動執行此編譯。
範例:以程式設計方式擷取裝置支援的原生閘道的保真度
您可以在 Braket 主控台的裝置頁面上檢視保真度資訊。有時,以程式設計方式存取相同的資訊會很有幫助。下列程式碼說明如何擷取這兩個 qubit 的兩個閘道之間的閘道保真度QPU。
# import the device module from braket.aws import AwsDevice device = AwsDevice("arn:aws:braket:us-west-1::device/qpu/rigetti/Ankaa-2") #specify the qubits a=10 b=11 print(f"Fidelity of the ISWAP gate between qubits {a} and {b}: ", device.properties.provider.specs["2Q"][f"{a}-{b}"]["fISWAP"])
部分測量
遵循上述範例,我們已測量量子電路中的所有 qubit。不過,您可以測量個別的 qubit 或一部分的 qubit。
範例:測量 qubit 的子集
在此範例中,我們將具有目標 qubit 的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 主控台
手動 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)
如需詳細資訊,請參閱 上的 Amazon Braket 範例 GitHub
逐字編譯
當您在以閘道為基礎的量子電腦上執行量子電路時,您可以指示編譯器完全依照定義執行電路,而不需進行任何修改。使用逐字編譯,您可以指定完全依照指定方式保留整個電路,或僅保留其特定部分 (由 支援 Rigetti 僅限 )。開發硬體基準測試或錯誤緩解通訊協定的演算法時,您需要選擇準確指定您在硬體上執行的閘道和電路配置。逐字編譯可讓您關閉特定最佳化步驟,直接控制編譯程序,進而確保電路完全按照設計執行。
目前支援逐字編譯 Rigetti, IonQ 和 IQM 裝置和 需要使用原生閘道。使用逐字編譯時,建議您檢查裝置的拓撲,以確保已連線時呼叫閘道 qubits 和 電路使用硬體上支援的原生閘道。下列範例示範如何以程式設計方式存取裝置支援的原生閘道清單。
device.properties.paradigm.nativeGateSet
用於 Rigetti, qubit 重新佈線必須透過設定 來關閉disableQubitRewiring=True
,以便與逐字編譯搭配使用。如果在編譯中使用逐字方塊時設定 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/Ankaa-2") device.properties.action[DeviceActionType.OPENQASM].supportedPragmas
使用逐字編譯沒有相關的額外費用。根據您在 Amazon Braket 定價
注意
如果您使用 OpenQASM 為 寫入電路 IonQ 裝置,而且您希望將電路直接映射到實體 qubit,您需要使用 ,#pragma braket verbatim
因為 Open 完全忽略disableQubitRewiring
了旗標QASM。
雜訊模擬
若要執行個體化本機雜訊模擬器,您可以變更後端,如下所示。
device = LocalSimulator(backend="braket_dm")
您可以透過兩種方式建置雜訊電路:
-
從下而上建置嘈雜電路。
-
採用現有的無雜訊電路,並在整個電路中注入雜訊。
下列範例顯示使用具有去極化雜訊的簡單電路和自訂 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 簡介雜訊模擬器範例