Exemple #1
0
    def test_create_program_rep_count_neg_declaration_with_measurements(
            self) -> None:
        repetitions = "foo"
        body_program = Loop(waveform=DummyWaveform(duration=1.0))
        body = DummyPulseTemplate(duration=2.0, program=body_program)

        # suppress warning about 0 repetitions on construction here, we are only interested in correct behavior during sequencing (i.e., do nothing)
        with warnings.catch_warnings(record=True):
            t = RepetitionPulseTemplate(body,
                                        repetitions,
                                        measurements=[('moth', 0, 'meas_end')])

        scope = DictScope.from_kwargs(foo=-1, meas_end=7.1)
        measurement_mapping = dict(moth='fire')
        channel_mapping = dict(asd='f')

        program = Loop()
        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.assertFalse(program.children)
        self.assertEqual(1, program.repetition_count)
        self.assertEqual(None, program._measurements)
Exemple #2
0
 def test_create_program_declaration_parameter_value_not_whole(
         self) -> None:
     repetitions = "foo"
     body = DummyPulseTemplate(duration=2.0,
                               waveform=DummyWaveform(duration=2.0))
     t = RepetitionPulseTemplate(body,
                                 repetitions,
                                 parameter_constraints=['foo<9'])
     scope = DictScope.from_kwargs(foo=(3.3))
     measurement_mapping = dict(moth='fire')
     channel_mapping = dict(asd='f')
     children = [Loop(waveform=DummyWaveform(duration=0))]
     program = Loop(children=children)
     with self.assertRaises(ParameterNotIntegerException):
         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 _internal_create_program(self, *,
                                 parameters: Dict[str, Parameter],
                                 measurement_mapping: Dict[str, Optional[str]],
                                 channel_mapping: Dict[ChannelID, Optional[ChannelID]],
                                 global_transformation: Optional['Transformation'],
                                 to_single_waveform: Set[Union[str, 'PulseTemplate']],
                                 parent_loop: Loop) -> None:
        self.validate_parameter_constraints(parameters=parameters)
        relevant_params = set(self._repetition_count.variables).union(self.measurement_parameters)
        try:
            real_parameters = {v: parameters[v].get_value() for v in relevant_params}
        except KeyError as e:
            raise ParameterNotProvidedException(str(e)) from e

        repetition_count = max(0, self.get_repetition_count_value(real_parameters))

        # todo (2018-07-19): could in some circumstances possibly just multiply subprogram repetition count?
        # could be tricky if any repetition count is volatile ? check later and optimize if necessary
        if repetition_count > 0:
            repj_loop = Loop(repetition_count=repetition_count)
            self.body._create_program(parameters=parameters,
                                      measurement_mapping=measurement_mapping,
                                      channel_mapping=channel_mapping,
                                      global_transformation=global_transformation,
                                      to_single_waveform=to_single_waveform,
                                      parent_loop=repj_loop)
            if repj_loop.waveform is not None or len(repj_loop.children) > 0:
                measurements = self.get_measurement_windows(real_parameters, measurement_mapping)
                if measurements:
                    parent_loop.add_measurements(measurements)

                parent_loop.append_child(loop=repj_loop)
Exemple #4
0
    def test_create_program_declaration_success(self) -> None:
        repetitions = "foo"
        body = DummyPulseTemplate(duration=2.0,
                                  waveform=DummyWaveform(
                                      duration=2, defined_channels={'A'}))
        t = RepetitionPulseTemplate(body,
                                    repetitions,
                                    parameter_constraints=['foo<9'])
        scope = DictScope.from_kwargs(foo=3)
        measurement_mapping = dict(moth='fire')
        channel_mapping = dict(asd='f')
        program = Loop()
        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.assertEqual(1, program.repetition_count)
        self.assertEqual(1, len(program.children))
        internal_loop = program.children[0]  # type: Loop
        self.assertEqual(scope[repetitions], internal_loop.repetition_count)

        self.assertEqual(1, len(internal_loop))
        self.assertEqual(
            (scope, measurement_mapping, channel_mapping, internal_loop),
            body.create_program_calls[-1])
        self.assertEqual(body.waveform, internal_loop[0].waveform)

        self.assert_measurement_windows_equal(
            {}, program.get_measurement_windows())
Exemple #5
0
    def _internal_create_program(
            self, *, scope: Scope, measurement_mapping: Dict[str,
                                                             Optional[str]],
            channel_mapping: Dict[ChannelID, Optional[ChannelID]],
            global_transformation: Optional[Transformation],
            to_single_waveform: Set[Union[str, 'PulseTemplate']],
            parent_loop: Loop) -> None:
        """Parameter constraints are validated in build_waveform because build_waveform is guaranteed to be called
        during sequencing"""
        ### current behavior (same as previously): only adds EXEC Loop and measurements if a waveform exists.
        ### measurements are directly added to parent_loop (to reflect behavior of Sequencer + MultiChannelProgram)
        assert not scope.get_volatile_parameters().keys(
        ) & self.parameter_names, "AtomicPT cannot be volatile"

        waveform = self.build_waveform(parameters=scope,
                                       channel_mapping=channel_mapping)
        if waveform:
            measurements = self.get_measurement_windows(
                parameters=scope, measurement_mapping=measurement_mapping)

            if global_transformation:
                waveform = TransformingWaveform(waveform,
                                                global_transformation)

            parent_loop.add_measurements(measurements=measurements)
            parent_loop.append_child(waveform=waveform)
Exemple #6
0
    def test_make_compatible_complete_unroll(self):
        wf1 = DummyWaveform(duration=1.5)
        wf2 = DummyWaveform(duration=2.0)

        program = Loop(children=[
            Loop(waveform=wf1, repetition_count=2),
            Loop(waveform=wf2, repetition_count=1)
        ],
                       repetition_count=2)

        _make_compatible(program,
                         min_len=5,
                         quantum=10,
                         sample_rate=time_from_float(1.))

        self.assertIsInstance(program.waveform, RepetitionWaveform)
        self.assertEqual(program.children, [])
        self.assertEqual(program.repetition_count, 1)

        self.assertIsInstance(program.waveform, RepetitionWaveform)

        self.assertIsInstance(program.waveform._body, SequenceWaveform)
        body_wf = program.waveform._body
        self.assertEqual(len(body_wf._sequenced_waveforms), 2)
        self.assertIsInstance(body_wf._sequenced_waveforms[0],
                              RepetitionWaveform)
        self.assertIs(body_wf._sequenced_waveforms[0]._body, wf1)
        self.assertEqual(body_wf._sequenced_waveforms[0]._repetition_count, 2)
        self.assertIs(body_wf._sequenced_waveforms[1], wf2)
Exemple #7
0
    def setUp(self) -> None:
        self.channels = ('A', None, 'C')
        self.marker = (None, 'M')
        self.amplitudes = (1., 1., .5)
        self.offset = (0., .5, .0)
        self.voltage_transformations = (mock.Mock(wraps=lambda x: x),
                                        mock.Mock(wraps=lambda x: x),
                                        mock.Mock(wraps=lambda x: x))
        self.sample_rate = TimeType.from_float(1)

        N = 100
        t = np.arange(N)

        self.sampled = [
            dict(A=np.linspace(-.1, .1, num=N),
                 C=.1 * np.sin(t),
                 M=np.arange(N) % 2),
            dict(A=np.linspace(.1, -.1, num=N // 2),
                 C=.1 * np.cos(t[::2]),
                 M=np.arange(N // 2) % 3)
        ]
        self.waveforms = [
            wf for wf in (DummyWaveform(sample_output=sampled,
                                        duration=sampled['A'].size)
                          for sampled in self.sampled)
        ]
        self.loop = Loop(children=[Loop(waveform=wf)
                                   for wf in self.waveforms] * 2)
Exemple #8
0
    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_scope = DictScope.from_kwargs(a=0, b=2, c=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(
                scope=invalid_scope,
                measurement_mapping=measurement_mapping,
                channel_mapping=channel_mapping,
                parent_loop=program,
                to_single_waveform=set(),
                global_transformation=None)

        self.assertEqual(children, list(program.children))
        self.assertEqual(1, program.repetition_count)
        self.assertIsNone(program._measurements)
        self.assert_measurement_windows_equal(
            {}, program.get_measurement_windows())
    def test_internal_create_program_no_measurement_mapping(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': DummyNoValueParameter()}
        seq = SequencePulseTemplate(sub1, sub2, measurements=[('a', 0, 1)])
        children = [Loop(waveform=DummyWaveform())]
        loop = Loop(measurements=[], children=children)

        with self.assertRaises(KeyError):
            seq._internal_create_program(parameters=parameters,
                                         measurement_mapping=dict(),
                                         channel_mapping=dict(),
                                         global_transformation=None,
                                         to_single_waveform=set(),
                                         parent_loop=loop)

        self.assertFalse(sub1.create_program_calls)
        self.assertFalse(sub2.create_program_calls)
        self.assertEqual(children, loop.children)
        self.assertEqual(1, loop.repetition_count)
        self.assertIsNone(loop.waveform)
        self.assert_measurement_windows_equal({}, loop.get_measurement_windows())

        # test for child level measurements (does not guarantee to leave parent_loop unchanged in this case)
        with self.assertRaises(KeyError):
            seq._internal_create_program(parameters=parameters,
                                         measurement_mapping=dict(a='a'),
                                         channel_mapping=dict(),
                                     global_transformation=None,
                                     to_single_waveform=set(),
                                         parent_loop=loop)
    def _internal_create_program(self, *,
                                 parameters: Dict[str, Parameter],
                                 measurement_mapping: Dict[str, Optional[str]],
                                 channel_mapping: Dict[ChannelID, Optional[ChannelID]],
                                 global_transformation: Optional['Transformation'],
                                 to_single_waveform: Set[Union[str, 'PulseTemplate']],
                                 parent_loop: Loop) -> None:
        self.validate_parameter_constraints(parameters=parameters)

        try:
            measurement_parameters = {parameter_name: parameters[parameter_name].get_value()
                                      for parameter_name in self.measurement_parameters}
            duration_parameters = {parameter_name: parameters[parameter_name].get_value()
                                      for parameter_name in self.duration.variables}
        except KeyError as e:
            raise ParameterNotProvidedException(str(e)) from e

        if self.duration.evaluate_numeric(**duration_parameters) > 0:
            measurements = self.get_measurement_windows(measurement_parameters, measurement_mapping)
            if measurements:
                parent_loop.add_measurements(measurements)

            for local_parameters in self._body_parameter_generator(parameters, forward=True):
                self.body._create_program(parameters=local_parameters,
                                          measurement_mapping=measurement_mapping,
                                          channel_mapping=channel_mapping,
                                          global_transformation=global_transformation,
                                          to_single_waveform=to_single_waveform,
                                          parent_loop=parent_loop)
Exemple #11
0
    def test_internal_create_program_no_waveform(self) -> None:
        measurement_windows = [('M', 0, 5)]

        template = AtomicPulseTemplateStub(measurements=measurement_windows,
                                           parameter_names={'foo'})
        scope = DictScope.from_kwargs(foo=3.5, bar=3, volatile={'bar'})
        measurement_mapping = {'M': 'N'}
        channel_mapping = {'B': 'A'}
        program = Loop()

        expected_program = Loop()

        with mock.patch.object(template, 'build_waveform',
                               return_value=None) as build_waveform:
            with mock.patch.object(template,
                                   'get_measurement_windows',
                                   wraps=template.get_measurement_windows
                                   ) as get_meas_windows:
                template._internal_create_program(
                    scope=scope,
                    measurement_mapping=measurement_mapping,
                    channel_mapping=channel_mapping,
                    parent_loop=program,
                    to_single_waveform=set(),
                    global_transformation=None)
                build_waveform.assert_called_once_with(
                    parameters=scope, channel_mapping=channel_mapping)
                get_meas_windows.assert_not_called()

        self.assertEqual(expected_program, program)
Exemple #12
0
    def test_loop_to_seqc_leaf(self):
        """Test the translation of leaves"""
        # we use None because it is not used in this test
        user_registers = None

        wf = DummyWaveform(duration=32)
        loop = Loop(waveform=wf)

        # with wrapping repetition
        loop.repetition_count = 15
        waveform_to_bin = mock.Mock(wraps=make_binary_waveform)
        expected = Repeat(loop.repetition_count,
                          WaveformPlayback(waveform=make_binary_waveform(wf)))
        result = loop_to_seqc(loop,
                              1,
                              1,
                              waveform_to_bin,
                              user_registers=user_registers)
        waveform_to_bin.assert_called_once_with(wf)
        self.assertEqual(expected, result)

        # without wrapping repetition
        loop.repetition_count = 1
        waveform_to_bin = mock.Mock(wraps=make_binary_waveform)
        expected = WaveformPlayback(waveform=make_binary_waveform(wf))
        result = loop_to_seqc(loop,
                              1,
                              1,
                              waveform_to_bin,
                              user_registers=user_registers)
        waveform_to_bin.assert_called_once_with(wf)
        self.assertEqual(expected, result)
Exemple #13
0
    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'])

        scope = DictScope.from_kwargs(a=1, b=4, c=2, volatile={'inner'})
        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(scope=scope,
                                     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())
Exemple #14
0
    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'})

        scope = DictScope.from_kwargs(k=1, a=0, b=2, c=1, f=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(scope=scope,
                                         measurement_mapping=dict(),
                                         channel_mapping=dict(),
                                         parent_loop=program,
                                         to_single_waveform=set(),
                                         global_transformation=None)
        self.assertEqual(children, list(program.children))
        self.assertEqual(1, program.repetition_count)
        self.assertIsNone(program._measurements)
        self.assert_measurement_windows_equal({}, program.get_measurement_windows())
Exemple #15
0
    def _internal_create_program(
            self, *, scope: Scope, measurement_mapping: Dict[str,
                                                             Optional[str]],
            channel_mapping: Dict[ChannelID, Optional[ChannelID]],
            global_transformation: Optional['Transformation'],
            to_single_waveform: Set[Union[str, 'PulseTemplate']],
            parent_loop: Loop) -> None:
        self.validate_scope(scope=scope)

        try:
            duration = self.duration.evaluate_in_scope(scope)
        except ExpressionVariableMissingException as err:
            raise ParameterNotProvidedException(err.variable) from err

        if duration > 0:
            measurements = self.get_measurement_windows(
                scope, measurement_mapping)
            if measurements:
                parent_loop.add_measurements(measurements)

            for local_scope in self._body_scope_generator(scope, forward=True):
                self.body._create_program(
                    scope=local_scope,
                    measurement_mapping=measurement_mapping,
                    channel_mapping=channel_mapping,
                    global_transformation=global_transformation,
                    to_single_waveform=to_single_waveform,
                    parent_loop=parent_loop)
Exemple #16
0
    def test_depth_1_single_sequence_2(self):
        """Use the same wf twice"""
        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=3),
            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.waveform_mode, TaborSequencing.SINGLE)

        self.assertEqual(t_program.get_sequencer_tables(),
                         [[(TableDescription(3, 0, 0), None),
                           (TableDescription(4, 1, 0), None),
                           (TableDescription(1, 0, 0), None)]])
        self.assertEqual(t_program.get_advanced_sequencer_table(),
                         [TableDescription(1, 1, 0)])
Exemple #17
0
    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())
Exemple #18
0
    def test_depth_1_advanced_sequence(self):
        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=3),
            Loop(waveform=wf_2, repetition_count=4),
            Loop(waveform=wf_1, repetition_count=1)
        ],
                       repetition_count=5)

        t_program = TaborProgram(program,
                                 channels=(None, 'A'),
                                 markers=(None, None),
                                 device_properties=self.instr_props,
                                 **self.program_entry_kwargs)

        self.assertEqual(t_program.waveform_mode, TaborSequencing.ADVANCED)

        # partial unroll of the last segment
        self.assertEqual(t_program.get_sequencer_tables(),
                         [[(TableDescription(3, 0, 0), None),
                           (TableDescription(4, 1, 0), None),
                           (TableDescription(1, 0, 0), None)]])
        self.assertEqual(t_program.get_advanced_sequencer_table(),
                         [TableEntry(5, 1, 0)])
Exemple #19
0
    def test_loop_to_seqc_len_1(self):
        """Test the translation of loops with len(loop) == 1"""
        loop = Loop(children=[Loop()])
        waveform_to_bin = mock.Mock(wraps=make_binary_waveform)
        loop_to_seqc_kwargs = dict(min_repetitions_for_for_loop=2,
                                   min_repetitions_for_shared_wf=3,
                                   waveform_to_bin=waveform_to_bin)

        expected = 'asdf'
        with mock.patch('qupulse._program.seqc.loop_to_seqc',
                        return_value=expected) as mocked_loop_to_seqc:
            result = loop_to_seqc(loop, **loop_to_seqc_kwargs)
            self.assertEqual(result, expected)
            mocked_loop_to_seqc.assert_called_once_with(
                loop[0], **loop_to_seqc_kwargs)

        loop.repetition_count = 14
        expected = Repeat(14, 'asdfg')
        with mock.patch('qupulse._program.seqc.loop_to_seqc',
                        return_value=expected.scope) as mocked_loop_to_seqc:
            result = loop_to_seqc(loop, **loop_to_seqc_kwargs)
            self.assertEqual(result, expected)
            mocked_loop_to_seqc.assert_called_once_with(
                loop[0], **loop_to_seqc_kwargs)

        waveform_to_bin.assert_not_called()
Exemple #20
0
    def test_create_program_defaults(self) -> None:
        template = PulseTemplateStub(defined_channels={'A', 'B'},
                                     parameter_names={'foo'},
                                     measurement_names={'hugo', 'foo'})

        expected_internal_kwargs = dict(scope=DictScope.from_kwargs(),
                                        measurement_mapping={
                                            'hugo': 'hugo',
                                            'foo': 'foo'
                                        },
                                        channel_mapping={
                                            'A': 'A',
                                            'B': 'B'
                                        },
                                        global_transformation=None,
                                        to_single_waveform=set())

        dummy_waveform = DummyWaveform()
        expected_program = Loop(children=[Loop(waveform=dummy_waveform)])

        with mock.patch.object(template,
                               '_internal_create_program',
                               wraps=get_appending_internal_create_program(
                                   dummy_waveform,
                                   True)) as _internal_create_program:
            program = template.create_program()
            _internal_create_program.assert_called_once_with(
                **expected_internal_kwargs, parent_loop=program)
        self.assertEqual(expected_program, program)
Exemple #21
0
    def _internal_create_program(self, *,
                                 parameters: Dict[str, Parameter],
                                 measurement_mapping: Dict[str, Optional[str]],
                                 channel_mapping: Dict[ChannelID, Optional[ChannelID]],
                                 global_transformation: Optional[Transformation],
                                 to_single_waveform: Set[Union[str, 'PulseTemplate']],
                                 parent_loop: Loop) -> None:
        """Parameter constraints are validated in build_waveform because build_waveform is guaranteed to be called
        during sequencing"""
        ### current behavior (same as previously): only adds EXEC Loop and measurements if a waveform exists.
        ### measurements are directly added to parent_loop (to reflect behavior of Sequencer + MultiChannelProgram)
        # todo (2018-08-08): could move measurements into own Loop object?

        # todo (2018-07-05): why are parameter constraints not validated here?
        try:
            parameters = {parameter_name: parameters[parameter_name].get_value()
                          for parameter_name in self.parameter_names}
        except KeyError as e:
            raise ParameterNotProvidedException(str(e)) from e

        waveform = self.build_waveform(parameters=parameters,
                                       channel_mapping=channel_mapping)
        if waveform:
            measurements = self.get_measurement_windows(parameters=parameters,
                                                        measurement_mapping=measurement_mapping)

            if global_transformation:
                waveform = TransformingWaveform(waveform, global_transformation)

            parent_loop.add_measurements(measurements=measurements)
            parent_loop.append_child(waveform=waveform)
Exemple #22
0
    def test_internal_create_program(self):
        wf = DummyWaveform(duration=2.)
        body = PulseTemplateStub()

        rpt = RepetitionPulseTemplate(body,
                                      'n_rep*mul',
                                      measurements=[('m', 'a', 'b')])

        scope = DictScope.from_kwargs(n_rep=3,
                                      mul=2,
                                      a=.1,
                                      b=.2,
                                      irrelevant=42)
        measurement_mapping = {'m': 'l'}
        channel_mapping = {'x': 'Y'}
        global_transformation = TransformationStub()
        to_single_waveform = {'to', 'single', 'waveform'}

        program = Loop()
        expected_program = Loop(
            children=[Loop(children=[Loop(waveform=wf)], repetition_count=6)],
            measurements=[('l', .1, .2)])

        real_relevant_parameters = dict(n_rep=3, mul=2, a=0.1, b=0.2)

        with mock.patch.object(body,
                               '_create_program',
                               wraps=get_appending_internal_create_program(
                                   wf,
                                   always_append=True)) as body_create_program:
            with mock.patch.object(rpt, 'validate_scope') as validate_scope:
                with mock.patch.object(
                        rpt, 'get_repetition_count_value',
                        return_value=6) as get_repetition_count_value:
                    with mock.patch.object(rpt,
                                           'get_measurement_windows',
                                           return_value=[('l', .1, .2)
                                                         ]) as get_meas:
                        rpt._internal_create_program(
                            scope=scope,
                            measurement_mapping=measurement_mapping,
                            channel_mapping=channel_mapping,
                            global_transformation=global_transformation,
                            to_single_waveform=to_single_waveform,
                            parent_loop=program)

                        self.assertEqual(program, expected_program)
                        body_create_program.assert_called_once_with(
                            scope=scope,
                            measurement_mapping=measurement_mapping,
                            channel_mapping=channel_mapping,
                            global_transformation=global_transformation,
                            to_single_waveform=to_single_waveform,
                            parent_loop=program.children[0])
                        validate_scope.assert_called_once_with(scope)
                        get_repetition_count_value.assert_called_once_with(
                            scope)
                        get_meas.assert_called_once_with(
                            scope, measurement_mapping)
Exemple #23
0
    def test_loop_to_seqc_cluster_handling(self):
        """Test handling of clusters"""
        with self.assertRaises(AssertionError):
            loop_to_seqc(Loop(repetition_count=12, children=[Loop()]),
                         min_repetitions_for_for_loop=3,
                         min_repetitions_for_shared_wf=2,
                         waveform_to_bin=make_binary_waveform)

        loop_to_seqc_kwargs = dict(min_repetitions_for_for_loop=3,
                                   min_repetitions_for_shared_wf=4,
                                   waveform_to_bin=make_binary_waveform)

        wf_same = map(WaveformPlayback,
                      map(make_binary_waveform, get_unique_wfs(100000, 32)))
        wf_sep, = map(WaveformPlayback,
                      map(make_binary_waveform, get_unique_wfs(1, 64)))

        node_clusters = [
            take(2, wf_same), [wf_sep],
            take(3, wf_same), [wf_sep],
            take(4, wf_same),
            take(4, wf_same)
        ]
        root = Loop(
            repetition_count=12,
            children=[Loop() for _ in range(2 + 1 + 3 + 1 + 4 + 1 + 4)])

        expected = Repeat(
            12,
            Scope([
                *node_clusters[0], wf_sep,
                SteppingRepeat(node_clusters[2]), wf_sep,
                SteppingRepeat(node_clusters[4]),
                SteppingRepeat(node_clusters[5])
            ]))

        def dummy_find_sharable_waveforms(cluster):
            if cluster is node_clusters[4]:
                return [True]
            else:
                return None

        p1 = mock.patch('qupulse._program.seqc.to_node_clusters',
                        return_value=node_clusters)
        p2 = mock.patch('qupulse._program.seqc.find_sharable_waveforms',
                        wraps=dummy_find_sharable_waveforms)
        p3 = mock.patch('qupulse._program.seqc.mark_sharable_waveforms')

        with p1 as to_node_clusters_mock, p2 as find_share_mock, p3 as mark_share_mock:
            result = loop_to_seqc(root, **loop_to_seqc_kwargs)
            self.assertEqual(expected, result)

            to_node_clusters_mock.assert_called_once_with(
                root, loop_to_seqc_kwargs)
            self.assertEqual(
                find_share_mock.mock_calls,
                [mock.call(node_clusters[4]),
                 mock.call(node_clusters[5])])
            mark_share_mock.assert_called_once_with(node_clusters[4], [True])
Exemple #24
0
    def test_is_compatible_leaf(self):
        self.assertEqual(_is_compatible(Loop(waveform=DummyWaveform(duration=1.1), repetition_count=10),
                                        min_len=11, quantum=1, sample_rate=TimeType.from_float(1.)),
                         _CompatibilityLevel.action_required)

        self.assertEqual(_is_compatible(Loop(waveform=DummyWaveform(duration=1.1), repetition_count=10),
                                        min_len=11, quantum=1, sample_rate=TimeType.from_float(10.)),
                         _CompatibilityLevel.compatible)
Exemple #25
0
    def test_render_warning(self) -> None:
        wf1 = DummyWaveform(duration=19)
        wf2 = DummyWaveform(duration=21)

        program = Loop(children=[Loop(waveform=wf1), Loop(waveform=wf2)])

        with self.assertWarns(UserWarning):
            render(program, sample_rate=0.51314323423)
Exemple #26
0
    def test_is_compatible_node(self):
        program = Loop(children=[Loop(waveform=DummyWaveform(duration=1.5), repetition_count=2),
                                 Loop(waveform=DummyWaveform(duration=2.0))])

        self.assertEqual(_is_compatible(program, min_len=1, quantum=1, sample_rate=TimeType.from_float(2.)),
                         _CompatibilityLevel.compatible)

        self.assertEqual(_is_compatible(program, min_len=1, quantum=1, sample_rate=TimeType.from_float(1.)),
                         _CompatibilityLevel.action_required)
Exemple #27
0
    def __init__(
        self,
        program: Loop,
        device_properties: Mapping,
        channels: Tuple[Optional[ChannelID], Optional[ChannelID]],
        markers: Tuple[Optional[ChannelID], Optional[ChannelID]],
        amplitudes: Tuple[float, float],
        offsets: Tuple[float, float],
        voltage_transformations: Tuple[Optional[callable], Optional[callable]],
        sample_rate: TimeType,
        mode: TaborSequencing = None,
        repetition_mode: str = "infinite",
    ):
        if len(channels) != device_properties['chan_per_part']:
            raise TaborException(
                'TaborProgram only supports {} channels'.format(
                    device_properties['chan_per_part']))
        if len(markers) != device_properties['chan_per_part']:
            raise TaborException(
                'TaborProgram only supports {} markers'.format(
                    device_properties['chan_per_part']))
        used_channels = frozenset(set(channels).union(markers) - {None})

        if program.repetition_count > 1 or program.depth() == 0:
            program.encapsulate()

        if mode is None:
            if program.depth() > 1:
                mode = TaborSequencing.ADVANCED
            else:
                mode = TaborSequencing.SINGLE

        super().__init__(
            loop=program,
            channels=channels,
            markers=markers,
            amplitudes=amplitudes,
            offsets=offsets,
            voltage_transformations=voltage_transformations,
            sample_rate=sample_rate,
            waveforms=[]  # no sampling happens here
        )

        self._used_channels = used_channels
        self._parsed_program = None  # type: Optional[ParsedProgram]
        self._mode = None
        self._device_properties = device_properties
        self._repetition_mode = repetition_mode

        assert mode in (TaborSequencing.ADVANCED,
                        TaborSequencing.SINGLE), "Invalid mode"
        if mode == TaborSequencing.SINGLE:
            self.setup_single_sequence_mode()
        else:
            self.setup_advanced_sequence_mode()

        self._sampled_segments = self._calc_sampled_segments()
Exemple #28
0
    def test_is_compatible_incompatible(self):
        wf = DummyWaveform(duration=1.1)

        self.assertEqual(_is_compatible(Loop(waveform=wf), min_len=1, quantum=1, sample_rate=time_from_float(1.)),
                         _CompatibilityLevel.incompatible_fraction)

        self.assertEqual(_is_compatible(Loop(waveform=wf, repetition_count=10), min_len=20, quantum=1, sample_rate=time_from_float(1.)),
                         _CompatibilityLevel.incompatible_too_short)

        self.assertEqual(_is_compatible(Loop(waveform=wf, repetition_count=10), min_len=10, quantum=3, sample_rate=time_from_float(1.)),
                         _CompatibilityLevel.incompatible_quantum)
Exemple #29
0
    def test_create_program_internal(self) -> None:
        sub1 = DummyPulseTemplate(duration=3,
                                  waveform=DummyWaveform(duration=3),
                                  measurements=[('b', 1, 2)],
                                  defined_channels={'A'})
        sub2 = DummyPulseTemplate(duration=2,
                                  waveform=DummyWaveform(duration=2),
                                  parameter_names={'foo'},
                                  defined_channels={'A'})
        scope = DictScope.from_kwargs()
        measurement_mapping = {'a': 'a', 'b': 'b'}
        channel_mapping = dict()
        seq = SequencePulseTemplate(sub1, sub2, measurements=[('a', 0, 1)])
        loop = Loop()
        seq._internal_create_program(scope=scope,
                                     measurement_mapping=measurement_mapping,
                                     channel_mapping=channel_mapping,
                                     global_transformation=None,
                                     to_single_waveform=set(),
                                     parent_loop=loop)
        self.assertEqual(1, loop.repetition_count)
        self.assertIsNone(loop.waveform)
        self.assertEqual([
            Loop(repetition_count=1, waveform=sub1.waveform),
            Loop(repetition_count=1, waveform=sub2.waveform)
        ], list(loop.children))
        self.assert_measurement_windows_equal(
            {
                'a': ([0], [1]),
                'b': ([1], [2])
            }, loop.get_measurement_windows())

        ### test again with inverted sequence
        seq = SequencePulseTemplate(sub2, sub1, measurements=[('a', 0, 1)])
        loop = Loop()
        seq._internal_create_program(scope=scope,
                                     measurement_mapping=measurement_mapping,
                                     channel_mapping=channel_mapping,
                                     global_transformation=None,
                                     to_single_waveform=set(),
                                     parent_loop=loop)
        self.assertEqual(1, loop.repetition_count)
        self.assertIsNone(loop.waveform)
        self.assertEqual([
            Loop(repetition_count=1, waveform=sub2.waveform),
            Loop(repetition_count=1, waveform=sub1.waveform)
        ], list(loop.children))
        self.assert_measurement_windows_equal(
            {
                'a': ([0], [1]),
                'b': ([3], [2])
            }, loop.get_measurement_windows())
Exemple #30
0
    def test_create_program(self) -> None:
        template = PulseTemplateStub(defined_channels={'A'},
                                     parameter_names={'foo'})
        parameters = {
            'foo': 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()
        volatile = {'foo'}

        expected_scope = DictScope.from_kwargs(foo=2.126,
                                               bar=-26.2,
                                               hugo=math.exp(
                                                   math.sin(math.pi / 2)),
                                               volatile=volatile,
                                               append_a_child=1)
        to_single_waveform = {'voll', 'toggo'}
        global_transformation = TransformationStub()

        expected_internal_kwargs = dict(
            scope=expected_scope,
            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,
                volatile=volatile)
            _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)