Supported passes

This section lists all the compiler pass types currently available within OpenQL.

Statistics cleaner

Type name(s): ana.statistics.Clean.

This pass just discards any statistics that previous passes might have attached to the kernel and program. It is inserted automatically after every normal pass that does not have statistics reporting enabled.

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

Statistics reporter

Type name(s): ana.statistics.Report.

This pass reports some basic statistics of the program and each kernel to a report file. Some passes may also attach additional pass-specific statistics to the program and kernels, in which case these are printed and subsequently discarded as well.

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

output_suffix

Must be any string, default .txt. Suffix to use for the output filename.

line_prefix

Must be any string, no default value. Historically, report files contain a “# ” prefix before each line. You can use this option to emulate that behavior.

Circuit visualizer

Type name(s): ana.visualize.Circuit.

The circuit visualizer produces an image of the circuit containing the operations on each qubit per cycle. If so configured, it can also render instrument waveforms alongside it.

Configuration file structure

The visualizer is configured by way of the visualizer configuration file. Each attribute has a default setting, so many can be omitted if no change is wanted.

The circuit visualizer supports the following top-level sections:

  • "circuit": contains options for the circuit visualization, including pulse visualization.

  • "saveImage": a boolean indicating whether the generated image should be saved to disk. When this is true, the file will be saved regardless of/in addition to the interactive window as controlled by the interactive option.

  • "backgroundColor": the background color of the generated image.

Note

A single visualizer configuration file may be used for all three visualization pass types. The configuration file format is designed to be cross-compatible.

Note

When the to-be-visualized circuit is very large, the interactive window may have trouble rendering the circuit even when zoomed in. Therefore, it is recommended to use non-interactive mode and view the generated bitmap with a more capable external viewer.

The "circuit" section has several child sections.

  • "cycles": contains parameters that govern cycle labels, edges, cycle compression and cutting.

  • "bitLines": defines the labels and lines, including grouping lines for both quantum and classical bitLines.

  • "grid": defines several parameters of the image grid.

  • "gateDurationOutlines": controls parameters for gate duration outlines.

  • "measurements": several parameters controlling measurement visualization.

  • "pulses": parameters for pulse visualization.

  • "instructions": a map of instruction types (the keys) with that type’s gate visualization as value, used for custom instructions.

Example configuration (self-explanatory attributes have no description):

"cycles": {
    // parameters for the labels above each cycle
    "labels": {
        "show": true,
        // whether the cycle labels should be shown in nanoseconds or
        // cycle numbers
        "inNanoSeconds": false,
        // the height of the cycle label row
        "rowHeight": 24,
        "fontHeight": 13,
        "fontColor": [0, 0, 0]
    },
    // parameters for the vertical edges between cycles
    "edges": {
        "show": true,
        "color": [0, 0, 0],
        "alpha": 0.2
    },
    // parameters for the cutting of cycles (cycles are cut when no new
    // gates are started)
    "cutting": {
        "cut": true,
        // how many cycles should be without a gate starting before the
        // cycle is cut
        "emptyCycleThreshold": 2,
        "cutCycleWidth": 16,
        // a multiplier on the width of the cut cycles
        "cutCycleWidthModifier": 0.5
    },
    // cycles are compressed by reducing each gate's duration to one cycle
    "compressCycles": false,
    // partitioning a cycle means that each gate in that cycle gets its
    // own column within the cycle; this can be done to remove visual
    // overlap
    "partitionCyclesWithOverlap": true
},
"bitLines": {
    // parameters for the labels on each quantum or classical bit line
    "labels": {
        "show": true,
        // the width of the label column
        "columnWidth": 32,
        "fontHeight": 13,
        // the colors of quantum and classical bit labels
        "qbitColor": [0, 0, 0],
        "cbitColor": [128, 128, 128]
    },
    // parameters specifically for quantum bit lines
    "quantum": {
        "color": [0, 0, 0]
    },
    // parameters specifically for classical bit lines
    "classical": {
        "show": true,
        // grouping classical bit lines collapses them into a double line
        // to reduce visual clutter
        "group": false,
        // controls the gap between the double line indicating the
        // collapsed classical lines
        "groupedLineGap": 2,
        "color": [128, 128, 128]
    },
    // parameters for the horizontal edges between bit lines
    "edges": {
        "show": false,
        "thickness": 5,
        "color": [0, 0, 0],
        "alpha": 0.4
    }
},
"grid": {
    // the size of each cell formed by a the crossing of a single bit line
    // and cycle
    "cellSize": 32,
    // the border at the edges of the generated image
    "borderSize": 32
},
"gateDurationOutlines": {
    "show": true,
    // the gap between the edge of the cell and the gate duration outline
    "gap": 2,
    // the filled background alpha
    "fillAlpha": 0.2,
    // the outline alpha
    "outlineAlpha": 0.3,
    "outlineColor": [0, 0, 0]
},
"measurements": {
    // whether to draw a connection from the measurement gate to the
    // classical line it stores the result in
    "drawConnection": true,
    // the gap between the double line representing the connection
    "lineSpacing": 2,
    "arrowSize": 10
},
"pulses": {
    // set this to true to use the pulse visualization
    "displayGatesAsPulses": false,
    // these heights control the line row heights
    "pulseRowHeightMicrowave": 32,
    "pulseRowHeightFlux": 32,
    "pulseRowHeightReadout": 32,
    // these colors control the line colors
    "pulseColorMicrowave": [0, 0, 255],
    "pulseColorFlux": [255, 0, 0],
    "pulseColorReadout": [0, 255, 0]
},
"instructions" {
    // defined below
}

Gate visualization

A visualization needs to be defined by the user for each gate type used in the circuit. In the instructions section of the visualizer configuration file, each instruction “type” has its own corresponding description of gate visualization parameters. These instruction types are mapped to actual custom instructions from the hardware configuration file by adding a "visual_type" key to the instructions. For example:

{
    ...,
    "instructions" {
        ...,
        "h q1": {
            "duration": 40,
            "qubits": ["q1"],
            "visual_type": "h"
        },
        ...
    },
    ...
}

This custom Hadamard gate defined on qubit 1 has one additional attribute "visual_type" describing its visualization type. The value of this attribute links to a key in the visualizer configuration file, which has the description of the gate visualization parameters that will be used to visualize this custom instruction. Note that this allows multiple custom instructions to share the same visualization parameters, without having to duplicate the parameters.

The instructions section of the visualizer configuration file then defines how each gate type is rendered. Here’s an excerpt from an example configuration file:

{
    ...,
    "instructions": {
        ...,
        "h": {
            "connectionColor": [0, 0, 0],
            "nodes": [
                {
                    "type": "GATE",
                    "radius": 13,
                    "displayName": "H",
                    "fontHeight": 13,
                    "fontColor": [255, 255, 255],
                    "backgroundColor": [70, 210, 230],
                    "outlineColor": [70, 210, 230]
                }
            ]
        },
        ...
    },
    ...
}

Each gate has a "connectionColor" which defines the color of the connection line for multi-operand gates, and an array of "nodes". A node is the visualization of the gate acting on a specific qubit or classical bit. If a Hadamard gate is acting on qubit 3, that is represented by one node. If a CNOT gate is acting on qubits 1 and 2, it will have two nodes, one describing the visualization of the CNOT gate at qubit 1 and one describing the visualization on qubit 2. A measurement gate measuring qubit 5 and storing the result in classical bit 0 will again have two nodes.

Each node has several attributes describing its visualization.

  • "type": the visualization type of the node, see below for a list of the available types.

  • "radius": the radius of the node in pixels.

  • "displayName": text that will be displayed on the node (for example "H" will be displayed on the Hadamard gate in the example above).

  • "fontHeight": the height of the font in pixels used by the "displayName".

  • "fontColor": the color of the font used by the "displayName".

  • "backgroundColor": the background color of the node.

  • "outlineColor": the color of the edge-line of the node.

The colors are defined as RGB arrays: [R, G, B].

The type of the nodes can be one of the following.

  • "NONE": the node will not be visible.

  • "GATE": a square representing a gate.

  • "CONTROL": a small filled circle.

  • "NOT": a circle outline with cross inside (a CNOT cross).

  • "CROSS": a diagonal cross.

When a gate has multiple operands, each operand should have a node associated with it. Simply create as many nodes in the node array as there are operands and define a type and visual parameters for it. Don’t forget the comma to separate each node in the array. Note that nodes are coupled to each operand sequentially, i.e. the first node in the node array will be used for the first qubit in the operand vector.

Pulse visualization

Along with an abstract representation of the gates used in the quantum circuit, the gates can also be represented by the RF pulses used in the real hardware. This will be done when the "displayGatesAsPulses" flag in the "pulses" section is set to true. In this case, the waveform_mapping option must be used to specify a waveform configuration file.

Each qubit consists of three lines, the microwave, flux and readout lines, controlling single-qubit gates, two-qubit gates and readouts respectively. The waveforms used by the hardware should be stored in the waveform mapping configuration file. Then, in the hardware configuration file the "visual_codeword" and "qubits" attributes of each instruction are used as key into the table contained in the waveform mapping file to find the corresponding waveform for the specific instruction and qubit (waveforms for the same instruction can be different for different qubits). Note that a two-qubit gate has two codeword attributes, one for each qubit: "visual_right_codeword" and "visual_left_codeword".

In the waveform mapping configuration file, the waveforms are grouped by codeword first and then by addressed qubit. The waveforms themselves are stored as an array of real numbers. The scale of these numbers does not matter, the visualizer will automatically scale the pulses to fit inside the graph. The time between samples is determined by the sample rate (the sample rate can be different for each of the three lines).

TODO: the structure of the waveform mapping configuration file should still be documented. For now, use the examples in tests/visualizer as a baseline.

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

config

Must be any string, default visualizer_config.json. Path to the visualizer configuration file.

waveform_mapping

Must be any string, default waveform_mapping.json. Path to the visualizer waveform mapping file.

interactive

Must be yes or no, default no. When yes, the visualizer will open a window when the pass is run. When no, an image will be saved as <output_prefix>.bmp instead.

Qubit interaction graph visualizer

Type name(s): ana.visualize.Interaction.

The qubit interaction graph visualizes the interactions between each of the qubits in the circuit. If a gate acts on two or more qubits, those qubits interact with each other and an edge will be drawn in the graph, with a number indicating the amount of times those qubits have interacted with each other. Note that the visualization of this is very simple, and the DOT graph the visualizer can produce should be used with the user’s favorite graphing software to create a better looking graph.

Configuration file structure

The visualizer is configured by way of the visualizer configuration file. Each attribute has a default setting, so many can be omitted if no change is wanted.

The circuit visualizer supports the following top-level sections:

  • "interactionGraph": contains options for the interaction graph.

  • "saveImage": a boolean indicating whether the generated image should be saved to disk. When this is true, the file will be saved regardless of/in addition to the interactive window as controlled by the interactive option.

  • "backgroundColor": the background color of the generated image.

Note

A single visualizer configuration file may be used for all three visualization pass types. The configuration file format is designed to be cross-compatible.

The "interactionGraph" section should have the following structure.

"interactionGraph": {
    // whether a DOT file should be generated for use with graphing
    // software
    "outputDotFile": true,
    "borderWidth": 32,
    // the minimum radius of the circle on which the qubits are placed
    "minInteractionCircleRadius": 100,
    "interactionCircleRadiusModifier": 3.0,
    "qubitRadius": 17,
    "labelFontHeight": 13,
    "circleOutlineColor": [0, 0, 0],
    "circleFillColor": [255, 255, 255],
    "labelColor": [0, 0, 0],
    "edgeColor": [0, 0, 0]
}

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

config

Must be any string, default visualizer_config.json. Path to the visualizer configuration file.

interactive

Must be yes or no, default no. When yes, the visualizer will open a window when the pass is run. When no, an image will be saved as <output_prefix>.bmp instead.

Qubit mapping graph visualizer

Type name(s): ana.visualize.Mapping.

The mapping graph tracks the journey of the virtual qubits through the real topology of the quantum hardware as the cycles of the quantum program are executed. The virtual qubits change location whenever a swap/move gate (or their decomposed parts) is finished executing. For convenience, the abstract circuit representation of the quantum program is shown above the qubit mappings for each cycle.

The topology of the quantum hardware is taken from the topology section in the hardware configuration file, together with the edges between the qubits. If no coordinates and/or edges are defined for the qubits, the qubits will simply be spaced sequentially in a grid structure without edges being shown.

Configuration file structure

The visualizer is configured by way of the visualizer configuration file. Each attribute has a default setting, so many can be omitted if no change is wanted.

The circuit visualizer supports the following top-level sections:

  • "mappingGraph": contains options for the mapping graph.

  • "saveImage": a boolean indicating whether the generated image should be saved to disk. When this is true, the file will be saved regardless of/in addition to the interactive window as controlled by the interactive option.

  • "backgroundColor": the background color of the generated image.

Note

A single visualizer configuration file may be used for all three visualization pass types. The configuration file format is designed to be cross-compatible.

The "mappingGraph" section should have the following structure.

"mappingGraph": {
    // whether qubits should be filled with the corresponding logical
    // qubit index in the first cycle
    "initDefaultVirtuals": false,
    // give each distinct virtual qubit a color
    "showVirtualColors": true,
    // show the real qubit indices above the qubits
    "showRealIndices": true,
    // whether to use the topology from the hardware configuration file
    "useTopology": true,
    // parameters for controlling the layout
    "qubitRadius": 15,
    "qubitSpacing": 7,
    "fontHeightReal": 13,
    "fontHeightVirtual": 13,
    "textColorReal": [0, 0, 255],
    "textColorVirtual": [255, 0, 0],
    // the gap between the qubit and the real index
    "realIndexSpacing": 1,
    "qubitFillColor": [255, 255, 255],
    "qubitOutlineColor": [0, 0, 0]
}

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

config

Must be any string, default visualizer_config.json. Path to the visualizer configuration file.

interactive

Must be yes or no, default no. When yes, the visualizer will open a window when the pass is run. When no, an image will be saved as <output_prefix>.bmp instead.

Central Controller code generator

Type name(s): arch.cc.gen.VQ1Asm.

Assembly code generator for the Q1 processor in the QuTech Central Controller, version 0.4.0

This pass actually generates three files:

  • <prefix>.vq1asm: the assembly code output file;

  • <prefix>.map: the instrument configuration file; and

  • <prefix>.vcd: a VCD (value change dump) file for viewing the waveforms that the program outputs.

The pass is compile-time configured with the following options:

  • OPT_CC_SCHEDULE_RC = 1

  • OPT_SUPPORT_STATIC_CODEWORDS = 1

  • OPT_STATIC_CODEWORDS_ARRAYS = 1

  • OPT_VECTOR_MODE = 0

  • OPT_CC_USER_FUNCTIONS = 1

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

map_input_file

Must be any string, no default value. Specifies the input map filename.

verbose

Must be yes or no, default yes. Selects whether verbose comments should be added to the generated .vq1asm file.

run_once

Must be yes or no, default no. When set, the emitted .vq1asm program runs once instead of repeating indefinitely.

Diamond microcode generator

Type name(s): arch.diamond.gen.Microcode.

Note

This is a legacy pass, operating on the old intermediate representation. If the program is using features that the old IR does not support when this pass is run, an internal compiler error will be thrown. Furthermore, kernel/block names may change regardless of whether the pass does anything with them, due to name uniquification logic.

Generates the microcode from the algorithm (cQASM/C++/Python) description for quantum computing in diamond.

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

Instruction generalizer

Type name(s): dec.Generalize.

This pass converts the format of all instructions in the program to their most generalized form. For example, if a specialized CNOT gate exists for qubits 1 and 2 and this specialization is used in the program, the instruction is changed to the generalized version for any set of qubits. This implements the reverse operation of dec.Specialize.

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

Instruction decomposer

Type name(s): dec.Instructions.

This pass (conditionally) applies instructions decomposition rules as specified in the platform configuration JSON structure. The pass returns the number of rules that were applied.

Rules can be disabled for the purpose of this pass using the predicate_key and predicate_value options. When set, the key given by predicate_key is resolved in the JSON data that may be associated with new-style decomposition rules (the ones associated with instructions, rather than the ones specified in the "gate_decomposition" section of the platform JSON file). If this resolves to a string, the predicate_value option is matched against it. The rule is then only applied if there is a match. Some special cases:

  • if the key does not exist in the JSON data associated with the decomposition rule, or if it exists but maps to something that isn’t a string, the predicate will match if predicate_value matches an empty string; and

  • the effective JSON structure for legacy decomposition rules is {"name": "legacy"}.

The ignore_schedule option controls how scheduling information is treated. When set to yes (the default), the cycle numbers of the decomposed instructions will be set to the same cycle number as the original instruction. When set to no, the schedule of the decomposed instructions is taken from the decomposition rule, and instructions are reordered accordingly after all decompositions have taken place.

For example, assume that we have the following decomposition rule for a CNOT gate:

ym90 op(1)
cz op(0), op(1)
skip 1
y90 op(1)

and that we have the following program as input:

{
    cnot q[0], q[1]
    cnot q[1], q[2]
}

Now, if ignore_schedule is enabled, the resulting program would be

{
    ym90 q[1]
    cz q[0], q[1]
    y90 q[1]
    ym90 q[2]
    cz q[1], q[2]
    y90 q[2]
}

The schedule is obviously invalid, because qubits are being used by multiple gates in the same cycle. But so was the input. Nevertheless, the order of the instructions is what we wanted; after scheduling, the program will be correct.

If we were to turn ignore_schedule off, however, this is what we’d get:

{
    ym90 q[1]
    ym90 q[2]
}
{
    cz q[0], q[1]
    cz q[1], q[2]
}
skip 1
{
    y90 q[1]
    y90 q[2]
}

Which is wrong! The ym90 and y90 gates execute out of order with the cz q[1], q[2] now. Scheduling won’t fix this.

The key takeaway here is that you should leave ignore_schedule enabled if A) the program has not been scheduled yet or B) you’re not sure that the schedules in the decomposition rules are actually defined correctly.

Of course, there are cases where ignore_schedule needs to be disabled, otherwise the option wouldn’t need to be there. It’s useful specifically when you need to process code expansions after scheduling. You will need to make sure that the decomposition rules that the predicate matches are written such that they won’t ever break a correctly scheduled program, but if that’s the case, you won’t have to schedule the program again after the decomposition. For example, if the input program had been

cnot q[0], q[1]
skip 3
cnot q[1], q[2]

the result with ignore_schedule disabled would have been

ym90 q[1]
cz q[0], q[1]
skip 1
y90 q[1]
ym90 q[2]
cz q[1], q[2]
skip 1
y90 q[2]

which is not an optimal schedule by any means, but a correct one nonetheless. A more reasonable use case for this than CNOT to CZ decomposition would be expanding a CZ gate to single-qubit flux and parking gates; it’s vital that these gates will not be shifted around with respect to each other, which scheduling after decomposing them might do.

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

predicate_key

Must be any string, default name. The key to use for the predicate check.

predicate_value

Must be any string, default *. Pattern that must match for the value of the key specified by the predicate_key option for a decomposition rule to be applied. * and ? may be used to construct nontrivial patterns. The entire pattern must match; for partial matches, prefix and append an *.Nonexistent keys or non-string values are treated as if they are an empty string.

ignore_schedule

Must be yes or no, default yes. When set, the schedule of the decomposition expansions is ignored. This prevents instructions from ever needing to be reordered, and thus prevents the behavior of the program from changing due to incorrect schedules in the decomposition rules, but will almost certainly require the program to be rescheduled. You should only turn this off when you really want to keep scheduling information, and are really sure that the schedules in the decomposition rule expansions are correct.

Instruction specializer

Type name(s): dec.Specialize.

This pass converts the format of all instructions in the program to their most specialized form. For example, if a generalized CNOT gate exists for qubits 1 and 2, and a specialization exists for this qubit pair as well, the instruction is changed to the specialized version. This implements the reverse operation of dec.Generalize.

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

Structure decomposer

Type name(s): dec.Structure.

This pass converts the program to basic block form. Specifically, the postcondition for this pass is:

  • all blocks consist of only instructions (no control-flow statements like loops or if-conditionals); and

  • only the last instruction of each block may be a goto instruction.

All control-flow that exists in the program before this pass is reduced to this basic form. This doesn’t change the behavior of the program, but all information about the program structure is lost. Because of this, this should be one of the last passes, if the pass is needed at all; this depends on the code generator used, or on whether there is a need for passes that rely on basic-block form and the corresponding control-flow graph to operate.

Optionally, the control-flow graph of the resulting program can be printed as in graphviz dot format.

Schedule preservation

This pass does its best to preserve the schedule of the original program, so it doesn’t need to be rescheduled after the transformation. Note however that this is only valid if classical instructions have (quantum) duration zero and do not use any scheduling resources.

Unfortunately, there are some situations where the resulting schedule ends up being longer than it should be. This has to do with block duration not currently being explicitly encoded in the IR. The schedule should at least be correct, though, if the above assumptions about classical instructions are applicable.

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

write_dot_graph

Must be yes or no, default no. Writes the control-flow graph of the resulting program in the dot format. The file is written with suffix “.dot”.

cQASM reader

Type name(s): io.cqasm.Read.

This pass completely discards the incoming program and replaces it with the program described by the given cQASM file.

The reader supports up to cQASM 1.2. However, rather than supporting the default cQASM instruction and function set, the instructions defined in the platform JSON description are used. In addition, the following special instructions are supported.

  • skip <int>: used in conjunction with bundle notation to represent a scheduled program. The instruction behaves like <int> consecutive empty bundles.

  • wait <int>: used as an input to the scheduler, forcing all instructions defined after the wait instruction to start at least <int> cycles after all instructions defined before the wait instruction have completed.

  • wait q[...], <int>: as above, but only affects instructions that operate on the specified qubit. Effectively, this means that the instruction enforces that the qubit is idled for at least <int> cycles. If single-gate-multiple-qubit notation is used, for example wait q[0,2], 3, the independent wait blocks are created as per the regular single-gate-multiple-qubit rules.

  • wait <int>, ...: generalization of the above, supporting any kind of object, and any number of them. That is, all preceding instructions operating on any object specified in place of the ellipsis must complete before the wait can be scheduled, and any following instructions operating on any object specified in place of the ellipsis must start after the wait completes. Unlike the above, if single-gate-multiple- qubit notation is used for qubit/bit objects, the result is a single wait instruction that waits for all indexed elements, rather than multiple parallel wait instructions (this is semantically different!).

  • barrier ...: shorthand for wait 0, .... A barrier without arguments is also valid.

  • measure_all: if the measure_all_target option is set, this is automatically expanded to single-qubit measurement instructions of the name defined by the value of the option for each qubit in the main qubit register.

  • pragma: supported as a means to place annotations inside statement lists. The reader uses this for some annotations of its own, but otherwise ignores it.

Registers as defined by the platform are implicitly defined by the reader, and must thus not be redefined as variables. The only exception is the main qubit register (qubits <int>), which may optionally be defined at the top of the file, as this statement is mandatory in the cQASM 1.0 language. Non-scalar registers, such as integer control registers (cregs) and bit registers beyond the bits associated with the main qubit register (bregs), must be referred to using a function call of the same name as the register with the index/indices as arguments (for example creg(2)), as cQASM doesn’t natively support non-scalar objects aside from the main qubit register and associated bits.

Various annotations may be used to fine-tune the behavior of the reader. Most of these are particularly important for accurate reproduction of OpenQL’s internal representation of the program after conversion to and from cQASM.

  • pragma @ql.platform(<json>) may be placed at the top of the program. If the load_platform option is not enabled, it is ignored. Otherwise, the following forms are supported (these mirror the constructors of the Platform class in the API for the most part):

    • not specified or pragma @ql.platform(): shorthand for ...("none", "none").

    • pragma @ql.platform(name: string): shorthand for ...(name, name).

    • pragma @ql.platform(name: string, platform_config: string): builds a platform with the given name (only used for log messages) and platform configuration, the latter of which can be either a recognized platform name with or without variant suffix (for example "cc" or "cc_light.s7"), or a path to a JSON configuration filename.

    • pragma @ql.platform(name: string, platform_config: string, compiler_config: string): as above, but specifies a custom compiler configuration file in addition.

    • pragma @ql.platform(name: string, platform_config: json): instead of loading the platform JSON data from a file, it is read from the given JSON literal directly.

    • pragma @ql.platform(platform_config: json): shorthand for the above, using just "platform" for the name.

    Note that the loaded compiler configuration is ignored, because we already have one by the time this pass is run! Use the compile_cqasm() API function to load everything from the cQASM file.

  • pragma @ql.name("<name>") may be placed at the top of the program to set the name of the program, in case no program exists in the IR yet. Otherwise it will simply default to "program".

  • Variables may be annotated with @ql.type("<name>") to specify the exact OpenQL type that should be used. If not specified, the first type defined in the platform that matches the primitive cQASM type will be used. You should only need this when you’re using a platform that, for instance, supports multiple types/sizes of integers.

  • Variables may be annotated with @ql.temp to specify that they are temporary objects that were automatically inferred. This is normally only used by generated cQASM code.

  • The first subcircuit may be annotated with @ql.entry if it consists of only a single, unconditional goto instruction. In that case, the subcircuit will be discarded, and the target of the goto instruction will be marked as the entry point of the program within OpenQL, rather than the first subcircuit.

  • The last subcircuit may be annotated with @ql.exit if it contains no instructions. In that case, the subcircuit will be discarded, but any subcircuits that end in an unconditional goto instruction to this subcircuit will be marked as ending the program within OpenQL.

The schedule option controls how scheduling information is interpreted.

  • If set to keep, skip instructions and bundles are used to determine the cycle numbers of the instructions within each block, using the following rules:

    • single-gate-multiple-qubit notation (for example x q[0,1]) is expanded to a bundle of instructions that start simultaneously;

    • the first instruction or bundle of instructions is assigned to start in cycle 0;

    • each subsequent single instruction or bundle of instructions starts one cycle after the previous instruction/bundle started; and

    • skip <int> behaves like <int> empty bundles.

  • If set to discard, skip instructions and bundles are ignored, and single-gate-multiple-qubit is ignored in terms of its timing implication; instead, instructions will be assigned consecutive cycle numbers in the order in which they appear in the file.

  • If set to bundles-as-barriers, timing information is ignored as for discard, but barriers are implicitly inserted before and after each bundle, sensitive to exactly those objects used as operands by the instructions that appear in the bundle. Single-gate-multiple-qubit notation expands to a bundle as well.

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

cqasm_file

Must be any string, no default value. cQASM file to read. Mandatory.

schedule

Must be one of keep, discard, or bundles-as-barriers, default keep. Controls how scheduling/timing information (via bundles and skip instructions) is interpreted. See pass description for more info.

measure_all_target

Must be any string, no default value. Standard cQASM has a measure_all instruction that implicitly measures all qubits in a certain way, while OpenQL platforms normally lack this instruction. When this option is set, it is treated as the name of a single-qubit measurement gate, that will be used to implement measure_all; i.e. the measure_all instruction will be expanded to a bundle of

<measure_all_target> instructions, for each qubit in the main qubit register.

load_platform

Must be yes or no, default no. When set, the platform is loaded from the cQASM file by means of a pragma @ql.platform(...) statement at the top of the code. See pass description for more information.

cQASM writer

Type name(s): io.cqasm.Report.

This pass writes the current program out as a cQASM file, targeting the given cQASM version. The writer supports cQASM versions 1.0, 1.1, and 1.2, but note that older cQASM versions do not support everything that OpenQL supports.

Several options are provided to control how the cQASM file is written. These are necessary because, even within a particular cQASM version, various dialects exist, based on instruction set, implicit register definitions, function definitions, and so on.

Regardless of configuration, the written file assumes that the target cQASM reader/interpreter supports the instruction- and function set as defined (or derived from) the platform JSON description. This means that if you want to target a cQASM reader/interpreter that only supports a subset of this instruction/function set, or one that supports a different instruction set entirely, you will have to ensure that all instructions have been decomposed to the instruction set supported by the target prior to printing the cQASM file, or write the program such that the unsupported instructions/functions aren’t used in the first place. It is also possible to embed the platform description into the cQASM file in JSON form via a pragma instruction, but of course the target cQASM reader/interpreter would then have to support that instead.

The only instructions that the cQASM writer can print that are not part of the instruction set as defined in the JSON file are pragmas, barriers, wait, and skip instructions, but they can be disabled via options.

  • pragma instructions are no-op placeholder instructions with no operands that are used to convey metadata via annotations within the context of a statement. If the with_metadata and with_platform options are disabled, no pragmas will be printed.

  • barrier and wait instructions are used for the builtin wait instruction. If the with_barriers option is disabled, they will not be printed. If the option is set to simple, the printed syntax and semantics are:

    • wait <int>: wait for all previous instructions to complete, then wait <int> cycles, where <int> may be zero;

    • barrier q[...]: wait for all instructions operating on the qubits in the single-gate-multiple-qubit list to complete.

    Note that this syntax only supports barriers acting on qubits, and doesn’t support wait instructions depending on a subset of objects. However, it conforms with the default cQASM 1.0 gateset as of libqasm 0.3.1 (in 0.3 and before, barrier did not exist in the default gateset). If the option is instead set to extended, the syntax is:

    • wait <int>: wait for all previous instructions to complete, then wait <int> >= 1 cycles;

    • wait <int>, [...]: wait for all previous instructions operating on the given objects to complete, when wait <int> >= 1 cycles;

    • barrier: wait for all previous instructions to complete;

    • barrier [...]: wait for all previous instructions operating on the given objects to complete.

    This encompasses all wait instructions possible within OpenQL’s IR. OpenQL’s cQASM reader supports both notations equally.

  • skip <int> instructions are printed in addition to the {} multiline bundle notation to convey scheduling information: all instructions in a bundle start in the same cycle, the subsequent bundle or instruction starts in the next cycle (regardless of the duration of the instructions in the former bundle), and a skip <int> instruction may be used in place of <int> empty bundles, thus skipping <int> cycles. skip instructions and bundles are not printed when the with_timing option is disabled.

None of the supported cQASM versions support non-scalar variables or registers, aside from the special-cased main qubit register and corresponding bit register. Therefore, some tricks are needed.

  • For non-scalar registers that are expected to be implicitly defined by the target cQASM reader/interpreter, references are printed as a function call, for example creg(2) for the integer control register 2.

  • For non-scalar variables (including registers when registers_as_variables is set), an independent cQASM variable will be printed for every element of the non-scalar OpenQL object, using the name format <name>_<major>_[...]_<minor>. For example, the creg(2) example above would be printed as creg_2 if registers_as_variables is set. Note that this notation obviously only supports literal indices, and also note that name conflicts may arise in contrived cases (for example, when a scalar variable named creg_2 was defined in addition to a one-dimensional creg variable).

Indices start from 0 in both cases.

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

output_suffix

Must be any string, default .cq. Suffix to use for the output filename.

cqasm_version

Must be one of 1.0, 1.1, or 1.2, default 1.2. The cQASM version to target.

with_platform

Must be yes or no, default no. Whether to include an annotation that includes the (preprocessed) JSON description of the platform.

registers_as_variables

Must be yes or no, default no. Whether to include variable declarations for registers. This must be enabled if the cQASM file is to be passed to a target that doesn’t implicitly define the registers. Note that the size of the main qubit register is always printed for version 1.0, because it can’t legally be omitted for that version. Also note that this is a lossy operation if the file is later read by OpenQL again, because register indices are lost (since only scalar variables are supported by cQASM).

with_statistics

Must be yes or no, default no. Whether to include the current statistics for each kernel and the complete program in the generated comments.

with_metadata

Must be yes or no, default yes. Whether to include metadata supported by the IR but not by cQASM as annotations, to allow the IR to be more accurately reproduced when read again via the cQASM reader pass.

with_barriers

Must be one of no, simple, or extended, default extended. Whether to include wait and barrier instructions, and if so, using which syntax (see pass description). These are only needed when the program will be fed to another compiler later on.

with_timing

Must be yes or no, default yes. Whether to include scheduling/timing information via bundle-and-skip notation.

Mapper

Type name(s): map.qubits.Map.

Note

This is a legacy pass, operating on the old intermediate representation. If the program is using features that the old IR does not support when this pass is run, an internal compiler error will be thrown. Furthermore, kernel/block names may change regardless of whether the pass does anything with them, due to name uniquification logic.

The purpose of this pass is to ensure that the qubit connectivity constraints are met for all multi-qubit gates in each kernel. This is done by optionally applying a mixed integer linear programming algorithm to look for a perfect solution that does not require routing or figure out a good initial qubit placement, and then by heuristically inserting swap/move gates to change the mapping on the fly as needed. Finally, it decomposes all gates in the circuit to primitive gates.

Note

The substeps of this pass will probably be subdivided into individual passes in the future.

Warning

This pass currently operates purely on a per-kernel basis. Because it may adjust the qubit mapping from input to output, a program consisting of multiple kernels that maintains a quantum state between the kernels may be silently destroyed.

Initial placement

This step attempts to find a single mapping of the virtual qubits of a circuit to the real qubits of the platform’s qubit topology that minimizes the sum of the distances between the two mapped operands of all two-qubit gates in the circuit. The distance between two real qubits is the minimum number of swaps that is required to move the state of one of the two qubits to the other. It employs a Mixed Integer Linear Programming (MIP) algorithm to solve this, modelled as a Quadratic Assignment Problem. If enabled, this step may find a mapping that is optimal for the whole circuit, but because its time-complexity is exponential with respect to the size of the circuit, this may take quite some computer time. Also, the result is only really useful when in the mapping found all mapped operands of two-qubit gates are nearest-neighbor (i.e. distance 1). So, there is no guarantee for success: it may take too long and the result may not be optimal.

Note

Availability of this step depends on the build configuration of OpenQL due to license conflicts with the library used for solving the MIP problem. If it is not included, the step is effectively no-op, and a warning message will be printed.

Heuristic routing

This step essentially transforms the program by iterating over its gates from front to back and inserting swap or move gates when needed. Whenever it does this, it updates its internal virtual to real qubit mapping. While iterating, the virtual qubit indices of the incoming gates are replaced with real qubit indices, i.e. those defined in the topology section of the platform.

Some platforms have gates for which parameters differ based on the qubits they operate on. For example, cz q0, q1 may have a different duration than cz q2, q3, and cz q0, q2 may not even exist because of topological constraints. However, rules like this make no sense when the cz gate is still using virtual qubit indices: it’s perfectly fine for the user to do cz q0, q2 at the input if the mapper is enabled.

To account for this, the mapper will look for an alternative gate definition when it converts the virtual qubit indices to real qubit indices: specifically, it will look for a gate with _real or _prim (see also the primitive decomposition step) appended to the original gate name. For example, cz q0, q2 may, after routing, be transformed to cz_real q2, q3. This allows you to define cz using a generalized gate definition (i.e. independent on qubit operands), and cz_real as a set of specialized gates as required by the platform.

Note

The resolution order is *_prim, *_real, and finally just the original gate name. Thus, if you don’t need this functionality, you don’t need to define any *_real gates.

Because the mapper inserts swap and/or move gates, it is important that these gates are actually defined in the configuration file (usually by means of a decomposition rule). The semantics for them must be as follows.

  • swap x, y or swap_real x, y: must apply a complete swap gate to the given qubits to exchange their state. If in the final decomposition one of the operands is used before the other, the second operand (y) is expected to be used first for the reverse_swap_if_better option to work right.

  • move x, y or move_real x, y: if use_moves is enabled, the mapper will attempt to use these gates instead of swap/swap_real if it knows that the y qubit is in the |0> state (or it can initialize it as such) and the result is better (or not sufficiently worse) than using a normal swap. Such a move gate can be implemented with two CNOTs instead of three.

The order in which non-nearest-neighbor two-qubit gates are routed, the route taken for them, and where along the route the actual two-qubit gate is performed, is determined heuristically. The way in which this is done is controlled by the various options for this pass; it can be made really simple by just iterating over the circuit in the specified order and just choosing a random routing alternative whenever routing is needed, or more intelligent methods can be used at the cost of execution time and memory usage (the latter especially when a lot of alternative solutions are generated before a choice is made). Based on these options, time and space complexity can be anywhere from linear to exponential!

Decomposition into primitives

As a final step, the mapper will try to decompose the “real” gates (i.e. gates with qubit operands referring to real qubits) generated by the previous step into primitive gates, as actually executable by the target architecture. It does this by attempting to suffix the name of each gate with _prim. Thus, if you define a decomposition rule named cz_prim rather than cz, this rule will only be applied after mapping.

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

initialize_one_to_one

Must be yes or no, default yes. Controls whether the mapper should assume that each kernel starts with a one-to-one mapping between virtual and real qubits. When disabled, the initial mapping is treated as undefined.

assume_initialized

Must be yes or no, default no. Controls whether the mapper should assume that each qubit starts out as zero at the start of each kernel, rather than with an undefined state.

assume_prep_only_initializes

Must be yes or no, default no. Controls whether the mapper may assume that a user-written prepz gate actually leaves the qubit in the zero state, rather than any other quantum state. This allows it to make some optimizations.

enable_mip_placer

Must be yes or no, default no. Controls whether the MIP-based initial placement algorithm should be run before resorting to heuristic mapping.

mip_horizon

Must be an integer less than or equal to 0, default 0. This controls how many two-qubit gates the MIP-based initial placement algorithm considers for each kernel (if enabled). If 0 or unspecified, all gates are considered.

route_heuristic

Must be one of base, baserc, minextend, minextendrc, or maxfidelity, default base. Controls which heuristic the router should use when selecting between possible routing operations. base and base_rc are the simplest forms: all routes are considered equally good, so the tie-breaking strategy is just applied immediately. minextend and minextendrc are way more involved (but also take longer to compute): these options will speculate what each option will do in terms of extending the duration of the circuit, optionally recursively, to find the best alternatives in terms of circuit duration within somelookahead window. The existence of the rc suffix specifies whether the internal scheduling for fitness determination should be done with or without resource constraints. maxfidelity is not supported in this build of OpenQL.

max_alternative_routes

Must be an integer less than or equal to 0, default 0. Controls the maximum number of alternative routing solutions to generate before applying the heuristic and/or tie-breaking method to choose one. Leave unspecified or set to 0 to disable this limit.

tie_break_method

Must be one of first, last, random, or critical, default random. Controls how to tie-break equally-scoring alternative mapping solutions. first and last choose respectively the first and last solution in the list (assuming the qubits have planar coordinates specified in the topology section, first selects the left-most alternative with the two-qubit gate near target, and last selects the right-most alternative with the two-qubit gate near source; when no coordinates are given the choice is undefined, though deterministic), random uses random number generation to select an alternative, and critical favors the alternative that maps the most critical gate as determined by the scheduler (if any).

lookahead_mode

Must be one of no, 1qfirst, noroutingfirst, or all, default noroutingfirst. Controls the strategy for selecting the next gate(s) to map. When no, just map the gates in the order of the circuit, disregarding commutation as allowed by the circuit’s dependency graph. Single-qubit and nearest-neighbor two-qubit gates are mapped trivially; non-nearest-neighbor gates are mapped when encountered by generating alternative routing solutions and picking the best one via route_heuristic. For 1qfirst, the dependency graph is used to greedily map all single-qubit gates, before proceeding with mapping the most critical two-qubit gate. If this gate is not nearest-neighbor, it is routed the same way as for no. noroutingfirst works the same, but also greedily maps two-qubit gates that don’t require any routing regardless of criticality, before routing the most critical non-nearest-neighbor two-qubit gate. Finally, all works the same as noroutingfirst, but instead of considering only routing alternatives for the most critical non-nearest-neighbor two-qubit gate, alternatives are generated for all available non-nearest-neighbor two-qubit gates, thus ignoring criticality and relying only on route_heuristic (which may be better depending on the heuristic chosen, but will cost execution time).

path_selection_mode

Must be one of all, borders, or random, default all. Controls whether to consider all paths from a source to destination qubit while routing, or to favor routing along the route search space. The latter is only supported and sensible when the qubits are given planar coordinates in the topology section of the platform configuration file. Both all and random consider all paths, but for the latter the order in which the paths are generated is shuffled, which is useful to reduce bias when max_alternative_routes is used.

swap_selection_mode

Must be one of one, all, or earliest, default all. This controls how routing interacts with speculation. When all, allswaps for a particular routing option are committed immediately, before trying anything else. When one, only the first swap in the route from source to target qubit is committed. When earliest, the swap that can be done at the earliest point is selected, which might be the one swapping the source or target qubit.

recurse_on_nn_two_qubit

Must be yes or no, default no. When a nearest-neighbor two-qubit gate is the next gate to be mapped, this controls whether the mapper will speculate on adding it now or later, or if it will add it immediately without speculation. NOTE: this is an advanced/unstable option that influences lookahead_mode in a complex way; don’t use it unless you know what you’re doing. May be removed or changed in a later version of OpenQL.

recursion_depth_limit

Must be an integer less than or equal to 0 or inf, default 0. Controls the maximum recursion depth while searching for alternative mapping solutions. NOTE: this is an advanced/unstable option; don’t use it unless you know what you’re doing. May be removed or changed in a later version of OpenQL.

recursion_width_factor

Must be an real number less than or equal to 0, default 1. Limits how many alternative mapping solutions are considered as a factor of the number of best-scoring alternatives, rounded up. NOTE: this is an advanced/unstable option; don’t use it unless you know what you’re doing. May be removed or changed in a later version of OpenQL.

recursion_width_exponent

Must be an real number between 0 and 1 inclusive, default 1. Adjustment for recursion_width_factor based on the current recursion depth. For each additional level of recursion, the effective width factor is multiplied by this number. NOTE: this is an advanced/unstable option; don’t use it unless you know what you’re doing. May be removed or changed in a later version of OpenQL.

use_moves

Must be an integer less than or equal to 0 or one of no or yes, default yes. Controls if/when the mapper inserts move gates rather than swap gates to perform routing. If no, swap gates are always used. Otherwise, a move gate is used if the other qubit has been initialized, or if initializing it only extends the circuit by the given number of cycles. yes implies this limit is 0 cycles.

reverse_swap_if_better

Must be yes or no, default yes. Controls whether the mapper will reverse the operands for a swap gate when reversal improves the schedule. NOTE: this currently assumes that the second qubit operand of the swap gate decomposition in the platform configuration file is used before than the first operand; if this is not the case, enabling this will worsen the routing result rather than improve it.

commute_multi_qubit

Must be yes or no, default no. Whether to consider commutation rules for the CZ and CNOT quantum gates.

commute_single_qubit

Must be yes or no, default no. Whether to consider commutation rules for single-qubit X and Z rotations.

scheduler_heuristic

Must be one of path_length or random, default path_length. This controls what scheduling heuristic should be used for ordering the list of available gates by criticality.

write_dot_graphs

Must be yes or no, default no. Whether to print dot graphs of the schedules created using the embedded scheduler.

MIP-based initial placer

Type name(s): map.qubits.PlaceMIP.

Note

This is a legacy pass, operating on the old intermediate representation. If the program is using features that the old IR does not support when this pass is run, an internal compiler error will be thrown. Furthermore, kernel/block names may change regardless of whether the pass does anything with them, due to name uniquification logic.

This pass was disabled due to configuration options when building the compiler. Therefore, this pass will simply fail when run. If you compiled OpenQL yourself and intend to use this pass, you’re probably missing GLPK.

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

horizon

Must be an integer between 0 and 100 inclusive, default 0. When specified, the placement algorithm will only consider the connectivity required to perform the first N two-qubit gates of each kernel. When not specified or zero, all two-qubit gates are considered.

Constant propagator

Type name(s): opt.ConstProp.

This pass replaces constant expressions by their result.

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

Dead code eliminator

Type name(s): opt.DeadCodeElim.

This pass removes dead code, currently only unreachable if-branches.

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

Clifford gate optimizer

Type name(s): opt.clifford.Optimize.

Note

This is a legacy pass, operating on the old intermediate representation. If the program is using features that the old IR does not support when this pass is run, an internal compiler error will be thrown. Furthermore, kernel/block names may change regardless of whether the pass does anything with them, due to name uniquification logic.

This pass tries to minimize sequences of single-qubit gates in the Clifford C1 set to their minimal counterpart in terms of cycles. The pass returns the total number of cycles saved by this optimization per qubit.

Note that the relation between the Clifford state transition corresponding to a particular gate is currently hardcoded based on gate name, and the equivalent cycle counts are also hardcoded.

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

List scheduler

Type name(s): sch.ListSchedule.

This pass analyzes the data dependencies between statements and applies quantum cycle numbers to them using optionally resource-constrained ASAP or ALAP list scheduling. All blocks in the program are scheduled independently.

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

resource_constraints

Must be yes or no, default yes. Whether to respect or ignore resource constraints when scheduling.

scheduler_target

Must be one of asap or alap, default alap. Which scheduling target is to be used; ASAP schedules all statements as soon as possible, while ALAP starts from the last statement and schedules all statements as late as possible. ALAP is best for most simple quantum circuits, because the measurements at the end will be done in parallel if possible, and state initialization is postponed as much as possible to reduce state lifetime.

scheduler_heuristic

Must be one of none, critical_path, or deep_criticality, default deep_criticality. This controls what heuristic is used to sort the list of statements available for scheduling. none effectively disables sorting; the available statements will be scheduled in the order in which they were specified in the original program. critical_path schedules the statement with the longest critical path first. deep_criticality is the same except for statements with equal critical path length; in this case, the deep-criticality of the most critical successor is recursively checked instead.

commute_multi_qubit

Must be yes or no, default no. Whether to consider commutation rules for multi-qubit gates.

commute_single_qubit

Must be yes or no, default no. Whether to consider commutation rules for single-qubit gates.

max_resource_block_cycles

Must be an integer less than or equal to 0, default 10000. The maximum number of cycles to wait for the resource constraints to unblock a statement when there is nothing else to do. This is used for deadlock detection. It should just be set to a high number, or can be set to 0 to disable deadlock detection (but then the scheduler might end up in an infinite loop).

write_dot_graphs

Must be yes or no, default no. Whether to emit a graphviz dot graph representation of the data dependency graph and schedule of each block. The emitted files will use suffix _<block-name>.dot, where <block-name> is a uniquified name for each block.

Scheduler

Type name(s): sch.Schedule.

Note

This is a legacy pass, operating on the old intermediate representation. If the program is using features that the old IR does not support when this pass is run, an internal compiler error will be thrown. Furthermore, kernel/block names may change regardless of whether the pass does anything with them, due to name uniquification logic.

Legacy list scheduler that operates on the old IR. This pass is deprecated in favor of sch.ListSchedule, and may be replaced with a wrapper around that in future version.

The pass analyzes the data dependencies between gates and applies cycle numbers to them based on some scheduling heuristic. Depending on options, the scheduler will either be resource-constrained or will ignore resources.

Options

output_prefix

Must be any string, default %N.%P. Format string for the prefix used for all output products. %n is substituted with the user-specified name of the program. %N is substituted with the optionally uniquified name of the program. %p is substituted with the local name of the pass within its group. %P is substituted with the fully-qualified name of the pass, using periods as hierarchy separators (guaranteed unique). %U is substituted with the fully-qualified name of the pass, using underscores as hierarchy separators. This may not be completely unique,%D is substituted with the fully-qualified name of the pass, using slashes as hierarchy separators. Any directories that don’t exist will be created as soon as an output file is written.

debug

Must be one of no, yes, stats, qasm, or both, default no. May be used to implicitly surround this pass with cQASM/report file output printers, to aid in debugging. Set to no to disable this functionality or to yes to write a tree dump and a cQASM file before and after, the latter of which includes statistics as comments. The filename is built using the output_prefix option, using suffix _debug_[in|out].ir for the IR dump, and _debug_[in|out].cq for the cQASM file. The option values stats, cqasm, and both are used for backward compatibility with the write_qasm_files and write_report_files global options; for stats and both a statistics report file is written with suffix _[in|out].report, and for qasm and both a cQASM file is written (without stats in the comments) with suffix _[in|out].qasm.

resource_constraints

Must be yes or no, default yes. Whether to respect or ignore resource constraints when scheduling.

scheduler_target

Must be one of asap, alap, or uniform, default alap. Which scheduling target is to be used; ASAP schedules all gates as soon as possible, ALAP starts from the last gate and schedules all gates as late as possible, and uniform tries to smoothen out the amount of parallelism throughout each kernel. Uniform scheduling is only supported without resource constraints. ALAP is best for most simple quantum circuits, because the measurements at the end will be done in parallel if possible, and state initialization is postponed as much as possible to reduce state lifetime.

scheduler_heuristic

Must be one of path_length or random, default path_length. This controls what scheduling heuristic should be used for ordering the list of available gates by criticality.

commute_multi_qubit

Must be yes or no, default no. Whether to consider commutation rules for the CZ and CNOT quantum gates.

commute_single_qubit

Must be yes or no, default no. Whether to consider commutation rules for single-qubit X and Z rotations.

write_dot_graphs

Must be yes or no, default no. Whether to emit a graphviz dot graph representation of the schedule of the kernel. The emitted file will use suffix _<kernel>.dot.