def test_build_sequence(self) -> None: sub1 = DummyPulseTemplate(requires_stop=False) sub2 = DummyPulseTemplate(requires_stop=True, parameter_names={'foo'}) parameters = {'foo': DummyNoValueParameter()} sequencer = DummySequencer() block = DummyInstructionBlock() seq = SequencePulseTemplate(sub1, (sub2, { 'foo': 'foo' }), external_parameters={'foo'}, measurements=[('a', 0, 1)]) seq.build_sequence(sequencer, parameters, conditions=dict(), channel_mapping={'default': 'a'}, measurement_mapping={'a': 'b'}, instruction_block=block) self.assertEqual(2, len(sequencer.sequencing_stacks[block])) self.assertEqual(block.instructions[0], MEASInstruction([('b', 0, 1)])) sequencer = DummySequencer() block = DummyInstructionBlock() seq = SequencePulseTemplate((sub2, { 'foo': 'foo' }), sub1, external_parameters={'foo'}) seq.build_sequence(sequencer, parameters, {}, {}, {}, block) self.assertEqual(2, len(sequencer.sequencing_stacks[block]))
def setUp(self) -> None: self.maxDiff = None self.if_dummy = DummyPulseTemplate(num_channels=3, parameter_names={'foo', 'bar'}) self.else_dummy = DummyPulseTemplate(num_channels=3, parameter_names={'foo', 'hugo'}) self.template = BranchPulseTemplate('foo_condition', self.if_dummy, self.else_dummy) self.sequencer = DummySequencer() self.block = DummyInstructionBlock()
def test_build_sequence(self): measurement_mapping = {'meas1': 'meas2'} parameter_mapping = {'t': 'k'} template = DummyPulseTemplate( measurement_names=set(measurement_mapping.keys()), parameter_names=set(parameter_mapping.keys())) st = MappingPulseTemplate(template, parameter_mapping=parameter_mapping, measurement_mapping=measurement_mapping) sequencer = DummySequencer() block = DummyInstructionBlock() pre_parameters = {'k': ConstantParameter(5)} pre_measurement_mapping = {'meas2': 'meas3'} pre_channel_mapping = {'default': 'A'} conditions = dict(a=True) st.build_sequence(sequencer, pre_parameters, conditions, pre_measurement_mapping, pre_channel_mapping, block) self.assertEqual(template.build_sequence_calls, 1) forwarded_args = template.build_sequence_arguments[0] self.assertEqual(forwarded_args[0], sequencer) self.assertEqual(forwarded_args[1], st.map_parameters(pre_parameters)) self.assertEqual(forwarded_args[2], conditions) self.assertEqual( forwarded_args[3], st.get_updated_measurement_mapping(pre_measurement_mapping)) self.assertEqual(forwarded_args[4], st.get_updated_channel_mapping(pre_channel_mapping)) self.assertEqual(forwarded_args[5], block)
def test_build_sequence(self): dt = DummyPulseTemplate(parameter_names={'i'}) flt = ForLoopPulseTemplate(body=dt, loop_index='i', loop_range=('a', 'b', 'c'), measurements=[('A', 0, 1)], parameter_constraints=['c > 1']) sequencer = DummySequencer() block = DummyInstructionBlock() invalid_parameters = {'a': ConstantParameter(1), 'b': ConstantParameter(4), 'c': ConstantParameter(1)} parameters = {'a': ConstantParameter(1), 'b': ConstantParameter(4), 'c': ConstantParameter(2)} measurement_mapping = dict(A='B') channel_mapping = dict(C='D') with self.assertRaises(ParameterConstraintViolation): flt.build_sequence(sequencer, invalid_parameters, dict(), measurement_mapping, channel_mapping, block) self.assertEqual(block.instructions, []) self.assertNotIn(block, sequencer.sequencing_stacks) flt.build_sequence(sequencer, parameters, dict(), measurement_mapping, channel_mapping, block) self.assertEqual(block.instructions, [MEASInstruction(measurements=[('B', 0, 1)])]) expected_stack = [(dt, {'i': ConstantParameter(3)}, dict(), measurement_mapping, channel_mapping), (dt, {'i': ConstantParameter(1)}, dict(), measurement_mapping, channel_mapping)] self.assertEqual(sequencer.sequencing_stacks[block], expected_stack)
def setUp(self) -> None: self.body = DummyPulseTemplate() self.repetitions = 'foo' self.template = RepetitionPulseTemplate( self.body, self.repetitions, parameter_constraints=['foo<9']) self.sequencer = DummySequencer() self.block = DummyInstructionBlock()
def test_build_sequence_no_waveform(self) -> None: sequencer = DummySequencer() block = DummyInstructionBlock() template = AtomicPulseTemplateStub(None) template.build_sequence(sequencer, {}, {}, block) self.assertFalse(block.instructions)
def test_missing_parameter(self): sequencer = DummySequencer() block = DummyInstructionBlock() parameters = copy.deepcopy(self.parameters) parameters.pop('uptime') with self.assertRaises(ParameterNotProvidedException): self.sequence.build_sequence(sequencer, parameters, {}, block)
def test_build_sequence_empty(self) -> None: table = TablePulseTemplate() sequencer = DummySequencer() instruction_block = DummyInstructionBlock() table.build_sequence(sequencer, {}, {}, instruction_block) self.assertFalse(instruction_block.instructions) self.assertIsNone(table.build_waveform({}))
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_build_sequence_no_waveform(self) -> None: sequencer = DummySequencer() block = DummyInstructionBlock() template = AtomicPulseTemplateStub() with mock.patch.object(template, 'build_waveform', return_value=None): template.build_sequence(sequencer, {}, {}, {}, {}, block) self.assertFalse(block.instructions)
def test_build_sequence(self) -> None: wf = DummyWaveform() sequencer = DummySequencer() block = DummyInstructionBlock() template = AtomicPulseTemplateStub(wf) template.build_sequence(sequencer, {}, {}, block) self.assertEqual([EXECInstruction(wf)], block.instructions)
def test_condition_missing(self) -> None: body = DummyPulseTemplate(requires_stop=False) t = WhileLoopPulseTemplate('foo_cond', body) sequencer = DummySequencer() block = DummyInstructionBlock() with self.assertRaises(ConditionMissingException): t.requires_stop({}, {}) t.build_sequence(sequencer, {}, {}, {}, block)
def test_build_sequence(self) -> None: sub1 = DummyPulseTemplate(requires_stop=False) sub2 = DummyPulseTemplate(requires_stop=True, parameter_names={'foo'}) parameters = {'foo': DummyNoValueParameter()} sequencer = DummySequencer() block = DummyInstructionBlock() seq = SequencePulseTemplate([(sub1, {}), (sub2, { 'foo': 'foo' })], {'foo'}) seq.build_sequence(sequencer, parameters, {}, block) self.assertEqual(2, len(sequencer.sequencing_stacks[block])) sequencer = DummySequencer() block = DummyInstructionBlock() seq = SequencePulseTemplate([(sub2, { 'foo': 'foo' }), (sub1, {})], {'foo'}) seq.build_sequence(sequencer, parameters, {}, block) self.assertEqual(2, len(sequencer.sequencing_stacks[block]))
def test_crash(self) -> None: table = TablePulseTemplate( { 'default': [('ta', 'va', 'hold'), ('tb', 'vb', 'linear'), ('tend', 0, 'jump')] }, identifier='foo') external_parameters = ['ta', 'tb', 'tc', 'td', 'va', 'vb', 'tend'] first_mapping = { 'ta': 'ta', 'tb': 'tb', 'va': 'va', 'vb': 'vb', 'tend': 'tend' } second_mapping = { 'ta': 'tc', 'tb': 'td', 'va': 'vb', 'vb': 'va + vb', 'tend': '2 * tend' } sequence = SequencePulseTemplate( (table, first_mapping, {}), (table, second_mapping, {}), external_parameters=external_parameters) parameters = { 'ta': ConstantParameter(2), 'va': ConstantParameter(2), 'tb': ConstantParameter(4), 'vb': ConstantParameter(3), 'tc': ConstantParameter(5), 'td': ConstantParameter(11), 'tend': ConstantParameter(6) } sequencer = DummySequencer() block = DummyInstructionBlock() self.assertFalse(sequence.requires_stop(parameters, {})) sequence.build_sequence(sequencer, parameters=parameters, conditions={}, measurement_mapping={}, channel_mapping={'default': 'default'}, instruction_block=block) from qctoolkit.pulses.sequencing import Sequencer s = Sequencer() s.push(sequence, parameters, channel_mapping={'default': 'EXAMPLE_A'}) s.build()
def test_build_sequence_multi_one_channel_empty(self) -> None: table = TablePulseTemplate(channels=2) table.add_entry('foo', 4) parameters = {'foo': 3} instantiated_entries = table.get_entries_instantiated(parameters) sequencer = DummySequencer() instruction_block = DummyInstructionBlock() table.build_sequence(sequencer, parameters, {}, instruction_block) expected_waveform = TableWaveform(instantiated_entries) self.assertEqual(1, len(instruction_block.instructions)) instruction = instruction_block.instructions[0] self.assertIsInstance(instruction, EXECInstruction) self.assertEqual(expected_waveform, instruction.waveform) waveform = table.build_waveform(parameters) self.assertEqual(expected_waveform, waveform)
def test_build_sequence(self) -> None: table = TablePulseTemplate() foo_decl = ParameterDeclaration('foo', min=1) bar_decl = ParameterDeclaration('bar') table.add_entry(foo_decl, 'v', 'linear') table.add_entry(bar_decl, 0, 'jump') parameters = {'v': 2.3, 'foo': 1, 'bar': 4} instantiated_entries = tuple(table.get_entries_instantiated(parameters)) waveform = table.build_waveform(parameters) sequencer = DummySequencer() instruction_block = DummyInstructionBlock() table.build_sequence(sequencer, parameters, {}, instruction_block) expected_waveform = TableWaveform(instantiated_entries) self.assertEqual(1, len(instruction_block.instructions)) instruction = instruction_block.instructions[0] self.assertIsInstance(instruction, EXECInstruction) self.assertEqual(expected_waveform, instruction.waveform) self.assertEqual(expected_waveform, waveform)
def test_build_cannot_evaluate(self) -> None: sequencer = DummySequencer() block = DummyInstructionBlock() delegator = DummySequencingElement() body = DummySequencingElement() condition = SoftwareCondition(lambda loop_iteration: None) self.assertTrue(condition.requires_stop()) with self.assertRaises(ConditionEvaluationException): condition.build_sequence_loop(delegator, body, sequencer, {}, {}, {}, {}, block) with self.assertRaises(ConditionEvaluationException): condition.build_sequence_branch(delegator, body, body, sequencer, {}, {}, {}, {}, block) self.assertEqual(str(ConditionEvaluationException()), "The Condition can currently not be evaluated.")
def test_build_sequence_no_params(self) -> None: dummy1 = DummyPulseTemplate(parameter_names={'foo'}) pulse = MultiChannelPulseTemplate([(dummy1, { 'foo': '2*bar' }, [1]), (dummy1, { 'foo': '3' }, [0])], {'bar'}) self.assertEqual({'bar'}, pulse.parameter_names) self.assertEqual({ParameterDeclaration('bar')}, pulse.parameter_declarations) with self.assertRaises(ParameterNotProvidedException): pulse.build_waveform({}) with self.assertRaises(ParameterNotProvidedException): pulse.build_sequence(DummySequencer(), dict(), dict(), DummyInstructionBlock())
def test_build_sequence(self) -> None: condition = DummyCondition() body = DummyPulseTemplate() t = LoopPulseTemplate('foo_cond', body) sequencer = DummySequencer() block = DummyInstructionBlock() parameters = {} conditions = {'foo_cond': condition} t.build_sequence(sequencer, parameters, conditions, block) expected_data = dict(delegator=t, body=body, sequencer=sequencer, parameters=parameters, conditions=conditions, instruction_block=block) self.assertEqual(expected_data, condition.loop_call_data) self.assertFalse(condition.branch_call_data) self.assertFalse(sequencer.sequencing_stacks)
def test_crash(self) -> None: table = TablePulseTemplate(identifier='foo') table.add_entry('ta', 'va', interpolation='hold') table.add_entry('tb', 'vb', interpolation='linear') table.add_entry('tend', 0, interpolation='jump') external_parameters = ['ta', 'tb', 'tc', 'td', 'va', 'vb', 'tend'] first_mapping = { 'ta': 'ta', 'tb': 'tb', 'va': 'va', 'vb': 'vb', 'tend': 'tend' } second_mapping = { 'ta': 'tc', 'tb': 'td', 'va': 'vb', 'vb': 'va + vb', 'tend': '2 * tend' } sequence = SequencePulseTemplate([(table, first_mapping), (table, second_mapping)], external_parameters) parameters = { 'ta': ConstantParameter(2), 'va': ConstantParameter(2), 'tb': ConstantParameter(4), 'vb': ConstantParameter(3), 'tc': ConstantParameter(5), 'td': ConstantParameter(11), 'tend': ConstantParameter(6) } sequencer = DummySequencer() block = DummyInstructionBlock() self.assertFalse(sequence.requires_stop(parameters, {})) sequence.build_sequence(sequencer, parameters, {}, block) from qctoolkit.pulses.sequencing import Sequencer s = Sequencer() s.push(sequence, parameters) s.build()
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 test_build_sequence_loop_false(self): sequencer = DummySequencer() block = DummyInstructionBlock() delegator = DummySequencingElement() body = DummySequencingElement() callback = IterationCallbackDummy(False) condition = SoftwareCondition( lambda loop_iteration: callback.callback(loop_iteration)) condition.build_sequence_loop(delegator, body, sequencer, {}, {}, {}, {}, block) self.assertEqual(0, callback.loop_iteration) self.assertFalse(block.instructions) self.assertFalse(sequencer.sequencing_stacks) condition.build_sequence_loop(delegator, body, sequencer, {}, {}, {}, {}, block) self.assertEqual(0, callback.loop_iteration)
def test_build_sequence(self) -> None: measurement_windows = [('M', 0, 5)] single_wf = DummyWaveform(duration=6, defined_channels={'A'}) wf = MultiChannelWaveform([single_wf]) sequencer = DummySequencer() block = DummyInstructionBlock() template = AtomicPulseTemplateStub(waveform=wf, measurements=measurement_windows) template.build_sequence(sequencer, {}, {}, measurement_mapping={'M': 'N'}, channel_mapping={}, instruction_block=block) self.assertEqual(len(block.instructions), 2) meas, exec = block.instructions self.assertIsInstance(meas, MEASInstruction) self.assertEqual(meas.measurements, [('N', 0, 5)]) self.assertIsInstance(exec, EXECInstruction) self.assertEqual(exec.waveform.defined_channels, {'A'})
def test_build_sequence_branch_true(self): sequencer = DummySequencer() block = DummyInstructionBlock() delegator = DummySequencingElement() if_branch = DummySequencingElement() else_branch = DummySequencingElement() callback = IterationCallbackDummy(True) condition = SoftwareCondition( lambda loop_iteration: callback.callback(loop_iteration)) condition.build_sequence_branch(delegator, if_branch, else_branch, sequencer, {}, {}, {}, {}, block) self.assertEqual(0, callback.loop_iteration) self.assertFalse(block.instructions) self.assertEqual({block: [(if_branch, {}, {}, {}, {})]}, sequencer.sequencing_stacks) condition.build_sequence_branch(delegator, if_branch, else_branch, sequencer, {}, {}, {}, {}, block) self.assertEqual(0, callback.loop_iteration)
def test_build_sequence(self) -> None: condition = DummyCondition() body = DummyPulseTemplate() t = WhileLoopPulseTemplate('foo_cond', body) sequencer = DummySequencer() block = DummyInstructionBlock() parameters = {} conditions = {'foo_cond': condition} measurement_mapping = {'swag': 'aufdrehen'} channel_mapping = {} t.build_sequence(sequencer, parameters, conditions, measurement_mapping, channel_mapping, block) expected_data = dict(delegator=t, body=body, sequencer=sequencer, parameters=parameters, conditions=conditions, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, instruction_block=block) self.assertEqual(expected_data, condition.loop_call_data) self.assertFalse(condition.branch_call_data) self.assertFalse(sequencer.sequencing_stacks)
def test_build_sequence(self) -> None: measurement_windows = [('M', 0, 5)] single_wf = DummyWaveform(duration=6, defined_channels={'A'}) wf = MultiChannelWaveform([single_wf]) sequencer = DummySequencer() block = DummyInstructionBlock() parameters = { 'a': ConstantParameter(1), 'b': ConstantParameter(2), 'c': ConstantParameter(3) } expected_parameters = {'a': 1, 'b': 2} channel_mapping = {'B': 'A'} template = AtomicPulseTemplateStub(measurements=measurement_windows, parameter_names={'a', 'b'}) with mock.patch.object(template, 'build_waveform', return_value=wf) as build_waveform: template.build_sequence(sequencer, parameters=parameters, conditions={}, measurement_mapping={'M': 'N'}, channel_mapping=channel_mapping, instruction_block=block) build_waveform.assert_called_once_with( parameters=expected_parameters, channel_mapping=channel_mapping) self.assertEqual(len(block.instructions), 2) meas, exec = block.instructions self.assertIsInstance(meas, MEASInstruction) self.assertEqual(meas.measurements, [('N', 0, 5)]) self.assertIsInstance(exec, EXECInstruction) self.assertEqual(exec.waveform.defined_channels, {'A'})
def test_build_sequence_constraint_on_loop_var_exception(self): """This test is to assure the status-quo behavior of ForLoopPT handling parameter constraints affecting the loop index variable. Please see https://github.com/qutech/qupulse/issues/232 .""" with self.assertWarnsRegex( UserWarning, "constraint on a variable shadowing the loop index", msg= "ForLoopPT did not issue a warning when constraining the loop index" ): flt = ForLoopPulseTemplate( body=DummyPulseTemplate(parameter_names={'k', 'i'}), loop_index='i', loop_range=( 'a', 'b', 'c', ), parameter_constraints=['k<=f', 'k>i']) # loop index showing up in parameter_names because it appears in consraints self.assertEqual(flt.parameter_names, {'f', 'k', 'a', 'b', 'c', 'i'}) parameters = { 'k': ConstantParameter(1), 'a': ConstantParameter(0), 'b': ConstantParameter(2), 'c': ConstantParameter(1), 'f': ConstantParameter(2) } sequencer = DummySequencer() block = DummyInstructionBlock() # loop index not accessible in current build_sequence -> Exception self.assertRaises(ParameterNotProvidedException, flt.build_sequence, sequencer, parameters, dict(), dict(), dict(), block)
def setUp(self) -> None: self.body = DummyPulseTemplate() self.repetitions = ParameterDeclaration('foo', max=5) self.template = RepetitionPulseTemplate(self.body, self.repetitions) self.sequencer = DummySequencer() self.block = DummyInstructionBlock()