def test_overwrite(self): inner = DictScope(FrozenDict({ 'a': 0.5, 'i': 3 }), volatile=frozenset(['a'])) fscope = _ForLoopScope(inner, 'i', 4) self.assertIn('i', fscope) self.assertIn('a', fscope) self.assertNotIn('j', fscope) equivalent = {'a': 0.5, 'i': 4} self.assertEqual(equivalent, dict(fscope)) self.assertEqual(equivalent.items(), fscope.items()) self.assertEqual(equivalent.keys(), fscope.keys()) self.assertEqual(set(equivalent.values()), set(fscope.values())) self.assertEqual(0.5, fscope['a']) self.assertEqual(4, fscope['i']) self.assertEqual(FrozenDict({'a': ExpressionScalar('a')}), fscope.get_volatile_parameters()) inner = DictScope(FrozenDict({ 'a': 0.5, 'i': 3 }), volatile=frozenset(['a', 'i'])) fscope = _ForLoopScope(inner, 'i', 4) self.assertEqual(FrozenDict({'a': ExpressionScalar('a')}), fscope.get_volatile_parameters())
def test_from_kwargs(self): m = {'a': 1, 'b': 2} volatile = {'a'} ds = DictScope.from_kwargs(a=1, b=2) self.assertEqual(DictScope(FrozenDict(m)), ds) ds = DictScope.from_kwargs(a=1, b=2, volatile=volatile.copy()) self.assertEqual(DictScope(FrozenDict(m), frozenset(volatile)), ds)
def test_init(self): with self.assertRaises(AssertionError): DictScope(dict()) fd = FrozenDict({'a': 2}) ds = DictScope(fd) self.assertIs(fd, ds._values) self.assertEqual(FrozenDict(), ds._volatile_parameters) vp = frozenset('a') ds = DictScope(fd, vp) self.assertIs(fd, ds._values) self.assertEqual(FrozenDict(a=ExpressionScalar('a')), ds._volatile_parameters)
def test_eq(self): ds = DictScope(FrozenDict({'a': 1, 'b': 2}), volatile=frozenset('a')) ds1 = DictScope(FrozenDict({'a': 1, 'b': 2}), volatile=frozenset()) ds2 = DictScope(FrozenDict({'a': 1, 'b': 2}), volatile=frozenset('a')) ds3 = DictScope(FrozenDict({'a': 1, 'b': 2}), volatile=frozenset('ab')) ds4 = DictScope(FrozenDict({'a': 1, 'b': 2, 'c': 3}), volatile=frozenset('a')) self.assertNotEqual(ds, ds1) self.assertNotEqual(ds, ds3) self.assertNotEqual(ds, ds4) self.assertEqual(ds, ds2) self.assertEqual(hash(ds), hash(ds2)) self.assertNotEqual(ds1, ds2) self.assertNotEqual(ds2, ds3) self.assertNotEqual(ds3, ds4)
def test_from_mapping(self): m = {'a': 1, 'b': 2} volatile = {'a'} ds = DictScope.from_mapping(m.copy()) self.assertEqual(m, dict(ds)) self.assertEqual(FrozenDict(), ds.get_volatile_parameters()) ds = DictScope.from_mapping(m.copy(), volatile=volatile.copy()) self.assertEqual(DictScope(FrozenDict(m), frozenset(volatile)), ds)
def test_get_parameter(self): ds = DictScope(FrozenDict({'a': 1, 'b': 2})) self.assertEqual(1, ds.get_parameter('a')) self.assertEqual(2, ds.get_parameter('b')) with self.assertRaises(ParameterNotProvidedException) as cm: ds.get_parameter('c') self.assertEqual('c', cm.exception.parameter_name)
def test_update_volatile_parameters_with_depth1(self): parameters = {'s': 10, 'not': 13} s = VolatileRepetitionCount(expression=ExpressionScalar('s'), scope=DictScope(values=FrozenDict(s=3), volatile=set('s'))) wf_1 = DummyWaveform(defined_channels={'A'}, duration=1) wf_2 = DummyWaveform(defined_channels={'A'}, duration=1) program = Loop(children=[ Loop(waveform=wf_1, repetition_count=s), Loop(waveform=wf_2, repetition_count=4), Loop(waveform=wf_1, repetition_count=1) ], repetition_count=1) t_program = TaborProgram(program, channels=(None, 'A'), markers=(None, None), device_properties=self.instr_props, **self.program_entry_kwargs) self.assertEqual(t_program.get_sequencer_tables(), [[(TableDescription(3, 0, 0), s.volatile_property), (TableDescription(4, 1, 0), None), (TableDescription(1, 0, 0), None)]]) self.assertEqual(t_program.get_advanced_sequencer_table(), [TableDescription(1, 1, 0)]) modifications = t_program.update_volatile_parameters(parameters) expected_seq = VolatileRepetitionCount( expression=ExpressionScalar('s'), scope=DictScope(values=FrozenDict(s=10), volatile=set('s'))) expected_modifications = {(0, 0): TableDescription(10, 0, 0)} self.assertEqual( t_program.get_sequencer_tables(), [[(TableDescription(10, 0, 0), expected_seq.volatile_property), (TableDescription(4, 1, 0), None), (TableDescription(1, 0, 0), None)]]) self.assertEqual(t_program.get_advanced_sequencer_table(), [TableDescription(1, 1, 0)]) self.assertEqual(modifications, expected_modifications)
def test_change_constants(self): volatile = frozenset('b') volatile_dict = FrozenDict(b=ExpressionScalar('b')) ds = DictScope(FrozenDict({'a': 1, 'b': 2}), volatile=volatile) changes = {'b': 3, 'c': 4} ds2 = ds.change_constants(changes) self.assertEqual({'a': 1, 'b': 2}, dict(ds)) self.assertEqual(volatile_dict, ds.get_volatile_parameters()) self.assertEqual({'a': 1, 'b': 3}, dict(ds2)) self.assertEqual(volatile_dict, ds2.get_volatile_parameters()) with self.assertWarns(NonVolatileChange): ds.change_constants({'a': 2, 'b': 3, 'c': 4})
def test_mapping(self): ds = DictScope(FrozenDict({'a': 1, 'b': 2})) self.assertIn('a', ds) self.assertNotIn('c', ds) self.assertEqual(set('ab'), set(ds.keys())) self.assertEqual(set('ab'), set(ds)) self.assertEqual({1, 2}, set(ds.values())) self.assertEqual({('a', 1), ('b', 2)}, set(ds.items())) self.assertEqual({'a': 1, 'b': 2}, dict(ds)) self.assertEqual(1, ds['a']) with self.assertRaises(KeyError): ds['c'] with self.assertRaises(TypeError): ds['a'] = 3
def create_program( self, *, parameters: Optional[Mapping[str, Union[Expression, str, Number, ConstantParameter]]] = 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, volatile: Set[str] = 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 volatile: Everything in the final program that depends on these parameters is marked as volatile 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() if volatile is None: volatile = 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 numbers if isinstance(parameters, Scope): assert not volatile scope = parameters else: parameters = dict(parameters) for parameter_name, value in parameters.items(): if isinstance(value, Parameter): parameters[parameter_name] = value.get_value() elif not isinstance(value, Number): parameters[parameter_name] = Expression( value).evaluate_numeric() scope = DictScope(values=FrozenDict(parameters), volatile=volatile) root_loop = Loop() # call subclass specific implementation self._create_program(scope=scope, 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 test_get_volatile(self): volatile = frozenset('ab') volatile_dict = FrozenDict(a=ExpressionScalar('a'), b=ExpressionScalar('b')) ds = DictScope(FrozenDict({'a': 1, 'b': 2}), volatile=volatile) self.assertEqual(volatile_dict, ds.get_volatile_parameters())