SDK에서 회로를 구성하세요. - Amazon Braket

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

SDK에서 회로를 구성하세요.

이 섹션에서는 회로 정의, 사용 가능한 게이트 보기, 회로 확장, 각 장치가 지원하는 게이트 보기의 예를 제공합니다. 또한 회로를 수동으로 할당하는 방법qubits, 컴파일러에 회로를 정의된 대로 정확하게 실행하도록 지시하는 방법, 노이즈 시뮬레이터로 잡음이 많은 회로를 구성하는 방법에 대한 지침도 포함되어 있습니다.

또한 Braket에서 특정 QPU를 사용하는 다양한 게이트의 펄스 레벨에서 작업할 수 있습니다. 자세한 내용은 Amazon Braket의 펄스 제어를 참조하십시오.

게이트 및 회로

양자 게이트 및 회로는 Amazon Braket Python SDK braket.circuits클래스에 정의되어 있습니다. SDK에서 를 호출하여 새 회로 객체를 인스턴스화할 수 있습니다. Circuit()

예: 회로 정의

이 예제는 표준 단일 큐비트 Hadamard 게이트와 2큐비트 CNOT 게이트로 구성된 네 개의 샘플 회로 qubits (,, 및 라고 q0 q3 표시됨) 를 정의하는 것으로 시작합니다. q1 q2 다음 예제와 같이 함수를 호출하여 이 회로를 시각화할 수 있습니다. 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])

예: 기존 회로 확장

명령을 추가하여 기존 회로를 확장할 수 있습니다. InstructionAn은 양자 장치에서 수행해야 하는 양자 작업을 설명하는 양자 지침입니다. 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']

지원되는 게이트를 퀀텀 하드웨어에서 실행하려면 먼저 네이티브 게이트로 컴파일해야 할 수 있습니다. 회로를 제출하면 Amazon Braket은 이 컴파일을 자동으로 수행합니다.

예: 기기에서 지원하는 네이티브 게이트의 충실도를 프로그래밍 방식으로 검색합니다.

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 SDK를 사용하면 선택한 양자 처리 장치 (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)

자세한 내용은 이 노트북의 Amazon Braket 예제 또는 보다 구체적으로 설명하자면 QPU 디바이스에 GitHub 큐비트 할당을 참조하십시오.

참고

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

축어 컴파일

RigettiIonQ, 또는 Oxford Quantum Circuits (OQC) 에서 양자 컴퓨터의 양자 회로를 실행하면 컴파일러가 회로를 수정하지 않고 정의된 대로 정확하게 실행하도록 지시할 수 있습니다. 축어 컴파일을 사용하면 전체 회로를 지정된 대로 정확하게 보존 (RigettiIonQ, 및 지원OQC) 하거나 회로의 특정 부분만 보존 (only 지원) 하도록 지정할 수 있습니다. Rigetti 하드웨어 벤치마킹 또는 오류 완화 프로토콜용 알고리즘을 개발할 때는 하드웨어에서 실행 중인 게이트 및 회로 레이아웃을 정확하게 지정할 수 있는 옵션이 필요합니다. 축어 컴파일을 사용하면 특정 최적화 단계를 해제하여 컴파일 프로세스를 직접 제어할 수 있으므로 회로가 설계된 대로 정확하게 실행되도록 할 수 있습니다.

Verbatim 컴파일은 현재Rigetti,IonQ, Oxford Quantum Circuits (OQC) 기기에서 지원되며 네이티브 게이트를 사용해야 합니다. 축어 컴파일을 사용하는 경우 장치의 토폴로지를 확인하여 연결된 상태에서 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

축어 컴파일 사용과 관련된 추가 비용은 없습니다. Braket QPU 디바이스, 노트북 인스턴스 및 온디맨드 시뮬레이터에서 실행된 양자 작업에 대해서는 Amazon Braket 가격 책정 페이지에 명시된 현재 요금을 기준으로 계속 요금이 부과됩니다. 자세한 내용은 Verbatim 컴파일 예제 노트북을 참조하십시오.

참고

OpenQASM을 사용하여 OQC 및 IonQ 장치의 회로를 작성하고 회로를 물리적 큐비트에 직접 매핑하려면 OpenQASM에서 disableQubitRewiring 플래그를 완전히 무시하므로 를 사용해야 합니다. #pragma braket verbatim

노이즈 시뮬레이션

로컬 노이즈 시뮬레이터를 인스턴스화하려면 다음과 같이 백엔드를 변경할 수 있습니다.

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)

Or

예제 2

task = device.run(circ_noise, s3_location)

더 많은 예제는 Braket 입문용 노이즈 시뮬레이터 예제를 참조하십시오.