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 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_empty_returning_main_block(self) -> None: block = InstructionBlock() self.assertEqual(0, block.get_start_address()) self.assertIsNone(block.return_ip) ip = InstructionPointer(InstructionBlock(), 7) block.return_ip = ip # must have no effect self.__verify_block(block, [], [STOPInstruction()])
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_add_instruction_stop(self) -> None: block = InstructionBlock() expected_instructions = [STOPInstruction(), STOPInstruction()] block.add_instruction_stop() block.add_instruction_stop() expected_compiled_instructions = expected_instructions.copy() expected_compiled_instructions.append(STOPInstruction()) self.__verify_block(block, expected_instructions, expected_compiled_instructions)
def test_empty_relative_block(self) -> None: return_block = InstructionBlock() block = InstructionBlock(return_block) self.assertRaises(InstructionBlockNotYetPlacedException, block.get_start_address) self.assertRaises(MissingReturnAddressException, block.compile_sequence) ip = InstructionPointer(return_block, 7) block.return_ip = ip self.__verify_block(block, [], [GOTOInstruction(ip.block, ip.offset)])
def test_add_instruction_stop(self) -> None: block = InstructionBlock() expected_instructions = [STOPInstruction(), STOPInstruction()] block.add_instruction_stop() block.add_instruction_stop() expected_compiled_instructions = expected_instructions.copy() expected_compiled_instructions.append(STOPInstruction()) self.__verify_block(block, expected_instructions, expected_compiled_instructions, None)
def test_create_embedded_block(self) -> None: parent_block = InstructionBlock() block = parent_block.create_embedded_block() self.assertRaises(InstructionBlockNotYetPlacedException, block.get_start_address) self.assertRaises(MissingReturnAddressException, block.compile_sequence) block.return_ip = InstructionPointer(parent_block, 0) self.__verify_block(block, [], [GOTOInstruction(parent_block, 0)]) self.__verify_block(parent_block, [], [STOPInstruction(), GOTOInstruction(parent_block, 0)]) self.assertEqual(1, block.get_start_address())
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 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_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_add_instruction_cjmp(self) -> None: block = InstructionBlock() expected_instructions = [] expected_compiled_instructions = [] targets = [(InstructionBlock(), 0), (InstructionBlock(), 1), (InstructionBlock(), 50)] 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]], targets[i[0]], 0)) expected_compiled_instructions = expected_instructions.copy() expected_compiled_instructions.append(STOPInstruction()) self.__verify_block(block, expected_instructions, expected_compiled_instructions)
def test_add_instruction_goto(self) -> None: block = InstructionBlock() expected_instructions = [] targets = [(InstructionBlock(), 0), (InstructionBlock(), 1), (InstructionBlock(), 50)] LOOKUP = [0, 1, 1, 0, 2, 1, 0, 0, 0, 1, 2, 2] for id in LOOKUP: target = targets[id] instruction = GOTOInstruction(target[0], target[1]) expected_instructions.append(instruction) block.add_instruction_goto(target[0], target[1]) expected_compiled_instructions = expected_instructions.copy() expected_compiled_instructions.append(STOPInstruction()) self.__verify_block(block, expected_instructions, expected_compiled_instructions)
def test_add_instruction_exec(self) -> None: block = InstructionBlock() expected_instructions = [] waveforms = [DummyWaveform(), DummyWaveform(), DummyWaveform()] LOOKUP = [0, 1, 1, 0, 2, 1, 0, 0, 0, 1, 2, 2] for id in LOOKUP: waveform = waveforms[id] instruction = EXECInstruction(waveform) expected_instructions.append(instruction) block.add_instruction_exec(waveform) expected_compiled_instructions = expected_instructions.copy() expected_compiled_instructions.append(STOPInstruction()) self.__verify_block(block, expected_instructions, expected_compiled_instructions)
def test_build_path_o2_m2_i1_t_i1_t_m2_i0_i0_one_element_custom_block_one_element_main_block( self) -> None: sequencer = Sequencer() ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} elem_main = DummySequencingElement(False) sequencer.push(elem_main, ps, cs) target_block = InstructionBlock() elem_cstm = DummySequencingElement(False) sequencer.push(elem_cstm, ps, cs, target_block) sequence = sequencer.build() self.assertTrue(sequencer.has_finished()) self.assertIs(elem_main, sequence[0].elem) self.assertEqual(ps, elem_main.parameters) self.assertEqual(cs, elem_main.conditions) self.assertEqual(1, elem_main.requires_stop_call_counter) self.assertEqual(1, elem_main.build_call_counter) self.assertIs(target_block, elem_cstm.target_block) self.assertEqual(ps, elem_cstm.parameters) self.assertEqual(cs, elem_cstm.conditions) self.assertEqual(1, elem_cstm.requires_stop_call_counter) self.assertEqual(1, elem_cstm.build_call_counter) self.assertEqual(STOPInstruction(), sequence[1]) self.assertEqual(2, len(sequence))
def test_build_path_o1_m2_i1_f_i1_f_one_element_custom_and_main_block_requires_stop( self) -> None: sequencer = Sequencer() ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} elem_main = DummySequencingElement(True) sequencer.push(elem_main, ps, cs) elem_cstm = DummySequencingElement(True) target_block = InstructionBlock() sequencer.push(elem_cstm, ps, cs, target_block) sequencer.build() self.assertFalse(sequencer.has_finished()) self.assertEqual(ps, elem_main.parameters) self.assertEqual(cs, elem_main.conditions) self.assertEqual(1, elem_main.requires_stop_call_counter) self.assertEqual(0, elem_main.build_call_counter) self.assertEqual(ps, elem_cstm.parameters) self.assertEqual(cs, elem_cstm.conditions) self.assertEqual(1, elem_cstm.requires_stop_call_counter) self.assertEqual(0, elem_cstm.build_call_counter)
def test_build_path_o2_m1_i2_tf_m2_i1_f_i1_f_two_elements_main_block_last_requires_stop_add_one_element_requires_stop_new_block( self) -> None: sequencer = Sequencer() ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} new_block = InstructionBlock() new_elem = DummySequencingElement(True) elem1 = DummySequencingElement(False, (new_block, [new_elem])) elem2 = DummySequencingElement(True) sequencer.push(elem2, ps, cs) sequencer.push(elem1, ps, cs) sequence = sequencer.build() self.assertFalse(sequencer.has_finished()) self.assertIs(elem1, sequence[0].elem) self.assertEqual(ps, elem1.parameters) self.assertEqual(cs, elem1.conditions) self.assertEqual(1, elem1.requires_stop_call_counter) self.assertEqual(1, elem1.build_call_counter) self.assertEqual(ps, elem2.parameters) self.assertEqual(cs, elem2.conditions) self.assertEqual(2, elem2.requires_stop_call_counter) self.assertEqual(0, elem2.build_call_counter) self.assertEqual(ps, new_elem.parameters) self.assertEqual(cs, new_elem.conditions) self.assertEqual(1, new_elem.requires_stop_call_counter) self.assertEqual(0, new_elem.build_call_counter) self.assertEqual(STOPInstruction(), sequence[1]) self.assertEqual(2, len(sequence))
def test_build_path_o2_m2_i1_f_i2_tf_m2_i1_f_i1_f_two_elements_custom_block_last_requires_stop_one_element_requires_stop_main_block( self) -> None: sequencer = Sequencer() ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} target_block = InstructionBlock() elem2 = DummySequencingElement(True) sequencer.push(elem2, ps, cs, target_block) elem1 = DummySequencingElement(False) sequencer.push(elem1, ps, cs, target_block) elem_main = DummySequencingElement(True) sequencer.push(elem_main, ps, cs) sequencer.build() self.assertFalse(sequencer.has_finished()) self.assertIs(target_block, elem1.target_block) self.assertEqual(ps, elem1.parameters) self.assertEqual(cs, elem1.conditions) self.assertEqual(1, elem1.requires_stop_call_counter) self.assertEqual(1, elem1.build_call_counter) self.assertEqual(ps, elem2.parameters) self.assertEqual(cs, elem2.conditions) self.assertEqual(2, elem2.requires_stop_call_counter) self.assertEqual(0, elem2.build_call_counter) self.assertEqual(ps, elem_main.parameters) self.assertEqual(cs, elem_main.conditions) self.assertEqual(2, elem_main.requires_stop_call_counter) self.assertEqual(0, elem_main.build_call_counter)
def test_add_instruction_exec(self) -> None: block = InstructionBlock() expected_instructions = [] waveforms = [DummyWaveform(), DummyWaveform(), DummyWaveform()] LOOKUP = [0, 1, 1, 0, 2, 1, 0, 0, 0, 1, 2, 2] for id in LOOKUP: waveform = waveforms[id] instruction = EXECInstruction(waveform) expected_instructions.append(instruction) block.add_instruction_exec(waveform) expected_compiled_instructions = expected_instructions.copy() expected_compiled_instructions.append(STOPInstruction()) self.__verify_block(block, expected_instructions, expected_compiled_instructions, None)
def test_build_path_o2_m2_i0_i1_t_m2_i0_i0_one_element_custom_block( self) -> None: sequencer = Sequencer() ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} wm = {'foo': 'bar'} cm = {'A': 'B'} target_block = InstructionBlock() elem = DummySequencingElement(False) sequencer.push(elem, ps, cs, window_mapping=wm, channel_mapping=cm, target_block=target_block) sequencer.build() self.assertTrue(sequencer.has_finished()) self.assertIs(target_block, elem.target_block) self.assertEqual(ps, elem.parameters) self.assertEqual(cs, elem.conditions) self.assertEqual(wm, elem.window_mapping) self.assertEqual(cm, elem.channel_mapping) self.assertEqual(1, elem.requires_stop_call_counter) self.assertEqual(1, elem.build_call_counter)
def __init__(self) -> None: """Create a Sequencer.""" super().__init__() self.__waveforms = dict() # type: Dict[int, Waveform] self.__main_block = InstructionBlock() self.__sequencing_stacks = \ {self.__main_block: []} # type: Dict[InstructionBlock, List[Sequencer.StackElement]]
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_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_add_instruction_already_compiled(self) -> None: block = InstructionBlock() wf1 = DummyWaveform() wf2 = DummyWaveform() block.add_instruction_exec(wf1) block.compile_sequence() block.add_instruction_exec(wf2) sequence = block.compile_sequence() expected_sequence = [EXECInstruction(wf1), EXECInstruction(wf2), STOPInstruction()] self.assertEqual(expected_sequence, sequence)
def test_render(self) -> None: wf1 = DummyWaveform(duration=19) wf2 = DummyWaveform(duration=21) block = InstructionBlock() block.add_instruction_exec(wf1) block.add_instruction_exec(wf2) plotter = Plotter(sample_rate=0.5) times, voltages = plotter.render(block.compile_sequence()) wf1_expected = [([0, 2, 4, 6, 8, 10, 12, 14, 16, 18], 0)] wf2_expected = [([20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40], 1)] expected_result = list(range(0, 41, 2)) self.assertEqual(wf1_expected, wf1.sample_calls) self.assertEqual(wf2_expected, wf2.sample_calls) self.assertEqual(expected_result, list(times)) self.assertEqual(expected_result, list(voltages))
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_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 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 test_init(self): with self.assertRaises(ValueError): MultiChannelProgram(InstructionBlock()) mcp = MultiChannelProgram(self.root_block, ['A', 'B']) self.assertEqual(mcp.channels, {'A', 'B'}) with self.assertRaises(KeyError): mcp['C']
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 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_render(self) -> None: wf1 = DummyWaveform(duration=19) wf2 = DummyWaveform(duration=21) block = InstructionBlock() block.add_instruction_exec(wf1) block.add_instruction_exec(wf2) plotter = Plotter(sample_rate=0.5) times, voltages = plotter.render(block) wf1_expected = [([0, 2, 4, 6, 8, 10, 12, 14, 16, 18], 0)] wf2_expected = [([20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40], 1)] expected_result = numpy.array([range(0, 41, 2)]) self.assertEqual(wf1_expected, wf1.sample_calls) self.assertEqual(wf2_expected, wf2.sample_calls) self.assertTrue(numpy.all(expected_result == times)) self.assertTrue(numpy.all(expected_result == voltages)) self.assertEqual(expected_result.shape, voltages.shape)
def test_build_path_o2_m2_i2_tt_t_i2_tt_m2_i0_i0_two_elements_custom_block_two_element_main_block( self) -> None: sequencer = Sequencer() ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} wm = {'foo': 'bar'} target_block = InstructionBlock() elem2 = DummySequencingElement(False) sequencer.push(elem2, ps, cs, window_mapping=wm, target_block=target_block) elem1 = DummySequencingElement(False) sequencer.push(elem1, ps, cs, window_mapping=wm, target_block=target_block) elem_main2 = DummySequencingElement(False) sequencer.push(elem_main2, ps, cs) elem_main1 = DummySequencingElement(False) sequencer.push(elem_main1, ps, cs) sequence = sequencer.build() self.assertTrue(sequencer.has_finished()) self.assertIs(target_block, elem1.target_block) self.assertEqual(ps, elem1.parameters) self.assertEqual(cs, elem1.conditions) self.assertEqual(1, elem1.requires_stop_call_counter) self.assertEqual(1, elem1.build_call_counter) self.assertIs(target_block, elem2.target_block) self.assertEqual(ps, elem2.parameters) self.assertEqual(cs, elem2.conditions) self.assertEqual(1, elem2.requires_stop_call_counter) self.assertEqual(1, elem2.build_call_counter) self.assertIs(elem_main1, sequence[0].elem) self.assertEqual(ps, elem_main1.parameters) self.assertEqual(cs, elem_main1.conditions) self.assertEqual(1, elem_main1.requires_stop_call_counter) self.assertEqual(1, elem_main1.build_call_counter) self.assertIs(elem_main2, sequence[1].elem) self.assertEqual(ps, elem_main2.parameters) self.assertEqual(cs, elem_main2.conditions) self.assertEqual(1, elem_main2.requires_stop_call_counter) self.assertEqual(1, elem_main2.build_call_counter) self.assertEqual(STOPInstruction(), sequence[2]) self.assertEqual(3, len(sequence))
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_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_insert_measurement_instruction(self): pulse = self.to_test_constructor(measurements=[('mw', 'a', 'd')]) parameters = {'a': ConstantParameter(0), 'd': ConstantParameter(0.9)} measurement_mapping = {'mw': 'as'} block = InstructionBlock() pulse.insert_measurement_instruction( instruction_block=block, parameters=parameters, measurement_mapping=measurement_mapping) expected_block = [MEASInstruction([('as', 0, 0.9)])] self.assertEqual(block.instructions, expected_block)
def test_render(self) -> None: wf1 = DummyWaveform(duration=19) wf2 = DummyWaveform(duration=21) block = InstructionBlock() block.add_instruction_exec(wf1) block.add_instruction_exec(wf2) wf1_expected = ('A', [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]) wf2_expected = ('A', [x-19 for x in [20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40]]) wf1_output_array_len_expected = len(wf1_expected[1]) wf2_output_array_len_expected = len(wf2_expected[1]) wf1.sample_output = numpy.linspace(start=4, stop=5, num=len(wf1_expected[1])) wf2.sample_output = numpy.linspace(6, 7, num=len(wf2_expected[1])) expected_times = numpy.arange(start=0, stop=42, step=2) expected_result = numpy.concatenate((wf1.sample_output, wf2.sample_output)) times, voltages = render(block, sample_rate=0.5) self.assertEqual(len(wf1.sample_calls), 1) self.assertEqual(len(wf2.sample_calls), 1) self.assertEqual(wf1_expected[0], wf1.sample_calls[0][0]) self.assertEqual(wf2_expected[0], wf2.sample_calls[0][0]) numpy.testing.assert_almost_equal(wf1_expected[1], wf1.sample_calls[0][1]) numpy.testing.assert_almost_equal(wf2_expected[1], wf2.sample_calls[0][1]) self.assertEqual(wf1_output_array_len_expected, len(wf1.sample_calls[0][2])) self.assertEqual(wf2_output_array_len_expected, len(wf2.sample_calls[0][2])) self.assertEqual(voltages.keys(), dict(A=0).keys()) numpy.testing.assert_almost_equal(expected_times, times) numpy.testing.assert_almost_equal(expected_result, voltages['A']) self.assertEqual(expected_result.shape, voltages['A'].shape)
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 test_render_unsupported_instructions(self) -> None: block = InstructionBlock() block.add_instruction(DummyInstruction()) plotter = Plotter() with self.assertRaises(NotImplementedError): plotter.render(block.compile_sequence())
def test_nested_block_construction(self) -> None: main_block = InstructionBlock() expected_instructions = [[], [], [], []] expected_compiled_instructions = [[], [], [], []] blocks = [] waveforms = [DummyWaveform(), DummyWaveform(), DummyWaveform()] main_block.add_instruction_exec(waveforms[0]) expected_instructions[0].append(EXECInstruction(waveforms[0])) block = main_block.create_embedded_block() trigger = Trigger() main_block.add_instruction_cjmp(trigger, block) expected_instructions[0].append(CJMPInstruction(trigger, block, 0)) block.return_ip = InstructionPointer(main_block, len(main_block)) blocks.append(block) block = main_block.create_embedded_block() trigger = Trigger() main_block.add_instruction_cjmp(trigger, block) expected_instructions[0].append(CJMPInstruction(trigger, block, 0)) block.return_ip = InstructionPointer(main_block, len(main_block)) blocks.append(block) WAVEFORM_LOOKUP = [[2, 2, 1, 1],[0, 1, 1, 0, 2, 1]] for i in [0, 1]: block = blocks[i] lookup = WAVEFORM_LOOKUP[i] for id in lookup: waveform = waveforms[id] expected_instructions[i + 1].append(EXECInstruction(waveform)) block.add_instruction_exec(waveform) block = blocks[0].create_embedded_block() blocks[0].add_instruction_cjmp(trigger, block) expected_instructions[1].append(CJMPInstruction(trigger, block, 0)) block.return_ip = InstructionPointer(blocks[0], len(blocks[0])) blocks.append(block) for id in [1, 2, 0, 2]: waveform = waveforms[id] expected_instructions[3].append(EXECInstruction(waveform)) block.add_instruction_exec(waveform) for i in [0, 1, 2, 3]: expected_compiled_instructions[i] = expected_instructions[i].copy() expected_compiled_instructions[0].append(STOPInstruction()) for i in [0, 1, 2]: expected_compiled_instructions[i + 1].append(GOTOInstruction(blocks[i].return_ip.block, blocks[i].return_ip.offset)) positions = [0, None, None, None] positions[3] = len(expected_compiled_instructions[1]) expected_compiled_instructions[1].extend(expected_compiled_instructions[3]) for i in [1, 2]: positions[i] = len(expected_compiled_instructions[0]) expected_compiled_instructions[0].extend(expected_compiled_instructions[i]) positions[3] += positions[1] self.__verify_block(blocks[2], expected_instructions[3], expected_compiled_instructions[3]) self.__verify_block(blocks[1], expected_instructions[2], expected_compiled_instructions[2]) self.__verify_block(blocks[0], expected_instructions[1], expected_compiled_instructions[1]) self.__verify_block(main_block, expected_instructions[0], expected_compiled_instructions[0]) self.assertEqual(positions[3], blocks[2].get_start_address()) self.assertEqual(positions[2], blocks[1].get_start_address()) self.assertEqual(positions[1], blocks[0].get_start_address()) self.assertEqual(positions[0], main_block.get_start_address()) for instruction in main_block.instructions: if isinstance(instruction, GOTOInstruction) or isinstance(instruction, CJMPInstruction): self.assertIsInstance(instruction.target.get_absolute_address(), int)
def __verify_block(self, block: InstructionBlock, expected_instructions: InstructionSequence, expected_compiled_instructions: InstructionSequence) -> None: self.assertEqual(len(expected_instructions), len(block)) self.assertEqual(expected_instructions, block.instructions) self.assertEqual(expected_compiled_instructions, block.compile_sequence())
def test_empty_unreturning_main_block(self) -> None: block = InstructionBlock() self.__verify_block(block, [], [STOPInstruction()]) self.assertEqual(0, block.get_start_address()) self.assertIsNone(block.return_ip) self.__verify_block(block, [], [STOPInstruction()])