---
title: QkCircuit (v2.3)
description: API reference for QkCircuit in qiskit-c v2.3
source: https://eu-de.quantum.cloud.ibm.com/docs/en/api/qiskit-c/2.3/qk-circuit
---

# QkCircuit

```c
typedef struct QkCircuit QkCircuit
```

The fundamental element of quantum computing is the *quantum circuit*. This is a computational routine that can be run, one shot at a time, on a quantum processing unit (QPU). A circuit will act on a predefined amount of quantum data (in Qiskit, we only directly support qubits) with unitary operations (gates), measurements and resets. In addition, a quantum circuit can contain operations on classical data, including real-time computations and control-flow constructs, which are executed by the controllers of the QPU. The `QkCircuit` struct exposes a low level interface to Qiskit’s quantum circuit data structure and exposes only what is defined in the inner data model of Qiskit. Therefore it is missing some functionality that is available in the higher level Python [`QuantumCircuit`](/docs/api/qiskit/2.3/qiskit.circuit.QuantumCircuit#qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") class.

Below is an example of a quantum circuit that makes a three-qubit Greenberger–Horne–Zeilinger (GHZ) state defined as:

$$
|\psi\rangle = \left( |000\rangle + |111\rangle \right) / \sqrt{2}
$$

```c
#include <qiskit.h>

// Create a circuit with three qubits and 3 classical bits
QkCircuit *qc = qk_circuit_new(3, 0);
// H gate on qubit 0, putting this qubit in a superposition of |0> + |1>.
qk_circuit_gate(qc, QkGate_H, (uint32_t[]){0}, NULL);
// A CX (CNOT) gate on control qubit 0 and target qubit 1 generating a Bell state.
qk_circuit_gate(qc, QkGate_CX, (uint32_t[]){0, 1}, NULL);
// A CX (CNOT) gate on control qubit 0 and target qubit 2 generating a GHZ state.
qk_circuit_gate(qc, QkGate_CX, (uint32_t[]){0, 2}, NULL);
// Free the created circuit.
qk_circuit_free(qc);
```

The circuit C API currently only supports creating circuits that contain operations defined in Qiskit’s internal Rust data model. Generally this includes only gates in the standard gate library, standard non-unitary operations (currently [`Barrier`](/docs/api/qiskit/2.3/circuit#qiskit.circuit.Barrier "qiskit.circuit.Barrier"), [`Measure`](/docs/api/qiskit/2.3/circuit#qiskit.circuit.Measure "qiskit.circuit.Measure"), [`Reset`](/docs/api/qiskit/2.3/circuit#qiskit.circuit.Reset "qiskit.circuit.Reset"), and [`Delay`](/docs/api/qiskit/2.3/circuit#qiskit.circuit.Delay "qiskit.circuit.Delay")) and [`UnitaryGate`](/docs/api/qiskit/2.3/qiskit.circuit.library.UnitaryGate#qiskit.circuit.library.UnitaryGate "qiskit.circuit.library.UnitaryGate"). This functionality will be expanded over time as the Rust data model is expanded to natively support more functionality.

## Data Types

### QkOpCount

`struct QkOpCount`

An individual operation count represented by the operation name and the number of instances in the circuit.

#### const char \*name

A nul terminated string representing the operation name

#### size\_t count

The number of instances of this operation in the circuit

### QkOpCounts

`struct QkOpCounts`

An array of `OpCount` objects representing the total counts of all the operation types in a circuit.

#### QkOpCount \*data

A array of size `len` containing `OpCount` objects for each type of operation in the circuit

#### size\_t len

The number of elements in `data`

### QkCircuitInstruction

`struct QkCircuitInstruction`

A circuit instruction representation.

This struct represents the data contained in an individual instruction in a `QkCircuit`. It is not a pointer to the underlying object, but contains a copy of the properties of the instruction for inspection.

#### char \*name

The instruction name

#### uint32\_t \*qubits

A pointer to an array of qubit indices this instruction operates on.

#### uint32\_t \*clbits

A pointer to an array of clbit indices this instruction operates on.

#### double \*params

A pointer to an array of parameter values for this instruction.

#### uint32\_t num\_qubits

The number of qubits for this instruction.

#### uint32\_t num\_clbits

The number of clbits for this instruction.

#### uint32\_t num\_params

The number of parameters for this instruction.

## Functions

### QkDelayUnit

`enum QkDelayUnit`

Units for circuit delays.

*Values:*

#### enumerator QkDelayUnit\_S

Seconds.

#### enumerator QkDelayUnit\_MS

Milliseconds.

#### enumerator QkDelayUnit\_US

Microseconds.

#### enumerator QkDelayUnit\_NS

Nanoseconds.

#### enumerator QkDelayUnit\_PS

Picoseconds.

### QkVarsMode

`enum QkVarsMode`

The mode to copy the classical variables, for operations that create a new circuit based on an existing one.

*Values:*

#### enumerator QkVarsMode\_Alike

Each variable has the same type it had in the input.

#### enumerator QkVarsMode\_Captures

Each variable becomes a “capture”.

#### enumerator QkVarsMode\_Drop

Do not copy the variable data.

### QkBlocksMode

`enum QkBlocksMode`

The mode to use to copy blocks in control-flow instructions, for operations that create a new circuit based on an existing one.

*Values:*

#### enumerator QkBlocksMode\_Drop

Drop the blocks.

#### enumerator QkBlocksMode\_Keep

Keep the blocks.

### qk\_circuit\_new

`QkCircuit *qk_circuit_new(uint32_t num_qubits, uint32_t num_clbits)`

Construct a new circuit with the given number of qubits and clbits.

#### Example

```c
QkCircuit *empty = qk_circuit_new(100, 100);
```

**Parameters**

- **num\_qubits** – The number of qubits the circuit contains.
- **num\_clbits** – The number of clbits the circuit contains.

**Returns**

A pointer to the created circuit.

### qk\_circuit\_add\_quantum\_register

`void qk_circuit_add_quantum_register(QkCircuit *circuit, const QkQuantumRegister *reg)`

Add a quantum register to a given quantum circuit

#### Example

```c
QkCircuit *qc = qk_circuit_new(0, 0);
QkQuantumRegister *qr = qk_quantum_register_new(1024, "my_little_register");
qk_circuit_add_quantum_register(qc, qr);
qk_quantum_register_free(qr);
qk_circuit_free(qc);
```

#### Safety

Behavior is undefined if `circuit` is not a valid, non-null pointer to a `QkCircuit` and if `reg` is not a valid, non-null pointer to a `QkQuantumRegister`.

**Parameters**

- **circuit** – A pointer to the circuit.
- **reg** – A pointer to the quantum register

### qk\_circuit\_add\_classical\_register

`void qk_circuit_add_classical_register(QkCircuit *circuit, const QkClassicalRegister *reg)`

Add a classical register to a given quantum circuit

#### Example

```c
QkCircuit *qc = qk_circuit_new(0, 0);
QkClassicalRegister *cr = qk_classical_register_new(24, "my_big_register");
qk_circuit_add_classical_register(qc, cr);
qk_classical_register_free(cr);
qk_circuit_free(qc);
```

#### Safety

Behavior is undefined if `circuit` is not a valid, non-null pointer to a `QkCircuit` and if `reg` is not a valid, non-null pointer to a `QkClassicalRegister`.

**Parameters**

- **circuit** – A pointer to the circuit.
- **reg** – A pointer to the classical register

### qk\_circuit\_copy

`QkCircuit *qk_circuit_copy(const QkCircuit *circuit)`

Create a copy of a `QkCircuit`.

#### Example

```c
QkCircuit *qc = qk_circuit_new(100, 100);
QkCircuit *copy = qk_circuit_copy(qc);
```

#### Safety

Behavior is undefined if `circuit` is not a valid, non-null pointer to a `QkCircuit`.

**Parameters**

- **circuit** – A pointer to the circuit to copy.

**Returns**

A new pointer to a copy of the input `circuit`.

### qk\_circuit\_num\_qubits

`uint32_t qk_circuit_num_qubits(const QkCircuit *circuit)`

Get the number of qubits the circuit contains.

#### Example

```c
QkCircuit *qc = qk_circuit_new(100, 100);
uint32_t num_qubits = qk_circuit_num_qubits(qc);  // num_qubits==100
```

#### Safety

Behavior is undefined if `circuit` is not a valid, non-null pointer to a `QkCircuit`.

**Parameters**

- **circuit** – A pointer to the circuit.

**Returns**

The number of qubits the circuit is defined on.

### qk\_circuit\_num\_clbits

`uint32_t qk_circuit_num_clbits(const QkCircuit *circuit)`

Get the number of clbits the circuit contains.

#### Example

```c
QkCircuit *qc = qk_circuit_new(100, 50);
uint32_t num_clbits = qk_circuit_num_clbits(qc);  // num_clbits==50
```

#### Safety

Behavior is undefined if `circuit` is not a valid, non-null pointer to a `QkCircuit`.

**Parameters**

- **circuit** – A pointer to the circuit.

**Returns**

The number of qubits the circuit is defined on.

### qk\_circuit\_free

`void qk_circuit_free(QkCircuit *circuit)`

Free the circuit.

#### Example

```c
QkCircuit *qc = qk_circuit_new(100, 100);
qk_circuit_free(qc);
```

#### Safety

Behavior is undefined if `circuit` is not either null or a valid pointer to a `QkCircuit`.

**Parameters**

- **circuit** – A pointer to the circuit to free.

### qk\_circuit\_gate

`QkExitCode qk_circuit_gate(QkCircuit *circuit, QkGate gate, const uint32_t *qubits, const double *params)`

Append a `QkGate` to the circuit.

#### Example

```c
QkCircuit *qc = qk_circuit_new(100, 0);
uint32_t qubit[1] = {0};
qk_circuit_gate(qc, QkGate_H, qubit, NULL);
```

#### Safety

The `qubits` and `params` types are expected to be a pointer to an array of `uint32_t` and `double` respectively where the length is matching the expectations for the standard gate. If the array is insufficiently long the behavior of this function is undefined as this will read outside the bounds of the array. It can be a null pointer if there are no qubits or params for a given gate. You can check `qk_gate_num_qubits` and `qk_gate_num_params` to determine how many qubits and params are required for a given gate.

Behavior is undefined if `circuit` is not a valid, non-null pointer to a `QkCircuit`.

**Parameters**

- **circuit** – A pointer to the circuit to add the gate to.
- **gate** – The StandardGate to add to the circuit.
- **qubits** – The pointer to the array of `uint32_t` qubit indices to add the gate on. This can be a null pointer if there are no qubits for `gate` (e.g. `QkGate_GlobalPhase`).
- **params** – The pointer to the array of `double` values to use for the gate parameters. This can be a null pointer if there are no parameters for `gate` (e.g. `QkGate_H`).

**Returns**

An exit code.

### qk\_gate\_num\_qubits

`uint32_t qk_gate_num_qubits(QkGate gate)`

Get the number of qubits for a `QkGate`.

#### Example

```c
uint32_t num_qubits = qk_gate_num_qubits(QkGate_CCX);
```

**Parameters**

- **gate** – The `QkGate` to get the number of qubits for.

**Returns**

The number of qubits the gate acts on.

### qk\_gate\_num\_params

`uint32_t qk_gate_num_params(QkGate gate)`

Get the number of parameters for a `QkGate`.

#### Example

```c
uint32_t num_params = qk_gate_num_params(QkGate_R);
```

**Parameters**

- **gate** – The `QkGate` to get the number of qubits for.

**Returns**

The number of parameters the gate has.

### qk\_circuit\_measure

`QkExitCode qk_circuit_measure(QkCircuit *circuit, uint32_t qubit, uint32_t clbit)`

Append a measurement to the circuit

#### Example

```c
QkCircuit *qc = qk_circuit_new(100, 1);
qk_circuit_measure(qc, 0, 0);
```

#### Safety

Behavior is undefined if `circuit` is not a valid, non-null pointer to a `QkCircuit`.

**Parameters**

- **circuit** – A pointer to the circuit to add the measurement to
- **qubit** – The `uint32_t` for the qubit to measure
- **clbit** – The `uint32_t` for the clbit to store the measurement outcome in

**Returns**

An exit code.

### qk\_circuit\_reset

`QkExitCode qk_circuit_reset(QkCircuit *circuit, uint32_t qubit)`

Append a reset to the circuit

#### Example

```c
QkCircuit *qc = qk_circuit_new(100, 0);
qk_circuit_reset(qc, 0);
```

#### Safety

Behavior is undefined if `circuit` is not a valid, non-null pointer to a `QkCircuit`.

**Parameters**

- **circuit** – A pointer to the circuit to add the reset to
- **qubit** – The `uint32_t` for the qubit to reset

**Returns**

An exit code.

### qk\_circuit\_barrier

`QkExitCode qk_circuit_barrier(QkCircuit *circuit, const uint32_t *qubits, uint32_t num_qubits)`

Append a barrier to the circuit.

#### Example

```c
QkCircuit *qc = qk_circuit_new(100, 1);
uint32_t qubits[5] = {0, 1, 2, 3, 4};
qk_circuit_barrier(qc, qubits, 5);
```

#### Safety

The length of the array `qubits` points to must be `num_qubits`. If there is a mismatch the behavior is undefined.

Behavior is undefined if `circuit` is not a valid, non-null pointer to a `QkCircuit`.

**Parameters**

- **circuit** – A pointer to the circuit to add the barrier to.
- **num\_qubits** – The number of qubits wide the barrier is.
- **qubits** – The pointer to the array of `uint32_t` qubit indices to add the barrier on.

**Returns**

An exit code.

### qk\_circuit\_unitary

`QkExitCode qk_circuit_unitary(QkCircuit *circuit, const QkComplex64 *matrix, const uint32_t *qubits, uint32_t num_qubits, bool check_input)`

Append an arbitrary unitary matrix to the circuit.

#### Example

```c
QkComplex64 c0 = {0, 0};  // 0+0i
QkComplex64 c1 = {1, 0};  // 1+0i

const uint32_t num_qubits = 1;
QkComplex64 unitary[2*2] = {c0, c1,  // row 0
                            c1, c0}; // row 1

QkCircuit *circuit = qk_circuit_new(1, 0);  // 1 qubit circuit
uint32_t qubit[1] = {0};  // qubit to apply the unitary on
qk_circuit_unitary(circuit, unitary, qubit, num_qubits, true);
```

#### Safety

Behavior is undefined if any of the following is violated:

- `circuit` is a valid, non-null pointer to a `QkCircuit`
- `matrix` is an aligned pointer to `4**num_qubits` initialized `QkComplex64` values
- `qubits` is an aligned pointer to `num_qubits` initialized `uint32_t` values

**Parameters**

- **circuit** – A pointer to the circuit to append the unitary to.
- **matrix** – A pointer to the `QkComplex64` array representing the unitary matrix. This must be a row-major, unitary matrix of dimension `2 ^ num_qubits x 2 ^ num_qubits`. More explicitly: the `(i, j)`-th element is given by `matrix[i * 2^n + j]`. The contents of `matrix` are copied inside this function before being added to the circuit, so caller keeps ownership of the original memory that `matrix` points to and can reuse it after the call and the caller is responsible for freeing it.
- **qubits** – A pointer to array of qubit indices, of length `num_qubits`.
- **num\_qubits** – The number of qubits the unitary acts on.
- **check\_input** – When true, the function verifies that the matrix is unitary. If set to False the caller is responsible for ensuring the matrix is unitary, if the matrix is not unitary this is undefined behavior and will result in a corrupt circuit.

**Returns**

An exit code.

### qk\_circuit\_count\_ops

`QkOpCounts qk_circuit_count_ops(const QkCircuit *circuit)`

Return a list of string names for instructions in a circuit and their counts.

To properly free the memory allocated by the struct, you should call `qk_opcounts_clear`. Dropping the `QkOpCounts` struct without doing so will leave the stored array of `QkOpCount` allocated and produce a memory leak.

#### Example

```c
QkCircuit *qc = qk_circuit_new(100, 0);
uint32_t qubits[1] = {0};
qk_circuit_gate(qc, QkGate_H, qubits, NULL);
QkOpCounts counts = qk_circuit_count_ops(qc);
// .. once done
qk_opcounts_clear(&counts);
```

#### Safety

Behavior is undefined if `circuit` is not a valid, non-null pointer to a `QkCircuit`.

**Parameters**

- **circuit** – A pointer to the circuit to get the counts for.

**Returns**

An `QkOpCounts` struct containing the circuit operation counts.

### qk\_circuit\_num\_instructions

`size_t qk_circuit_num_instructions(const QkCircuit *circuit)`

Return the total number of instructions in the circuit.

#### Example

```c
QkCircuit *qc = qk_circuit_new(100, 0);
uint32_t qubit[1] = {0};
qk_circuit_gate(qc, QkGate_H, qubit, NULL);
size_t num = qk_circuit_num_instructions(qc); // 1
```

#### Safety

Behavior is undefined if `circuit` is not a valid, non-null pointer to a `QkCircuit`.

**Parameters**

- **circuit** – A pointer to the circuit to get the total number of instructions for.

**Returns**

The total number of instructions in the circuit.

### qk\_circuit\_get\_instruction

`void qk_circuit_get_instruction(const QkCircuit *circuit, size_t index, QkCircuitInstruction *instruction)`

Return the instruction details for an instruction in the circuit.

This function is used to get the instruction details for a given instruction in the circuit.

This function allocates memory internally for the provided `QkCircuitInstruction` and thus you are responsible for calling `qk_circuit_instruction_clear` to free it.

#### Example

```c
QkCircuitInstruction inst;
QkCircuit *qc = qk_circuit_new(100, 0);
uint32_t qubit[1] = {0};
qk_circuit_gate(qc, QkGate_H, qubit, NULL);
qk_circuit_get_instruction(qc, 0, &inst);
qk_circuit_instruction_clear(&inst);
```

#### Safety

Behavior is undefined if `circuit` is not a valid, non-null pointer to a `QkCircuit`. The value for `index` must be less than the value returned by `qk_circuit_num_instructions` otherwise this function will panic. Behavior is undefined if `instruction` is not a valid, non-null pointer to a memory allocation with sufficient space for a `QkCircuitInstruction`.

**Parameters**

- **circuit** – A pointer to the circuit to get the instruction details for.
- **index** – The instruction index to get the instruction details of.
- **instruction** – A pointer to where to write out the `QkCircuitInstruction`

### qk\_circuit\_instruction\_clear

`void qk_circuit_instruction_clear(QkCircuitInstruction *inst)`

Clear the data in circuit instruction object.

This function doesn’t free the allocation for the provided `QkCircuitInstruction` pointer, it only frees the internal allocations for the data contained in the instruction. You are responsible for allocating and freeing the actual allocation used to store a `QkCircuitInstruction`.

#### Example

```c
QkCircuitInstruction *inst = malloc(sizeof(QkCircuitInstruction));
QkCircuit *qc = qk_circuit_new(100, 0);
uint32_t q0[1] = {0};
qk_circuit_gate(qc, QkGate_H, q0, NULL);
qk_circuit_get_instruction(qc, 0, inst);
qk_circuit_instruction_clear(inst); // clear internal allocations
free(inst); // free struct
qk_circuit_free(qc); // free the circuit
```

#### Safety

Behavior is undefined if `inst` is not a valid, non-null pointer to a `QkCircuitInstruction`.

**Parameters**

- **inst** – A pointer to the instruction to free.

### qk\_opcounts\_clear

`void qk_opcounts_clear(QkOpCounts *op_counts)`

Clear the content in a circuit operation count list.

#### Safety

Behavior is undefined if `op_counts` is not the object returned by `qk_circuit_count_ops`.

**Parameters**

- **op\_counts** – The returned op count list from `qk_circuit_count_ops`.

### qk\_circuit\_to\_python

`PyObject *qk_circuit_to_python(QkCircuit *circuit)`

Convert to a Python-space `QuantumCircuit`.

This function takes ownership of the pointer and gives it to Python. Using the input `circuit` pointer after it’s passed to this function is undefined behavior. In particular, `qk_circuit_free` should not be called on this pointer anymore.

#### Safety

Behavior is undefined if `circuit` is not a valid, non-null pointer to a `QkCircuit`

It is assumed that the thread currently executing this function holds the Python GIL. This is required to create the Python object returned by this function.

**Parameters**

- **circuit** – The C-space `QkCircuit` pointer.

**Returns**

A Python `QuantumCircuit` object.

### qk\_circuit\_delay

`QkExitCode qk_circuit_delay(QkCircuit *circuit, uint32_t qubit, double duration, QkDelayUnit unit)`

Append a delay instruction to the circuit.

#### Example

```c
QkCircuit *qc = qk_circuit_new(1, 0);
qk_circuit_delay(qc, 0, 100.0, QkDelayUnit_NS);
```

#### Safety

Behavior is undefined if `circuit` is not a valid, non-null pointer to a `QkCircuit`.

**Parameters**

- **circuit** – A pointer to the circuit to add the delay to.
- **qubit** – The `uint32_t` index of the qubit to apply the delay to.
- **duration** – The duration of the delay.
- **unit** – An enum representing the unit of the duration.

**Returns**

An exit code.

### qk\_circuit\_to\_dag

`QkDag *qk_circuit_to_dag(const QkCircuit *circuit)`

Convert a given circuit to a DAG.

The new DAG is copied from the circuit; the original `circuit` reference is still owned by the caller and still required to be freed with `qk_circuit_free`. You must free the returned DAG with `qk_dag_free` when done with it.

#### Example

```c
QkCircuit *qc = qk_circuit_new(0, 0);
QkQuantumRegister *qr = qk_quantum_register_new(3, "qr");
qk_circuit_add_quantum_register(qc, qr);
qk_quantum_register_free(qr);

QkDag *dag = qk_circuit_to_dag(qc);

qk_dag_free(dag);
qk_circuit_free(qc);
```

#### Safety

Behavior is undefined if `circuit` is not a valid, non-null pointer to a `QkCircuit`.

**Parameters**

- **circuit** – A pointer to the circuit from which to create the DAG.

**Returns**

A pointer to the new DAG.

### qk\_circuit\_copy\_empty\_like

`QkCircuit *qk_circuit_copy_empty_like(const QkCircuit *circuit, QkVarsMode vars_mode, QkBlocksMode blocks_mode)`

Return a copy of self with the same structure but empty.

That structure includes:

- global phase
- all the qubits and clbits, including the registers.

#### Example

```c
QkCircuit *qc = qk_circuit_new(10, 10);
for (int i = 0; i < 10; i++) {
    qk_circuit_measure(qc, i, i);
    uint32_t qubits[1] = {i};
    qk_circuit_gate(qc, QkGate_H, qubits, NULL);
}

// As the circuit does not contain any control-flow instructions,
// vars_mode and blocks_mode do not have any effect.
QkCircuit *copy = qk_circuit_copy_empty_like(qc, QkVarsMode_Alike, QkBlocksMode_Drop);

size_t num_copy_instructions = qk_circuit_num_instructions(copy); // 0

// do something with the copy

qk_circuit_free(qc);
qk_circuit_free(copy);
```

#### Safety

Behavior is undefined if `circuit` is not a valid, non-null pointer to a `QkCircuit`.

**Parameters**

- **circuit** – A pointer to the circuit to copy.
- **vars\_mode** – The mode for handling classical variables.
- **blocks\_mode** – The mode for handling blocks.

**Returns**

The pointer to the copied circuit.
