def test_is_interruptable(self) -> None: body = DummyPulseTemplate(is_interruptable=False) t = RepetitionPulseTemplate(body, 6) self.assertFalse(t.is_interruptable) body.is_interruptable_ = True self.assertTrue(t.is_interruptable)
def test_is_interruptable(self) -> None: condition = DummyCondition() body = DummyPulseTemplate(is_interruptable=False) t = LoopPulseTemplate(condition, body) self.assertFalse(t.is_interruptable) body.is_interruptable_ = True self.assertTrue(t.is_interruptable)
def test_parameter_names_and_declarations(self) -> None: body = DummyPulseTemplate() t = RepetitionPulseTemplate(body, 5) self.assertEqual(body.parameter_names, t.parameter_names) self.assertEqual(body.parameter_declarations, t.parameter_declarations) body.parameter_names_ = {'foo', 't', 'bar'} self.assertEqual(body.parameter_names, t.parameter_names) self.assertEqual(body.parameter_declarations, t.parameter_declarations)
def test_parameter_names_and_declarations(self) -> None: condition = DummyCondition() body = DummyPulseTemplate() t = LoopPulseTemplate(condition, body) self.assertEqual(body.parameter_names, t.parameter_names) self.assertEqual(body.parameter_declarations, t.parameter_declarations) body.parameter_names_ = {'foo', 't', 'bar'} self.assertEqual(body.parameter_names, t.parameter_names) self.assertEqual(body.parameter_declarations, t.parameter_declarations)
def test_requires_stop(self) -> None: condition = DummyCondition(requires_stop=False) conditions = {'foo_cond': condition} body = DummyPulseTemplate(requires_stop=False) t = LoopPulseTemplate('foo_cond', body) self.assertFalse(t.requires_stop({}, conditions)) condition.requires_stop_ = True self.assertTrue(t.requires_stop({}, conditions)) body.requires_stop_ = True condition.requires_stop_ = False self.assertFalse(t.requires_stop({}, conditions))
def test_requires_stop_declaration(self) -> None: body = DummyPulseTemplate(requires_stop=False) t = RepetitionPulseTemplate(body, ParameterDeclaration('foo')) parameter = DummyParameter() parameters = dict(foo=parameter) condition = DummyCondition() conditions = dict(foo=condition) for body_requires_stop in [True, False]: for condition_requires_stop in [True, False]: for parameter_requires_stop in [True, False]: body.requires_stop_ = body_requires_stop condition.requires_stop_ = condition_requires_stop parameter.requires_stop_ = parameter_requires_stop self.assertEqual(parameter_requires_stop, t.requires_stop(parameters, conditions))
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 __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.subtemplates = [ DummyPulseTemplate(parameter_names={'p1'}, measurement_names={'m1'}, defined_channels={'c1'}), DummyPulseTemplate(parameter_names={'p2'}, measurement_names={'m2'}, defined_channels={'c2'}), DummyPulseTemplate(parameter_names={'p3'}, measurement_names={'m3'}, defined_channels={'c3'}) ] self.no_param_maps = [{'p1': '1'}, {'p2': '2'}, {'p3': '3'}] self.param_maps = [{'p1': 'pp1'}, {'p2': 'pp2'}, {'p3': 'pp3'}] self.chan_maps = [{'c1': 'cc1'}, {'c2': 'cc2'}, {'c3': 'cc3'}]
def test_duration(self): seconds2ns = 1e9 pulse_duration = 1.0765001496284785e-07 dpt = DummyPulseTemplate(duration=Expression('duration'), parameter_names={'duration'}, defined_channels={'A'}) mpt = MappingPulseTemplate(dpt, parameter_mapping={'duration': seconds2ns * pulse_duration}) self.assertEqual(seconds2ns * pulse_duration, mpt.duration)
def test_constrained(self): template = DummyPulseTemplate(parameter_names={'foo', 'bar'}) st = MappingPulseTemplate(template, parameter_mapping={'foo': 't*k', 'bar': 't*l'}, parameter_constraints=['t < m']) external_params = {'t', 'l', 'k', 'm'} self.assertEqual(st.parameter_names, external_params) with self.assertRaises(ParameterConstraintViolation): st.map_parameters(dict(t=1, l=2, k=3, m=0))
def test_requires_stop_declaration(self) -> None: body = DummyPulseTemplate(requires_stop=False) t = RepetitionPulseTemplate(body, 'foo') parameter = DummyParameter() parameters = dict(foo=parameter) condition = DummyCondition() conditions = dict(foo=condition) for body_requires_stop in [True, False]: for condition_requires_stop in [True, False]: for parameter_requires_stop in [True, False]: body.requires_stop_ = body_requires_stop condition.requires_stop_ = condition_requires_stop parameter.requires_stop_ = parameter_requires_stop self.assertEqual(parameter_requires_stop, t.requires_stop(parameters, conditions))
def test_simple_attributes(self): lhs = DummyPulseTemplate(defined_channels={'a', 'b'}, duration=ExpressionScalar('t_dur'), measurement_names={'m1'}) rhs = 4 arith = ArithmeticPulseTemplate(lhs, '+', rhs) self.assertIs(lhs.duration, arith.duration) self.assertIs(lhs.measurement_names, arith.measurement_names)
def test_init(self): lhs = DummyPulseTemplate(duration=4, defined_channels={'a', 'b'}, parameter_names={'x', 'y'}) rhs = DummyPulseTemplate(duration=4, defined_channels={'a', 'c'}, parameter_names={'x', 'z'}) with self.assertRaisesRegex(TypeError, 'needs to be a pulse template'): ArithmeticPulseTemplate('a', '+', 'b') with self.assertRaisesRegex(TypeError, 'two PulseTemplates'): ArithmeticPulseTemplate(lhs, '+', rhs) with self.assertRaisesRegex( ValueError, r'Operands \(scalar, PulseTemplate\) require'): ArithmeticPulseTemplate(4, '/', rhs) with self.assertRaisesRegex( ValueError, r'Operands \(PulseTemplate, scalar\) require'): ArithmeticPulseTemplate(lhs, '%', 4) scalar = mock.Mock() non_pt = mock.Mock() with mock.patch.object(ArithmeticPulseTemplate, '_parse_operand', return_value=scalar) as parse_operand: arith = ArithmeticPulseTemplate(lhs, '/', non_pt) parse_operand.assert_called_once_with(non_pt, lhs.defined_channels) self.assertEqual(lhs, arith.lhs) self.assertEqual(scalar, arith.rhs) self.assertEqual(lhs, arith._pulse_template) self.assertEqual(scalar, arith._scalar) self.assertEqual('/', arith._arithmetic_operator) with mock.patch.object(ArithmeticPulseTemplate, '_parse_operand', return_value=scalar) as parse_operand: arith = ArithmeticPulseTemplate(non_pt, '-', rhs) parse_operand.assert_called_once_with(non_pt, rhs.defined_channels) self.assertEqual(scalar, arith.lhs) self.assertEqual(rhs, arith.rhs) self.assertEqual(rhs, arith._pulse_template) self.assertEqual(scalar, arith._scalar) self.assertEqual('-', arith._arithmetic_operator)
def test_code_operator(self): a = DummyPulseTemplate(duration=4, defined_channels={'a', 'b'}, parameter_names={'x', 'y'}) b = DummyPulseTemplate(duration=4, defined_channels={'a', 'c'}, parameter_names={'x', 'z'}) c = a + b self.assertEqual('+', c.arithmetic_operator) self.assertIs(c.lhs, a) self.assertIs(c.rhs, b) c = a - b self.assertEqual('-', c.arithmetic_operator) self.assertIs(c.lhs, a) self.assertIs(c.rhs, b)
def test_get_remaining_mappings(self) -> None: map = PulseTemplateParameterMapping({'bar', 'barbar'}) dummy = DummyPulseTemplate(parameter_names={'foo', 'hugo'}) self.assertEqual({'foo', 'hugo'}, map.get_remaining_mappings(dummy)) map.add(dummy, 'hugo', '4*bar') self.assertEqual({'foo'}, map.get_remaining_mappings(dummy)) map.add(dummy, 'foo', Expression('barbar')) self.assertEqual(set(), map.get_remaining_mappings(dummy))
def make_kwargs(self): return { 'body': DummyPulseTemplate(parameter_names={'i'}), 'loop_index': 'i', 'loop_range': ('A', 'B', 1), 'parameter_constraints': [str(ParameterConstraint('foo < 3'))], 'measurements': [('a', 0, 1), ('b', 1, 1)] }
def test_measurement_names(self): template = DummyPulseTemplate(measurement_names={'foo', 'bar'}) st = MappingPulseTemplate(template, measurement_mapping={ 'foo': 'froop', 'bar': 'kneipe' }) self.assertEqual(st.measurement_names, {'froop', 'kneipe'})
def test_parameter_names(self) -> None: template = DummyPulseTemplate(parameter_names={'foo'}, measurement_names={'meas1'}) mt = MappingPulseTemplate(template, parameter_mapping={'foo': 't*k'}, parameter_constraints={'t >= m'}, measurement_mapping={'meas1': 'meas2'}) self.assertEqual({'t', 'k', 'm'}, mt.parameter_names)
def test_parameter_names(self) -> None: body = DummyPulseTemplate(parameter_names={'foo', 'bar'}) t = RepetitionPulseTemplate(body, 5, parameter_constraints={'foo > hugo'}, measurements=[('meas', 'd', 0)]) self.assertEqual({'foo', 'bar', 'hugo', 'd'}, t.parameter_names)
def test_init_multi_subtemplates_wrong_channel_mapping(self) -> None: st1 = DummyPulseTemplate(parameter_names={'foo'}, is_interruptable=True, num_channels=2, duration=1.3) st2 = DummyPulseTemplate(parameter_names={'bar'}, is_interruptable=True, num_channels=1, duration=6.34) with self.assertRaises(ValueError): MultiChannelPulseTemplate([(st1, { 'foo': "2.3 ** bar" }, [0, 3]), (st2, { 'bar': "bar" }, [1])], {'bar'}) with self.assertRaises(ValueError): MultiChannelPulseTemplate([(st1, { 'foo': "2.3 ** bar" }, [0, -1]), (st2, { 'bar': "bar" }, [1])], {'bar'}) with self.assertRaises(ValueError): MultiChannelPulseTemplate([(st1, { 'foo': "2.3 ** bar" }, [0, 2]), (st2, { 'bar': "bar" }, [-1])], {'bar'}) with self.assertRaises(ValueError): MultiChannelPulseTemplate([(st1, { 'foo': "2.3 ** bar" }, [0, 2]), (st2, { 'bar': "bar" }, [3])], {'bar'}) with self.assertRaises(ValueError): MultiChannelPulseTemplate([(st1, { 'foo': "2.3 ** bar" }, [0, 0]), (st2, { 'bar': "bar" }, [1])], {'bar'}) with self.assertRaises(ValueError): MultiChannelPulseTemplate([(st1, { 'foo': "2.3 ** bar" }, [0, 2]), (st2, { 'bar': "bar" }, [2])], {'bar'})
def test_integral(self) -> None: condition = DummyCondition() body = DummyPulseTemplate(defined_channels={'A', 'B'}) pulse = WhileLoopPulseTemplate(condition, body) self.assertEqual( { 'A': ExpressionScalar('nan'), 'B': ExpressionScalar('nan') }, pulse.integral)
def test_measurement_names(self): measurement_names = {'M'} body = DummyPulseTemplate(measurement_names=measurement_names) t = RepetitionPulseTemplate(body, 9) self.assertEqual(measurement_names, t.measurement_names) t = RepetitionPulseTemplate(body, 9, measurements=[('N', 1, 2)]) self.assertEqual({'M', 'N'}, t.measurement_names)
def test_get_serialization_data_old(self) -> None: # test for deprecated version during transition period, remove after final switch with self.assertWarnsRegex(DeprecationWarning, "deprecated", msg="SequencePT does not issue warning for old serialization routines."): dummy1 = DummyPulseTemplate() dummy2 = DummyPulseTemplate() sequence = SequencePulseTemplate(dummy1, dummy2, parameter_constraints=['a<b'], measurements=[('m', 0, 1)], registry=dict()) serializer = DummySerializer(serialize_callback=lambda x: str(x)) expected_data = dict( subtemplates=[str(dummy1), str(dummy2)], parameter_constraints=['a < b'], measurements=[('m', 0, 1)] ) data = sequence.get_serialization_data(serializer) self.assertEqual(expected_data, data)
def test_external_params(self): template = DummyPulseTemplate(parameter_names={'foo', 'bar'}) st = MappingPulseTemplate(template, parameter_mapping={ 'foo': 't*k', 'bar': 't*l' }) external_params = {'t', 'l', 'k'} self.assertEqual(st.parameter_names, external_params)
def test_external_parameters_warning(self): dummy = DummyPulseTemplate() with self.assertWarnsRegex( DeprecationWarning, "external_parameters", msg= "SequencePT did not issue a warning for argument external_parameters" ): SequencePulseTemplate(dummy, external_parameters={'a'})
def test_serialize(self): sts = [DummyPulseTemplate(duration='t1', defined_channels={'A'}, parameter_names={'a', 'b'}), DummyPulseTemplate(duration='t1', defined_channels={'B'}, parameter_names={'a', 'c'})] constraints = ['a < d'] template = AtomicMultiChannelPulseTemplate(*sts, parameter_constraints=constraints) expected_data = dict(subtemplates=['0', '1'], parameter_constraints=['a < d']) def serialize_callback(obj) -> str: self.assertIn(obj, sts) return str(sts.index(obj)) serializer = DummySerializer(serialize_callback=serialize_callback, identifier_callback=serialize_callback) data = template.get_serialization_data(serializer=serializer) self.assertEqual(expected_data, data)
def test_external_parameters_warning(self): with self.assertWarnsRegex( DeprecationWarning, "external_parameters", msg= "AtomicMultiChannelPulseTemplate did not issue a warning for argument external_parameters" ): AtomicMultiChannelPulseTemplate(DummyPulseTemplate(), external_parameters={'a'})
def test_wrong_type(self): dummy = DummyPulseTemplate() tpt = TablePulseTemplate({ 'A': [(0, 1), ('a', 5, 'linear')], 'B': [(0, 2), ('b', 7)] }) with self.assertRaisesRegex(TypeError, 'not a TablePulseTemplate'): concatenate(dummy, tpt)
def test_integral(self) -> None: dummy1 = DummyPulseTemplate(defined_channels={'A', 'B'}, integrals={ 'A': ExpressionScalar('k+2*b'), 'B': ExpressionScalar('3') }) dummy2 = DummyPulseTemplate(defined_channels={'A', 'B'}, integrals={ 'A': ExpressionScalar('7*(b-f)'), 'B': ExpressionScalar('0.24*f-3.0') }) pulse = SequencePulseTemplate(dummy1, dummy2) self.assertEqual( { 'A': ExpressionScalar('k+2*b+7*(b-f)'), 'B': ExpressionScalar('0.24*f') }, pulse.integral)
def test_parameter_names(self): dt = DummyPulseTemplate(parameter_names={'i', 'k'}) flt = ForLoopPulseTemplate(body=dt, loop_index='i', loop_range=('a', 'b', 'c'), parameter_constraints={'c > hugo'}, measurements=[('meas', 'd', 1)]) self.assertEqual({'k', 'a', 'b', 'c', 'd', 'hugo'}, flt.parameter_names)
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) scope = DictScope.from_kwargs(c=1.2, a=3.4) kwargs = { **other_kwargs, 'scope': scope, '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 } with mock.patch.object(template, '_create_program', spec=template._create_program) as cp_mock: pccpt._internal_create_program(**kwargs) cp_mock.assert_called_once_with(**expected_kwargs) global_transformation = LinearTransformation(numpy.zeros((0, 0)), [], []) expected_transformation = chain_transformations( global_transformation, expected_transformation) kwargs = { **other_kwargs, 'scope': scope, 'global_transformation': global_transformation } expected_kwargs = { **kwargs, 'global_transformation': expected_transformation } with mock.patch.object(template, '_create_program', spec=template._create_program) as cp_mock: pccpt._internal_create_program(**kwargs) cp_mock.assert_called_once_with(**expected_kwargs)
def test_repr(self): pt = DummyPulseTemplate(defined_channels={'a'}) scalar = 'x' with mock.patch.object(DummyPulseTemplate, '__repr__', wraps=lambda *args: 'dummy'): r = repr(ArithmeticPulseTemplate(pt, '-', scalar)) self.assertEqual("(dummy - ExpressionScalar('x'))", r) arith = ArithmeticPulseTemplate(pt, '-', scalar, identifier='id') self.assertEqual(super(ArithmeticPulseTemplate, arith).__repr__(), repr(arith))
def test_integral(self) -> None: sts = [ DummyPulseTemplate(duration='t1', defined_channels={'A'}, integrals={'A': ExpressionScalar('2+k')}), DummyPulseTemplate(duration='t1', defined_channels={'B', 'C'}, integrals={ 'B': ExpressionScalar('t1-t0*3.1'), 'C': ExpressionScalar('l') }) ] pulse = AtomicMultiChannelPulseTemplate(*sts) self.assertEqual( { 'A': ExpressionScalar('2+k'), 'B': ExpressionScalar('t1-t0*3.1'), 'C': ExpressionScalar('l') }, pulse.integral)
def test_try_operation(self): apt = DummyPulseTemplate(duration=1, defined_channels={'a'}) npt = PulseTemplateStub(defined_channels={'a'}) self.assertIsInstance(try_operation(npt, '+', 6), ArithmeticPulseTemplate) self.assertIsInstance(try_operation(apt, '+', apt), ArithmeticAtomicPulseTemplate) self.assertIs(NotImplemented, try_operation(npt, '/', npt)) self.assertIs(NotImplemented, try_operation(npt, '//', 6))
def test_requires_stop(self) -> None: sub1 = (DummyPulseTemplate(requires_stop=False), {}, {}) sub2 = (DummyPulseTemplate(requires_stop=True, parameter_names={'foo'}), { 'foo': 'foo' }, {}) parameters = {'foo': DummyNoValueParameter()} seq = SequencePulseTemplate(sub1) self.assertFalse(seq.requires_stop(parameters, {})) seq = SequencePulseTemplate(sub2, external_parameters={'foo'}) self.assertFalse(seq.requires_stop(parameters, {})) seq = SequencePulseTemplate(sub1, sub2, external_parameters={'foo'}) self.assertFalse(seq.requires_stop(parameters, {})) seq = SequencePulseTemplate(sub2, sub1, external_parameters={'foo'}) self.assertFalse(seq.requires_stop(parameters, {}))
def test_requires_stop(self): parameters = dict(A=DummyParameter(requires_stop=False), B=DummyParameter(requires_stop=False)) dt = DummyPulseTemplate(parameter_names={'i'}) flt = ForLoopPulseTemplate(body=dt, loop_index='i', loop_range=('A', 'B')) self.assertFalse(flt.requires_stop(parameters, dict())) parameters['A'] = DummyParameter(requires_stop=True) self.assertTrue(flt.requires_stop(parameters, dict()))
def test_requires_stop_constant(self) -> None: body = DummyPulseTemplate(requires_stop=False) t = RepetitionPulseTemplate(body, 2) self.assertFalse(t.requires_stop({}, {})) body.requires_stop_ = True self.assertFalse(t.requires_stop({}, {}))