Quantum platforms sit inside a fast-moving ecosystem of languages, intermediate representations, cloud APIs, provider SDKs, simulators, control systems, and research tools. Without interface discipline, every experiment becomes a custom integration and every migration becomes a rewrite.
This chapter focuses on how to design for portability without pretending that all quantum backends are interchangeable. OpenQASM 3 and QIR are two important ecosystem interfaces already discussed in this book. QIR is documented as a hardware-agnostic LLVM-based intermediate representation and a common interface between quantum programming languages/frameworks and target platforms [R37], and the QIR Alliance specification defines an LLVM-based intermediate representation for quantum programs [R61].
31.1 Interface stack
View diagram source
flowchart TB
App[Application intent] --> Domain[Domain model]
Domain --> Algorithm[Algorithm layer]
Algorithm --> Circuit[Circuit / program representation]
Circuit --> IR[Intermediate representation]
IR --> Compiler[Compiler / transpiler]
Compiler --> Target[Target contract]
Target --> Provider[Provider API]
Provider --> Hardware[Hardware / simulator]The boundary between layers should be explicit. Hidden coupling makes portability fragile.
31.2 Portability is graded, not binary
A workload can be portable at one layer and non-portable at another.
View diagram source
flowchart LR
Source[Source code portability] --> Circuit[Circuit portability]
Circuit --> IR[IR portability]
IR --> Target[Target portability]
Target --> Result[Result portability]Portability levels:
| Level | Meaning |
|---|---|
| L0 | provider-specific script |
| L1 | same source, different simulator |
| L2 | same circuit family, provider-specific compilation |
| L3 | shared IR with target-specific lowering |
| L4 | portable service API with provider-specific execution hidden |
| L5 | validated result portability across providers |
L5 is rare. Do not require it for all workloads. Require clarity about which level is being claimed.
31.3 Target contracts
A target contract describes what a backend can accept and what the compiler may assume.
View diagram source
classDiagram
class TargetContract {
string backend_id
string modality
string[] native_gates
string connectivity
int max_shots
int max_circuits
string timing_model
string measurement_model
string quality_snapshot
}
class CompilerPolicy {
int optimization_level
string layout_strategy
bool dynamic_circuits
bool mitigation_allowed
}
TargetContract --> CompilerPolicyTarget contracts should include:
| Field | Why it matters |
|---|---|
| native operations | determines decomposition |
| connectivity | determines routing overhead |
| timing constraints | affects scheduling and crosstalk |
| measurement support | affects dynamic circuits and feedback |
| shot limits | affects batching |
| result format | affects aggregation and trust reports |
| calibration snapshot | binds execution to device state |
31.4 Adapter pattern
Provider adapters should isolate platform internals from vendor APIs.
View diagram source
flowchart LR
Platform[Internal platform API] --> Adapter[Provider adapter]
Adapter --> IBM[IBM Quantum]
Adapter --> AWS[Amazon Braket]
Adapter --> Azure[Azure Quantum]
Adapter --> Other[Other provider]
Adapter --> Simulator[Internal simulator]Adapter responsibilities:
| Responsibility | Description |
|---|---|
| translate job request | internal schema to provider API |
| validate limits | reject impossible jobs before submission |
| normalize result | provider result to internal result schema |
| attach metadata | target, version, queue, cost, calibration |
| handle retries | provider-specific transient failures |
| preserve raw artifacts | support audit and debugging |
31.5 Conformance tests
Every adapter should pass conformance tests. Otherwise the same workload means different things on different targets.
View diagram source
flowchart TB
TestSuite[Conformance suite] --> AdapterA[Adapter A]
TestSuite --> AdapterB[Adapter B]
TestSuite --> AdapterC[Adapter C]
AdapterA --> Report[Conformance report]
AdapterB --> Report
AdapterC --> ReportConformance test categories:
| Category | Example |
|---|---|
| schema validation | missing fields, illegal shot counts |
| circuit semantics | simple gates and measurements |
| parameter binding | parameterized circuits and repeated execution |
| result normalization | counts, quasi-probabilities, metadata |
| error handling | queue failures, provider errors, timeouts |
| provenance | raw provider IDs and versions retained |
31.6 Versioning strategy
Quantum interfaces change quickly. Versioning must cover schemas, compilers, adapters, circuits, algorithms, and trust reports.
View diagram source
flowchart LR
Schema[Schema version] --> Bundle[Experiment bundle]
Compiler[Compiler version] --> Bundle
Adapter[Adapter version] --> Bundle
Algorithm[Algorithm version] --> Bundle
Target[Target contract version] --> Bundle
Bundle --> Reproduce[Reproduction attempt]Versioning rules:
- never overwrite a schema without a migration path,
- store compiler and provider versions with every run,
- keep raw provider responses,
- hash circuit artifacts,
- record random seeds where relevant,
- make trust report versions explicit.
31.7 Standards watch process
A standards watch is not passive reading. It is a process that turns ecosystem changes into platform decisions.
View diagram source
flowchart TB
Watch[Monitor standards and SDKs] --> Impact[Impact analysis]
Impact --> Decision{Action needed?}
Decision -- no --> Record[Record no-op]
Decision -- yes --> RFC[Platform RFC]
RFC --> Implement[Implement migration]
Implement --> Deprecate[Deprecate old interface]Watch items:
| Area | Examples |
|---|---|
| languages | OpenQASM, Q#, Python SDKs |
| IR | QIR and compiler representations |
| cloud APIs | job, result, identity, quota changes |
| security | PQC standards, cloud IAM, artifact signing |
| telemetry | OpenTelemetry conventions and internal schemas |
| hardware | target metadata, calibration data, dynamic control support |
31.8 Vendor-neutral internal vocabulary
Teams should maintain internal vocabulary that maps provider-specific terms into stable platform concepts.
View diagram source
flowchart LR
ProviderTerms[Provider-specific terms] --> Glossary[Internal glossary]
Glossary --> Schemas[Internal schemas]
Schemas --> Reports[Trust reports]
Reports --> Users[Users]Example mapping:
| Internal concept | Provider-specific examples |
|---|---|
| target | backend, device, QPU, simulator |
| workload | job, task, circuit batch, experiment |
| execution group | session, batch, hybrid job, reservation |
| quality snapshot | calibration, properties, benchmark snapshot |
| result bundle | counts, samples, quasi-probabilities, observables |
31.9 Avoiding lowest-common-denominator design
Portability does not mean hiding every special capability. Some targets have distinctive features. A strong platform exposes capabilities through negotiated contracts.
View diagram source
flowchart TB
Workload[Workload request] --> Required[Required capabilities]
Required --> Match[Target matching]
Match --> Common[Common path]
Match --> Specialized[Specialized path]
Specialized --> Evidence[Evidence notes capability dependency]Design principle:
Use portable abstractions for governance and evidence; use target-specific capabilities when they materially improve results and are recorded as dependencies.
31.10 Chapter checklist
Interface strategy should include:
- layered interface map,
- portability-level definitions,
- target contract schema,
- provider adapter interface,
- adapter conformance tests,
- schema versioning policy,
- standards watch process,
- vendor-neutral glossary,
- capability negotiation.
View diagram source
flowchart LR
Contracts[Contracts] --> Strategy[Interface strategy]
Adapters[Adapters] --> Strategy
Tests[Conformance tests] --> Strategy
Versions[Versions] --> Strategy
Watch[Standards watch] --> Strategy