debug.h

Note

As the SimulationState interface is defined in C, “member functions” are declared as function pointers. When using the interface, these function pointers can be accessed like normal C++ methods.

Provides a C-style interface for the debugging and simulation interface.

Typedefs

typedef struct SimulationStateStruct SimulationState

A C-style interface for the debugging and simulation interface.

This interface provides a way to interact with the simulation state, stepping through the simulation, and inspecting the state of the simulation.

When an executed instruction is a failing assertion, the simulation will stop

before the assertion and the didAssertionFail method will return true. Continuing the simulation from there will skip the failing assertion and didAssertionFail will return false until another assertion fails.

struct SimulationStateStruct

Public Members

Result (*init)(SimulationState *self)

Initializes the simulation state.

Param self:

The instance to initialize.

Return:

The result of the operation.

LoadResult (*loadCode)(SimulationState *self, const char *code)

Loads the given code into the simulation state.

Param self:

The instance to load the code into.

Param code:

The code to load.

Return:

The result of the load operation.

Result (*stepForward)(SimulationState *self)

Steps the simulation forward by one instruction.

Param self:

The instance to step forward.

Return:

The result of the operation.

Result (*stepOverForward)(SimulationState *self)

Steps the simulation forward by one instruction, skipping over possible custom gate calls.

Param self:

The instance to step forward.

Return:

The result of the operation.

Result (*stepOutForward)(SimulationState *self)

Steps the simulation forward until the current custom gate call returns.

Param self:

The instance to step forward.

Return:

The result of the operation.

Result (*stepBackward)(SimulationState *self)

Steps the simulation backward by one instruction.

Param self:

The instance to step backward.

Return:

The result of the operation.

Result (*stepOverBackward)(SimulationState *self)

Steps the simulation backward by one instruction, skipping over possible custom gate calls.

Param self:

The instance to step backward.

Return:

The result of the operation.

Result (*stepOutBackward)(SimulationState *self)

Steps the simulation backward until the instruction calling the current custom gate is encountered.

Param self:

The instance to step backward.

Return:

The result of the operation.

Result (*runAll)(SimulationState *self, size_t *failedAssertions)

Runs the simulation until it finishes, even if assertions fail.

Param self:

The instance to run.

Param failedAssertions:

A reference to a size_t integer to store the number of failed assertions.

Return:

The result of the operation.

Result (*runSimulation)(SimulationState *self)

Runs the simulation until it finishes or an assertion fails.

If an assertion fails, the simulation stops and the didAssertionFail method will return true. This method is still expected to return OK.

Param self:

The instance to run.

Return:

The result of the operation.

Result (*runSimulationBackward)(SimulationState *self)

Runs the simulation backward until it finishes or an assertion fails.

Param self:

The instance to run.

Return:

The result of the operation.

Result (*resetSimulation)(SimulationState *self)

Resets the simulation to the initial state.

This will reset measured variables and state vectors and go back to the start of the code.

Param self:

The instance to reset.

Return:

The result of the operation.

Result (*pauseSimulation)(SimulationState *self)

Pauses the simulation.

If the simulation is running in a concurrent thread, the execution will stop as soon as possible, but it is not guaranteed to stop immediately.

If the simulation is not running, then the next call to continue the simulation will stop as soon as possible.

step over and step out methods, in particular, may still execute the next instruction.

Param self:

The instance to pause.

Return:

The result of the operation.

bool (*canStepForward)(SimulationState *self)

Indicates whether the simulation can step forward.

The simulation is unable to step forward if it has finished or if the simulation has not been set up yet.

Param self:

The instance to query.

Return:

True if the simulation can step forward, false otherwise.

bool (*canStepBackward)(SimulationState *self)

Indicates whether the simulation can step backward.

The simulation is unable to step backward if it is at the beginning or if the simulation has not been set up yet.

Param self:

The instance to query.

Return:

True if the simulation can step backward, false otherwise.

Result (*changeClassicalVariableValue)(SimulationState *self, const char *variableName, const VariableValue *value)

Updates the value of a classical variable.

Param self:

The instance to query.

Param variableName:

The name of the classical variable to update.

Param value:

The desired value.

Return:

The result of the operation.

Result (*changeAmplitudeValue)(SimulationState *self, const char *basisState, const Complex *value)

Updates the amplitude of a given computational basis state.

The basis state is provided as a bitstring whose length matches the current number of qubits. Implementations are expected to renormalize the remaining amplitudes so that the state vector stays normalized and to reject invalid bitstrings or amplitudes that violate normalization.

Param self:

The instance to query.

Param basisState:

The bitstring identifying the basis state to update.

Param value:

The desired complex amplitude.

Return:

The result of the operation.

bool (*isFinished)(SimulationState *self)

Indicates whether the execution has finished.

The execution is considered finished if it has reached the end of the code.

Param self:

The instance to query.

Return:

True if the execution has finished, false otherwise.

bool (*didAssertionFail)(SimulationState *self)

Indicates whether an assertion has failed in the previous step.

If execution is continued after a failed assertion, then this flag will be set to false again.

Param self:

The instance to query.

Return:

True if an assertion has failed, false otherwise.

bool (*wasBreakpointHit)(SimulationState *self)

Indicates whether a breakpoint was hit in the previous step.

If execution is continued after a breakpoint, then this flag will be set to false again.

Param self:

The instance to query.

Return:

True if a breakpoint was hit, false otherwise.

size_t (*getCurrentInstruction)(SimulationState *self)

Gets the current instruction index.

Param self:

The instance to query.

Return:

The current instruction index.

size_t (*getInstructionCount)(SimulationState *self)

Gets the number of instructions in the code.

Param self:

The instance to query.

Return:

The total number of instructions.

Result (*getInstructionPosition)(SimulationState *self, size_t instruction, size_t *start, size_t *end)

Gets the position of the given instruction in the code.

Start and end positions are inclusive and white-spaces are ignored.

Param self:

The instance to query.

Param instruction:

The instruction index.

Param start:

A reference to a size_t integer to store the start position.

Param end:

A reference to a size_t integer to store the end position.

Return:

The result of the operation.

size_t (*getNumQubits)(SimulationState *self)

Gets the number of qubits used by the program.

Param self:

The instance to query.

Return:

The number of qubits.

Result (*getAmplitudeIndex)(SimulationState *self, size_t index, Complex *output)

Gets the complex amplitude of a state in the full state vector.

The amplitude is selected by an integer index that corresponds to the binary representation of the state.

Param self:

The instance to query.

Param index:

The index of the state.

Param output:

A reference to a Complex instance to store the amplitude.

Return:

The result of the operation.

Result (*getAmplitudeBitstring)(SimulationState *self, const char *bitstring, Complex *output)

Gets the complex amplitude of a state in the full state vector.

The amplitude is selected by a bitstring representing the state.

Param self:

The instance to query.

Param bitstring:

The index of the state as a bitstring.

Param output:

A reference to a Complex instance to store the amplitude.

Return:

The result of the operation.

Result (*getClassicalVariable)(SimulationState *self, const char *name, Variable *output)

Gets a classical variable by name.

For registers, the name should be the register name followed by the index in square brackets.

Param self:

The instance to query.

Param name:

The name of the variable.

Param output:

A reference to a Variable instance to store the variable.

Return:

The result of the operation.

size_t (*getNumClassicalVariables)(SimulationState *self)

Gets the number of classical variables in the simulation.

For registers, each index is counted as a separate variable.

Param self:

The instance to query.

Return:

The number of classical variables.

Result (*getClassicalVariableName)(SimulationState *self, size_t variableIndex, char *output)

Gets the name of a classical variable by its index.

For registers, each index is counted as a separate variable and can be accessed separately. This method will return the name of the specific index of the register.

Param self:

The instance to query.

Param variableIndex:

The index of the variable.

Param output:

A buffer to store the name of the variable.

Return:

The result of the operation.

Result (*getQuantumVariableName)(SimulationState *self, size_t variableIndex, char *output)

Gets the name of a quantum variable by its index.

For registers, each index is counted as a separate variable and can be accessed separately. This method will return the name of the specific index of the register.

Param self:

The instance to query.

Param variableIndex:

The index of the variable.

Param output:

A buffer to store the name of the variable.

Return:

The result of the operation.

Result (*getStateVectorFull)(SimulationState *self, Statevector *output)

Gets the full state vector of the simulation at the current time.

The state vector is expected to be initialized with the correct number of qubits and allocated space for the amplitudes before calling this method.

Param self:

The instance to query.

Param output:

A reference to a Statevector instance to store the state vector.

Return:

The result of the operation.

Result (*getStateVectorSub)(SimulationState *self, size_t subStateSize, const size_t *qubits, Statevector *output)

Gets a sub-state of the state vector of the simulation at the current time.

The state vector is expected to be initialized with the correct number of qubits and allocated space for the amplitudes before calling this method.

This method also supports the re-ordering of qubits, but does not allow qubits to be repeated.

Param self:

The instance to query.

Param subStateSize:

The number of qubits in the sub-state.

Param qubits:

An array of qubit indices to include in the sub-state.

Param output:

The state vector to store the sub-state.

Return:

The result of the operation.

Result (*setBreakpoint)(SimulationState *self, size_t desiredPosition, size_t *targetInstruction)

Sets a breakpoint at the desired position in the code.

The position is given as a 0-indexed character position in the full code string. The instruction at which the breakpoint was set is returned in the targetInstruction parameter.

Param self:

The instance to set the breakpoint in.

Param desiredPosition:

The desired position in the code as a 0-indexed character index.

Param targetInstruction:

A reference to a size_t integer to store the target instruction.

Return:

The result of the operation.

Result (*clearBreakpoints)(SimulationState *self)

Clears all breakpoints set in the simulation.

Param self:

The instance to clear the breakpoints in.

Return:

The result of the operation.

Result (*getStackDepth)(SimulationState *self, size_t *depth)

Gets the current stack depth of the simulation.

Each custom gate call corresponds to one stack entry.

Param self:

The instance to query.

Param depth:

A reference to a size_t integer to store the stack depth.

Return:

The result of the operation.

Result (*getStackTrace)(SimulationState *self, size_t maxDepth, size_t *output)

Gets the current stack trace of the simulation.

The stack trace is represented as a list of instruction indices. Each instruction index represents a single return address for the corresponding stack entry.

This method expects a continuous memory block of integers with size equal to the maximum depth. Each element represents a stack entry and will be set to the instruction index of the return address.

Param self:

The instance to query.

Param maxDepth:

The maximum depth of the stack trace.

Param output:

A buffer to store the stack trace.

Return:

The result of the operation.

Diagnostics *(*getDiagnostics)(SimulationState *self)

Gets the diagnostics interface instance employed by this debugger.

Param self:

The instance to query.

Return:

The diagnostics interface instance.

size_t (*compile)(SimulationState *self, char *buffer, CompilationSettings settings)

Compiles the given code into a quantum circuit without assertions.

Param self:

The SimulationState instance from which the original assertion code should be taken.

Param buffer:

The buffer that should be filled with the compiled code, or NULL to compute the required buffer size.

Param settings:

The settings to use for the compilation.

Return:

The size of the compiled code.