# `device.h`

### *group* QDMI Device Interface

Describes the functions to be implemented by a device or backend to be used with QDMI. 

This is an interface between the QDMI driver and the device. It includes functions to initialize and finalize a device, as well as to manage sessions between a QDMI driver and a device, query properties of the device, and submit jobs to the device.

The device interface is split into three parts:
* The [device session interface](#group__device__session__interface) for managing sessions between a QDMI driver and a device.
* The [device query interface](#group__device__query__interface) for querying properties of the device.
* The [device job interface](#group__device__job__interface) for submitting jobs to the device. 

### Typedefs

### typedef struct IQM_QDMI_Child_Device_impl_d \*IQM_QDMI_Child_Device

A handle for a child device. 

An opaque pointer to an implementation of the QDMI child device concept. A child device generally represents a core or processing unit of a multicore device. Each implementation of the [QDMI Device Interface](#group__device__interface) may define the actual implementation of the concept.


A simple example of an implementation is a struct that merely contains an index, which can be used to identify the respective core / processing unit. 
```cpp
struct IQM_QDMI_Child_Device_impl_d {
size_t id;
};
```

 #### SEE ALSO
[QDMI_DEVICE_PROPERTY_CHILDDEVICES](constants.html.md#constants_8h_1ad251d8ae8fbbe9a5c7a10d66b243d526a223cba616b016a4b33e06b53854a18f6)

#### SEE ALSO
[QDMI_DEVICE_SESSION_PARAMETER_CHILDDEVICE](constants.html.md#constants_8h_1a9f1e467b2b3870263b0e9d7e5d36cea4ac137dfd9d9edc8d822bc7bfb9d574fcb)

#### NOTE
Only authors of a multicore device library that want to facilitate job execution on a dedicated core and/or need to expose device properties on a child device level must implement the concept.

### Functions

### int IQM_QDMI_device_initialize(void)

Initialize a device. 

A device can expect that this function is called exactly once in the beginning and has returned before any other functions are invoked on that device. 

* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the device was initialized successfully. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if an unexpected error occurred. 

### int IQM_QDMI_device_finalize(void)

Finalize a device. 

A device can expect that this function is called exactly once at the end of using the device, and no other functions are invoked on that device afterward. 

* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the device was finalized successfully. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if the finalization failed, this could, for example, be due to a job that is still running. 

### *group* QDMI Device Session Interface

Provides functions to manage sessions between the driver and device. 

A device session is a connection between a driver and a device that allows the driver to interact with the device. Sessions are used to authenticate with the device and to manage resources required for the interaction with the device.

The typical workflow for a device session is as follows:
* Allocate a session with [IQM_QDMI_device_session_alloc](#group__device__session__interface_1gaf75451d8b3bf8506f6b399e684c57943).
* Set parameters for the session with [IQM_QDMI_device_session_set_parameter](#group__device__session__interface_1ga99ac380422ce730245d895c0eb95e3c1).
* Initialize the session with [IQM_QDMI_device_session_init](#group__device__session__interface_1gad6f9dbb2fd2c6923d686fa17009d350c).
* Run code to interact with the device using the [device query interface](#group__device__query__interface) and the [device job interface](#group__device__job__interface).
* Free the session with [IQM_QDMI_device_session_free](#group__device__session__interface_1gafd9187e300622f6b1215955d96ebc4ee) when it is no longer needed. 

### Typedefs

### typedef struct IQM_QDMI_Device_Session_impl_d \*IQM_QDMI_Device_Session

A handle for a device session. 

An opaque pointer to a type defined by the device that encapsulates all information about a session between a driver and a device. 

### Functions

### int IQM_QDMI_device_session_alloc([IQM_QDMI_Device_Session](#_CPPv423IQM_QDMI_Device_Session) \*session)

Allocate a new device session. 

This is the main entry point for a driver to establish a session with a device. The returned handle can be used throughout the [device session interface](#group__device__session__interface) to refer to the session. 

#### SEE ALSO
[IQM_QDMI_device_session_set_parameter](#group__device__session__interface_1ga99ac380422ce730245d895c0eb95e3c1) [IQM_QDMI_device_session_init](#group__device__session__interface_1gad6f9dbb2fd2c6923d686fa17009d350c)

* **Parameters:**
  **session** – **[out]** A handle to the session that is allocated. Must not be `NULL`. The session must be freed by calling [IQM_QDMI_device_session_free](#group__device__session__interface_1gafd9187e300622f6b1215955d96ebc4ee) when it is no longer used. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the session was allocated successfully. 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if `session` is `NULL`. 
* **Returns:**
  [QDMI_ERROR_OUTOFMEM](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a0cf40a28841e7b8bcba223ae28a3713d) if memory space ran out. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if an unexpected error occurred. 

### int IQM_QDMI_device_session_set_parameter([IQM_QDMI_Device_Session](#_CPPv423IQM_QDMI_Device_Session) session, [QDMI_Device_Session_Parameter](constants.html.md#_CPPv429QDMI_Device_Session_Parameter) param, [size_t](_cpp_compat.html.md#_CPPv46size_t) size, const void \*value)

Set a parameter for a device session. 

#### SEE ALSO
[IQM_QDMI_device_session_init](#group__device__session__interface_1gad6f9dbb2fd2c6923d686fa17009d350c)

#### NOTE
By calling this function with `value` set to `NULL`, the function can be used to check if the device supports the specified parameter without setting a value.

For example, to check whether the device supports setting a token for authentication, the following code pattern can be used:

```cpp
// Check if the device supports setting a token.
auto ret = [IQM_QDMI_device_session_set_parameter](#group__device__session__interface_1ga99ac380422ce730245d895c0eb95e3c1)(
  session, [QDMI_DEVICE_SESSION_PARAMETER_TOKEN](constants.html.md#constants_8h_1a9f1e467b2b3870263b0e9d7e5d36cea4a497c89c2b59737d70086a54e1958c292), 0, nullptr);
if (ret == [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651)) {
// The device does not support setting a token.
  ...
}

// Set the token.
std::string token = "token";
ret = [IQM_QDMI_device_session_set_parameter](#group__device__session__interface_1ga99ac380422ce730245d895c0eb95e3c1)(
  session, [QDMI_DEVICE_SESSION_PARAMETER_TOKEN](constants.html.md#constants_8h_1a9f1e467b2b3870263b0e9d7e5d36cea4a497c89c2b59737d70086a54e1958c292), token.size() + 1,
  token.c_str());
```

* **Parameters:**
  * **session** – **[in]** A handle to the session to set the parameter for. Must not be `NULL`. 
  * **param** – **[in]** The parameter to set. Must be one of the values specified for [QDMI_Device_Session_Parameter](constants.html.md#constants_8h_1ab99cb3929c8d79596e66fb276711ebda). 
  * **size** – **[in]** The size of the data pointed by `value` in bytes. Must not be zero, except when `value` is `NULL`, in which case it is ignored. 
  * **value** – **[in]** A pointer to the memory location that contains the value of the parameter to be set. The data pointed to by `value` is copied and can be safely reused after this function returns. If this is `NULL`, it is ignored. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the device supports the specified [QDMI_Device_Session_Parameter](constants.html.md#constants_8h_1ab99cb3929c8d79596e66fb276711ebda) and, when `value` is not `NULL`, the value of the parameter was set successfully. 
* **Returns:**
  [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651) if the device does not support the parameter or the value of the parameter. 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if
  * `session` is `NULL`,
  * `param` is invalid, or
  * `value` is not `NULL` and `size` is zero or not the expected size for the parameter (if specified by the [QDMI_Device_Session_Parameter](constants.html.md#constants_8h_1ab99cb3929c8d79596e66fb276711ebda) documentation). 
* **Returns:**
  [QDMI_ERROR_BADSTATE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a916e0810bf915e2ad67f2c1430c54fec) if the parameter cannot be set in the current state of the session, for example, because the session is already initialized. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if an unexpected error occurred. 

### int IQM_QDMI_device_session_init([IQM_QDMI_Device_Session](#_CPPv423IQM_QDMI_Device_Session) session)

Initialize a device session. 

This function initializes the device session and prepares it for use. The session must be initialized before it can be used as part of the [device query interface](#group__device__query__interface) or the [device job interface](#group__device__job__interface). If a device requires authentication, the required authentication information must be set using [IQM_QDMI_device_session_set_parameter](#group__device__session__interface_1ga99ac380422ce730245d895c0eb95e3c1) before calling this function. A session may only be successfully initialized once. 

#### SEE ALSO
[IQM_QDMI_device_session_set_parameter](#group__device__session__interface_1ga99ac380422ce730245d895c0eb95e3c1) [IQM_QDMI_device_session_query_device_property](#group__device__query__interface_1ga7aa9e25ee75e0f92b05447d95f30f55a) [IQM_QDMI_device_session_query_site_property](#group__device__query__interface_1ga86dea66138d5f78b08de04a15aed54ad) [IQM_QDMI_device_session_query_operation_property](#group__device__query__interface_1ga0b6c1ca179d5f5b20d6db030965e1ae2) [IQM_QDMI_device_session_create_device_job](#group__device__job__interface_1ga9afeca53c518d271428cb810867cb2c4)

* **Parameters:**
  **session** – **[in]** The session to initialize. Must not be `NULL`. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the session was initialized successfully. 
* **Returns:**
  [QDMI_ERROR_PERMISSIONDENIED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8ab875f28072043ad44f7ee5290bba8d01) if the session could not be initialized due to missing permissions. This could be due to missing authentication information that should be set using [IQM_QDMI_device_session_set_parameter](#group__device__session__interface_1ga99ac380422ce730245d895c0eb95e3c1). 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if `session` is `NULL`. 
* **Returns:**
  [QDMI_ERROR_BADSTATE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a916e0810bf915e2ad67f2c1430c54fec) if the session is not in a state allowing initialization, for example, because the session is already initialized. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if an unexpected error occurred. 

### void IQM_QDMI_device_session_free([IQM_QDMI_Device_Session](#_CPPv423IQM_QDMI_Device_Session) session)

Free a QDMI device session. 

This function frees the memory allocated for the session. Using a session handle after it was freed is undefined behavior. 

* **Parameters:**
  **session** – **[in]** The session to free. 

### *group* QDMI Device Query Interface

Provides functions to query properties of a device. 

The query interface enables to query static and dynamic properties of a device and its constituents in a unified fashion. It operates on [IQM_QDMI_Device_Session](#group__device__session__interface_1gad388aee7897f7f990bd7d6894bf71e75) handles created via the [device session interface](#group__device__session__interface). 

### Functions

### int IQM_QDMI_device_session_query_device_property([IQM_QDMI_Device_Session](#_CPPv423IQM_QDMI_Device_Session) session, [QDMI_Device_Property](constants.html.md#_CPPv420QDMI_Device_Property) prop, [size_t](_cpp_compat.html.md#_CPPv46size_t) size, void \*value, [size_t](_cpp_compat.html.md#_CPPv46size_t) \*size_ret)

Query a device property. 

**Attention**
: May only be called after the session has been initialized with [IQM_QDMI_device_session_init](#group__device__session__interface_1gad6f9dbb2fd2c6923d686fa17009d350c). 

#### NOTE
By calling this function with `value` set to `NULL`, the function can be used to check if the device supports the specified property without retrieving the property and without the need to provide a buffer for it. Additionally, the size of the buffer needed to retrieve the property is returned in `size_ret` if `size_ret` is not `NULL`.

For example, to query the name of a device implementation, the following code pattern can be used: 
```cpp
// Query the size of the property.
size_t size;
[IQM_QDMI_device_session_query_device_property](#group__device__query__interface_1ga7aa9e25ee75e0f92b05447d95f30f55a)(
  session, [QDMI_DEVICE_PROPERTY_NAME](constants.html.md#constants_8h_1ad251d8ae8fbbe9a5c7a10d66b243d526a18d3f183afc4d65c9e368f7cedf2d741), 0, nullptr, &size);

// Allocate memory for the property.
auto name = std::string(size - 1, '\0');

// Query the property.
[IQM_QDMI_device_session_query_device_property](#group__device__query__interface_1ga7aa9e25ee75e0f92b05447d95f30f55a)(
  session, [QDMI_DEVICE_PROPERTY_NAME](constants.html.md#constants_8h_1ad251d8ae8fbbe9a5c7a10d66b243d526a18d3f183afc4d65c9e368f7cedf2d741), size, name.data(), nullptr);
```

* **Parameters:**
  * **session** – **[in]** The session used for the query. Must not be `NULL`. 
  * **prop** – **[in]** The property to query. Must be one of the values specified for [QDMI_Device_Property](constants.html.md#constants_8h_1afeaad074a7321ebb8fb87e06598fc055) or a reserved numeric value of a removed property. 
  * **size** – **[in]** The size of the memory pointed to by `value` in bytes. Must be greater or equal to the size of the return type specified for `prop`, except when `value` is `NULL`, in which case it is ignored. 
  * **value** – **[out]** A pointer to the memory location where the value of the property will be stored. If this is `NULL`, it is ignored. 
  * **size_ret** – **[out]** The actual size of the data being queried in bytes. If this is `NULL`, it is ignored. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the device supports the specified property and, when `value` is not `NULL`, the property was successfully retrieved. 
* **Returns:**
  [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651) if the device does not support the property. This includes reserved numeric values of properties removed from QDMI. Such values are unsupported, not invalid arguments. 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if
  * `session` is `NULL`,
  * `prop` is invalid, or
  * `value` is not `NULL` and `size` is less than the size of the data being queried. 
* **Returns:**
  [QDMI_ERROR_BADSTATE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a916e0810bf915e2ad67f2c1430c54fec) if the property cannot be queried in the current state of the session, for example, because the session is not initialized. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if an unexpected error occurred.

### int IQM_QDMI_device_session_query_site_property([IQM_QDMI_Device_Session](#_CPPv423IQM_QDMI_Device_Session) session, [IQM_QDMI_Site](types.html.md#_CPPv413IQM_QDMI_Site) site, [QDMI_Site_Property](constants.html.md#_CPPv418QDMI_Site_Property) prop, [size_t](_cpp_compat.html.md#_CPPv46size_t) size, void \*value, [size_t](_cpp_compat.html.md#_CPPv46size_t) \*size_ret)

Query a site property. 

**Attention**
: May only be called after the session has been initialized with [IQM_QDMI_device_session_init](#group__device__session__interface_1gad6f9dbb2fd2c6923d686fa17009d350c). 

#### NOTE
By calling this function with `value` set to `NULL`, the function can be used to check if the device supports the specified property without retrieving the property and without the need to provide a buffer for it. Additionally, the size of the buffer needed to retrieve the property is returned in `size_ret` if `size_ret` is not `NULL`.

For example, to query the T1 time of a site, the following code pattern can be used: 
```cpp
// Check if the device supports the property.
auto ret = [IQM_QDMI_device_session_query_site_property](#group__device__query__interface_1ga86dea66138d5f78b08de04a15aed54ad)(
  session, site, [QDMI_SITE_PROPERTY_T1](constants.html.md#constants_8h_1a69ef10d452cc6f03cac8a917ba48d6e2a60262ea30467ff3d36cbe4730c4a23f3), 0, nullptr, nullptr);
if (ret == [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651)) {
// The device does not support the property.
  ...
}

// Query the property.
uint64_t t1;
[IQM_QDMI_device_session_query_site_property](#group__device__query__interface_1ga86dea66138d5f78b08de04a15aed54ad)(
  session, site, [QDMI_SITE_PROPERTY_T1](constants.html.md#constants_8h_1a69ef10d452cc6f03cac8a917ba48d6e2a60262ea30467ff3d36cbe4730c4a23f3), sizeof(uint64_t), &t1, nullptr);
```

* **Parameters:**
  * **session** – **[in]** The session used for the query. Must not be `NULL`. 
  * **site** – **[in]** The site to query. Must not be `NULL`. 
  * **prop** – **[in]** The property to query. Must be one of the values specified for [QDMI_Site_Property](constants.html.md#constants_8h_1a699a82efc1fb132a1b67a6e9d5592080). 
  * **size** – **[in]** The size of the memory pointed to by `value` in bytes. Must be greater or equal to the size of the return type specified for `prop`, except when `value` is `NULL`, in which case it is ignored. 
  * **value** – **[out]** A pointer to the memory location where the value of the property will be stored. If this is `NULL`, it is ignored. 
  * **size_ret** – **[out]** The actual size of the data being queried in bytes. If this is `NULL`, it is ignored. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the device supports the specified property and, when `value` is not `NULL`, the property was successfully retrieved. 
* **Returns:**
  [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651) if the device does not support the property. 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if
  * `session` or `site` is `NULL`,
  * `prop` is invalid, or
  * `value` is not `NULL` and `size` is less than the size of the data being queried. 
* **Returns:**
  [QDMI_ERROR_BADSTATE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a916e0810bf915e2ad67f2c1430c54fec) if the property cannot be queried in the current state of the session, for example, because the session is not initialized. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if an unexpected error occurred.

### int IQM_QDMI_device_session_query_operation_property([IQM_QDMI_Device_Session](#_CPPv423IQM_QDMI_Device_Session) session, [IQM_QDMI_Operation](types.html.md#_CPPv418IQM_QDMI_Operation) operation, [size_t](_cpp_compat.html.md#_CPPv46size_t) num_sites, const [IQM_QDMI_Site](types.html.md#_CPPv413IQM_QDMI_Site) \*sites, [size_t](_cpp_compat.html.md#_CPPv46size_t) num_params, const double \*params, [QDMI_Operation_Property](constants.html.md#_CPPv423QDMI_Operation_Property) prop, [size_t](_cpp_compat.html.md#_CPPv46size_t) size, void \*value, [size_t](_cpp_compat.html.md#_CPPv46size_t) \*size_ret)

Query an operation property. 

**Attention**
: May only be called after the session has been initialized with [IQM_QDMI_device_session_init](#group__device__session__interface_1gad6f9dbb2fd2c6923d686fa17009d350c). 

#### NOTE
By calling this function with `sites` set to `NULL`, the function can be used to query properties of the device that are independent of the sites. A device will return [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651) if the queried property is site-dependent and `sites` is `NULL`.

By calling this function with `params` set to `NULL`, the function can be used to query properties of the device that are independent of the values of the parameters. A device will return [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651) if the queried property is parameter-dependent and `params` is `NULL`.

By calling this function with `value` set to `NULL`, the function can be used to check if the device supports the specified property without retrieving the property and without the need to provide a buffer for it. Additionally, the size of the buffer needed to retrieve the property is returned in `size_ret` if `size_ret` is not `NULL`.

For example, to query the site-independent fidelity of an operation without parameters, the following code snippet can be used: 
```cpp
// Check if the device supports the property.
auto ret = [IQM_QDMI_device_session_query_operation_property](#group__device__query__interface_1ga0b6c1ca179d5f5b20d6db030965e1ae2)(
  session, operation, 0, nullptr, 0, nullptr,
[QDMI_OPERATION_PROPERTY_FIDELITY](constants.html.md#constants_8h_1ab23d5f0c5296e3eab4243e91f1213726aeff33960f7a3da9e17058cf9bf05da77), 0, nullptr, nullptr);
if (ret == [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651)) {
// The device does not support the site-independent property.
// Check if the device supports the site-dependent property.
  ...
}

// Query the property.
double fidelity;
[IQM_QDMI_device_session_query_operation_property](#group__device__query__interface_1ga0b6c1ca179d5f5b20d6db030965e1ae2)(
  session, operation, 0, nullptr, 0, nullptr,
[QDMI_OPERATION_PROPERTY_FIDELITY](constants.html.md#constants_8h_1ab23d5f0c5296e3eab4243e91f1213726aeff33960f7a3da9e17058cf9bf05da77), sizeof(double), &fidelity, nullptr);
```

* **Parameters:**
  * **session** – **[in]** The session used for the query. Must not be `NULL`. 
  * **operation** – **[in]** The operation to query. Must not be `NULL`. 
  * **num_sites** – **[in]** The number of sites that the operation is applied to. 
  * **sites** – **[in]** A pointer to a list of handles where the sites that the operation is applied to are stored. If this is `NULL`, it is ignored. 
  * **num_params** – **[in]** The number of parameters that the operation takes. 
  * **params** – **[in]** A pointer to a list of parameters the operation takes. If this is `NULL`, it is ignored. 
  * **prop** – **[in]** The property to query. Must be one of the values specified for [QDMI_Operation_Property](constants.html.md#constants_8h_1abc8a0427b96af9020c80aedabcf393b3). 
  * **size** – **[in]** The size of the memory pointed to by `value` in bytes. Must be greater or equal to the size of the return type specified for the [QDMI_Operation_Property](constants.html.md#constants_8h_1abc8a0427b96af9020c80aedabcf393b3) `prop`, except when `value` is `NULL`, in which case it is ignored. 
  * **value** – **[out]** A pointer to the memory location where the value of the property will be stored. If this is `NULL`, it is ignored. 
  * **size_ret** – **[out]** The actual size of the data being queried in bytes. If this is `NULL`, it is ignored. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the device supports the specified property and, when `value` is not `NULL`, the property was successfully retrieved. 
* **Returns:**
  [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651) if the property is not supported by the device or if the queried property cannot be provided for the given sites or parameters. 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if
  * `session` or `operation` are `NULL`,
  * `prop` is invalid, or
  * `value` is not `NULL` and `size` is less than the size of the data being queried. 
* **Returns:**
  [QDMI_ERROR_BADSTATE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a916e0810bf915e2ad67f2c1430c54fec) if the property cannot be queried in the current state of the session, for example, because the session is not initialized. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if an unexpected error occurred.

### *group* QDMI Device Job Interface

Provides functions to manage jobs on a device. 

A job is a task submitted to a device for execution. Most jobs are quantum circuits to be executed on a quantum device. However, jobs can also be a different type of task, such as calibration.

The typical workflow for a device job is as follows:
* Create a job with [IQM_QDMI_device_session_create_device_job](#group__device__job__interface_1ga9afeca53c518d271428cb810867cb2c4).
* Set programs with [IQM_QDMI_device_job_set_programs](#group__device__job__interface_1ga42f63c106a73e6a5ef87d20f4303e3c6) and other parameters with [IQM_QDMI_device_job_set_parameter](#group__device__job__interface_1gaf6a0e5a14e7cc81d9af3a1ff4fcad760).
* Submit the job with [IQM_QDMI_device_job_submit](#group__device__job__interface_1gaa29ade2688cd0aff4114aee2db5d7be8).
* Check the status of the job with [IQM_QDMI_device_job_check](#group__device__job__interface_1ga0c1816a53ce4c8599f7955a4a4b369f4).
* Wait for the job to finish with [IQM_QDMI_device_job_wait](#group__device__job__interface_1ga244a637cd8c5026c3901522d03427152).
* Retrieve each program’s results with [IQM_QDMI_device_job_get_results](#group__device__job__interface_1gab59e410f07258345dd8dafe913c7a66b).
* Free the job with [IQM_QDMI_device_job_free](#group__device__job__interface_1gabb695b72804d3de103045307d0f9abce) when it is no longer used.

Alternatively, a driver may retrieve a previously submitted job with [IQM_QDMI_device_session_retrieve_device_job_by_id](#group__device__job__interface_1gad2bc9ec6c329bb18fd293a876e409488) and continue managing it through the same interface. 

### Typedefs

### typedef struct IQM_QDMI_Device_Job_impl_d \*IQM_QDMI_Device_Job

A handle for a device job. 

An opaque pointer to a type defined by the device that encapsulates all information about a job on a device. 

#### SEE ALSO
QDMI_Job for the client-side job handle. 

### Functions

### int IQM_QDMI_device_session_create_device_job([IQM_QDMI_Device_Session](#_CPPv423IQM_QDMI_Device_Session) session, [IQM_QDMI_Device_Job](#_CPPv419IQM_QDMI_Device_Job) \*job)

Create a job. 

This is the main entry point for a driver to create a job for a device. The returned handle can be used throughout the [device job interface](#group__device__job__interface) to refer to the job. 

**Attention**
: May only be called after the session has been initialized with [IQM_QDMI_device_session_init](#group__device__session__interface_1gad6f9dbb2fd2c6923d686fa17009d350c). 

* **Parameters:**
  * **session** – **[in]** The session to create the job on. Must not be `NULL`. 
  * **job** – **[out]** A pointer to a handle that will store the created job. Must not be `NULL`. The job must be freed by calling [IQM_QDMI_device_job_free](#group__device__job__interface_1gabb695b72804d3de103045307d0f9abce) when it is no longer used. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the job was successfully created. 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if `session` or `job` are `NULL`. 
* **Returns:**
  [QDMI_ERROR_BADSTATE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a916e0810bf915e2ad67f2c1430c54fec) if the session is not in a state allowing the creation of a job, for example, because the session is not initialized. 
* **Returns:**
  [QDMI_ERROR_PERMISSIONDENIED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8ab875f28072043ad44f7ee5290bba8d01) if the device does not allow using the [device job interface](#group__device__job__interface) for the current session. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if job creation failed due to a fatal error.

### int IQM_QDMI_device_session_retrieve_device_job_by_id([IQM_QDMI_Device_Session](#_CPPv423IQM_QDMI_Device_Session) session, const char \*job_id, [IQM_QDMI_Device_Job](#_CPPv419IQM_QDMI_Device_Job) \*job)

Retrieve an existing device job by its ID. 

Creates a new local device-job handle for the existing remote job identified by `job_id`. Retrieving a job does not submit, clone, or otherwise modify the remote job. The returned handle can be used to query properties, check or wait for completion, cancel the job, and retrieve results.

The job is accessed with the credentials and configuration of `session`. The job ID is an identifier, not an authentication credential. Parameters cannot be set on a retrieved job, and a retrieved job cannot be submitted again. The device must reconstruct the program count and input-to-result mapping. If historical input metadata is unavailable, queries for the original format or program bytes may return [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651) without preventing retrieval.

* **Parameters:**
  * **session** – **[in]** The initialized session with which to retrieve the job. Must not be `NULL`. 
  * **job_id** – **[in]** The nonempty, null-terminated ID returned by [QDMI_DEVICE_JOB_PROPERTY_ID](constants.html.md#constants_8h_1a6e4d18c7fa5d383bbcc1498abe090d4fad991a6a3b0a17e58b59f9180463855ec). Must not be `NULL`. 
  * **job** – **[out]** A pointer to a handle that will store the retrieved job. Must not be `NULL`. The handle must be freed by calling [IQM_QDMI_device_job_free](#group__device__job__interface_1gabb695b72804d3de103045307d0f9abce) when it is no longer used. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the job was successfully retrieved. 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if `session`, `job_id`, or `job` is `NULL`, or if `job_id` is empty. 
* **Returns:**
  [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651) if the device does not support retrieving existing jobs or cannot reconstruct the program count and result-index mapping. 
* **Returns:**
  [QDMI_ERROR_NOTFOUND](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a03b271eb2b26780e3152e13e3e7ef7be) if no accessible job with `job_id` exists. 
* **Returns:**
  [QDMI_ERROR_BADSTATE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a916e0810bf915e2ad67f2c1430c54fec) if `session` is not initialized. 
* **Returns:**
  [QDMI_ERROR_PERMISSIONDENIED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8ab875f28072043ad44f7ee5290bba8d01) if `session` is not permitted to access the job. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if retrieving the job failed due to a fatal error. 

### int IQM_QDMI_device_job_set_parameter([IQM_QDMI_Device_Job](#_CPPv419IQM_QDMI_Device_Job) job, [QDMI_Device_Job_Parameter](constants.html.md#_CPPv425QDMI_Device_Job_Parameter) param, [size_t](_cpp_compat.html.md#_CPPv46size_t) size, const void \*value)

Set a parameter for a job. 

#### NOTE
By calling this function with `value` set to `NULL`, the function can be used to check if the device supports the specified parameter without setting the parameter and without the need to provide a value.

For example, to check whether the device supports setting the number of shots for a quantum circuit job, the following code pattern can be used: 
```cpp
// Check if the device supports setting the number of shots.
auto ret = [IQM_QDMI_device_job_set_parameter](#group__device__job__interface_1gaf6a0e5a14e7cc81d9af3a1ff4fcad760)(
  job, [QDMI_DEVICE_JOB_PARAMETER_SHOTSNUM](constants.html.md#constants_8h_1a40dd25c531ebf99fb4b46469083b609ea4ecec990e69afb205f9801433be37b26), 0, nullptr);
if (ret == [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651)) {
// The device does not support setting the number of shots.
  ...
}

// Set the number of shots.
size_t shots = 8192;
[IQM_QDMI_device_job_set_parameter](#group__device__job__interface_1gaf6a0e5a14e7cc81d9af3a1ff4fcad760)(
  job, [QDMI_DEVICE_JOB_PARAMETER_SHOTSNUM](constants.html.md#constants_8h_1a40dd25c531ebf99fb4b46469083b609ea4ecec990e69afb205f9801433be37b26), sizeof(size_t), &shots);
```

* **Parameters:**
  * **job** – **[in]** A handle to a job for which to set `param`. Must not be `NULL`. 
  * **param** – **[in]** The parameter whose value will be set. Must be one of the values specified for [QDMI_Device_Job_Parameter](constants.html.md#constants_8h_1a65db59774d7c61601159d00d505d835c). 
  * **size** – **[in]** The size of the data pointed to by `value` in bytes. Must not be zero, except when `value` is `NULL`, in which case it is ignored. 
  * **value** – **[in]** A pointer to the memory location that contains the value of the parameter to be set. The data pointed to by `value` is copied and can be safely reused after this function returns. If this is `NULL`, it is ignored. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the device supports the specified [QDMI_Device_Job_Parameter](constants.html.md#constants_8h_1a65db59774d7c61601159d00d505d835c) `param` and, when `value` is not `NULL`, the parameter was successfully set. 
* **Returns:**
  [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651) if the device does not support the parameter or the value of the parameter. 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if
  * `job` is `NULL`,
  * `param` is invalid, or
  * `value` is not `NULL` and `size` is zero or not the expected size for the parameter (if specified by the [QDMI_Device_Job_Parameter](constants.html.md#constants_8h_1a65db59774d7c61601159d00d505d835c) documentation). 
* **Returns:**
  [QDMI_ERROR_BADSTATE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a916e0810bf915e2ad67f2c1430c54fec) if the parameter cannot be set in the current state of the job, for example, because the job is already submitted. 
* **Returns:**
  [QDMI_ERROR_OUTOFMEM](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a0cf40a28841e7b8bcba223ae28a3713d) if a parameter value cannot be copied. 
* **Returns:**
  [QDMI_ERROR_PERMISSIONDENIED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8ab875f28072043ad44f7ee5290bba8d01) if the device does not allow using the [device job interface](#group__device__job__interface) for the current session. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if setting the parameter failed due to a fatal error.

### int IQM_QDMI_device_job_set_programs([IQM_QDMI_Device_Job](#_CPPv419IQM_QDMI_Device_Job) job, [QDMI_Program_Format](constants.html.md#_CPPv419QDMI_Program_Format) format, [size_t](_cpp_compat.html.md#_CPPv46size_t) count, const [size_t](_cpp_compat.html.md#_CPPv46size_t) \*sizes, const void \*const \*programs)

Set one or more programs for a job. 

All programs use the same `format` and the same job parameters, including the shot count. On success, the device replaces the complete program list with a deep copy of `sizes` and the program bytes. If validation or copying fails, the existing program list remains unchanged. A device that accepts a list must report its size through [QDMI_DEVICE_JOB_PROPERTY_PROGRAMSNUM](constants.html.md#constants_8h_1a6e4d18c7fa5d383bbcc1498abe090d4faa24add14b040fb44b0daac7f5714fafc) and expose each result through [IQM_QDMI_device_job_get_results](#group__device__job__interface_1gab59e410f07258345dd8dafe913c7a66b). A result’s index equals its input program’s index; execution order is unspecified. The list has one ID, status, wait operation, and cancellation operation. The job reaches [QDMI_JOB_STATUS_DONE](constants.html.md#constants_8h_1a04e5c793bcbe8b354a9223bb60f828a6ad3dad6dd89491e223f42ff9cd9bdade2) only after all programs succeed. Failed or canceled jobs become terminal only after all programs have stopped. Optional per-program outcomes are available through [IQM_QDMI_device_job_get_program_status](#group__device__job__interface_1ga2de3c037111c972833262654e5a5e0d9); results of successful programs remain accessible when other programs fail or are canceled. 

* **Parameters:**
  * **job** – **[in]** A handle to the job. Must not be `NULL`. 
  * **format** – **[in]** The exact format of every program. Must be a valid [QDMI_Program_Format](constants.html.md#constants_8h_1a475336f0c08bd0218dd76a6016098231), including for a single program. 
  * **count** – **[in]** The number of programs. Must be greater than zero. A support check succeeds only if the device supports this exact cardinality with the configured job parameters. 
  * **sizes** – **[in]** An array of `count` program sizes in bytes. Must not be `NULL` and each size must be greater than zero when `programs` is not `NULL`. A text program contains exactly one `'\0'` as its final byte. Binary programs are arbitrary nonempty byte sequences. When `programs` is `NULL`, `sizes` is ignored. 
  * **programs** – **[in]** An array of `count` program pointers. When the array is not `NULL`, each pointer must not be `NULL`. The device copies all input data before returning. If the array is `NULL`, the function checks support for the format and cardinality without changing the job. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the device supports the count in `format` and, when `programs` is not `NULL`, set the complete list. 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if
  * `job` is `NULL`, `count` is zero, or `format` is not valid, or
  * the device supports program lists, `programs` is not `NULL`, and `sizes` is `NULL`, an element of `programs` is `NULL`, an element of `sizes` is zero, or a text program does not contain exactly one trailing `'\0'`. 
* **Returns:**
  [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651) if the arguments are valid but the device cannot accept the format, count, or programs with the configured job parameters. Reserved numeric values of removed formats also return [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651). 
* **Returns:**
  [QDMI_ERROR_BADSTATE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a916e0810bf915e2ad67f2c1430c54fec) if programs cannot be set in the current state of the job, for example, because the job is already submitted. 
* **Returns:**
  [QDMI_ERROR_PERMISSIONDENIED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8ab875f28072043ad44f7ee5290bba8d01) if the device does not allow using the [device job interface](#group__device__job__interface) for the current session. 
* **Returns:**
  [QDMI_ERROR_OUTOFMEM](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a0cf40a28841e7b8bcba223ae28a3713d) if the device cannot copy the program list. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if setting the programs failed due to a fatal error. 

### int IQM_QDMI_device_job_get_program([IQM_QDMI_Device_Job](#_CPPv419IQM_QDMI_Device_Job) job, [size_t](_cpp_compat.html.md#_CPPv46size_t) program_index, [size_t](_cpp_compat.html.md#_CPPv46size_t) size, void \*data, [size_t](_cpp_compat.html.md#_CPPv46size_t) \*size_ret)

Retrieve one program in input order. 

The returned bytes include the terminating NUL for text formats. A retrieved job may return [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651) when its original program bytes are unavailable. The program count is reported by [QDMI_DEVICE_JOB_PROPERTY_PROGRAMSNUM](constants.html.md#constants_8h_1a6e4d18c7fa5d383bbcc1498abe090d4faa24add14b040fb44b0daac7f5714fafc). 

* **Parameters:**
  * **job** – **[in]** The job to query. Must not be `NULL`. 
  * **program_index** – **[in]** The zero-based program index. 
  * **size** – **[in]** The size of `data` in bytes. Ignored if `data` is `NULL`. 
  * **data** – **[out]** The buffer for the program bytes, or `NULL` for a size query. 
  * **size_ret** – **[out]** The required buffer size, or `NULL`. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the program bytes were copied, or their size was returned when `data` is `NULL`. 
* **Returns:**
  [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651) if the original program is unavailable. 
* **Returns:**
  [QDMI_ERROR_BADSTATE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a916e0810bf915e2ad67f2c1430c54fec) if no program list has been set. 
* **Returns:**
  [QDMI_ERROR_OUTOFRANGE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8ab6858000dc2e49368e3caba68054423c) if `program_index` is out of range. 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if `job` is `NULL` or `data` is non-`NULL` and `size` is too small. 
* **Returns:**
  [QDMI_ERROR_PERMISSIONDENIED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8ab875f28072043ad44f7ee5290bba8d01) if the session cannot access jobs. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if an unexpected error occurred. 

### int IQM_QDMI_device_job_get_program_status([IQM_QDMI_Device_Job](#_CPPv419IQM_QDMI_Device_Job) job, [size_t](_cpp_compat.html.md#_CPPv46size_t) program_index, [QDMI_Job_Status](constants.html.md#_CPPv415QDMI_Job_Status) \*status)

Query the current status of one program in a device job. 

Individual outcomes are optional. Once reached, a program’s terminal status cannot change. An out-of-range index returns [QDMI_ERROR_OUTOFRANGE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8ab6858000dc2e49368e3caba68054423c) even if individual outcomes are unsupported; results of successful programs remain available when siblings fail or are canceled. A temporary retrieval failure is an error, not [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651). 

* **Parameters:**
  * **job** – **[in]** The job to query. Must not be `NULL`. 
  * **program_index** – **[in]** The zero-based input program index. 
  * **status** – **[out]** The program status. Must not be `NULL` when individual outcomes are supported. An implementation that always returns [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651) need not inspect this pointer. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the status was retrieved. 
* **Returns:**
  [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651) if individual outcomes are unavailable. 
* **Returns:**
  [QDMI_ERROR_BADSTATE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a916e0810bf915e2ad67f2c1430c54fec) if no program list has been set or supported outcomes are not yet ready. 
* **Returns:**
  [QDMI_ERROR_OUTOFRANGE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8ab6858000dc2e49368e3caba68054423c) if `program_index` is out of range. 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if `job` is `NULL`, or if individual outcomes are supported and `status` is `NULL`. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if an unexpected error occurred. 

### int IQM_QDMI_device_job_query_property([IQM_QDMI_Device_Job](#_CPPv419IQM_QDMI_Device_Job) job, [QDMI_Device_Job_Property](constants.html.md#_CPPv424QDMI_Device_Job_Property) prop, [size_t](_cpp_compat.html.md#_CPPv46size_t) size, void \*value, [size_t](_cpp_compat.html.md#_CPPv46size_t) \*size_ret)

Query a job property. 

#### NOTE
By calling this function with `value` set to `NULL`, the function can be used to check if the job supports the specified property without retrieving the property and without the need to provide a buffer for it. Additionally, the size of the buffer needed to retrieve the property is returned in `size_ret` if `size_ret` is not `NULL`.

For example, to query the ID of a job, the following code pattern can be used: 
```cpp
// Query the size of the property.
size_t size;
[IQM_QDMI_device_job_query_property](#group__device__job__interface_1ga08c698fecf68b09d15d68e8c8453c3a6)(
  job, [QDMI_DEVICE_JOB_PROPERTY_ID](constants.html.md#constants_8h_1a6e4d18c7fa5d383bbcc1498abe090d4fad991a6a3b0a17e58b59f9180463855ec), 0, nullptr, &size);

// Allocate memory for the property.
auto id = std::string(size - 1, '\0');

// Query the property.
[IQM_QDMI_device_job_query_property](#group__device__job__interface_1ga08c698fecf68b09d15d68e8c8453c3a6)(
  job, [QDMI_DEVICE_JOB_PROPERTY_ID](constants.html.md#constants_8h_1a6e4d18c7fa5d383bbcc1498abe090d4fad991a6a3b0a17e58b59f9180463855ec), size, id.data(), nullptr);
```

* **Parameters:**
  * **job** – **[in]** A handle to a job for which to query `prop`. Must not be `NULL`. 
  * **prop** – **[in]** The property to query. Must be one of the values specified for [QDMI_Device_Job_Property](constants.html.md#constants_8h_1a9962b2d3a2ebb0791c8c6196069e499e). 
  * **size** – **[in]** The size of the memory pointed to by `value` in bytes. Must be greater or equal to the size of the return type specified for `prop`, except when `value` is `NULL`, in which case it is ignored. 
  * **value** – **[out]** A pointer to the memory location where the value of the property will be stored. If this is `NULL`, it is ignored. 
  * **size_ret** – **[out]** The actual size of the data being queried in bytes. If this is `NULL`, it is ignored. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the job supports the specified property and, when `value` is not `NULL`, the property was successfully retrieved. 
* **Returns:**
  [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651) if the job does not support the property. 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if
  * `job` is `NULL`,
  * `prop` is invalid, or
  * `value` is not `NULL` and `size` is less than the size of the data being queried. 
* **Returns:**
  [QDMI_ERROR_BADSTATE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a916e0810bf915e2ad67f2c1430c54fec) if the property cannot be queried in the current state of the job, for example, because the job failed or the property is not initialized because it has no default value and was not set. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if an unexpected error occurred.

### int IQM_QDMI_device_job_submit([IQM_QDMI_Device_Job](#_CPPv419IQM_QDMI_Device_Job) job)

Submit a job to the device. 

This function can either be blocking until the job is finished or non-blocking and return while the job is running. In the latter case, the functions [IQM_QDMI_device_job_check](#group__device__job__interface_1ga0c1816a53ce4c8599f7955a4a4b369f4) and [IQM_QDMI_device_job_wait](#group__device__job__interface_1ga244a637cd8c5026c3901522d03427152) can be used to check the status and wait for the job to finish. 

* **Parameters:**
  **job** – **[in]** The job to submit. Must not be `NULL`. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the job was successfully submitted. 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if `job` is `NULL`. 
* **Returns:**
  [QDMI_ERROR_BADSTATE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a916e0810bf915e2ad67f2c1430c54fec) if a required program or format is missing, the job was retrieved with [IQM_QDMI_device_session_retrieve_device_job_by_id](#group__device__job__interface_1gad2bc9ec6c329bb18fd293a876e409488). 
* **Returns:**
  [QDMI_ERROR_PERMISSIONDENIED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8ab875f28072043ad44f7ee5290bba8d01) if the device does not allow using the [device job interface](#group__device__job__interface) for the current session. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if the job submission failed. 

### int IQM_QDMI_device_job_cancel([IQM_QDMI_Device_Job](#_CPPv419IQM_QDMI_Device_Job) job)

Cancel an already submitted job. 

Remove the job from the queue of waiting jobs. This changes the status of the job to [QDMI_JOB_STATUS_CANCELED](constants.html.md#constants_8h_1a04e5c793bcbe8b354a9223bb60f828a6a05163481e57725e91bb22ff798394f33). 

* **Parameters:**
  **job** – **[in]** The job to cancel. Must not be `NULL`. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the job was successfully canceled. 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if `job` is `NULL` or the job already has the status [QDMI_JOB_STATUS_DONE](constants.html.md#constants_8h_1a04e5c793bcbe8b354a9223bb60f828a6ad3dad6dd89491e223f42ff9cd9bdade2). 
* **Returns:**
  [QDMI_ERROR_PERMISSIONDENIED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8ab875f28072043ad44f7ee5290bba8d01) if the device does not allow using the [device job interface](#group__device__job__interface) for the current session. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if the job could not be canceled. 

### int IQM_QDMI_device_job_check([IQM_QDMI_Device_Job](#_CPPv419IQM_QDMI_Device_Job) job, [QDMI_Job_Status](constants.html.md#_CPPv415QDMI_Job_Status) \*status)

Check the status of a job. 

This function is non-blocking and returns immediately with the job status. It is not required to call this function before calling [IQM_QDMI_device_job_get_results](#group__device__job__interface_1gab59e410f07258345dd8dafe913c7a66b). 

* **Parameters:**
  * **job** – **[in]** The job to check the status of. Must not be `NULL`. 
  * **status** – **[out]** The status of the job. Must not be `NULL`. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the job status was successfully checked. 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if `job` or `status` is `NULL`. 
* **Returns:**
  [QDMI_ERROR_PERMISSIONDENIED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8ab875f28072043ad44f7ee5290bba8d01) if the device does not allow using the [device job interface](#group__device__job__interface) for the current session. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if the job status could not be checked. 

### int IQM_QDMI_device_job_wait([IQM_QDMI_Device_Job](#_CPPv419IQM_QDMI_Device_Job) job, [size_t](_cpp_compat.html.md#_CPPv46size_t) timeout)

Wait for a job to finish. 

This function blocks until the job reaches [QDMI_JOB_STATUS_DONE](constants.html.md#constants_8h_1a04e5c793bcbe8b354a9223bb60f828a6ad3dad6dd89491e223f42ff9cd9bdade2), [QDMI_JOB_STATUS_CANCELED](constants.html.md#constants_8h_1a04e5c793bcbe8b354a9223bb60f828a6a05163481e57725e91bb22ff798394f33), or [QDMI_JOB_STATUS_FAILED](constants.html.md#constants_8h_1a04e5c793bcbe8b354a9223bb60f828a6ab9b201ad1770dc23b9c1d4753e238d4f), or until the timeout is reached. Call [IQM_QDMI_device_job_check](#group__device__job__interface_1ga0c1816a53ce4c8599f7955a4a4b369f4) after a successful wait to distinguish terminal states. If `timeout` is not zero, this function returns latest after the specified number of seconds. 

* **Parameters:**
  * **job** – **[in]** The job to wait for. Must not be `NULL`. 
  * **timeout** – **[in]** The timeout in seconds. If this is zero, the function waits indefinitely for a terminal state. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the job reached any terminal state. 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if `job` is `NULL`. 
* **Returns:**
  [QDMI_ERROR_PERMISSIONDENIED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8ab875f28072043ad44f7ee5290bba8d01) if the device does not allow using the [device job interface](#group__device__job__interface) for the current session. 
* **Returns:**
  [QDMI_ERROR_TIMEOUT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8acf9abde59858a1087762ba3e287e9fdd) if `timeout` is not zero and the job did not reach a terminal state within the specified time. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if the job could not be waited for and this function returns before the job reached a terminal state. 

### int IQM_QDMI_device_job_get_results([IQM_QDMI_Device_Job](#_CPPv419IQM_QDMI_Device_Job) job, [size_t](_cpp_compat.html.md#_CPPv46size_t) program_index, [QDMI_Job_Result](constants.html.md#_CPPv415QDMI_Job_Result) result, [size_t](_cpp_compat.html.md#_CPPv46size_t) size, void \*data, [size_t](_cpp_compat.html.md#_CPPv46size_t) \*size_ret)

Retrieve one program’s results from a job. 

Results are available when the selected program has succeeded, even if other programs are still running, failed, or canceled. Devices exposing only aggregate outcomes provide results after the job reaches [QDMI_JOB_STATUS_DONE](constants.html.md#constants_8h_1a04e5c793bcbe8b354a9223bb60f828a6ad3dad6dd89491e223f42ff9cd9bdade2). 

#### NOTE
Calling this function with `data` set to `NULL` checks support and returns the required buffer size in `size_ret` when it is not `NULL`.

For example, to query the first program’s measurement results: 
```cpp
size_t size;
auto ret = [IQM_QDMI_device_job_get_results](#group__device__job__interface_1gab59e410f07258345dd8dafe913c7a66b)(
  job, 0, [QDMI_JOB_RESULT_SHOTS](constants.html.md#constants_8h_1aa154b942b0f67e437c393ad7b33cadd1ae878a5198fe5907bd3c7683a6ccaab97), 0, nullptr, &size);
std::string shots(size, '\0');
[IQM_QDMI_device_job_get_results](#group__device__job__interface_1gab59e410f07258345dd8dafe913c7a66b)(
  job, 0, [QDMI_JOB_RESULT_SHOTS](constants.html.md#constants_8h_1aa154b942b0f67e437c393ad7b33cadd1ae878a5198fe5907bd3c7683a6ccaab97), size, shots.data(), nullptr);
shots.pop_back();
```

* **Parameters:**
  * **job** – **[in]** The job to retrieve the results from. Must not be `NULL`. 
  * **program_index** – **[in]** The zero-based program index. Must be less than [QDMI_DEVICE_JOB_PROPERTY_PROGRAMSNUM](constants.html.md#constants_8h_1a6e4d18c7fa5d383bbcc1498abe090d4faa24add14b040fb44b0daac7f5714fafc). 
  * **result** – **[in]** The result to retrieve. Must be one of the values specified for [QDMI_Job_Result](constants.html.md#constants_8h_1a52254cd217f8627659a19c8e0c2feed6). 
  * **size** – **[in]** The size of the buffer pointed to by `data` in bytes. Must be greater than or equal to the size of the requested result, except when `data` is `NULL`, in which case it is ignored. 
  * **data** – **[out]** The buffer in which to store the result. If this is `NULL`, it is ignored. 
  * **size_ret** – **[out]** The required buffer size in bytes. If this is `NULL`, it is ignored. 
* **Returns:**
  [QDMI_SUCCESS](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a8039f5cd8202553b2a91a1c0b01d6751) if the device supports the specified result and, when `data` is not `NULL`, retrieved it successfully. 
* **Returns:**
  [QDMI_ERROR_NOTSUPPORTED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a327c1ff469cce7beacddd9c6d428b651) if the device does not support the specified result. 
* **Returns:**
  [QDMI_ERROR_BADSTATE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a916e0810bf915e2ad67f2c1430c54fec) if the selected program has not succeeded. 
* **Returns:**
  [QDMI_ERROR_OUTOFRANGE](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8ab6858000dc2e49368e3caba68054423c) if `program_index` is greater than or equal to the number of programs in the job. 
* **Returns:**
  [QDMI_ERROR_INVALIDARGUMENT](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a72b5274b4f2a76101255ac8409410642) if
  * `job` is `NULL`,
  * `result` is invalid, or
  * `data` is not `NULL` and `size` is too small. 
* **Returns:**
  [QDMI_ERROR_PERMISSIONDENIED](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8ab875f28072043ad44f7ee5290bba8d01) if the device does not allow using the [device job interface](#group__device__job__interface) for the current session. 
* **Returns:**
  [QDMI_ERROR_FATAL](constants.html.md#constants_8h_1a450b1adf81abc6f0accbf0ce4abe92f8a74b2c0dafe09d9c6d819751e1ec120d3) if an error occurred during retrieval.

### void IQM_QDMI_device_job_free([IQM_QDMI_Device_Job](#_CPPv419IQM_QDMI_Device_Job) job)

Free a job. 

Free the resources associated with a job. Using a job handle after it was freed is undefined behavior. Freeing a job handle does not necessarily cancel or delete the underlying job; this behavior is device-specific. 

* **Parameters:**
  **job** – **[in]** The job to free. 

## IQM calibration extension (`calibration.h`)

### int IQM_QDMI_device_job_submit_calibration([IQM_QDMI_Device_Job](#_CPPv419IQM_QDMI_Device_Job) job)

Submit an IQM calibration job. 

Create the job with IQM_QDMI_device_session_create_device_job and use IQM_QDMI_device_job_set_programs to set one program in QDMI_PROGRAM_FORMAT_IQMJSON containing the IQM Server calibration configuration as a JSON string with exactly one trailing NUL byte. The program format, shot count, and circuit-specific parameters are ignored. Calibration support is checked during session initialization.

On success, use the normal QDMI job check, wait, cancel, and free functions. QDMI_JOB_RESULT_CUSTOM1 returns the new calibration set ID and refreshes the session’s calibration data, invalidating previously queried operation handles. Program-format and shot-count queries return QDMI_ERROR_NOTSUPPORTED.

* **Parameters:**
  **job** – An unsubmitted job belonging to an initialized IQM session. 
* **Returns:**
  QDMI_SUCCESS if the job was submitted; QDMI_ERROR_INVALIDARGUMENT for a null job or an unset program; QDMI_ERROR_BADSTATE for a job that is not in QDMI_JOB_STATUS_CREATED; QDMI_ERROR_NOTSUPPORTED if calibration is unavailable or the job contains multiple programs; QDMI_ERROR_PERMISSIONDENIED for an authentication failure; QDMI_ERROR_OUTOFMEM for an allocation failure; QDMI_ERROR_FATAL otherwise.
