QuTech-Delft / OpenQL

OpenQL: A Portable Quantum Programming Framework for Quantum Accelerators. https://dl.acm.org/doi/10.1145/3474222
https://openql.readthedocs.io
Other
97 stars 44 forks source link

Generate measurement masks after compilation #432

Closed MiguelSMoreira closed 2 years ago

MiguelSMoreira commented 2 years ago

This issue will track developments meant to generate measurement masks after OpenQL program compilation with the purpose of automating the preparation of readout instruments. These developments are necessary for the next planned release of Quantum Inspire with support for multiple measurement definition per program

wvlothuizen commented 2 years ago

The next development release 0.10.3 generates a JSON map of measurements, e.g.:

    "measurements": {
        "data": [
            [
                "ro_1",
                [
                    6
                ]
            ],
            [
                "ro_0",
                [
                    1,
                    4,
                    5,
                    7,
                    8,
                    10,
                    11,
                    14,
                    15
                ]
            ],
            [
                "ro_1",
                [
                    0,
                    2,
                    3,
                    6,
                    9,
                    12
                ]
            ],
            [
                "ro_2",
                [
                    13,
                    16
                ]
            ]
        ],
        "version": 1
    },

for input program:

measure q[0:16]  
measure q[6]

The qubits of simultaneous measurements are organised into records per measurement instrument. Do note the effect of the scheduler in the example above, which may be counter-intuitive: measure q[0:16] is not executed in parallel:

# Generated by OpenQL 0.10.3 for program test_measure_map_output
version 1.2

pragma @ql.name("test_measure_map_output")

.__1 @ql.name("")
    _do_measure q[6]
    skip 39
    { # start at cycle 40
        _do_measure q[0]
        _do_measure q[1]
        _do_measure q[2]
        _do_measure q[3]
        _do_measure q[4]
        _do_measure q[5]
        _do_measure q[7]
        _do_measure q[8]
        _do_measure q[9]
        _do_measure q[10]
        _do_measure q[11]
        _do_measure q[12]
        _do_measure q[13]
        _do_measure q[14]
        _do_measure q[15]
        _do_measure q[16]
        _do_measure q[6]
    }
    skip 39

Note that the organisation of the JSON map may be changed if necessary during the development of the downstream software that actually extracts the measurements from the instruments.

Also note that program flow is not taken into account: results may not be useful in the presence of conditional program flow

MiguelSMoreira commented 2 years ago

The structure looks good. It would be ideal to organize all measurements (in different arrays per measurement block) per measurement instrument, if possible. This would ensure the simplest translation and interpretation of data structures

wvlothuizen commented 2 years ago

Changed to:

    "measurements": {
        "data": {
            "ro_0": [
                [
                    1,
                    4,
                    5,
                    7,
                    8,
                    10,
                    11,
                    14,
                    15
                ]
            ],
            "ro_1": [
                [
                    6
                ],
                [
                    0,
                    2,
                    3,
                    6,
                    9,
                    12
                ]
            ],
            "ro_2": [
                [
                    13,
                    16
                ]
            ]
        },
        "version": 1
    },
MiguelSMoreira commented 2 years ago

Tested in the Ferrari setup to be working according to its definition

wvlothuizen commented 2 years ago

After some discussion, below is an updated proposal that groups simultaneous measurements, and adds the number of shots per instrument (for instruments that have at least 1 shot, otherwise the instrument key does not exist).

    "measurements": {
        "data": [
            {
                "ro_1": [
                    6
                ]
            },
            {
                "ro_0": [
                    1,
                    4,
                    5,
                    7,
                    8,
                    10,
                    11,
                    14,
                    15
                ],
                "ro_1": [
                    0,
                    2,
                    3,
                    6,
                    9,
                    12
                ],
                "ro_2": [
                    13,
                    16
                ]
            },
            {
                "ro_0": [
                    1,
                    4,
                    5,
                    7,
                    8
                ],
                "ro_1": [
                    0,
                    2,
                    3,
                    6
                ]
            }
        ],
        "nr-shots": {
            "ro_0": 2,
            "ro_1": 3,
            "ro_2": 1
        },
        "version": 2
    },

Note that an extra measurement was added to the input program to have some more difference in nr-shots