def test_instructionset_c_if_calls_custom_requester(self): """Test that :meth:`.InstructionSet.c_if` calls a custom requester, and uses its output.""" # This isn't expected to be useful to end users, it's more about the principle that you can # control the resolution paths, so future blocking constructs can forbid the method from # accessing certain resources. sentinel_bit = Clbit() sentinel_register = ClassicalRegister(2) def dummy_requester(specifier): """A dummy requester that returns sentinel values.""" if not isinstance(specifier, (int, Clbit, ClassicalRegister)): raise CircuitError return sentinel_bit if isinstance(specifier, (int, Clbit)) else sentinel_register dummy_requester = unittest.mock.MagicMock(wraps=dummy_requester) with self.subTest("calls requester with bit"): dummy_requester.reset_mock() instruction = HGate() instructions = InstructionSet(resource_requester=dummy_requester) instructions.add(instruction, [Qubit()], []) bit = Clbit() instructions.c_if(bit, 0) dummy_requester.assert_called_once_with(bit) self.assertIs(instruction.condition[0], sentinel_bit) with self.subTest("calls requester with index"): dummy_requester.reset_mock() instruction = HGate() instructions = InstructionSet(resource_requester=dummy_requester) instructions.add(instruction, [Qubit()], []) index = 0 instructions.c_if(index, 0) dummy_requester.assert_called_once_with(index) self.assertIs(instruction.condition[0], sentinel_bit) with self.subTest("calls requester with register"): dummy_requester.reset_mock() instruction = HGate() instructions = InstructionSet(resource_requester=dummy_requester) instructions.add(instruction, [Qubit()], []) register = ClassicalRegister(2) instructions.c_if(register, 0) dummy_requester.assert_called_once_with(register) self.assertIs(instruction.condition[0], sentinel_register) with self.subTest("calls requester only once when broadcast"): dummy_requester.reset_mock() instruction_list = [HGate(), HGate(), HGate()] instructions = InstructionSet(resource_requester=dummy_requester) for instruction in instruction_list: instructions.add(instruction, [Qubit()], []) register = ClassicalRegister(2) instructions.c_if(register, 0) dummy_requester.assert_called_once_with(register) for instruction in instruction_list: self.assertIs(instruction.condition[0], sentinel_register)
def test_instructionset_c_if_with_no_requester(self): """Test that using a raw :obj:`.InstructionSet` with no classical-resource resoluer accepts arbitrary :obj:`.Clbit` and `:obj:`.ClassicalRegister` instances, but rejects integers.""" with self.subTest("accepts arbitrary register"): instruction = HGate() instructions = InstructionSet() instructions.add(instruction, [Qubit()], []) register = ClassicalRegister(2) instructions.c_if(register, 0) self.assertIs(instruction.condition[0], register) with self.subTest("accepts arbitrary bit"): instruction = HGate() instructions = InstructionSet() instructions.add(instruction, [Qubit()], []) bit = Clbit() instructions.c_if(bit, 0) self.assertIs(instruction.condition[0], bit) with self.subTest("rejects index"): instruction = HGate() instructions = InstructionSet() instructions.add(instruction, [Qubit()], []) with self.assertRaisesRegex( CircuitError, r"Cannot pass an index as a condition .*"): instructions.c_if(0, 0)
def test_instructionset_c_if_deprecated_resolution(self): r"""Test that the deprecated path of passing an iterable of :obj:`.ClassicalRegister`\ s to :obj:`.InstructionSet` works, issues a deprecation warning, and resolves indices in the simple cases it was meant to handle.""" # The deprecated path can only cope with non-overlapping classical registers, with no loose # clbits in the mix. registers = [ ClassicalRegister(2), ClassicalRegister(3), ClassicalRegister(1) ] bits = [bit for register in registers for bit in register] deprecated_regex = r"The 'circuit_cregs' argument to 'InstructionSet' is deprecated .*" def dummy_requester(specifier): """A dummy requester that technically fulfills the spec.""" raise CircuitError with self.subTest("cannot pass both registers and requester"): with self.assertRaisesRegex( CircuitError, r"Cannot pass both 'circuit_cregs' and 'resource_requester'\." ): InstructionSet(registers, resource_requester=dummy_requester) with self.subTest("classical register"): instruction = HGate() with self.assertWarnsRegex(DeprecationWarning, deprecated_regex): instructions = InstructionSet(registers) instructions.add(instruction, [Qubit()], []) instructions.c_if(registers[0], 0) self.assertIs(instruction.condition[0], registers[0]) with self.subTest("classical bit"): instruction = HGate() with self.assertWarnsRegex(DeprecationWarning, deprecated_regex): instructions = InstructionSet(registers) instructions.add(instruction, [Qubit()], []) instructions.c_if(registers[0][1], 0) self.assertIs(instruction.condition[0], registers[0][1]) for i, bit in enumerate(bits): with self.subTest("bit index", index=i): instruction = HGate() with self.assertWarnsRegex(DeprecationWarning, deprecated_regex): instructions = InstructionSet(registers) instructions.add(instruction, [Qubit()], []) instructions.c_if(i, 0) self.assertIs(instruction.condition[0], bit) with self.subTest("raises on bad register"): instruction = HGate() with self.assertWarnsRegex(DeprecationWarning, deprecated_regex): instructions = InstructionSet(registers) instructions.add(instruction, [Qubit()], []) with self.assertRaisesRegex( CircuitError, r"Condition register .* is not one of the registers known here: .*" ): instructions.c_if(ClassicalRegister(2), 0) with self.subTest("raises on bad bit"): instruction = HGate() with self.assertWarnsRegex(DeprecationWarning, deprecated_regex): instructions = InstructionSet(registers) instructions.add(instruction, [Qubit()], []) with self.assertRaisesRegex( CircuitError, "Condition bit .* is not in the registers known here: .*"): instructions.c_if(Clbit(), 0) with self.subTest("raises on bad index"): instruction = HGate() with self.assertWarnsRegex(DeprecationWarning, deprecated_regex): instructions = InstructionSet(registers) instructions.add(instruction, [Qubit()], []) with self.assertRaisesRegex(CircuitError, r"Bit index .* is out-of-range\."): instructions.c_if(len(bits), 0) with self.subTest("raises on bad type"): instruction = HGate() with self.assertWarnsRegex(DeprecationWarning, deprecated_regex): instructions = InstructionSet(registers) instructions.add(instruction, [Qubit()], []) with self.assertRaisesRegex(CircuitError, r"Invalid classical condition\. .*"): instructions.c_if([0], 0)