def test_from_braket_non_parameterized_two_qubit_gates(): braket_circuit = BKCircuit() instructions = [ Instruction(braket_gates.CNot(), target=[2, 3]), Instruction(braket_gates.Swap(), target=[3, 4]), Instruction(braket_gates.ISwap(), target=[2, 3]), Instruction(braket_gates.CZ(), target=(3, 4)), Instruction(braket_gates.CY(), target=(2, 3)), ] for instr in instructions: braket_circuit.add_instruction(instr) cirq_circuit = from_braket(braket_circuit) qreg = LineQubit.range(2, 5) expected_cirq_circuit = Circuit( ops.CNOT(*qreg[:2]), ops.SWAP(*qreg[1:]), ops.ISWAP(*qreg[:2]), ops.CZ(*qreg[1:]), ops.ControlledGate(ops.Y).on(*qreg[:2]), ) assert np.allclose( protocols.unitary(cirq_circuit), protocols.unitary(expected_cirq_circuit), )
def test_ir_instruction_level(testclass, subroutine_name, irclass, irsubclasses, kwargs): expected = irclass(**create_valid_ir_input(irsubclasses)) instruction = Instruction( **create_valid_instruction_input(testclass, irsubclasses, **kwargs)) actual = instruction.to_ir() assert actual == expected
def test_add_verbatim_box_with_target(cnot): circ = Circuit().add_verbatim_box(cnot, target=[10, 11]) expected = (Circuit().add_instruction( Instruction(compiler_directives.StartVerbatimBox())).add_instruction( Instruction(Gate.CNot(), [10, 11])).add_instruction( Instruction(compiler_directives.EndVerbatimBox()))) assert circ == expected
def _translate_cirq_operation_to_braket_instruction( op: cirq_ops.Operation, ) -> List[Instruction]: """Converts the Cirq operation to an equivalent Braket instruction or list of instructions. Args: op: Cirq operation to convert. Raises: ValueError: If the operation cannot be converted to Braket. """ nqubits = protocols.num_qubits(op) if nqubits == 1: return _translate_one_qubit_cirq_operation_to_braket_instruction(op) elif nqubits == 2: return _translate_two_qubit_cirq_operation_to_braket_instruction(op) elif nqubits == 3: qubits = [q.x for q in op.qubits] if isinstance(op.gate, cirq_ops.TOFFOLI): return [Instruction(braket_gates.CCNot(), qubits)] elif isinstance(op.gate, cirq_ops.FREDKIN): return [Instruction(braket_gates.CSwap(), qubits)] # Unsupported gates. else: raise ValueError( f"Unable to convert {op} to Braket. If you think this is a bug, " "you can open an issue on the Mitiq GitHub at" " https://github.com/unitaryfund/mitiq.")
def test_add_circuit_with_target_and_non_continuous_qubits(): widget = Circuit().h(5).h(50).h(100) circ = Circuit().add_circuit(widget, target=[1, 3, 5]) expected = (Circuit().add_instruction(Instruction( Gate.H(), 1)).add_instruction(Instruction( Gate.H(), 3)).add_instruction(Instruction(Gate.H(), 5))) assert circ == expected
def _translate_cirq_operation_to_braket_instruction( op: cirq_ops.Operation, ) -> List[Instruction]: """Converts the Cirq operation to an equivalent Braket instruction or list of instructions. Args: op: Cirq operation to convert. Raises: ValueError: If the operation cannot be converted to Braket. """ nqubits = protocols.num_qubits(op) if nqubits == 1: return _translate_one_qubit_cirq_operation_to_braket_instruction(op) elif nqubits == 2: return _translate_two_qubit_cirq_operation_to_braket_instruction(op) elif nqubits == 3: qubits = [q.x for q in op.qubits] if op == cirq_ops.TOFFOLI.on(*op.qubits): return [Instruction(braket_gates.CCNot(), qubits)] elif op == cirq_ops.FREDKIN.on(*op.qubits): return [Instruction(braket_gates.CSwap(), qubits)] else: _raise_cirq_to_braket_error(op) # Unsupported gates. else: _raise_cirq_to_braket_error(op)
def test_add_circuit_with_target(bell_pair): circ = Circuit().add_circuit(bell_pair, target=[10, 11]) expected = (Circuit().add_instruction(Instruction( Gate.H(), 10)).add_instruction(Instruction(Gate.CNot(), [10, 11])).add_result_type( ResultType.Probability([10, 11]))) assert circ == expected
def test_basis_rotation_instructions_multiple_result_types_same_targets(): circ = (Circuit().h(0).cnot(0, 1).expectation( observable=Observable.H() @ Observable.X(), target=[0, 1]).sample(observable=Observable.H() @ Observable.X(), target=[0, 1]).variance( observable=Observable.H() @ Observable.X(), target=[0, 1])) expected = [Instruction(Gate.Ry(-np.pi / 4), 0), Instruction(Gate.H(), 1)] assert circ.basis_rotation_instructions == expected
def test_add_verbatim_box_no_preceding(): circ = Circuit().add_verbatim_box(Circuit().h(0)).cnot(2, 3) expected = (Circuit().add_instruction( Instruction(compiler_directives.StartVerbatimBox())).add_instruction( Instruction(Gate.H(), 0)).add_instruction( Instruction( compiler_directives.EndVerbatimBox())).add_instruction( Instruction(Gate.CNot(), [2, 3]))) assert circ == expected
def test_equality(): instr_1 = Instruction(Gate.H(), 0) instr_2 = Instruction(Gate.H(), 0) other_instr = Instruction(Gate.CNot(), [0, 1]) non_instr = "non instruction" assert instr_1 == instr_2 assert instr_1 is not instr_2 assert instr_1 != other_instr assert instr_1 != non_instr
def test_add_verbatim_box_different_qubits(): circ = Circuit().h(1).add_verbatim_box(Circuit().h(0)).cnot(3, 4) expected = (Circuit().add_instruction(Instruction( Gate.H(), 1)).add_instruction(Instruction( compiler_directives.StartVerbatimBox())).add_instruction( Instruction(Gate.H(), 0)).add_instruction( Instruction( compiler_directives.EndVerbatimBox())).add_instruction( Instruction(Gate.CNot(), [3, 4]))) assert circ == expected
def test_basis_rotation_instructions_multiple_result_types_tensor_product_hermitian_qubit_count_2( ): circ = (Circuit().h(0).cnot(0, 1).cnot(1, 2).expectation( observable=Observable.I(), target=[1]).sample( observable=Observable.Hermitian(matrix=np.eye(4)) @ Observable.H(), target=[0, 1, 2]).variance(observable=Observable.H(), target=[2]).expectation( observable=Observable.I(), target=[0])) expected = [ Instruction(Gate.Unitary(matrix=np.eye(4)), target=[0, 1]), Instruction(Gate.Ry(-np.pi / 4), 2), ] assert circ.basis_rotation_instructions == expected
def test_to_ir(): expected_target = QubitSet([0, 1]) expected_ir = "foo bar value" class FooGate(Gate): def __init__(self): super().__init__(qubit_count=2, ascii_symbols=["foo", "bar"]) def to_ir(self, target): assert target == expected_target return expected_ir instr = Instruction(FooGate(), expected_target) assert instr.to_ir() == expected_ir
def test_from_braket_parameterized_single_qubit_gates(qubit_index): braket_circuit = BKCircuit() pgates = [ braket_gates.Rx, braket_gates.Ry, braket_gates.Rz, braket_gates.PhaseShift, ] angles = np.random.RandomState(11).random(len(pgates)) instructions = [ Instruction(rot(a), target=qubit_index) for rot, a in zip(pgates, angles) ] for instr in instructions: braket_circuit.add_instruction(instr) cirq_circuit = from_braket(braket_circuit) for i, op in enumerate(cirq_circuit.all_operations()): assert np.allclose(instructions[i].operator.to_matrix(), protocols.unitary(op)) qubit = LineQubit(qubit_index) expected_cirq_circuit = Circuit( ops.rx(angles[0]).on(qubit), ops.ry(angles[1]).on(qubit), ops.rz(angles[2]).on(qubit), ops.Z.on(qubit)**(angles[3] / np.pi), ) assert _equal(cirq_circuit, expected_cirq_circuit, require_qubit_equality=True)
def test_from_braket_three_qubit_gates(): braket_circuit = BKCircuit() instructions = [ Instruction(braket_gates.CCNot(), target=[1, 2, 3]), Instruction(braket_gates.CSwap(), target=[1, 2, 3]), ] for instr in instructions: braket_circuit.add_instruction(instr) cirq_circuit = from_braket(braket_circuit) qreg = LineQubit.range(1, 4) expected_cirq_circuit = Circuit(ops.TOFFOLI(*qreg), ops.FREDKIN(*qreg)) assert np.allclose( protocols.unitary(cirq_circuit), protocols.unitary(expected_cirq_circuit), )
def test_from_braket_parameterized_two_qubit_gates(): pgates = [ braket_gates.CPhaseShift, braket_gates.CPhaseShift00, braket_gates.CPhaseShift01, braket_gates.CPhaseShift10, braket_gates.PSwap, braket_gates.XX, braket_gates.YY, braket_gates.ZZ, braket_gates.XY, ] angles = np.random.RandomState(2).random(len(pgates)) instructions = [ Instruction(rot(a), target=[0, 1]) for rot, a in zip(pgates, angles) ] cirq_circuits = list() for instr in instructions: braket_circuit = BKCircuit() braket_circuit.add_instruction(instr) cirq_circuits.append(from_braket(braket_circuit)) for instr, cirq_circuit in zip(instructions, cirq_circuits): assert np.allclose(instr.operator.to_matrix(), cirq_circuit.unitary())
def apply(self, operations: Sequence[Operation], rotations: Sequence[Operation] = None, **run_kwargs) -> Circuit: """Instantiate Braket Circuit object.""" rotations = rotations or [] circuit = Circuit() # Add operations to Braket Circuit object for operation in operations + rotations: params = [ p.numpy() if isinstance(p, np.tensor) else p for p in operation.parameters ] gate = translate_operation(operation, params) dev_wires = self.map_wires(operation.wires).tolist() ins = Instruction(gate, dev_wires) circuit.add_instruction(ins) unused = set(range( self.num_wires)) - {int(qubit) for qubit in circuit.qubits} # To ensure the results have the right number of qubits for qubit in sorted(unused): circuit.i(qubit) return circuit
def test_getters(): target = [0, 1] operator = Gate.CNot() instr = Instruction(operator, target) assert instr.operator == operator assert instr.target == QubitSet([0, 1])
def many_layers(n_qubits: int, n_layers: int) -> Circuit: """ Function to return circuit with many layers. :param int n_qubits: number of qubits :param int n_layers: number of layers :return: Constructed easy circuit :rtype: Circuit """ qubits = range(n_qubits) circuit = Circuit() # instantiate circuit object for q in range(n_qubits): circuit.h(q) for layer in range(n_layers): if (layer + 1) % 100 != 0: for qubit in range(len(qubits)): angle = np.random.uniform(0, 2 * math.pi) gate = np.random.choice( [Gate.Rx(angle), Gate.Ry(angle), Gate.Rz(angle), Gate.H()], 1, replace=True )[0] circuit.add_instruction(Instruction(gate, qubit)) else: for q in range(0, n_qubits, 2): circuit.cnot(q, q + 1) for q in range(1, n_qubits - 1, 2): circuit.cnot(q, q + 1) return circuit
def test_subroutine_returns_instruction(): @circuit.subroutine() def foo(target): return Instruction(Gate.H(), 0) circ = Circuit().add(foo, 0) assert circ == Circuit(Instruction(Gate.H(), 0))
def test_basis_rotation_instructions_multiple_result_types_different_hermitian_targets( ): circ = (Circuit().h(0).cnot(0, 1).sample( observable=Observable.Hermitian(matrix=np.array([[1, 0], [0, -1]])), target=[1]).expectation( observable=Observable.Hermitian(matrix=np.array([[0, 1], [1, 0]])), target=[0])) expected = [ Instruction( Gate.Unitary(matrix=1.0 / np.sqrt(2.0) * np.array([[1.0, 1.0], [1.0, -1.0]], dtype=complex)), target=[0], ), Instruction(Gate.Unitary(matrix=np.array([[0, 1], [1, 0]])), target=[1]), ] assert circ.basis_rotation_instructions == expected
def test_subroutine_returns_iterable(): @circuit.subroutine() def foo(target): for qubit in range(1): yield Instruction(Gate.H(), qubit) circ = Circuit().add(foo, 0) assert circ == Circuit(Instruction(Gate.H(), 0))
def test_basis_rotation_instructions_multiple_result_types_tensor_product_probability( ): circ = (Circuit().h(0).cnot(0, 1).cnot(1, 2).probability([0, 1]).sample( observable=Observable.Z() @ Observable.Z() @ Observable.H(), target=[0, 1, 2]).variance(observable=Observable.H(), target=[2])) expected = [ Instruction(Gate.Ry(-np.pi / 4), 2), ] assert circ.basis_rotation_instructions == expected
def test_from_braket_raises_on_unsupported_gates(): for num_qubits in range(1, 5): braket_circuit = BKCircuit() instr = Instruction( braket_gates.Unitary(_rotation_of_pi_over_7(num_qubits)), target=list(range(num_qubits)), ) braket_circuit.add_instruction(instr) with pytest.raises(ValueError): from_braket(braket_circuit)
def test_subroutine_register(): # register a private method to avoid Sphinx docs picking this up @circuit.subroutine(register=True) def _foo(target): """this docstring will be added to the registered attribute""" return Instruction(Gate.H(), target) circ = Circuit()._foo(0) assert circ == Circuit(Instruction(Gate.H(), 0)) assert Circuit._foo.__doc__ == _foo.__doc__
def test_to_ir(): expected_target = QubitSet([0, 1]) expected_ir = "foo bar value" expected_ir_type = IRType.OPENQASM expected_serialization_properties = OpenQASMSerializationProperties( qubit_reference_type=QubitReferenceType.PHYSICAL) class FooGate(Gate): def __init__(self): super().__init__(qubit_count=2, ascii_symbols=["foo", "bar"]) def to_ir(self, target, ir_type, serialization_properties): assert target == expected_target assert ir_type == expected_ir_type assert serialization_properties == expected_serialization_properties return expected_ir instr = Instruction(FooGate(), expected_target) assert instr.to_ir(expected_ir_type, expected_serialization_properties) == expected_ir
def test_basis_rotation_instructions_multiple_result_types_same_targets_hermitian( ): circ = (Circuit().h(0).cnot(0, 1).sample( observable=Observable.Hermitian(matrix=np.array([[1, 0], [0, -1]])), target=[1]).expectation(observable=Observable.Hermitian( matrix=np.array([[1, 0], [0, -1]])), target=[1])) expected = [ Instruction(Gate.Unitary(matrix=np.array([[0, 1], [1, 0]])), target=[1]) ] assert circ.basis_rotation_instructions == expected
def test_gate_subroutine(testclass, subroutine_name, irclass, irsubclasses, kwargs): qubit_count = calculate_qubit_count(irsubclasses) subroutine = getattr(Circuit(), subroutine_name) assert subroutine(**create_valid_subroutine_input(irsubclasses, **kwargs)) == Circuit( Instruction(**create_valid_instruction_input(testclass, irsubclasses, **kwargs)) ) if qubit_count == 1: multi_targets = [0, 1, 2] instruction_list = [] for target in multi_targets: instruction_list.append( Instruction( operator=testclass(**create_valid_gate_class_input(irsubclasses, **kwargs)), target=target, ) ) subroutine = getattr(Circuit(), subroutine_name) subroutine_input = {"target": multi_targets} if Angle in irsubclasses: subroutine_input.update(angle_valid_input()) assert subroutine(**subroutine_input) == Circuit(instruction_list)
def test_noise_subroutine(testclass, subroutine_name, irclass, irsubclasses, kwargs): qubit_count = calculate_qubit_count(irsubclasses) subroutine = getattr(Circuit(), subroutine_name) assert subroutine( **create_valid_subroutine_input(irsubclasses, **kwargs)) == Circuit( Instruction(**create_valid_instruction_input( testclass, irsubclasses, **kwargs))) if qubit_count == 1: multi_targets = [0, 1, 2] instruction_list = [] for target in multi_targets: instruction_list.append( Instruction( operator=testclass(**create_valid_noise_class_input( irsubclasses, **kwargs)), target=target, )) subroutine = getattr(Circuit(), subroutine_name) subroutine_input = {"target": multi_targets} if SingleProbability in irsubclasses: subroutine_input.update(single_probability_valid_input()) if SingleProbability_34 in irsubclasses: subroutine_input.update(single_probability_34_valid_input()) if SingleProbability_1516 in irsubclasses: subroutine_input.update(single_probability_1516_valid_input()) if DampingSingleProbability in irsubclasses: subroutine_input.update(damping_single_probability_valid_input()) if DampingProbability in irsubclasses: subroutine_input.update(damping_probability_valid_input()) if TripleProbability in irsubclasses: subroutine_input.update(triple_probability_valid_input()) if MultiProbability in irsubclasses: subroutine_input.update(multi_probability_valid_input()) circuit1 = subroutine(**subroutine_input) circuit2 = Circuit(instruction_list) assert circuit1 == circuit2
def _( circuit: Circuit, aws_session: AwsSession, create_task_kwargs: Dict[str, Any], device_arn: str, device_parameters: Union[ dict, BraketSchemaBase], # Not currently used for circuits disable_qubit_rewiring: bool, *args, **kwargs, ) -> AwsQuantumTask: validate_circuit_and_shots(circuit, create_task_kwargs["shots"]) # TODO: Update this to use `deviceCapabilities` from Amazon Braket's GetDevice operation # in order to decide what parameters to build. paradigm_parameters = GateModelParameters( qubitCount=circuit.qubit_count, disableQubitRewiring=disable_qubit_rewiring) if "ionq" in device_arn: device_parameters = IonqDeviceParameters( paradigmParameters=paradigm_parameters) elif "rigetti" in device_arn: device_parameters = RigettiDeviceParameters( paradigmParameters=paradigm_parameters) elif "oqc" in device_arn: device_parameters = OqcDeviceParameters( paradigmParameters=paradigm_parameters) else: # default to use simulator device_parameters = GateModelSimulatorDeviceParameters( paradigmParameters=paradigm_parameters) qubit_reference_type = QubitReferenceType.VIRTUAL if disable_qubit_rewiring or Instruction( StartVerbatimBox()) in circuit.instructions: qubit_reference_type = QubitReferenceType.PHYSICAL serialization_properties = OpenQASMSerializationProperties( qubit_reference_type=qubit_reference_type) create_task_kwargs.update({ "action": circuit.to_ir( ir_type=IRType.OPENQASM, serialization_properties=serialization_properties, ).json(), "deviceParameters": device_parameters.json(), }) task_arn = aws_session.create_quantum_task(**create_task_kwargs) return AwsQuantumTask(task_arn, aws_session, *args, **kwargs)