def test_map_parameters(self): template = DummyPulseTemplate(parameter_names={'foo', 'bar'}) st = MappingPulseTemplate(template, parameter_mapping={ 'foo': 't*k', 'bar': 't*l' }) parameters = { 't': ConstantParameter(3), 'k': ConstantParameter(2), 'l': ConstantParameter(7) } values = {'foo': 6, 'bar': 21} for k, v in st.map_parameters(parameters).items(): self.assertEqual(v.get_value(), values[k]) parameters.popitem() with self.assertRaises(ParameterNotProvidedException): st.map_parameters(parameters) parameters = dict(t=3, k=2, l=7) values = {'foo': 6, 'bar': 21} for k, v in st.map_parameters(parameters).items(): self.assertEqual(v, values[k]) with self.assertRaisesRegex(ValueError, "type of return value"): st.map_parameters({}) parameters = dict(t=3, k=2, l=ConstantParameter(7)) with self.assertRaisesRegex(TypeError, "neither all Parameter nor Real"): st.map_parameters(parameters)
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()} wm = {'foo': 'bar'} target_block = InstructionBlock() elem2 = DummySequencingElement(True) 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_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_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) instr, stop = sequencer.build() self.assertFalse(sequencer.has_finished()) self.assertIs(elem1, instr.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(), stop)
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=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_o2_m1_i2_tt_m1_i0_two_elements_main_block(self) -> None: sequencer = Sequencer() ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} elem1 = DummySequencingElement(False) elem2 = DummySequencingElement(False) sequencer.push(elem2, ps, cs) sequencer.push(elem1, ps, cs) sequence = sequencer.build() self.assertTrue(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.assertIs(elem2, sequence[1].elem) 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.assertEqual(STOPInstruction(), sequence[2]) self.assertEqual(3, len(sequence))
def test_build_path_o2_m1_i1_t_m2_i0_i1_f_one_element_main_block_adds_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) elem = DummySequencingElement(False, (new_block, [new_elem])) sequencer.push(elem, ps, cs) sequence = sequencer.build() self.assertFalse(sequencer.has_finished()) self.assertIs(elem, sequence[0].elem) self.assertEqual(ps, elem.parameters) self.assertEqual(cs, elem.conditions) self.assertEqual(1, elem.requires_stop_call_counter) self.assertEqual(1, elem.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 __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) # Setup test data self.square = TablePulseTemplate( { 'default': [(0, 0), ('up', 'v', 'hold'), ('down', 0, 'hold'), ('length', 0)] }, measurements=[('mw1', 'up', 'length-up')]) self.mapping1 = { 'up': 'uptime', 'down': 'uptime + length', 'v': 'voltage', 'length': '0.5 * pulse_length' } self.window_name_mapping = {'mw1': 'test_window'} self.outer_parameters = {'uptime', 'length', 'pulse_length', 'voltage'} self.parameters = dict() self.parameters['uptime'] = ConstantParameter(5) self.parameters['length'] = ConstantParameter(10) self.parameters['pulse_length'] = ConstantParameter(100) self.parameters['voltage'] = ConstantParameter(10) self.sequence = SequencePulseTemplate( MappingPulseTemplate(self.square, parameter_mapping=self.mapping1, measurement_mapping=self.window_name_mapping))
def test__create_program(self): parameters = {'a': ConstantParameter(.1), 'b': ConstantParameter(.2)} measurement_mapping = {'M': 'N'} channel_mapping = {'B': 'A'} global_transformation = TransformationStub() to_single_waveform = {'voll', 'toggo'} parent_loop = Loop() template = PulseTemplateStub() with mock.patch.object( template, '_internal_create_program') as _internal_create_program: template._create_program( parameters=parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, global_transformation=global_transformation, to_single_waveform=to_single_waveform, parent_loop=parent_loop) _internal_create_program.assert_called_once_with( parameters=parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, global_transformation=global_transformation, to_single_waveform=to_single_waveform, parent_loop=parent_loop) self.assertEqual(parent_loop, Loop())
def test_create_program_invalid_params(self) -> None: dt = DummyPulseTemplate(parameter_names={'i'}, waveform=DummyWaveform(duration=4.0), duration=4, measurements=[('b', 2, 1)]) flt = ForLoopPulseTemplate(body=dt, loop_index='i', loop_range=('a', 'b', 'c'), measurements=[('A', 0, 1)], parameter_constraints=['c > 1']) invalid_parameters = { 'a': ConstantParameter(1), 'b': ConstantParameter(4), 'c': ConstantParameter(1) } measurement_mapping = dict(A='B') channel_mapping = dict(C='D') children = [Loop(waveform=DummyWaveform(duration=2.0))] program = Loop(children=children) with self.assertRaises(ParameterConstraintViolation): flt._internal_create_program( parameters=invalid_parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, parent_loop=program, to_single_waveform=set(), global_transformation=None) self.assertEqual(children, program.children) self.assertEqual(1, program.repetition_count) self.assertIsNone(program._measurements) self.assert_measurement_windows_equal( {}, program.get_measurement_windows())
def test_create_program_none(self) -> None: template = PulseTemplateStub(defined_channels={'A'}, parameter_names={'foo'}) parameters = { 'foo': ConstantParameter(2.126), 'bar': -26.2, 'hugo': 'exp(sin(pi/2))' } measurement_mapping = {'M': 'N'} channel_mapping = {'A': 'B'} expected_parameters = { 'foo': ConstantParameter(2.126), 'bar': ConstantParameter(-26.2), 'hugo': ConstantParameter('exp(sin(pi/2))') } expected_internal_kwargs = dict( parameters=expected_parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, global_transformation=None, to_single_waveform=set()) with mock.patch.object( template, '_internal_create_program') as _internal_create_program: program = template.create_program( parameters=parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping) _internal_create_program.assert_called_once_with( **expected_internal_kwargs, parent_loop=Loop()) self.assertIsNone(program)
def test_internal_create_program_parameter_missing(self) -> None: sub1 = DummyPulseTemplate(duration=3, waveform=DummyWaveform(duration=3), measurements=[('b', 1, 2)]) sub2 = DummyPulseTemplate(duration='d', waveform=DummyWaveform(duration=2), parameter_names={'foo'}) seq = SequencePulseTemplate(sub1, sub2, measurements=[('a', 'bar', 1)], parameter_constraints={'foo < 2'}) loop = Loop() # test parameter from constraints parameters = {} with self.assertRaises(ParameterNotProvidedException): seq._internal_create_program(parameters=parameters, measurement_mapping={'a': 'a', 'b': 'b'}, channel_mapping=dict(), global_transformation=None, to_single_waveform=set(), parent_loop=loop) # test parameter from measurements parameters = {'foo': ConstantParameter(1)} with self.assertRaises(ParameterNotProvidedException): seq._internal_create_program(parameters=parameters, measurement_mapping={'a': 'a', 'b': 'b'}, channel_mapping=dict(), global_transformation=None, to_single_waveform=set(), parent_loop=loop) # test parameter from duration parameters = {'foo': ConstantParameter(1), 'bar': ConstantParameter(0)} with self.assertRaises(ParameterNotProvidedException): seq._internal_create_program(parameters=parameters, measurement_mapping={'a': 'a', 'b': 'b'}, channel_mapping=dict(), global_transformation=None, to_single_waveform=set(), parent_loop=loop)
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()} wm = {} cm = {} elem_main = DummySequencingElement(True) sequencer.push(elem_main, ps, cs, channel_mapping=cm) elem_cstm = DummySequencingElement(True) target_block = InstructionBlock() sequencer.push(elem_cstm, ps, cs, window_mapping=wm, channel_mapping=cm, target_block=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_push(self) -> None: sequencer = Sequencer() ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} wm = {'foo' : 'bar'} elem = DummySequencingElement() sequencer.push(elem, ps, cs, window_mapping=wm) self.assertFalse(sequencer.has_finished()) sequencer.build() self.assertEqual(ps, elem.parameters)
def test_internal_create_program(self): template = DummyPulseTemplate(duration='t1', defined_channels={'X', 'Y'}, parameter_names={'a', 'b'}, measurement_names={'M'}, waveform=DummyWaveform()) overwritten_channels = {'Y': 'c', 'Z': 'a'} parent_loop = object() measurement_mapping = object() channel_mapping = object() to_single_waveform = object() other_kwargs = dict(measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, to_single_waveform=to_single_waveform, parent_loop=parent_loop) pccpt = ParallelConstantChannelPulseTemplate(template, overwritten_channels) parameters = {'c': ConstantParameter(1.2), 'a': ConstantParameter(3.4)} kwargs = { **other_kwargs, 'parameters': parameters.copy(), 'global_transformation': None } expected_overwritten_channels = {'Y': 1.2, 'Z': 3.4} expected_transformation = ParallelConstantChannelTransformation( expected_overwritten_channels) expected_kwargs = { **kwargs, 'global_transformation': expected_transformation } template._create_program = mock.Mock() pccpt._internal_create_program(**kwargs) template._create_program.assert_called_once_with(**expected_kwargs) global_transformation = LinearTransformation(numpy.zeros((0, 0)), [], []) expected_transformation = chain_transformations( global_transformation, expected_transformation) kwargs = { **other_kwargs, 'parameters': parameters.copy(), 'global_transformation': global_transformation } expected_kwargs = { **kwargs, 'global_transformation': expected_transformation } template._create_program = mock.Mock() pccpt._internal_create_program(**kwargs) template._create_program.assert_called_once_with(**expected_kwargs)
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_build_path_o1_m1_i1_f_single_element_requires_stop_main_block(self) -> None: sequencer = Sequencer() elem = DummySequencingElement(True) ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} sequencer.push(elem, ps, cs) sequencer.build() self.assertFalse(sequencer.has_finished()) self.assertEqual(ps, elem.parameters) self.assertEqual(cs, elem.conditions) self.assertEqual(1, elem.requires_stop_call_counter) self.assertEqual(0, elem.build_call_counter)
def test_create_program(self) -> None: template = PulseTemplateStub(defined_channels={'A'}, parameter_names={'foo'}) parameters = { 'foo': ConstantParameter(2.126), 'bar': -26.2, 'hugo': 'exp(sin(pi/2))', 'append_a_child': '1' } previous_parameters = parameters.copy() measurement_mapping = {'M': 'N'} previos_measurement_mapping = measurement_mapping.copy() channel_mapping = {'A': 'B'} previous_channel_mapping = channel_mapping.copy() expected_parameters = { 'foo': ConstantParameter(2.126), 'bar': ConstantParameter(-26.2), 'hugo': ConstantParameter('exp(sin(pi/2))'), 'append_a_child': ConstantParameter('1') } to_single_waveform = {'voll', 'toggo'} global_transformation = TransformationStub() expected_internal_kwargs = dict( parameters=expected_parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, global_transformation=global_transformation, to_single_waveform=to_single_waveform) dummy_waveform = DummyWaveform() expected_program = Loop(children=[Loop(waveform=dummy_waveform)]) with mock.patch.object(template, '_create_program', wraps=get_appending_internal_create_program( dummy_waveform)) as _create_program: program = template.create_program( parameters=parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, to_single_waveform=to_single_waveform, global_transformation=global_transformation) _create_program.assert_called_once_with(**expected_internal_kwargs, parent_loop=program) self.assertEqual(expected_program, program) self.assertEqual(previos_measurement_mapping, measurement_mapping) self.assertEqual(previous_channel_mapping, channel_mapping) self.assertEqual(previous_parameters, parameters)
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_create_program_parameter_constraint_violation(self) -> None: measurement_mapping = {'meas1': 'meas2'} parameter_mapping = {'t': 'k'} channel_mapping = {'B': 'default'} template = DummyPulseTemplate(measurements=[('meas1', 0, 1)], measurement_names={'meas1'}, defined_channels={'B'}, waveform=DummyWaveform(duration=2.0), duration=2, parameter_names={'t'}) st = MappingPulseTemplate(template, parameter_mapping=parameter_mapping, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, parameter_constraints={'k > 6'}) pre_parameters = {'k': ConstantParameter(5)} pre_measurement_mapping = {'meas2': 'meas3'} pre_channel_mapping = {'default': 'A'} program = Loop() with self.assertRaises(ParameterConstraintViolation): st._internal_create_program( parameters=pre_parameters, measurement_mapping=pre_measurement_mapping, channel_mapping=pre_channel_mapping, to_single_waveform=set(), global_transformation=None, parent_loop=program)
def test_create_program_declaration_parameter_not_provided(self) -> None: repetitions = "foo" body = DummyPulseTemplate(waveform=DummyWaveform(duration=2.0)) t = RepetitionPulseTemplate(body, repetitions, parameter_constraints=['foo<9'], measurements=[('a', 'd', 1)]) scope = DictScope.from_kwargs() measurement_mapping = dict(moth='fire') channel_mapping = dict(asd='f') children = [Loop(waveform=DummyWaveform(duration=0))] program = Loop(children=children) with self.assertRaises(ParameterNotProvidedException): t._internal_create_program(scope=scope, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, to_single_waveform=set(), global_transformation=None, parent_loop=program) parameters = {'foo': ConstantParameter(7)} with self.assertRaises(ParameterNotProvidedException): t._internal_create_program(scope=scope, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, to_single_waveform=set(), global_transformation=None, parent_loop=program) self.assertFalse(body.create_program_calls) self.assertEqual(1, program.repetition_count) self.assertEqual(children, list(program.children)) self.assertIsNone(program.waveform) self.assert_measurement_windows_equal( {}, program.get_measurement_windows())
def test_create_program_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) } # loop index not accessible in current build_sequence -> Exception children = [Loop(waveform=DummyWaveform(duration=2.0))] program = Loop(children=children) with self.assertRaises(ParameterNotProvidedException): flt._internal_create_program(parameters=parameters, measurement_mapping=dict(), channel_mapping=dict(), parent_loop=program, to_single_waveform=set(), global_transformation=None) self.assertEqual(children, program.children) self.assertEqual(1, program.repetition_count) self.assertIsNone(program._measurements) self.assert_measurement_windows_equal( {}, program.get_measurement_windows())
def test_build_sequence(self): wfs = [ DummyWaveform(duration=1.1, defined_channels={'A'}), DummyWaveform(duration=1.1, defined_channels={'B'}) ] sts = [ DummyPulseTemplate(duration='t1', defined_channels={'A'}, waveform=wfs[0], measurements=[('m', 0, 1)]), DummyPulseTemplate(duration='t1', defined_channels={'B'}, waveform=wfs[1]), DummyPulseTemplate(duration='t1', defined_channels={'C'}, waveform=None) ] pt = AtomicMultiChannelPulseTemplate(*sts, parameter_constraints=['a < b'], measurements=[('n', .1, .2)]) params = dict(a=ConstantParameter(1.0), b=ConstantParameter(1.1)) measurement_mapping = dict(m='foo', n='bar') channel_mapping = {'A': 'A', 'B': 'B', 'C': None} block = InstructionBlock() pt.build_sequence(None, parameters=params, conditions={}, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, instruction_block=block) expected_waveform = MultiChannelWaveform(wfs) expected_block = InstructionBlock() measurements = [('bar', .1, .2), ('foo', 0, 1)] expected_block.add_instruction_meas(measurements) expected_block.add_instruction_exec(waveform=expected_waveform) self.assertEqual(len(block.instructions), len(expected_block.instructions)) self.assertEqual(block.instructions[0].compare_key, expected_block.instructions[0].compare_key) self.assertEqual(block.instructions[1].compare_key, expected_block.instructions[1].compare_key)
def test_create_program_body_none(self) -> None: dt = DummyPulseTemplate(parameter_names={'i'}, waveform=None, duration=0, measurements=[('b', 2, 1)]) flt = ForLoopPulseTemplate(body=dt, loop_index='i', loop_range=('a', 'b', 'c'), measurements=[('A', 0, 1)], parameter_constraints=['c > 1']) parameters = { 'a': ConstantParameter(1), 'b': ConstantParameter(4), 'c': ConstantParameter(2) } measurement_mapping = dict(A='B', b='b') channel_mapping = dict(C='D') program = Loop() flt._internal_create_program(parameters=parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, parent_loop=program, to_single_waveform=set(), global_transformation=None) self.assertEqual(0, len(program.children)) self.assertEqual(1, program.repetition_count) self.assertEqual([], program.children) # ensure same result as from Sequencer sequencer = Sequencer() sequencer.push(flt, parameters=parameters, conditions={}, window_mapping=measurement_mapping, channel_mapping=channel_mapping) block = sequencer.build() program_old = MultiChannelProgram( block, channels={'A'}).programs[frozenset({'A'})] self.assertEqual(program_old.repetition_count, program.repetition_count) self.assertEqual(program_old.children, program.children) self.assertEqual(program_old.waveform, program.waveform)
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 create_program(self, *, parameters: Optional[Mapping[str, Union[Parameter, float, Expression, str, Real]]]=None, measurement_mapping: Optional[Mapping[str, Optional[str]]]=None, channel_mapping: Optional[Mapping[ChannelID, Optional[ChannelID]]]=None, global_transformation: Optional[Transformation]=None, to_single_waveform: Set[Union[str, 'PulseTemplate']]=None) -> Optional['Loop']: """Translates this PulseTemplate into a program Loop. The returned Loop represents the PulseTemplate with all parameter values instantiated provided as dictated by the parameters argument. Optionally, channels and measurements defined in the PulseTemplate can be renamed/mapped via the channel_mapping and measurement_mapping arguments. Args: parameters: A mapping of parameter names to Parameter objects. measurement_mapping: A mapping of measurement window names. Windows that are mapped to None are omitted. channel_mapping: A mapping of channel names. Channels that are mapped to None are omitted. global_transformation: This transformation is applied to every waveform to_single_waveform: A set of pulse templates (or identifiers) which are directly translated to a waveform. This might change how transformations are applied. TODO: clarify Returns: A Loop object corresponding to this PulseTemplate. """ if parameters is None: parameters = dict() if measurement_mapping is None: measurement_mapping = {name: name for name in self.measurement_names} if channel_mapping is None: channel_mapping = dict() if to_single_waveform is None: to_single_waveform = set() # make sure all channels are mapped complete_channel_mapping = {channel: channel for channel in self.defined_channels} complete_channel_mapping.update(channel_mapping) non_unique_targets = {channel for channel, count in collections.Counter(channel_mapping.values()).items() if count > 1 and channel is not None} if non_unique_targets: raise ValueError('The following channels are mapped to twice', non_unique_targets) # make sure all values in the parameters dict are of type Parameter parameters = {key: value if isinstance(value, Parameter) else ConstantParameter(value) for key, value in parameters.items()} root_loop = Loop() # call subclass specific implementation self._create_program(parameters=parameters, measurement_mapping=measurement_mapping, channel_mapping=complete_channel_mapping, global_transformation=global_transformation, to_single_waveform=to_single_waveform, parent_loop=root_loop) if root_loop.waveform is None and len(root_loop.children) == 0: return None # return None if no program return root_loop
def _body_parameter_generator(self, parameters: Dict[str, Parameter], forward=True) -> Generator: loop_range_parameters = dict((parameter_name, parameters[parameter_name].get_value()) for parameter_name in self._loop_range.parameter_names) loop_range = self._loop_range.to_range(loop_range_parameters) parameters = dict((parameter_name, parameters[parameter_name]) for parameter_name in self.body.parameter_names if parameter_name != self._loop_index) loop_range = loop_range if forward else reversed(loop_range) for loop_index_value in loop_range: local_parameters = parameters.copy() local_parameters[self._loop_index] = ConstantParameter(loop_index_value) yield local_parameters
def test_create_program_append(self) -> None: dt = DummyPulseTemplate(parameter_names={'i'}, waveform=DummyWaveform(duration=4.0), duration=4, measurements=[('b', 2, 1)]) flt = ForLoopPulseTemplate(body=dt, loop_index='i', loop_range=('a', 'b', 'c'), measurements=[('A', 0, 1)], parameter_constraints=['c > 1']) parameters = { 'a': ConstantParameter(1), 'b': ConstantParameter(4), 'c': ConstantParameter(2) } measurement_mapping = dict(A='B', b='b') channel_mapping = dict(C='D') children = [Loop(waveform=DummyWaveform(duration=2.0))] program = Loop(children=children) flt._internal_create_program(parameters=parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, parent_loop=program, to_single_waveform=set(), global_transformation=None) self.assertEqual(3, len(program.children)) self.assertIs(children[0], program.children[0]) self.assertEqual(dt.waveform, program.children[1].waveform) self.assertEqual(dt.waveform, program.children[2].waveform) self.assertEqual(1, program.children[1].repetition_count) self.assertEqual(1, program.children[2].repetition_count) self.assertEqual(1, program.repetition_count) self.assert_measurement_windows_equal( { 'b': ([4, 8], [1, 1]), 'B': ([2], [1]) }, program.get_measurement_windows())
def test_internal_create_program_invalid_measurement_mapping(self) -> None: measurement_windows = [('M', 0, 5)] wf = DummyWaveform(duration=6, defined_channels={'A'}) template = AtomicPulseTemplateStub(measurements=measurement_windows, parameter_names={'foo'}) parameters = {'foo': ConstantParameter(7.2)} program = Loop() with self.assertRaises(KeyError): template._internal_create_program(parameters=parameters, measurement_mapping=dict(), channel_mapping=dict(), parent_loop=program)
def test_internal_create_program_parameter_constraint_violations(self) -> None: sub1 = DummyPulseTemplate(duration=3, waveform=DummyWaveform(duration=3), measurements=[('b', 1, 2)]) sub2 = DummyPulseTemplate(duration=2, waveform=DummyWaveform(duration=2), parameter_names={'foo'}) parameters = {'foo': ConstantParameter(7)} seq = SequencePulseTemplate(sub1, sub2, measurements=[('a', 0, 1)], parameter_constraints={'foo < 2'}) loop = Loop() with self.assertRaises(ParameterConstraintViolation): seq._internal_create_program(parameters=parameters, measurement_mapping={'a': 'a', 'b': 'b'}, channel_mapping=dict(), global_transformation=None, to_single_waveform=set(), parent_loop=loop)