Configuring the builtin MQT Core QDMI driver

The configuration format on this page belongs to the builtin MQT Core QDMI driver. Other QDMI drivers may use different configuration and discovery mechanisms. MQT Core’s C++ and Python Session and open_device APIs use the standard QDMI Client Interface with any compatible driver library; they do not require this manifest format or the MQT Core driver’s private extensions.

The builtin driver discovers device manifests: versioned JSON files that map stable IDs to device libraries and session settings. The driver uses a manifest to find a device when an application opens it by ID. Discovery only parses metadata. When a session initializes, the driver opens the configured native libraries. builtin_driver.open_device opens only the requested device.

This lets applications list installed devices without loading device libraries or contacting services. They can then open one device by stable ID. Distinct IDs can select independently configured instances of the same library.

Warning

QDMI configuration is a native-code loading trust boundary. Use configuration files and device libraries only from trusted sources. Project discovery starts at the current working directory and searches its parent directories. Before you process an untrusted checkout, set MQT_CORE_QDMI_CONFIG_FILE to an administrator-controlled file or use a working directory outside that checkout. The explicit file replaces system, user, and project discovery but retains packaged device definitions. Treat MQT_CORE_QDMI_CONFIG_JSON as trusted input too.

Device definitions

The following qdmi.json registers one device:

{
  "schema-version": 1,
  "qdmi": {
    "devices": [
      {
        "id": "example.device",
        "library": "libexample-device.so",
        "prefix": "EXAMPLE",
        "enabled": true,
        "session": {
          "base-url": "https://device.example",
          "auth-file": "credentials.json",
          "device-config": {
            "file": "device.json"
          }
        }
      }
    ]
  }
}

The driver returns the configured id through QDMI_DEVICE_PROPERTY_ID, overriding any device-reported default. Child-device IDs remain optional; the driver forwards a reported ID or QDMI_ERROR_NOTSUPPORTED without generating child IDs.

Every enabled definition requires a stable, unique id, a library, and a QDMI symbol prefix. The session object supports base-url, token, auth-file, auth-url, username, password, device-config, and custom1 through custom5.

device-config selects exactly one device configuration source:

{"device-config": {"inline": {"schema-version": 1}}}

or:

{"device-config": {"file": "device.json"}}

The inline value must be a JSON object. A relative file path is resolved against the registry file that declares it. The complete source is one merge field: changing from inline to file at a higher-precedence layer replaces the inherited inline JSON. The MQT Core driver adapts inline JSON to QDMI v1 CUSTOM1 and a file path to CUSTOM2 when opening the native session. Consequently, device-config cannot be combined with raw custom1 or custom2; CUSTOM3 through CUSTOM5 remain available to device implementations.

Relative library and authentication-file paths are resolved against the file that declared them. For MQT_CORE_QDMI_CONFIG_JSON, they resolve against the current working directory.

Unknown keys, invalid types, duplicate IDs within one source, unsupported schema versions, and incomplete enabled definitions are hard errors. Diagnostics name the source and configuration path. Credentials and session values are not included in Driver warnings.

Discovery and precedence

Definitions are merged field by field by ID, from lowest to highest precedence:

  1. generated *.qdmi.json fragments packaged beside the MQT Core Driver and trusted manifests staged by installed packages;

  2. the system qdmi.json;

  3. the user or XDG qdmi.json;

  4. the nearest project qdmi.json;

  5. MQT_CORE_QDMI_CONFIG_JSON.

On Unix, file configuration uses /etc/mqt-core/qdmi.json and then ${XDG_CONFIG_HOME}/mqt-core/qdmi.json, falling back to ${HOME}/.config/mqt-core/qdmi.json. On Windows, it uses the corresponding mqt-core/qdmi.json files below PROGRAMDATA and APPDATA.

An entry containing only its ID and "enabled": false masks an inherited definition. Since definitions are merged field by field, a later definition with the same ID must explicitly set "enabled": true to enable it again. The final disabled ID remains reserved, so fallback registration cannot silently re-enable a device that an administrator disabled.

MQT_CORE_QDMI_CONFIG_FILE replaces the system, user, and project levels while retaining packaged built-ins.

Installed device manifests

Python distributions advertise the module containing their device manifests:

[project.entry-points]
"mqt.core.qdmi.manifests".vendor = "vendor.qdmi"

The entry-point name identifies the device implementation. Its value is a module path, not a function to import. MQT Core reads the distribution’s installed file list and registers the *.qdmi.json files below that module. Discovery imports no device modules and loads no device libraries. Invalid entries emit a warning and are skipped. Installed manifests form the lowest-precedence configuration layer.

Applications can register a manifest explicitly when a missing or invalid file must stop startup:

from mqt.core.qdmi import builtin_driver

builtin_driver.add_manifest("vendor/device/example.qdmi.json")

Register manifests before listing or opening devices with the MQT Core QDMI driver. Registering the same file again is harmless; conflicting IDs in distinct manifests are errors. Configuration becomes immutable when the driver first reads the catalogue, either for enumeration or for opening a device.

builtin_driver always uses the builtin MQT Core QDMI driver, independently of MQT_CORE_QDMI_DRIVER. Standard Session and open_device calls honor that environment variable.

Using configured devices

List enabled stable IDs without loading device libraries or contacting devices:

from mqt.core.qdmi import builtin_driver

print(builtin_driver.registered_device_ids())

The list includes configured devices that are unavailable or need credentials. Use builtin_driver.open_device(device_id, ...) to open only the selected device. MQT Core supplies mqt.ddsim.default for local execution. Other configured IDs may refer to simulator or compilation-only devices, including the models described in Superconducting QDMI device.

With the MQT Core driver, standard Session enumeration initializes configured devices and skips those that fail to open. Another driver may present a different device list and configuration behavior.

Set MQT_CORE_QDMI_CONFIG_FILE or MQT_CORE_QDMI_CONFIG_JSON before the first driver call. Every open_device() call creates a fresh driver session and finds the stable ID in the session’s device list. The returned Device and any Site, Operation, or Job wrapper derived from it keeps that driver session alive. The session is released after the last such wrapper is destroyed.

The equivalent C++ API is qdmi::Session. getDevices() enumerates the devices of one authenticated session. qdmi::Session::openDevice creates a fresh session and opens one enumerated ID.

Multiple definitions may refer to the same library and prefix. MQT Core reuses the initialized library while creating a fresh QDMI device session, with its own session parameters, for every definition.

Native applications

The Python wheel supplies a runtime CMake package for the builtin driver, QDMI devices, and tools. Use MQT::CoreQDMIDriver to link the QDMI C client interface; see C++ libraries and API reference for a complete example.

The C++ QDMI wrapper requires a source installation. Request its Development component and copy the driver and selected devices beside your application:

find_package(mqt-core CONFIG REQUIRED COMPONENTS Development)
add_executable(my-application main.cpp)
target_link_libraries(my-application PRIVATE MQT::CoreQDMI)
mqt_copy_qdmi_runtime(my-application MQT::CoreQDMIScDevice MQT::CoreQDMI_DDSIM_Device)

The helper copies each library and its declared bundle files, including manifests, configuration files, and the DDSIM worker. Builtin devices statically link their implementation dependencies. Keep each bundle together when moving it; supported platform runtimes are still required. The application uses its build RPATH during the build.

Manifests contain library filenames relative to their own directory. Keep each manifest beside its device library when moving an installation. The MQT Core QDMI driver discovers manifests beside itself; an explicit MQT_CORE_QDMI_CONFIG_FILE can instead select devices installed elsewhere.

Inside a Core build, omitting the device list copies all devices registered through mqt_configure_qdmi_device. An installed consumer selects the exported targets it needs, as above.

An external device implementation needs no Core build dependency. QDMI’s CMake helper exports the stable ID and symbol prefix as target metadata:

configure_qdmi_device_target(TARGET example-device ID example.device PREFIX EXAMPLE)

For such a target, mqt_copy_qdmi_runtime generates the manifest. Targets with an existing manifest can export QDMI_MANIFEST_NAME instead. Additional files listed in QDMI_RUNTIME_FILES are copied from the device library’s directory. Providers must declare any companion files their device needs; the helper does not discover transitive shared-library dependencies.