def test_initialization_main_block(self) -> None: block = InstructionBlock() for offset in [0, 1, 924]: ip = InstructionPointer(block, offset) self.assertIs(block, ip.block) self.assertEqual(offset, ip.offset) self.assertEqual(offset, ip.get_absolute_address())
def test_build_sequence_loop(self) -> None: sequencer = DummySequencer() block = DummyInstructionBlock() block.add_instruction(DummyInstruction()) delegator = DummySequencingElement() body = DummySequencingElement() trigger = Trigger() condition = HardwareCondition(trigger) condition.build_sequence_loop(delegator, body, sequencer, {}, {}, {}, {}, block) self.assertEqual(1, len(block.embedded_blocks)) body_block = block.embedded_blocks[0] self.assertEqual( [ DummyInstruction(), CJMPInstruction(trigger, InstructionPointer(body_block)) ], block.instructions, "The expected conditional jump was not generated by HardwareConditon." ) self.assertEqual( InstructionPointer(block, 1), body_block.return_ip, "The return address of the loop body block was set wrongly by HardwareCondition." ) self.assertEqual( {body_block: [(body, {}, {}, {}, {})]}, sequencer.sequencing_stacks, "HardwareCondition did not correctly push the body element to the stack" ) self.assertFalse(condition.requires_stop())
def test_str(self) -> None: block = DummyInstructionBlock() trigger = Trigger() instr = CJMPInstruction(trigger, InstructionPointer(block, 3)) self.assertEqual( "cjmp to {} on {}".format(InstructionPointer(block, 3), trigger), str(instr))
def test_create_embedded_block(self) -> None: parent_block = InstructionBlock() block = InstructionBlock() block.return_ip = InstructionPointer(parent_block, 18) self.__verify_block( block, [], [GOTOInstruction(InstructionPointer(parent_block, 18))], InstructionPointer(parent_block, 18)) self.__verify_block(parent_block, [], [STOPInstruction()], None)
def test_iterable_empty_return(self) -> None: parent_block = InstructionBlock() block = AbstractInstructionBlockStub([], InstructionPointer( parent_block, 13)) count = 0 for instruction in block: self.assertEqual(0, count) self.assertIsInstance(instruction, GOTOInstruction) self.assertEqual(InstructionPointer(parent_block, 13), instruction.target) count += 1
def test_item_access_empty_return(self) -> None: parent_block = InstructionBlock() block = AbstractInstructionBlockStub([], InstructionPointer( parent_block, 84)) self.assertEqual(GOTOInstruction(InstructionPointer(parent_block, 84)), block[0]) with self.assertRaises(IndexError): block[1] self.assertEqual(GOTOInstruction(InstructionPointer(parent_block, 84)), block[-1]) with self.assertRaises(IndexError): block[-2]
def test_iterable_return(self) -> None: parent_block = InstructionBlock() wf = DummyWaveform() block = AbstractInstructionBlockStub([EXECInstruction(wf)], InstructionPointer( parent_block, 11)) count = 0 for expected_instruction, instruction in zip([ EXECInstruction(wf), GOTOInstruction(InstructionPointer(parent_block, 11)) ], block): self.assertEqual(expected_instruction, instruction) count += 1 self.assertEqual(2, count)
def __verify_block( self, block: AbstractInstructionBlock, immutable_block: ImmutableInstructionBlock, context: Dict[AbstractInstructionBlock, ImmutableInstructionBlock] ) -> None: self.assertIsInstance(immutable_block, ImmutableInstructionBlock) self.assertEqual(len(block.instructions), len(immutable_block.instructions)) self.assertEqual(len(block), len(immutable_block)) if block.return_ip is None: self.assertIsNone(immutable_block.return_ip) else: self.assertEqual( InstructionPointer(context[block.return_ip.block], block.return_ip.offset), immutable_block.return_ip) for instruction, immutable_instruction in zip( block.instructions, immutable_block.instructions): self.assertEqual(type(instruction), type(immutable_instruction)) if isinstance(instruction, (GOTOInstruction, CJMPInstruction, REPJInstruction)): target_block = instruction.target.block immutable_target_block = immutable_instruction.target.block self.assertEqual(instruction.target.offset, immutable_instruction.target.offset) self.assertIsInstance(immutable_target_block, ImmutableInstructionBlock) self.assertEqual(context[target_block], immutable_target_block) self.assertEqual(immutable_block, immutable_target_block.return_ip.block) self.__verify_block(target_block, immutable_target_block, context)
def build_sequence_branch(self, delegator: sequencing.SequencingElement, if_branch: sequencing.SequencingElement, else_branch: sequencing.SequencingElement, sequencer: sequencing.Sequencer, parameters: Dict[str, Parameter], conditions: Dict[str, Condition], measurement_mapping: Dict[str, str], channel_mapping: Dict[ChannelID, ChannelID], instruction_block: InstructionBlock) -> None: if_block = InstructionBlock() else_block = InstructionBlock() instruction_block.add_instruction_cjmp(self.__trigger, if_block) sequencer.push(if_branch, parameters, conditions, window_mapping=measurement_mapping, channel_mapping=channel_mapping, target_block=if_block) instruction_block.add_instruction_goto(else_block) sequencer.push(else_branch, parameters, conditions, window_mapping=measurement_mapping, channel_mapping=channel_mapping, target_block=else_block) if_block.return_ip = InstructionPointer(instruction_block, len(instruction_block.instructions)) else_block.return_ip = if_block.return_ip
def test_item_access_return(self) -> None: wf = DummyWaveform() parent_block = InstructionBlock() block = AbstractInstructionBlockStub([EXECInstruction(wf)], InstructionPointer( parent_block, 29)) self.assertEqual(EXECInstruction(wf), block[0]) self.assertEqual(GOTOInstruction(InstructionPointer(parent_block, 29)), block[1]) with self.assertRaises(IndexError): block[2] self.assertEqual(GOTOInstruction(InstructionPointer(parent_block, 29)), block[-1]) self.assertEqual(EXECInstruction(wf), block[-2]) with self.assertRaises(IndexError): block[-3]
def build_sequence(self, sequencer: Sequencer, parameters: Dict[str, Parameter], conditions: Dict[str, Condition], measurement_mapping: Dict[str, Optional[str]], channel_mapping: Dict[ChannelID, Optional[ChannelID]], instruction_block: InstructionBlock) -> None: self.validate_parameter_constraints(parameters=parameters) body_block = InstructionBlock() body_block.return_ip = InstructionPointer(instruction_block, len(instruction_block)) try: real_parameters = { v: parameters[v].get_value() for v in self._repetition_count.variables } except KeyError: raise ParameterNotProvidedException( next(v for v in self.repetition_count.variables if v not in parameters)) self.insert_measurement_instruction( instruction_block, parameters=parameters, measurement_mapping=measurement_mapping) instruction_block.add_instruction_repj( self.get_repetition_count_value(real_parameters), body_block) sequencer.push(self.body, parameters=parameters, conditions=conditions, window_mapping=measurement_mapping, channel_mapping=channel_mapping, target_block=body_block)
def test_nested_goto(self) -> None: parent_block = InstructionBlock() block = InstructionBlock() block.return_ip = InstructionPointer(parent_block, 1) parent_block.add_instruction_goto(block) context = dict() immutable_block = ImmutableInstructionBlock(parent_block, context) self.__verify_block(parent_block, immutable_block, context)
def test_initialization(self) -> None: block = InstructionBlock() trigger = Trigger() for offset in [0, 1, 23]: instr = CJMPInstruction(trigger, InstructionPointer(block, offset)) self.assertEqual(trigger, instr.trigger) self.assertEqual(block, instr.target.block) self.assertEqual(offset, instr.target.offset)
def test_empty_returning_block(self) -> None: return_block = InstructionBlock() block = InstructionBlock() block.return_ip = InstructionPointer(return_block, 7) context = { return_block: ImmutableInstructionBlock(return_block, dict()) } immutable_block = ImmutableInstructionBlock(block, context) self.__verify_block(block, immutable_block, context)
def test_initialization(self) -> None: block = InstructionBlock() for count in [0, 1, 47]: for offset in [0, 1, 23]: instr = REPJInstruction(count, InstructionPointer(block, offset)) self.assertEqual(count, instr.count) self.assertEqual(block, instr.target.block) self.assertEqual(offset, instr.target.offset)
def test_equality(self) -> None: blocks = [InstructionBlock(), InstructionBlock()] for offset in [0, 1, 23]: instrA = GOTOInstruction(InstructionPointer(blocks[0], offset)) instrB = GOTOInstruction(InstructionPointer(blocks[0], offset)) self.assertEqual(instrA, instrB) self.assertEqual(instrB, instrA) instrs = [] for block in blocks: for offset in [0, 17]: instruction = GOTOInstruction(InstructionPointer( block, offset)) self.assertEqual(instruction, instruction) for other in instrs: self.assertNotEqual(instruction, other) self.assertNotEqual(other, instruction) self.assertNotEqual(hash(instruction), hash(other)) instrs.append(instruction)
def test_build_sequence_branch(self) -> None: sequencer = DummySequencer() block = DummyInstructionBlock() delegator = DummySequencingElement() if_branch = DummySequencingElement() else_branch = DummySequencingElement() trigger = Trigger() condition = HardwareCondition(trigger) condition.build_sequence_branch(delegator, if_branch, else_branch, sequencer, {}, {}, {}, {}, instruction_block=block) self.assertEqual(2, len(block.embedded_blocks)) if_block = block.embedded_blocks[0] else_block = block.embedded_blocks[1] self.assertEqual( [ CJMPInstruction(trigger, InstructionPointer(if_block)), GOTOInstruction(InstructionPointer(else_block)) ], block.instructions, "The expected jump instruction were not generated by HardwareConditon." ) self.assertEqual( InstructionPointer(block, 2), if_block.return_ip, "The return address of the if branch block was set wrongly by HardwareConditon." ) self.assertEqual( InstructionPointer(block, 2), else_block.return_ip, "The return address of the else branch block was set wrongly by HardwareConditon." ) self.assertEqual( { if_block: [(if_branch, {}, {}, {}, {})], else_block: [(else_branch, {}, {}, {}, {})] }, sequencer.sequencing_stacks, "HardwareCondition did not correctly push the branch elements to the stack" )
def build_sequence_loop(self, delegator: SequencingElement, body: SequencingElement, sequencer: Sequencer, parameters: Dict[str, Parameter], conditions: Dict[str, Condition], instruction_block: InstructionBlock) -> None: body_block = InstructionBlock() body_block.return_ip = InstructionPointer( instruction_block, len(instruction_block.instructions)) instruction_block.add_instruction_cjmp(self.__trigger, body_block) sequencer.push(body, parameters, conditions, body_block)
def test_build_sequence_declaration_success(self) -> None: parameters = dict(foo=3) conditions = dict(foo=DummyCondition(requires_stop=True)) self.template.build_sequence(self.sequencer, parameters, conditions, self.block) self.assertTrue(self.block.embedded_blocks) body_block = self.block.embedded_blocks[0] self.assertEqual({body_block}, set(self.sequencer.sequencing_stacks.keys())) self.assertEqual([(self.body, parameters, conditions)], self.sequencer.sequencing_stacks[body_block]) self.assertEqual([REPJInstruction(parameters['foo'], InstructionPointer(body_block, 0))], self.block.instructions)
def test_nested_no_context_argument(self) -> None: parent_block = InstructionBlock() block = InstructionBlock() block.return_ip = InstructionPointer(parent_block, 1) parent_block.add_instruction_goto(block) immutable_block = ImmutableInstructionBlock(parent_block) context = { parent_block: immutable_block, block: immutable_block.instructions[0].target.block } self.__verify_block(parent_block, immutable_block, context)
def test_build_sequence_constant(self) -> None: repetitions = 3 t = RepetitionPulseTemplate(self.body, repetitions) parameters = {} conditions = dict(foo=DummyCondition(requires_stop=True)) t.build_sequence(self.sequencer, parameters, conditions, self.block) self.assertTrue(self.block.embedded_blocks) body_block = self.block.embedded_blocks[0] self.assertEqual({body_block}, set(self.sequencer.sequencing_stacks.keys())) self.assertEqual([(self.body, parameters, conditions)], self.sequencer.sequencing_stacks[body_block]) self.assertEqual([REPJInstruction(repetitions, InstructionPointer(body_block, 0))], self.block.instructions)
def test_equality(self) -> None: blocks = [InstructionBlock(), InstructionBlock()] blocks.append(InstructionBlock()) ips = [] for block in blocks: for offset in [0, 1, 2352]: ip = InstructionPointer(block, offset) self.assertEqual(ip, ip) for other in ips: self.assertNotEqual(ip, other) self.assertNotEqual(other, ip) self.assertNotEqual(hash(ip), hash(other)) ips.append(ip)
def test_sliced_item_access(self) -> None: wf = DummyWaveform() parent_block = InstructionBlock() block = AbstractInstructionBlockStub( [EXECInstruction(wf), EXECInstruction(wf)], InstructionPointer(parent_block, 29)) for instruction in block[:-1]: self.assertEqual(EXECInstruction(wf), instruction) expections = [ EXECInstruction(wf), EXECInstruction(wf), GOTOInstruction(InstructionPointer(parent_block, 29)) ] for expected, instruction in zip(expections, block[:4]): self.assertEqual(expected, instruction) for instruction, expected in zip(block[::-1], reversed(expections)): self.assertEqual(expected, instruction) with self.assertRaises(StopIteration): next(iter(block[3:]))
def test_add_instruction_goto(self) -> None: block = InstructionBlock() expected_instructions = [] targets = [InstructionBlock(), InstructionBlock(), InstructionBlock()] LOOKUP = [0, 1, 1, 0, 2, 1, 0, 0, 0, 1, 2, 2] for id in LOOKUP: target = targets[id] instruction = GOTOInstruction(InstructionPointer(target)) expected_instructions.append(instruction) block.add_instruction_goto(target) expected_compiled_instructions = expected_instructions.copy() expected_compiled_instructions.append(STOPInstruction()) self.__verify_block(block, expected_instructions, expected_compiled_instructions, None)
def build_sequence_loop(self, delegator: sequencing.SequencingElement, body: sequencing.SequencingElement, sequencer: sequencing.Sequencer, parameters: Dict[str, Parameter], conditions: Dict[str, Condition], measurement_mapping: Dict[str, str], channel_mapping: Dict[ChannelID, ChannelID], instruction_block: InstructionBlock) -> None: body_block = InstructionBlock() body_block.return_ip = InstructionPointer(instruction_block, len(instruction_block.instructions)) instruction_block.add_instruction_cjmp(self.__trigger, body_block) sequencer.push(body, parameters, conditions, window_mapping=measurement_mapping, channel_mapping=channel_mapping, target_block=body_block)
def test_str(self) -> None: IB = InstructionBlock() T = Trigger() W = DummyWaveform() a = [ W, T, InstructionPointer(IB, 1), CJMPInstruction(T, IB), GOTOInstruction(IB), EXECInstruction(W), IB ] b = [x.__str__() for x in a] for s in b: self.assertIsInstance(s, str)
def test_add_instruction_repj(self) -> None: block = InstructionBlock() expected_instructions = [] targets = [InstructionBlock(), InstructionBlock(), InstructionBlock()] counts = [3, 8, 857] LOOKUP = [(0, 0), (0, 1), (1, 1), (0, 2), (2, 0), (1, 0), (2, 2), (2, 1), (1, 0), (1, 2)] for i in LOOKUP: block.add_instruction_repj(counts[i[0]], targets[i[1]]) expected_instructions.append( REPJInstruction(counts[i[0]], InstructionPointer(targets[i[1]], 0))) expected_compiled_instructions = expected_instructions.copy() expected_compiled_instructions.append(STOPInstruction()) self.__verify_block(block, expected_instructions, expected_compiled_instructions, None)
def test_add_instruction_cjmp(self) -> None: block = InstructionBlock() expected_instructions = [] targets = [InstructionBlock(), InstructionBlock(), InstructionBlock()] triggers = [Trigger(), Trigger()] LOOKUP = [(0, 0), (1, 0), (1, 1), (0, 1), (2, 0), (1, 0), (0, 1), (0, 1), (0, 0), (1, 0), (2, 1), (2, 1)] for i in LOOKUP: block.add_instruction_cjmp(triggers[i[1]], targets[i[0]]) expected_instructions.append( CJMPInstruction(triggers[i[1]], InstructionPointer(targets[i[0]], 0))) expected_compiled_instructions = expected_instructions.copy() expected_compiled_instructions.append(STOPInstruction()) self.__verify_block(block, expected_instructions, expected_compiled_instructions, None)
def build_sequence(self, sequencer: Sequencer, parameters: Dict[str, Parameter], conditions: Dict[str, Condition], instruction_block: InstructionBlock) -> None: repetition_count = self.__repetition_count if isinstance(repetition_count, ParameterDeclaration): repetition_count = repetition_count.get_value(parameters) if not repetition_count.is_integer(): raise ParameterNotIntegerException( self.__repetition_count.name, repetition_count) body_block = InstructionBlock() body_block.return_ip = InstructionPointer(instruction_block, len(instruction_block)) instruction_block.add_instruction_repj(int(repetition_count), body_block) sequencer.push(self.body, parameters, conditions, body_block)
def build_sequence_branch(self, delegator: SequencingElement, if_branch: SequencingElement, else_branch: SequencingElement, sequencer: Sequencer, parameters: Dict[str, Parameter], conditions: Dict[str, Condition], instruction_block: InstructionBlock) -> None: if_block = InstructionBlock() else_block = InstructionBlock() instruction_block.add_instruction_cjmp(self.__trigger, if_block) sequencer.push(if_branch, parameters, conditions, if_block) instruction_block.add_instruction_goto(else_block) sequencer.push(else_branch, parameters, conditions, else_block) if_block.return_ip = InstructionPointer( instruction_block, len(instruction_block.instructions)) else_block.return_ip = if_block.return_ip
def test_build_sequence_declaration_success(self) -> None: parameters = dict(foo=ConstantParameter(3)) conditions = dict(foo=DummyCondition(requires_stop=True)) measurement_mapping = dict(moth='fire') channel_mapping = dict(asd='f') self.template.build_sequence(self.sequencer, parameters, conditions, measurement_mapping, channel_mapping, self.block) self.assertTrue(self.block.embedded_blocks) body_block = self.block.embedded_blocks[0] self.assertEqual({body_block}, set(self.sequencer.sequencing_stacks.keys())) self.assertEqual([(self.body, parameters, conditions, measurement_mapping, channel_mapping)], self.sequencer.sequencing_stacks[body_block]) self.assertEqual( [REPJInstruction(3, InstructionPointer(body_block, 0))], self.block.instructions)