Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,31 @@ clients compiled against a different minor or major version.

## [Unreleased]

### Added

- ✨ Add descriptor-scoped execution-feature queries, exact descriptor equality,
and a format-defined program-output result ([#508]) ([\@simon1hofmann],
[\@burgholzer]).

### Changed

- 💥 Replace program-format enums with exact format descriptors, validate text
and binary payload framing, and place logical output slot zero at the right of
shot and histogram strings ([#508]) ([\@simon1hofmann], [\@burgholzer]).
- 💥 Treat every enum value from `999999995` through `INT32_MAX` as a valid
provider-defined value while keeping the intervening gap invalid ([#508])
([\@simon1hofmann], [\@burgholzer]).
- 💥 Require device libraries to export
`QDMI_device_session_retrieve_device_job_by_id`, while allowing the function
to return `QDMI_ERROR_NOTSUPPORTED` ([#508]) ([\@simon1hofmann],
[\@burgholzer]).

### Removed

- 💥 Remove calibration, batch-job, QPY, and IQM JSON values from the standard
program-format vocabulary. Providers can expose proprietary formats with a
namespaced descriptor ID ([#508]) ([\@simon1hofmann], [\@burgholzer]).

## [1.3.3] - 2026-08-19

_If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md#133)._
Expand Down Expand Up @@ -218,6 +243,7 @@ for previous changelogs._

<!-- PR links -->

[#508]: https://github.com/Munich-Quantum-Software-Stack/QDMI/pull/508
[#486]: https://github.com/Munich-Quantum-Software-Stack/QDMI/pull/486
[#485]: https://github.com/Munich-Quantum-Software-Stack/QDMI/pull/485
[#475]: https://github.com/Munich-Quantum-Software-Stack/QDMI/pull/475
Expand Down Expand Up @@ -266,6 +292,7 @@ for previous changelogs._

<!-- Contributors -->

[@simon1hofmann]: https://github.com/simon1hofmann
[@burgholzer]: https://github.com/burgholzer
[@ystade]: https://github.com/ystade
[@mnfarooqi]: https://github.com/mnfarooqi
Expand Down
128 changes: 128 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,134 @@ releases, please refer to the

## [Unreleased]

### Program-format execution features

QDMI replaces the program-format enum with an exact `QDMI_Program_Format`
descriptor. The descriptor contains an ID, packed Semantic Versioning release,
profile, and text or binary encoding. Devices list every accepted descriptor in
`QDMI_DEVICE_PROPERTY_SUPPORTEDPROGRAMFORMATS`. Clients must submit one of those
exact values and must not infer version compatibility. Descriptor identity is a
value contract: callers can reconstruct a canonical value and compare it with
`QDMI_program_format_equal`.

```c
const QDMI_Program_Format qasm3 = {
QDMI_MAKE_VERSION(3, 0, 0), QDMI_PROGRAM_ENCODING_TEXT, "openqasm", ""};
```

Text payloads contain exactly one trailing NUL and no earlier NUL; their size
includes that NUL. Binary payloads are nonempty arbitrary byte sequences.

QDMI reserves the unqualified IDs `openqasm` and `qir` for standard formats.
Vendor formats use `<vendor>.<custom-format-identifier>` IDs such as
`iqm.circuit`; the vendor component is not a reverse domain name.

Use the following replacements for the removed enum values:

| Removed value | `QDMI_Program_Format` replacement |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `QDMI_PROGRAM_FORMAT_QASM2` | `{QDMI_MAKE_VERSION(2, 0, 0), QDMI_PROGRAM_ENCODING_TEXT, "openqasm", ""}` |
| `QDMI_PROGRAM_FORMAT_QASM3` | `{QDMI_MAKE_VERSION(3, 0, 0), QDMI_PROGRAM_ENCODING_TEXT, "openqasm", ""}` |
| `QDMI_PROGRAM_FORMAT_QIRBASESTRING` | `{QDMI_MAKE_VERSION(1, 0, 0), QDMI_PROGRAM_ENCODING_TEXT, "qir", "base"}` |
| `QDMI_PROGRAM_FORMAT_QIRBASEMODULE` | `{QDMI_MAKE_VERSION(1, 0, 0), QDMI_PROGRAM_ENCODING_BINARY, "qir", "base"}` |
| `QDMI_PROGRAM_FORMAT_QIRADAPTIVESTRING` | `{QDMI_MAKE_VERSION(1, 0, 0), QDMI_PROGRAM_ENCODING_TEXT, "qir", "adaptive"}` |
| `QDMI_PROGRAM_FORMAT_QIRADAPTIVEMODULE` | `{QDMI_MAKE_VERSION(1, 0, 0), QDMI_PROGRAM_ENCODING_BINARY, "qir", "adaptive"}` |
| `QDMI_PROGRAM_FORMAT_QPY` | No standard replacement; providers must document a vendor-namespaced descriptor |
| `QDMI_PROGRAM_FORMAT_IQMJSON` | A provider-defined descriptor with a namespaced ID |
| `QDMI_PROGRAM_FORMAT_CALIBRATION` | No descriptor; use a provider extension to trigger calibration |
| `QDMI_PROGRAM_FORMAT_BATCHJOB` | No descriptor; QDMI v1 has no portable multi-program submission API |
| `QDMI_PROGRAM_FORMAT_CUSTOM1` through `CUSTOM5` | A provider-defined descriptor with a namespaced ID |
| `QDMI_PROGRAM_FORMAT_MAX` | No replacement |

QDMI defines no version, profile, wire, or result semantics for the removed QPY
and IQM JSON values. A provider can expose either format with a
vendor-namespaced descriptor and must document that descriptor and its payload
and result contract.

The QIR replacements above preserve the QIR 1.0 meaning of the removed enum
values. A current QIR 2.1 descriptor instead uses `QDMI_MAKE_VERSION(2, 1, 0)`.
The descriptor version identifies the QIR specification and is independent of
the version in a QIR output-schema stream.

Standard descriptors define exact mappings. They filter zone sites from
`QDMI_DEVICE_PROPERTY_SITES` and preserve the provider order of the remaining
regular sites. OpenQASM quantum instructions match a reported local operation by
name, qubit arity, and parameter arity. OpenQASM `q[i]` maps to the i-th regular
site, while OpenQASM 3 `$i` maps by `QDMI_SITE_PROPERTY_INDEX` to a regular
site. A QIR function named `__quantum__qis__NAME__body` matches the reported
local operation named `NAME`, with the same qubit and parameter arity.
Statically identified QIR qubits map by `QDMI_SITE_PROPERTY_INDEX` to regular
sites. A device that advertises QIR must assign the regular sites exactly the
index set `[0, N)`, where `N` is `QDMI_DEVICE_PROPERTY_QUBITSNUM`. Format- or
profile-mandated measurement, output, and runtime primitives do not need
corresponding operation records. The standard mappings do not define how a
payload selects a zoned operation.

The new `QDMI_device_session_query_program_features` device function and
`QDMI_device_query_program_features` client function query optional execution
features for one exact descriptor. A successful query returns the complete list
of optional `QDMI_Program_Feature` records. A successful empty query means that
only the format's normative baseline is supported. `QDMI_ERROR_NOTSUPPORTED`
means that feature metadata is unknown. Boolean features use value zero. Width
features, such as integer computation, use one feature group per supported
width. A standard descriptor does not imply support for every construct that its
source format can express.

Use `QDMI_PROGRAM_FEATURE_UNCONSTRAINED(id, value)` to initialize an
unrestricted feature without naming the constraint fields. Repeated records for
one feature and value add conjunctive typed constraints. QDMI initially defines
maximum control-flow nesting depth, loop iteration count, and multiway case
count. A client must treat a known feature group as unusable if any constraint
is unknown, malformed, duplicated, or not defined for that feature.

Device plugins and clients must use matching minor-version headers. A QDMI 1.3
client must not pass an enum value to a QDMI 1.4 device, and a QDMI 1.4 client
must not call the new query on a QDMI 1.3 device.

Calibration and batch submission are no longer program formats.
`QDMI_DEVICE_PROPERTY_NEEDSCALIBRATION` remains available, but QDMI does not
define a portable calibration trigger. QDMI v1 currently has no portable
multi-program submission API.

`QDMI_JOB_RESULT_SHOTS` and histogram keys now describe payload-declared flat
bit outputs. OpenQASM 2 uses `creg` declarations in source order. OpenQASM 3
uses explicit bit-valued outputs, or the language's implicit outputs when none
are declared. Both use increasing bit indices within each declaration. QIR uses
primitive result-recording call order. These rules assign logical slots from
zero. Strings write the highest slot first and slot zero at the right, so slot
values `[1, 0, 0]` produce `"001"`. The payload schema owns the slots; their
width and order are independent of device sites. Logical qubit zero remains the
least-significant basis bit for state and probability results. A provider
returns `QDMI_ERROR_NOTSUPPORTED` when an output cannot be represented
losslessly as a fixed-width bit string. `QDMI_JOB_RESULT_PROGRAMOUTPUT` returns
a format-defined output byte sequence when a flat bit result cannot represent
the payload result. A QIR specification that defines an output schema uses a
complete output-schema stream for every shot. Older QIR or provider-defined
descriptors can return `QDMI_ERROR_NOTSUPPORTED`. The byte sequence need not be
NUL-terminated.

On the client interface, job properties report the exact descriptor submitted by
the client. On the device interface, they report the descriptor executed by the
device. A translating driver must retain this mapping, including for job
retrieval, or reject retrieval with `QDMI_ERROR_NOTSUPPORTED`. A retrieved job
can report its historical descriptor after the device stops advertising that
descriptor.

Each QDMI enum with `CUSTOM` members reserves the inclusive range from
`999999995` through `INT32_MAX` for provider-defined values. The existing
`CUSTOM1` through `CUSTOM5` names remain aliases for the first five values.
Values between an enum's regular `MAX` member and `999999995` are invalid;
unrecognized values in the custom range are valid inputs that return
`QDMI_ERROR_NOTSUPPORTED`.

### Required device job retrieval symbol

Every QDMI 1.4 device library must export
`QDMI_device_session_retrieve_device_job_by_id`. A device that cannot retrieve
jobs by ID returns `QDMI_ERROR_NOTSUPPORTED` from the function. Drivers no
longer accept a missing symbol. Add a stub implementation before rebuilding an
older device library against the QDMI 1.4 headers.

## [1.3.3]

### Retrieving existing jobs by ID
Expand Down
1 change: 1 addition & 0 deletions cmake/prefix_defs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ QDMI_device_job_check
QDMI_device_job_wait
QDMI_device_job_get_results
QDMI_device_session_query_device_property
QDMI_device_session_query_program_features
QDMI_device_session_query_site_property
QDMI_device_session_query_operation_property
QDMI_Device_Session
Expand Down
2 changes: 2 additions & 0 deletions cmake/test_defs.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ int main() {
@QDMI_PREFIX@_QDMI_device_session_free(session);
@QDMI_PREFIX@_QDMI_device_session_set_parameter(session, QDMI_DEVICE_SESSION_PARAMETER_MAX, 0, nullptr);
@QDMI_PREFIX@_QDMI_device_session_create_device_job(session, &job);
@QDMI_PREFIX@_QDMI_device_session_retrieve_device_job_by_id(session, "", &job);
@QDMI_PREFIX@_QDMI_device_job_free(job);
@QDMI_PREFIX@_QDMI_device_job_set_parameter(job, QDMI_DEVICE_JOB_PARAMETER_MAX, 0, nullptr);
@QDMI_PREFIX@_QDMI_device_job_query_property(job, QDMI_DEVICE_JOB_PROPERTY_MAX, 0, nullptr, nullptr);
Expand All @@ -30,6 +31,7 @@ int main() {
@QDMI_PREFIX@_QDMI_device_job_wait(job, 0);
@QDMI_PREFIX@_QDMI_device_job_get_results(job, QDMI_JOB_RESULT_MAX, 0, nullptr, nullptr);
@QDMI_PREFIX@_QDMI_device_session_query_device_property(session, QDMI_DEVICE_PROPERTY_MAX, 0, nullptr, nullptr);
@QDMI_PREFIX@_QDMI_device_session_query_program_features(session, nullptr, 0, nullptr, nullptr);
@QDMI_PREFIX@_QDMI_device_session_query_site_property(session, site, QDMI_SITE_PROPERTY_MAX, 0, nullptr, nullptr);
@QDMI_PREFIX@_QDMI_device_session_query_operation_property(session, operation, 0, nullptr, 0, nullptr, QDMI_OPERATION_PROPERTY_MAX, 0, nullptr, nullptr);
}
26 changes: 26 additions & 0 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,32 @@ QDMI_Site pairs. The pairs are flattened into a single list of @ref QDMI_Site's.
\until DOXYGEN FUNCTION END
<!-- rumdl-enable -->

### Program-Format Execution Features {#device-program-format-features}

The @ref QDMI_device_session_query_program_features function reports atomic
execution features for one exact program-format descriptor. The following
example device reports two unrestricted OpenQASM features and forward branching
with a maximum nesting depth of one. Its QIR Base descriptors return a
successful empty list because they support no optional feature beyond the QIR
Base baseline.

<!-- rumdl-disable -->
\dontinclude cxx_device.cpp
\skipline QASM2_FEATURES{
\until };
\skip int CXX_QDMI_device_session_query_program_features
\until {
\until DOXYGEN FUNCTION END
<!-- rumdl-enable -->

Each @ref QDMI_Program_Feature record carries a feature ID, a feature-specific
value, and an optional typed constraint. Records for one feature and value form
one conjunctive group. An empty constraint ID means unrestricted support. Use
@ref QDMI_PROGRAM_FEATURE_UNCONSTRAINED to initialize such a record. Unknown or
malformed constraints make the group unusable. The returned list is complete.
Returning @ref QDMI_ERROR_NOTSUPPORTED keeps feature metadata unknown.
Requirements guaranteed by a standard descriptor remain implicit.

### Complex Properties {#device-complex}

The properties that are returned by @ref
Expand Down
Loading
Loading