qat.purr.compiler.execution module

class DeviceInjector(target)

Bases: object

Injects a value into a device for the entirety of a sweeps duration. Analogous to setting a device value before execution.

inject()
revert()
class DeviceInjectors(instructions)

Bases: object

Special sort of injector that is a sort of double-injection. It takes an object that needs to be modified during a sweep, replaces certain fields with Variable (and others) and lets normal injection do it’s work, then at the end of the sweep resets the field with the original value.

inject()
revert()
class InjectionMetadata

Bases: object

A class which is injected into an instruction to hold data about its state before injection started, as well as objects that facilitate dynamic injection of values into fields.

It’ll replace fields in the object that hold Variable('X') with the value of X. When revert is called it replaces the field with Variable('X') again, essentially reseting it for next execution.

field: str = '_$injection_metadata'
inject(node, replacements, index)
is_empty()
revert(node)
class InstructionExecutionEngine(model=None, startup_engine=True)

Bases: ABC

abstract execute(instructions)
Return type:

Dict[str, Any]

load_model(model, startup_engine=True)

Shuts down the current hardware, loads the new model then restarts.

abstract optimize(instructions)
Return type:

List[Instruction]

run_calibrations(qubits_to_calibrate=None)
shutdown()

Shuts down the underlying hardware when this instance is no longer in use.

startup()

Starts up the underlying hardware or does nothing if already started.

abstract validate(instructions)
class IteratorInjector(iteration)

Bases: ValueReplacement

Value injector for objects in lists, tuples and dictionaries.

Currently when we inject an iteration into an iteration of the same type - resolving a ValueReplacer entry in a dictionary also returns a dictionary - it merges that value into the iteration instead of a simple insertion.

So the list [1, 2, ValueReplacer(...)] that resolves into [1, 2, [3, 4, 5]] will become [1, 2, 3, 4, 5]. But if it was [1, 2, (3, 4, 5)] it will stay as such.

replace(field_value, replacements, index)
revert()
class QuantumExecutionEngine(model=None, startup_engine=True, max_instruction_len=200000)

Bases: InstructionExecutionEngine

build_acquire_list(position_map)
build_physical_channel_buffers(pulse_channel_buffers)
build_pulse_channel_buffers(position_map, do_upconvert=True)
create_duration_timeline(instructions)

Builds a dictionary mapping channels to a list of instructions and at what precise sample time they should be associated with. It’s important that the times are absolute here, not relative.

Example:

{"drive": [
    (0, 1000, pulse),
    (1000, 2000, pulse),
    (1000, 2000, acquire)
    ...
]}
do_upconvert(buffer, time, pulse_channel, frequency)
property error_mitigation
execute(instructions)

Executes this qat file against this current hardware.

optimize(instructions)

Runs optimization passes specific to this hardware.

Return type:

List[Instruction]

process_frequencyshift(position, frequency, pulse_channel)
process_phasereset(position, phase)

Child hardware types might need to know the phase and instruction

process_phaseshift(position, phase)
process_pulse(position, buffer, pulse_channel, phase, frequency, do_upconvert)
process_reset(position)
run_post_processing(post_processing, value, value_axis)

Run post-processing on the response via software.

validate(instructions)

Validates this graph for execution on the current hardware.

class SweepIterator(sweep=None, nested_sweep=None)

Bases: object

Acts as a controller for sweep-reliant values and iterates the amount of times designated by the sweep.

Every time do_sweep is called it will inject the current sweep values into the variable, so if passed a sweep list with {'dave': [1, 2, 3, 4, 5]} it will iterate 5 times and inject the values 1...5 into objects that has Variable('dave').

Nested sweeps act as inner loops, and iterates inner to outer. So with a nested sweep of {'sam': [5, 10, 15]} and using our previous example we will sweep a total of 15 times, looking a little like this:

dave = 1, sam = 5
dave = 1, sam = 10
dave = 1, sam = 15
dave = 2, sam = 5
...
property accumulated_sweep_iteration

The current number of total iterations this sweep as run as a whole, including nested sweeps.

add_sweep(nested)

Adds a sweep onto this iterator. If it already has a sweep, adds it as a nested one.

do_sweep(instructions)

Start/continue sweeping. Injects values into the instructions appropriate for this sweep.

static from_qfile(qfile)

Build a sweep iterator from a .qat file.

get_current_sweep_iteration()

Returns the current iteration of the entire loop nest seen as a polyhedra. The returned structure is a list representing a lattice point p where p[i] indicates the current iteration of the sweep at level i

get_results_shape(shape=None)

Return a default array that mirrors the structure for this set of sweeps.

insert_result_at_sweep_position(results_array, value)

Insert the response value into the appropriate nested array.

is_finished()

Is this sweep finished.

property length

Returns actual length of the entire sweep, so

sweep_length * nested_length * nested_length ...

reset_iteration()

Resets iteration of this sweep and all children since we infer that if we’ve finished, then our children have too.

revert(instructions)

Revert all instruction modifications to their pre-sweep state.

class ValueReplacement

Bases: ABC

Abstract class for values that inject during a sweep.

abstract replace(field_value, symbols, index)
abstract revert()
class VariableInjector(var)

Bases: ValueReplacement

All injected values are assumed to be in a list of len(sweep_length), this just fetches out the particular value of a list to inject as we’re sweeping.

So calling this with name='frequency', index=5, from:

{
    'frequency': [1, 2, 4, 8, 16, 32, 64, ...],
    ...
}

Would inject 32 into this field, as we’re on the 6th iteration of this sweep.

replace(field_value, replacements, index)
revert()