qat.middleend.passes.purr.transform module
- class AcquireSanitisation
Bases:
TransformPassSanitises the
Acquireinstruction: the first per pulse channel is split into anAcquireand aDelay, and other acquisitions have their delay removed.Acquireinstructions are defined by a “duration” for which they instruct the target to readout. They also contain a “delay” attribute, which instructions the acquisition to start after some given time. This pass separates acqusitions with a delay into two instructions for the first acquire that acts on the channel. For multiple acquisitions on a single channel, the delay is not needed for the following acquisitions, and is set to zero.- run(ir, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.- Return type:
- class BatchedShots(target_data)
Bases:
TransformPassDetermines how shots should be grouped when the total number exceeds that maximum allowed.
The target machine might have an allowed number of shots that can be executed by a single execution call. To execute a number of shots greater than this value, shots can be batched, with each batch executed by its own “execute” call on the target machine. For example, if the maximum number of shots for a target machine is 2000, but you required 4000 shots, then this could be done as [2000, 2000] shots.
Now consider the more complex scenario where 4001 shots are required. Clearly this can be done in three batches. While it is tempting to do this in batches of [2000, 2000, 1], for some target machines, specification of the number of shots can only be achieved at compilation (as opposed to runtime). Batching as described above would result in us needing to compile two separate programs. Instead, it makes more sense to batch the shots as three lots of 1334 shots, which gives a total of 4002 shots. The extra two shots can just be discarded at run time.
Warning
This pass makes certain assumptions about the IR, including that there is only at most one
Repeatinstruction that contributes to the number of readouts, and there is at most one readout per shot. It will change the number of shots in theRepeatinstruction to the decided batch size, and store the total required shots in the IR, which is less than ideal. It would be nice to save this as an analysis result, but an unfortante side effect of the decoupled nature of the middle- and back-end is that the results manager might not necessarily be passed along.- Parameters:
target_data¶ (
TargetData) – Target-related information.
- run(ir, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.
- class DeviceUpdateSanitisation
Bases:
TransformPassDuplicate DeviceUpdate instructions upsets the device injection mechanism, which causes corruption of the HW model.
In fact, a DeviceInjector is currently 1-1 associated with a DeviceUpdate instruction. When multiple DeviceUpdate instructions (sequentially) inject the same “target”, the first DeviceInjector assigns the (correct) value of the attribute (on the target) to the revert_value. At this point the HW model (or any other target kind) is dirty, and any subsequent DeviceInjector updater would surely assign the (wrong, usually a placeholder Variable) to its revert_value. This results in a corrupt HW model whereby reversion wouldn’t have the desired effect.
This pass is a (lazy) fix, which is to analyse when such cases happen and eliminate duplicate DeviceUpdate instructions that target THE SAME “attribute” on THE SAME “target” with THE SAME variable.
- run(ir, res_mgr, met_mgr, *args, **kwargs)
- class EndOfTaskResetSanitisation
Bases:
TransformPassChecks for a reset on each active qubit at the end of a task, and adds Reset operations if not found.
After each shot, it is expected that the qubit is returned to its ground state, ready for the next shot. This pass ensures this is the case by checking if the last “active” operation on an qubit is a
Reset, and if not, adds aResetto the end of the instruction list. By default, theResetoperation will have the drive channel of a qubit as its target. However, if the drive channel is not an active channel, a different active channel on the qubit will be used its place.Resetinstructions currently sit in a weird place. Their targets are drive channels to match the semantics of other quantum instructions (but are instantiated with a :class:Qubit). However, like measurements, resets are a qubit-level operation. You cannot reset the state of a pulse channel, the state is a property of the qubit! To avoid breaking changes, we’ll just deal with that for now, but hope to do better in the refactored instructions…- run(ir, res_mgr, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.res_mgr¶ (
ResultManager) – The result manager to store the analysis results.
- Return type:
- class EvaluatePulses(ignored_shapes=None, acquire_ignored_shapes=None, eval_function=<function evaluate_shape>)
Bases:
TransformPassEvaluates the amplitudes of
Pulseinstructions, replacing them with aCustomPulseand accounting for the scale of the pulse channel.Pulseinstructions are defined by (often many) parameters. With the exception of specific shapes, they cannot be implemented directly on hardware. Instead, we evaluate the waveform at discrete times, and communicate these values to the target. This pass evaluates pulses early in the compilation pipeline.The
CustomPulseinstructions will haveignore_channel_scale=True.- Parameters:
ignored_shapes¶ (
Optional[list[PulseShapeType]]) – A list of pulse shapes that are not evaluated to a custom pulse, defaults to [PulseShapeType.SQUARE].acquire_ignored_shapes¶ (
Optional[list[PulseShapeType]]) – A list of pulse shapes that are not evaluated to a custom pulse forAcquirefilters, defaults to [].eval_function¶ (
callable) – Allows a pulse evaluation function to be injected, defaults toevaluate_shape().
- evaluate_waveform(inst, ignored_shapes, pulse_lookup)
Evaluates the waveform for a
PulseorCustomPulse, accounting for the pulse channel scale.- Return type:
- hash_pulse(pulse)
Hashs a pulse object.
- Return type:
str
- run(ir, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions as an instruction builder.- Return type:
- class FreqShiftSanitisation(model)
Bases:
TransformPassLooks for any active frequency shift pulse channels in the hardware model and adds square pulses for the duration.
Warning
This pass assumes the following, which is achieved via other passes:
Synchronizeinstructions have already been lowered toDelayinstructions.Durations are static.
- Parameters:
model¶ (
QuantumHardwareModel) – The hardware model containing the frequency shift channels.
- static add_freq_shift_to_ir(ir, freq_shift_channels)
Adds frequency shift instructions to the instruction builder.
- Return type:
- get_freq_shift_channels()
Returns all active frequency shift pulse channels found in the hardware model.
- Return type:
dict[PulseChannel,Qubit]
- run(ir, res_mgr, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The QatIR as an instruction builder.res_mgr¶ (
ResultManager) – The results manager.
- Return type:
- class InactivePulseChannelSanitisation
Bases:
TransformPassRemoves instructions that act on inactive pulse channels.
Many channels that aren’t actually needed to execute the program contain instructions, mainly
Synchronizeinstructions andPhaseShiftinstructions which can happen when either of the instructions are applied to qubits. To simplify analysis and optimisations in later passes, it makes sense to filter these out to reduce the overall instruction amount.Note
This pass requires results from the
ActivePulseChannelAnalysisto be stored in the results manager.- run(ir, res_mgr, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.res_mgr¶ (
ResultManager) – The result manager to store the analysis results.
- Return type:
- class InitialPhaseResetSanitisation
Bases:
TransformPassChecks if every active pulse channel has a phase reset in the beginning.
Warning
This pass implies that an ActiveChannelAnalysis is performed prior to this pass.
- run(ir, res_mgr, *args, **kwargs)
- class InstructionGranularitySanitisation(model, target_data)
Bases:
TransformPassRounds the durations of quantum instructions so they are multiples of the clock cycle.
Only supports quantum instructions with static non-zero durations. Assumes that instructions with a non-zero duration only act on a single pulse channel. The santisiation is done for all instructions simultaneously using numpy for performance.
For
CustomPulseinstructions, the durations are rounded up by padding the pulse with zero amplitude at the end. For other relevant instructions, we round down: this is for compatibility with calibration files that are calibrated using legacy code. However, in the future we might consider changing this to round up for consistency.Warning
This pass has the potential to invalidate the timings for sequences of instructions that are time-sensitive. For example, if a pulse has an invalid time, it will round it up to the nearest integer multiple. Furthemore, it will assume that
Acquireinstructions have no delay. This can be forced explicitly using theAcquireSanitisationpass.- Parameters:
target_data¶ (
TargetData) – Target-related information.
- run(ir, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.- Return type:
- sanitise_acquire_filters(instructions)
Sanitises the durations of
Acquirefilters by matching it to the duration of theAcquire. ForCustomPulsefilters, this strips away the samples that are not needed.
- sanitise_custom_pulses(instructions)
Sanitises the durations of
CustomPulseinstructions by padding the pulses with zero amplitudes.
- sanitise_quantum_instructions(instructions)
Sanitises the durations quantum instructions with non-zero duration by rounding down to the nearest clock cycle.
- class InstructionLengthSanitisation(model, target_data)
Bases:
TransformPassChecks if quantum instructions are too long and splits if necessary.
- Parameters:
duration_limit¶ – The maximum allowed clock cycles per instruction.
Warning
The pass will assume that the durations of instructions are sanitised to the granularity of the pulse channels. If instructions that do not meet the criteria are provided, it might produce incorrect instructions (i.e., instructions that are shorter than the clock cycle). This can be enforced using the
InstructionGranularitySanitisationpass.- run(ir, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.
- class IntegratorAcquireSanitisation
Bases:
TransformPassChanges AcquireMode.INTEGRATOR acquisitions to AcquireMode.RAW.
The legacy echo/RTCS engines expect the acquisition mode to be either RAW or SCOPE. While the actual execution can process INTEGRATOR by treating it as RAW, they are typically santitised the runtime using
EchoEngine.optimize(). If not done in the new pipelines, it will conflict withPostProcessingSantisiation, and return the wrong results. The new echo engine supports all acquisition modes, so this is not a problem here.- run(ir, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.
- class LegacyPhaseOptimisation
Bases:
TransformPassIterates through the list of instructions and compresses contiguous
PhaseShiftinstructions.- run(ir, res_mgr, met_mgr, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.res_mgr¶ (
ResultManager) – The result manager to save the analysis results.met_mgr¶ (
MetricsManager) – The metrics manager to store the number of instructions after optimisation.
- class LoopCount
Bases:
int
- class LowerSyncsToDelays
Bases:
TransformPassLowers
Synchronizeinstructions toDelayinstructions with static times.Increments through the instruction list, keeping track of the cumulative duration. When
Synchronizeinstructions are encountered, it is replaced withDelayinstructions with timings calculated from the cumulative durations.Warning
Any manipulations of the instruction set that will alter the timeline and occur after this pass could invalidate the intention of the
Synchronizeinstruction.- run(ir, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.- Return type:
- class MeasurePhaseResetSanitisation
Bases:
TransformPassAdds a phase reset before every measure pulse.
- run(ir, *args, **kwargs)
- class PhaseOptimisation
Bases:
TransformPassIterates through the list of instructions and compresses contiguous
PhaseShiftinstructions. This pass will changePhaseResettoPhaseSetinstructions.- static merge_phase_instructions(target, phase1, phase2)
- run(ir, res_mgr, met_mgr, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.res_mgr¶ (
ResultManager) – The result manager to save the analysis results.met_mgr¶ (
MetricsManager) – The metrics manager to store the number of instructions after optimisation.
- class PostProcessingSanitisation
Bases:
TransformPassChecks that the
PostProcessinginstructions that follow an acquisition are suitable for the acquisition mode, and removes them if not.Extracted from
qat.purr.backends.live.LiveDeviceEngine.optimize().- run(ir, _, met_mgr, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.met_mgr¶ (
MetricsManager) – The metrics manager to store the number of instructions after optimisation.
- class QiskitInstructionsWrapper
Bases:
TransformPassWraps the Qiskit builder in a wrapper to match the pipelines API.
A really silly pass needed to wrap the
QiskitBuilderin an object that allows QiskitBuilderWrapper.instructions to be called, allowing the builder to be used in the theLegacyRuntime. This is needed because the qiskit engine has a different API to other purr engines, requiring the whole builder to be passed (as opposed to builder.instructions).- run(ir, *args, **kwargs)
- Parameters:
ir¶ (
QiskitBuilder) – The Qiskit instructions- Return type:
- class RepeatSanitisation(model, target_data)
Bases:
TransformPassAdds repeat counts and repetition periods to
Repeatinstructions. If none is found, a repeat instruction is added.- Parameters:
model¶ (
QuantumHardwareModel) – The hardware model contains the default repeat value, defaults to None.target_data¶ (
TargetData) – Target-related information.
- run(ir, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.
- class RepeatTranslation(target_data)
Bases:
TransformPassTransform
Repeatinstructions so that they are replaced with:Variable,Assign, andLabelinstructions at the start, andAssignandJumpinstructions at the end.- run(ir, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.- Return type:
- class ResetsToDelays(target_data)
Bases:
TransformPassTransforms
Resetoperations to :class:`Delay`s.Note that the delays do not necessarily agree with the granularity of the underlying target machine. This can be enforced using the
InstructionGranularitySanitisationpass.- Parameters:
target_data¶ (
TargetData) – Target-related information.
- run(ir, res_mgr, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.res_mgr¶ (
ResultManager) – The result manager to store the analysis results.
- Return type:
- class ReturnSanitisation
Bases:
TransformPassSquashes all
Returninstructions into a single one. Adds aReturnwith all acquisitions if none is found.- run(ir, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.
- class ScopeSanitisation
Bases:
TransformPassBubbles up all sweeps and repeats to the beginning of the list and adds delimiter instructions to the repeats and sweeps signifying the end of their scopes.
Warning
This pass is intended for use with legacy builders that do not use
EndRepeatandEndSweepinstructions. It will add a delimiter instruction for eachRepeatandSweepfound in the IR.- run(ir, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.
- class SquashDelaysOptimisation
Bases:
TransformPassLooks for consecutive
Delayinstructions on a pulse channel and squashes them into a single instruction.Because
Synchronizeinstructions across multiple pulse channels are used so frequently to ensure pulses play at the correct timings, it means we can have sequences of many delays. Reducing the number of delays will simplify timing analysis later in the compilation.Delayinstructions commute with phase related instructions, so the only instructions that separate delays in a meaningful way are:Pulse:,CustomPulseandAcquireinstructions. We also need to be careful to not squash delays that contain a variable time.- run(ir, res_mgr, met_mgr, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.res_mgr¶ (
ResultManager) – The result manager to save the analysis results.met_mgr¶ (
MetricsManager) – The metrics manager to store the number of instructions after optimisation.
- class SynchronizeTask
Bases:
TransformPassSynchronizes all active pulse channels in a task.
Adds a synchronize to the end of the instruction list for all active pulse channels, which is extracted from the
ActivePulseChannelAnalysispass. This is useful to do before resetting the qubits, as it ensures no qubit is reset while the task is still “active”, reducing the effects of cross-talk.- run(ir, res_mgr, *args, **kwargs)
- Parameters:
ir¶ (
InstructionBuilder) – The list of instructions stored in anInstructionBuilder.res_mgr¶ (
ResultManager) – The result manager to store the analysis results.
- Return type: