def assemble_schedules(schedules: List[Schedule], qobj_id: int,
                       qobj_header: QobjHeader,
                       run_config: RunConfig) -> PulseQobj:
    """Assembles a list of schedules into a qobj that can be run on the backend.

    Args:
        schedules: Schedules to assemble.
        qobj_id: Identifier for the generated qobj.
        qobj_header: Header to pass to the results.
        run_config: Configuration of the runtime environment.

    Returns:
        The Qobj to be run on the backends.

    Raises:
        QiskitError: when frequency settings are not supplied.
    """
    if not hasattr(run_config, 'qubit_lo_freq'):
        raise QiskitError('qubit_lo_freq must be supplied.')
    if not hasattr(run_config, 'meas_lo_freq'):
        raise QiskitError('meas_lo_freq must be supplied.')

    lo_converter = LoConfigConverter(PulseQobjExperimentConfig,
                                     **run_config.to_dict())
    experiments, experiment_config = _assemble_experiments(
        schedules, lo_converter, run_config)
    qobj_config = _assemble_config(lo_converter, experiment_config, run_config)

    return PulseQobj(experiments=experiments,
                     qobj_id=qobj_id,
                     header=qobj_header,
                     config=qobj_config)
Esempio n. 2
0
def assemble_schedules(schedules, qobj_id, qobj_header, run_config):
    """Assembles a list of schedules into a qobj which can be run on the backend.

    Args:
        schedules (list[Schedule]): schedules to assemble
        qobj_id (int): identifier for the generated qobj
        qobj_header (QobjHeader): header to pass to the results
        run_config (RunConfig): configuration of the runtime environment
    Returns:
        PulseQobj: the Qobj to be run on the backends
    Raises:
        QiskitError: when invalid schedules or configs are provided
    """
    if hasattr(run_config, 'instruction_converter'):
        instruction_converter = run_config.instruction_converter
    else:
        instruction_converter = InstructionToQobjConverter

    qobj_config = run_config.to_dict()

    qubit_lo_freq = qobj_config.get('qubit_lo_freq', None)
    if qubit_lo_freq is None:
        raise QiskitError('qubit_lo_freq must be supplied.')

    meas_lo_freq = qobj_config.get('meas_lo_freq', None)
    if meas_lo_freq is None:
        raise QiskitError('meas_lo_freq must be supplied.')

    qubit_lo_range = qobj_config.pop('qubit_lo_range', None)
    meas_lo_range = qobj_config.pop('meas_lo_range', None)
    meas_map = qobj_config.pop('meas_map', None)

    # convert enums to serialized values
    meas_return = qobj_config.get('meas_return', 'avg')
    if isinstance(meas_return, MeasReturnType):
        qobj_config['meas_return'] = meas_return.value

    meas_level = qobj_config.get('meas_return', 2)
    if isinstance(meas_level, MeasLevel):
        qobj_config['meas_level'] = meas_level.value

    instruction_converter = instruction_converter(PulseQobjInstruction, **qobj_config)

    lo_converter = LoConfigConverter(PulseQobjExperimentConfig,
                                     qubit_lo_range=qubit_lo_range,
                                     meas_lo_range=meas_lo_range,
                                     **qobj_config)

    memory_slot_size = 0

    # Pack everything into the Qobj
    qobj_schedules = []
    user_pulselib = {}
    for idx, schedule in enumerate(schedules):
        # instructions
        max_memory_slot = 0
        qobj_instructions = []

        # Instructions are returned as tuple of shifted time and instruction
        for shift, instruction in schedule.instructions:
            # TODO: support conditional gate

            if isinstance(instruction, DelayInstruction):
                # delay instructions are ignored as timing is explicit within qobj
                continue

            elif isinstance(instruction, PulseInstruction):
                name = instruction.command.name
                if name in user_pulselib and instruction.command != user_pulselib[name]:
                    name = "{0}-{1:x}".format(name, hash(instruction.command.samples.tostring()))
                    instruction = PulseInstruction(
                        command=SamplePulse(name=name, samples=instruction.command.samples),
                        name=instruction.name,
                        channel=instruction.channels[0])
                # add samples to pulse library
                user_pulselib[name] = instruction.command
            elif isinstance(instruction, AcquireInstruction):
                max_memory_slot = max(max_memory_slot,
                                      *[slot.index for slot in instruction.mem_slots])
                if meas_map:
                    # verify all acquires satisfy meas_map
                    _validate_meas_map(instruction, meas_map)

            converted_instruction = instruction_converter(shift, instruction)
            qobj_instructions.append(converted_instruction)

        # memory slot size is memory slot index + 1 because index starts from zero
        exp_memory_slot_size = max_memory_slot + 1
        memory_slot_size = max(memory_slot_size, exp_memory_slot_size)

        # experiment header
        # TODO: add other experimental header items (see circuit assembler)
        qobj_experiment_header = QobjExperimentHeader(
            memory_slots=exp_memory_slot_size,
            name=schedule.name or 'Experiment-%d' % idx
        )

        qobj_schedules.append({
            'header': qobj_experiment_header,
            'instructions': qobj_instructions
        })

    # set number of memoryslots
    qobj_config['memory_slots'] = memory_slot_size

    # setup pulse_library
    qobj_config['pulse_library'] = [PulseLibraryItem(name=pulse.name, samples=pulse.samples)
                                    for pulse in user_pulselib.values()]

    # create qobj experiment field
    experiments = []
    schedule_los = qobj_config.pop('schedule_los', [])

    if len(schedule_los) == 1:
        lo_dict = schedule_los[0]
        # update global config
        q_los = lo_converter.get_qubit_los(lo_dict)
        if q_los:
            qobj_config['qubit_lo_freq'] = q_los
        m_los = lo_converter.get_meas_los(lo_dict)
        if m_los:
            qobj_config['meas_lo_freq'] = m_los

    if schedule_los:
        # multiple frequency setups
        if len(qobj_schedules) == 1:
            # frequency sweep
            for lo_dict in schedule_los:
                experiments.append(PulseQobjExperiment(
                    instructions=qobj_schedules[0]['instructions'],
                    header=qobj_schedules[0]['header'],
                    config=lo_converter(lo_dict)
                ))
        elif len(qobj_schedules) == len(schedule_los):
            # n:n setup
            for lo_dict, schedule in zip(schedule_los, qobj_schedules):
                experiments.append(PulseQobjExperiment(
                    instructions=schedule['instructions'],
                    header=schedule['header'],
                    config=lo_converter(lo_dict)
                ))
        else:
            raise QiskitError('Invalid LO setting is specified. '
                              'The LO should be configured for each schedule, or '
                              'single setup for all schedules (unique), or '
                              'multiple setups for a single schedule (frequency sweep),'
                              'or no LO configured at all.')
    else:
        # unique frequency setup
        for schedule in qobj_schedules:
            experiments.append(PulseQobjExperiment(
                instructions=schedule['instructions'],
                header=schedule['header'],
            ))

    qobj_config = PulseQobjConfig(**qobj_config)

    return PulseQobj(qobj_id=qobj_id,
                     config=qobj_config,
                     experiments=experiments,
                     header=qobj_header)
Esempio n. 3
0
def assemble_schedules(schedules,
                       qobj_id=None,
                       qobj_header=None,
                       run_config=None):
    """Assembles a list of schedules into a qobj which can be run on the backend.
    Args:
        schedules (list[Schedule]): schedules to assemble
        qobj_id (int): identifier for the generated qobj
        qobj_header (QobjHeader): header to pass to the results
        run_config (RunConfig): configuration of the runtime environment
    Returns:
        PulseQobj: the Qobj to be run on the backends
    Raises:
        QiskitError: when invalid schedules or configs are provided
    """
    qobj_config = QasmQobjConfig()
    if run_config:
        qobj_config = QasmQobjConfig(**run_config.to_dict())

    # Get appropriate convertors
    instruction_converter = PulseQobjConverter
    instruction_converter = instruction_converter(PulseQobjInstruction,
                                                  **run_config.to_dict())
    lo_converter = LoConfigConverter(PulseQobjExperimentConfig,
                                     run_config.qubit_lo_freq,
                                     run_config.meas_lo_freq,
                                     **run_config.to_dict())

    # Pack everything into the Qobj
    qobj_schedules = []
    user_pulselib = set()
    for idx, schedule in enumerate(schedules):
        # instructions
        qobj_instructions = []
        # Instructions are returned as tuple of shifted time and instruction
        for shift, instruction in list(schedule.flatten()):
            # TODO: support conditional gate
            qobj_instructions.append(instruction_converter(shift, instruction))
            if isinstance(instruction, PulseInstruction):
                # add samples to pulse library
                user_pulselib.add(instruction.command)
        # experiment header
        qobj_experiment_header = QobjExperimentHeader(
            name=schedule.name or 'Experiment-%d' % idx)

        qobj_schedules.append({
            'header': qobj_experiment_header,
            'instructions': qobj_instructions
        })

    # setup pulse_library
    run_config.pulse_library = [
        QobjPulseLibrary(name=pulse.name, samples=pulse.samples)
        for pulse in user_pulselib
    ]

    # create qob experiment field
    experiments = []
    if len(run_config.schedule_los) == 1:
        lo_dict = run_config.schedule_los.pop()
        # update global config
        q_los = lo_converter.get_qubit_los(lo_dict)
        if q_los:
            run_config.qubit_lo_freq = q_los
        m_los = lo_converter.get_meas_los(lo_dict)
        if m_los:
            run_config.meas_lo_freq = m_los

    if run_config.schedule_los:
        # multiple frequency setups
        if len(qobj_schedules) == 1:
            # frequency sweep
            for lo_dict in run_config.schedule_los:
                experiments.append(
                    PulseQobjExperiment(
                        instructions=qobj_schedules[0]['instructions'],
                        experimentheader=qobj_schedules[0]['header'],
                        experimentconfig=lo_converter(lo_dict)))
        elif len(qobj_schedules) == len(run_config.schedule_los):
            # n:n setup
            for lo_dict, schedule in zip(run_config.schedule_los,
                                         qobj_schedules):
                experiments.append(
                    PulseQobjExperiment(
                        instructions=schedule['instructions'],
                        experimentheader=schedule['header'],
                        experimentconfig=lo_converter(lo_dict)))
        else:
            raise QiskitError(
                'Invalid LO setting is specified. '
                'The LO should be configured for each schedule, or '
                'single setup for all schedules (unique), or '
                'multiple setups for a single schedule (frequency sweep),'
                'or no LO configured at all.')
    else:
        # unique frequency setup
        for schedule in qobj_schedules:
            experiments.append(
                PulseQobjExperiment(
                    instructions=schedule['instructions'],
                    experimentheader=schedule['header'],
                ))

    qobj_config = PulseQobjConfig(**run_config.to_dict())

    return PulseQobj(qobj_id=qobj_id,
                     config=qobj_config,
                     experiments=experiments,
                     header=qobj_header)
Esempio n. 4
0
 def setUp(self):
     self.valid_qobj = PulseQobj(
         qobj_id='12345',
         header=QobjHeader(),
         config=PulseQobjConfig(shots=1024,
                                memory_slots=2,
                                max_credits=10,
                                meas_level=1,
                                memory_slot_size=8192,
                                meas_return='avg',
                                pulse_library=[
                                    PulseLibraryItem(name='pulse0',
                                                     samples=[
                                                         0.0 + 0.0j,
                                                         0.5 + 0.0j,
                                                         0.0 + 0.0j
                                                     ])
                                ],
                                qubit_lo_freq=[4.9],
                                meas_lo_freq=[6.9],
                                rep_time=1000),
         experiments=[
             PulseQobjExperiment(instructions=[
                 PulseQobjInstruction(name='pulse0', t0=0, ch='d0'),
                 PulseQobjInstruction(name='fc', t0=5, ch='d0', phase=1.57),
                 PulseQobjInstruction(name='fc', t0=5, ch='d0', phase=0.),
                 PulseQobjInstruction(name='fc', t0=5, ch='d0', phase='P1'),
                 PulseQobjInstruction(
                     name='pv', t0=10, ch='d0', val=0.1 + 0.0j),
                 PulseQobjInstruction(name='pv', t0=10, ch='d0', val='P1'),
                 PulseQobjInstruction(name='acquire',
                                      t0=15,
                                      duration=5,
                                      qubits=[0],
                                      memory_slot=[0],
                                      kernels=[
                                          QobjMeasurementOption(
                                              name='boxcar',
                                              params={
                                                  "start_window": 0,
                                                  "stop_window": 5
                                              })
                                      ])
             ])
         ])
     self.valid_dict = {
         'qobj_id':
         '12345',
         'type':
         'PULSE',
         'schema_version':
         '1.1.0',
         'header': {},
         'config': {
             'max_credits': 10,
             'memory_slots': 2,
             'shots': 1024,
             'meas_level': 1,
             'memory_slot_size': 8192,
             'meas_return': 'avg',
             'pulse_library': [{
                 'name': 'pulse0',
                 'samples': [0, 0.5, 0]
             }],
             'qubit_lo_freq': [4.9],
             'meas_lo_freq': [6.9],
             'rep_time': 1000
         },
         'experiments': [{
             'instructions': [{
                 'name': 'pulse0',
                 't0': 0,
                 'ch': 'd0'
             }, {
                 'name': 'fc',
                 't0': 5,
                 'ch': 'd0',
                 'phase': 1.57
             }, {
                 'name': 'fc',
                 't0': 5,
                 'ch': 'd0',
                 'phase': 0
             }, {
                 'name': 'fc',
                 't0': 5,
                 'ch': 'd0',
                 'phase': 'P1'
             }, {
                 'name': 'pv',
                 't0': 10,
                 'ch': 'd0',
                 'val': 0.1 + 0j
             }, {
                 'name': 'pv',
                 't0': 10,
                 'ch': 'd0',
                 'val': 'P1'
             }, {
                 'name':
                 'acquire',
                 't0':
                 15,
                 'duration':
                 5,
                 'qubits': [0],
                 'memory_slot': [0],
                 'kernels': [{
                     'name': 'boxcar',
                     'params': {
                         'start_window': 0,
                         'stop_window': 5
                     }
                 }]
             }]
         }]
     }
Esempio n. 5
0
def assemble_schedules(schedules, qobj_id, qobj_header, run_config):
    """Assembles a list of schedules into a qobj which can be run on the backend.
    Args:
        schedules (list[Schedule]): schedules to assemble
        qobj_id (int): identifier for the generated qobj
        qobj_header (QobjHeader): header to pass to the results
        run_config (RunConfig): configuration of the runtime environment
    Returns:
        PulseQobj: the Qobj to be run on the backends
    Raises:
        QiskitError: when invalid schedules or configs are provided
    """
    if hasattr(run_config, 'instruction_converter'):
        instruction_converter = run_config.instruction_converter
    else:
        instruction_converter = InstructionToQobjConverter

    qobj_config = run_config.to_dict()
    qubit_lo_range = qobj_config.pop('qubit_lo_range')
    meas_lo_range = qobj_config.pop('meas_lo_range')
    meas_map = qobj_config.pop('meas_map', None)
    instruction_converter = instruction_converter(PulseQobjInstruction, **qobj_config)

    lo_converter = LoConfigConverter(PulseQobjExperimentConfig, qubit_lo_range=qubit_lo_range,
                                     meas_lo_range=meas_lo_range, **qobj_config)

    # Pack everything into the Qobj
    qobj_schedules = []
    user_pulselib = set()
    for idx, schedule in enumerate(schedules):
        # instructions
        qobj_instructions = []
        # Instructions are returned as tuple of shifted time and instruction
        for shift, instruction in schedule.instructions:
            # TODO: support conditional gate
            qobj_instructions.append(instruction_converter(shift, instruction))
            if isinstance(instruction, PulseInstruction):
                # add samples to pulse library
                user_pulselib.add(instruction.command)
            if isinstance(instruction, AcquireInstruction):
                if meas_map:
                    # verify all acquires satisfy meas_map
                    _validate_meas_map(instruction, meas_map)

        # experiment header
        qobj_experiment_header = QobjExperimentHeader(
            name=schedule.name or 'Experiment-%d' % idx
        )

        qobj_schedules.append({
            'header': qobj_experiment_header,
            'instructions': qobj_instructions
        })

    # setup pulse_library
    qobj_config['pulse_library'] = [PulseLibraryItem(name=pulse.name, samples=pulse.samples)
                                    for pulse in user_pulselib]

    # create qobj experiment field
    experiments = []
    schedule_los = qobj_config.pop('schedule_los', [])

    if len(schedule_los) == 1:
        lo_dict = schedule_los[0]
        # update global config
        q_los = lo_converter.get_qubit_los(lo_dict)
        if q_los:
            qobj_config['qubit_lo_freq'] = q_los
        m_los = lo_converter.get_meas_los(lo_dict)
        if m_los:
            qobj_config['meas_lo_freq'] = m_los

    if schedule_los:
        # multiple frequency setups
        if len(qobj_schedules) == 1:
            # frequency sweep
            for lo_dict in schedule_los:
                experiments.append(PulseQobjExperiment(
                    instructions=qobj_schedules[0]['instructions'],
                    header=qobj_schedules[0]['header'],
                    config=lo_converter(lo_dict)
                ))
        elif len(qobj_schedules) == len(schedule_los):
            # n:n setup
            for lo_dict, schedule in zip(schedule_los, qobj_schedules):
                experiments.append(PulseQobjExperiment(
                    instructions=schedule['instructions'],
                    header=schedule['header'],
                    config=lo_converter(lo_dict)
                ))
        else:
            raise QiskitError('Invalid LO setting is specified. '
                              'The LO should be configured for each schedule, or '
                              'single setup for all schedules (unique), or '
                              'multiple setups for a single schedule (frequency sweep),'
                              'or no LO configured at all.')
    else:
        # unique frequency setup
        for schedule in qobj_schedules:
            experiments.append(PulseQobjExperiment(
                instructions=schedule['instructions'],
                header=schedule['header'],
            ))

    qobj_config = PulseQobjConfig(**qobj_config)

    return PulseQobj(qobj_id=qobj_id,
                     config=qobj_config,
                     experiments=experiments,
                     header=qobj_header)
Esempio n. 6
0
 def setUp(self):
     super().setUp()
     self.valid_qobj = PulseQobj(
         qobj_id="12345",
         header=QobjHeader(),
         config=PulseQobjConfig(
             shots=1024,
             memory_slots=2,
             max_credits=10,
             meas_level=1,
             memory_slot_size=8192,
             meas_return="avg",
             pulse_library=[
                 PulseLibraryItem(
                     name="pulse0",
                     samples=[0.0 + 0.0j, 0.5 + 0.0j, 0.0 + 0.0j])
             ],
             qubit_lo_freq=[4.9],
             meas_lo_freq=[6.9],
             rep_time=1000,
         ),
         experiments=[
             PulseQobjExperiment(instructions=[
                 PulseQobjInstruction(name="pulse0", t0=0, ch="d0"),
                 PulseQobjInstruction(name="fc", t0=5, ch="d0", phase=1.57),
                 PulseQobjInstruction(name="fc", t0=5, ch="d0", phase=0.0),
                 PulseQobjInstruction(name="fc", t0=5, ch="d0", phase="P1"),
                 PulseQobjInstruction(
                     name="setp", t0=10, ch="d0", phase=3.14),
                 PulseQobjInstruction(
                     name="setf", t0=10, ch="d0", frequency=8.0),
                 PulseQobjInstruction(
                     name="shiftf", t0=10, ch="d0", frequency=4.0),
                 PulseQobjInstruction(
                     name="acquire",
                     t0=15,
                     duration=5,
                     qubits=[0],
                     memory_slot=[0],
                     kernels=[
                         QobjMeasurementOption(name="boxcar",
                                               params={
                                                   "start_window": 0,
                                                   "stop_window": 5
                                               })
                     ],
                 ),
             ])
         ],
     )
     self.valid_dict = {
         "qobj_id":
         "12345",
         "type":
         "PULSE",
         "schema_version":
         "1.2.0",
         "header": {},
         "config": {
             "max_credits": 10,
             "memory_slots": 2,
             "shots": 1024,
             "meas_level": 1,
             "memory_slot_size": 8192,
             "meas_return": "avg",
             "pulse_library": [{
                 "name": "pulse0",
                 "samples": [0, 0.5, 0]
             }],
             "qubit_lo_freq": [4.9],
             "meas_lo_freq": [6.9],
             "rep_time": 1000,
         },
         "experiments": [{
             "instructions": [
                 {
                     "name": "pulse0",
                     "t0": 0,
                     "ch": "d0"
                 },
                 {
                     "name": "fc",
                     "t0": 5,
                     "ch": "d0",
                     "phase": 1.57
                 },
                 {
                     "name": "fc",
                     "t0": 5,
                     "ch": "d0",
                     "phase": 0
                 },
                 {
                     "name": "fc",
                     "t0": 5,
                     "ch": "d0",
                     "phase": "P1"
                 },
                 {
                     "name": "setp",
                     "t0": 10,
                     "ch": "d0",
                     "phase": 3.14
                 },
                 {
                     "name": "setf",
                     "t0": 10,
                     "ch": "d0",
                     "frequency": 8.0
                 },
                 {
                     "name": "shiftf",
                     "t0": 10,
                     "ch": "d0",
                     "frequency": 4.0
                 },
                 {
                     "name":
                     "acquire",
                     "t0":
                     15,
                     "duration":
                     5,
                     "qubits": [0],
                     "memory_slot": [0],
                     "kernels": [{
                         "name": "boxcar",
                         "params": {
                             "start_window": 0,
                             "stop_window": 5
                         }
                     }],
                 },
             ]
         }],
     }