Amazon Braket lowering and execution bridge for the Resonant Quantum Mechanics (RQM) ecosystem.
rqm-braket receives compiler-optimized circuit representations from
rqm-compiler and translates them into Amazon Braket circuit and task objects,
then executes them on:
- the Amazon Braket Local Simulator
- AWS Braket quantum devices
This package is a backend adapter / execution bridge, not a compiler, not a
math engine, and not the owner of the public circuit schema. The canonical
external circuit IR lives in rqm-circuits; optimization logic lives in
rqm-compiler. rqm-braket is the final, AWS-facing step in that pipeline.
This project uses quaternions because they preserve more of what physical systems are doing: phase, rotation, orientation, polarization, and coherence. Standard complex-number methods are powerful, but they can flatten these relationships too early. Quaternionic coordinates keep them together as one structured object, giving software a richer view of the measured system.
For RQM Technologies, better coordinates mean better measurement: more informative diagnostics, cleaner transformations, and more precise control across quantum, wave, sensing, imaging, and communications workflows.
The RQM software stack is intentionally layered:
rqm-docs
|
-------------------------------------------
| | |
rqm-core rqm-circuits rqm-notebooks
|
rqm-compiler
|
----------------------
| |
rqm-qiskit rqm-braket
| |
└────────────────────┘
|
rqm-optimize (optional)
|
rqm-api
|
RQM Studio
| Layer | Responsibility |
|---|---|
rqm-core |
Canonical math (quaternion, spinor, Bloch, SU(2)) |
rqm-circuits |
Canonical external / public circuit IR — the shared schema for Studio, API, and inter-service communication |
rqm-compiler |
Parse, optimize, and rewrite circuits in an internal model; produce backend-ready instruction sequences |
rqm-braket |
Lower compiler output into Amazon Braket objects; execute on local simulator or AWS devices |
rqm-qiskit |
Lower compiler output into Qiskit objects; execute on IBM / Qiskit devices |
rqm-optimize |
Optional backend-adjacent optimization / compression (post-compiler, pre-execution) |
rqm-api |
REST API layer exposing backends to RQM Studio |
rqm-notebooks |
Examples, demos, tutorials |
The typical data flow from an external caller through to execution is:
RQM Studio / API caller
│ (rqm-circuits payload)
▼
rqm-circuits ← public/external circuit schema lives here
│ (parsed & validated)
▼
rqm-compiler ← optimization, rewriting, instruction lowering
│ (compiler-internal circuit or descriptor list)
▼
rqm-braket ← Braket lowering & execution (this package)
│ (Braket Circuit + task)
▼
Amazon Braket / AWS
External callers (RQM Studio, rqm-api) originate from rqm-circuits
payloads. rqm-compiler validates and optimizes those payloads.
rqm-braket only sees the compiler-produced output — it does not parse
or own the public wire format.
If rqm-braket exposes helper functions that accept compiler Circuit
objects or descriptor lists directly (e.g. run_descriptors, to_backend_circuit),
those helpers assume upstream parsing and validation have already happened.
rqm-braket provides five core capabilities:
Convert compiled programs into Braket Circuit objects.
compiled_program → Braket Circuit
Handled by:
BraketTranslator
compile_to_braket_circuit(...)
Run circuits on:
- Local simulator (offline-safe)
- AWS Braket devices (synchronous — blocks until complete)
Circuit → execution → BraketResult
Handled by:
run_local(...)
run_device(...)
BraketBackend
Submit jobs without blocking and poll for results later:
Circuit → submit → task_arn → poll status → retrieve result
Handled by:
run_device_async(...) → task ARN
get_task_status(arn) → "QUEUED" / "RUNNING" / "COMPLETED" / ...
get_task_result(arn) → BraketResult
List available AWS Braket devices:
from rqm_braket import list_devices
simulators = list_devices(device_types=["SIMULATOR"])
qpu_devices = list_devices(device_types=["QPU"])
all_devices = list_devices()Returns JSON-serializable dicts with deviceArn, deviceName,
deviceType, status, and providerName.
Execute directly from canonical descriptors (JSON output of
rqm_compiler.Circuit.to_descriptors()):
from rqm_braket import run_descriptors
descriptors = [
{"gate": "h", "targets": [0], "controls": [], "params": {}},
{"gate": "cx", "targets": [1], "controls": [0], "params": {}},
]
result = run_descriptors(descriptors, shots=200)
print(result.counts)This is the primary API entry point for rqm-api / RQM Studio.
Note: In production, descriptor lists originate from
rqm-circuitspayloads that have been parsed and optimized byrqm-compilerupstream.rqm-braketreceives the compiler-produced output and does not validate the public wire format itself.
Normalize Braket outputs into a simple interface:
result.counts
result.probabilities
result.shots
result.most_likely_bitstring()
result.to_dict() # base fields
result.to_dict(include_probabilities=True) # + probabilities
result.to_dict(include_task_id=True) # + task ARN
result.to_dict(include_status=True) # + task statusrqm-braket exposes thin bridge functions for users who want to prepare
quantum states without going through the compiler first.
These bridges are not the primary API.
For production use, prefer the compiler-first path.rqm-compiler → compiled_program → backend.run(...)Bridges are intended for students, quick experiments, and direct state preparation. All underlying mathematics is handled by
rqm-core.
Prepares the qubit state |ψ⟩ = α|0⟩ + β|1⟩ from the given spinor.
Bloch-sphere math is delegated to rqm_core.state_to_bloch.
import math
from rqm_braket import spinor_to_circuit
s = 1 / math.sqrt(2)
circuit = spinor_to_circuit(s, s) # prepares |+⟩Prepares the qubit state parameterized by Bloch-sphere polar angles.
import math
from rqm_braket import bloch_to_circuit
circuit = bloch_to_circuit(math.pi / 2, 0.0) # prepares |+⟩The Quaternion class from rqm-core is re-exported for user convenience.
All quaternion mathematics lives in rqm-core.
from rqm_braket import Quaternion
q = Quaternion.from_axis_angle("z", math.pi / 2)| Capability | Description |
|---|---|
| Braket lowering | Translation of compiler output into Amazon Braket Circuit / task objects |
| Backend execution helpers | run_local, run_device, run_device_async |
| AWS / Braket device integration | Device discovery, task submission, status polling |
| Result normalization | BraketResult wrapper around Braket task outputs |
| Concern | Owner |
|---|---|
| Quaternion / SU(2) math | rqm-core |
| Spinor normalization | rqm-core |
| Bloch sphere conversions | rqm-core |
| Canonical external circuit schema | rqm-circuits |
| Optimization pass design | rqm-compiler |
| Internal circuit compilation logic | rqm-compiler |
| API wire format | rqm-circuits / rqm-api |
| Studio payload format | rqm-circuits / rqm-api |
The rule: rqm-braket may call math and compiler APIs, but never define them.
pip install rqm-braketDevelopment install:
pip install -e .from rqm_braket import BraketBackend, RQMGate
program = [
RQMGate("H", target=0),
RQMGate("CNOT", control=0, target=1),
]
backend = BraketBackend()
result = backend.run_local(program, shots=1000)
print(result.counts)rqm-braket supports multiple entry points depending on your audience and use case.
rqm-circuits → rqm-compiler → compiled_program → backend.run(...)
from rqm_braket import BraketBackend, RQMGate
backend = BraketBackend()
result = backend.run_local([
RQMGate("H", target=0),
RQMGate("CNOT", control=0, target=1),
], shots=500)
print(result.counts)Intended for: researchers, engineers, production workflows.
Note: In a full stack flow, the gate sequence originates as an
rqm-circuitspayload, is parsed and optimized byrqm-compiler, and the compiler's output is then passed intorqm-braket. UsingRQMGatedirectly (as above) is fine for direct scripting and experiments.
rqm-circuits → rqm-compiler → descriptors (JSON) → run_descriptors(...)
from rqm_braket import run_descriptors
descriptors = [
{"gate": "h", "targets": [0], "controls": [], "params": {}},
{"gate": "cx", "targets": [1], "controls": [0], "params": {}},
]
result = run_descriptors(descriptors, shots=200)
print(result.to_dict(include_probabilities=True))Intended for: the rqm-api layer and RQM Studio integration.
Note: Descriptor lists are the compiler-internal format produced by
rqm_compiler.Circuit.to_descriptors(). In Studio / API workflows the original circuit is expressed inrqm-circuitsformat and is parsed and optimized byrqm-compilerbefore descriptors reachrqm-braket.
run_device_async(...) → task_arn → get_task_status(arn) → get_task_result(arn)
from rqm_braket import run_device_async, get_task_status, get_task_result
task_arn = run_device_async(
program,
device_arn="arn:aws:braket:::device/quantum-simulator/amazon/sv1",
s3_folder=("my-bucket", "results"),
shots=100,
)
status = get_task_status(task_arn)
print(status) # "QUEUED", "RUNNING", "COMPLETED", ...
if status == "COMPLETED":
result = get_task_result(task_arn)
print(result.counts)Intended for: long-running QPU jobs where blocking is undesirable.
spinor_to_circuit(...)
bloch_to_circuit(...)
import math
from rqm_braket import spinor_to_circuit, bloch_to_circuit, run_local
# From a spinor
s = 1 / math.sqrt(2)
circuit = spinor_to_circuit(s, s)
result = run_local(circuit, shots=200)
print(result.counts)
# From Bloch angles
circuit = bloch_to_circuit(math.pi / 2, 0.0)
result = run_local(circuit, shots=200)
print(result.counts)Intended for: students, tutorials, quick experiments.
All quantum mathematics (Bloch conversion, spinor normalization) is delegated to
rqm-core.rqm-braketonly maps the results to gates.
RQM Studio communicates with rqm-api, which calls into rqm-braket.
The recommended call pattern is:
- Design circuit in RQM Studio UI → expressed as an
rqm-circuitspayload. - Compile via
rqm-compiler→ validates, optimizes, and produces descriptors. - Choose device via
GET /v1/devices→ callslist_devices(). - Submit job via
POST /v1/run/async→ callsrun_device_async(...), returnstask_arn. - Poll status via
GET /v1/tasks/<task_arn>/status→ callsget_task_status(task_arn). - Retrieve result via
GET /v1/tasks/<task_arn>/result→ callsget_task_result(task_arn). - Visualize result in RQM Studio UI.
For synchronous (blocking) local or device runs use POST /v1/run.
rqm-braket only participates from step 4 onward. The public circuit schema
and wire format belong to rqm-circuits; rqm-braket receives already-
compiled / already-validated data.
from flask import Flask
from rqm_braket.api import api_blueprint
app = Flask(__name__)
app.register_blueprint(api_blueprint, url_prefix="/v1")from rqm_braket import list_devices
# List all simulators
simulators = list_devices(device_types=["SIMULATOR"])
# List all QPUs
qpus = list_devices(device_types=["QPU"])
# RQM Studio can display these to the user for device selectionrqm-braket uses the standard AWS credential chain. Configure via:
aws configure(CLI)- Environment variables (
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_DEFAULT_REGION) - IAM roles (recommended for production)
Never store AWS credentials in code.
Device execution requires an S3 bucket for Braket to store task results.
For large circuits or production deployments, use a dedicated S3 bucket and
prefix managed by rqm-api to consolidate result storage across jobs.
result = run_descriptors(
descriptors,
backend="device",
device_arn="arn:aws:braket:us-east-1::device/qpu/ionq/Harmony",
s3_folder=("your-braket-bucket", "rqm-results"),
shots=1000,
)from rqm_braket import compile_to_braket_circuit, RQMGate
program = [
RQMGate("RX", target=0, angle=1.57),
]
circuit = compile_to_braket_circuit(program)
print(circuit)examples/basic_local_simulator.py
examples/bell_state_demo.py
examples/compiled_program_demo.py
api_blueprint # Flask Blueprint — mount in rqm-api Flask applicationMount in your rqm-api application:
from flask import Flask
from rqm_braket.api import api_blueprint
app = Flask(__name__)
app.register_blueprint(api_blueprint, url_prefix="/v1")Endpoints exposed:
| Method | Path | Description |
|---|---|---|
POST |
/v1/run |
Execute circuit synchronously (local or device backend) |
POST |
/v1/run/async |
Submit circuit to AWS Braket device; returns task_arn |
GET |
/v1/tasks/<task_arn>/status |
Poll task state (QUEUED, RUNNING, COMPLETED, …) |
GET |
/v1/tasks/<task_arn>/result |
Retrieve result of completed task |
GET |
/v1/devices |
List available AWS Braket devices |
Install the optional [api] extra to pull in Flask:
pip install rqm-braket[api]BraketBackend # unified backend object
BraketTranslator # compile programs → Braket Circuit
RQMGate # typed gate descriptor
compile_to_braket_circuit # convenience translation
run_local # execute on local simulator (offline-safe)
run_device # execute on AWS Braket device (synchronous)
BraketResult # result wrapperrun_device_async # submit job → task ARN (non-blocking)
get_task_status # query task state ("QUEUED" / "RUNNING" / ...)
get_task_result # retrieve BraketResult for completed tasklist_devices # list available AWS Braket devicesrun_descriptors # translate descriptors + execute (API-ready)BraketDeviceError # raised for device/task failures (RuntimeError subclass)spinor_to_circuit # spinor (α, β) → Braket Circuit
bloch_to_circuit # Bloch angles (θ, φ) → Braket Circuit
Quaternion # re-exported from rqm-coreresult = run_local(program, shots=100)No AWS credentials required.
result = run_device(
program,
device_arn="arn:aws:braket:...",
s3_folder=("bucket", "prefix"),
shots=100
)Requires standard AWS + Braket configuration.
task_arn = run_device_async(
program,
device_arn="arn:aws:braket:...",
s3_folder=("bucket", "prefix"),
shots=100,
)
status = get_task_status(task_arn) # "QUEUED", "RUNNING", "COMPLETED", ...
result = get_task_result(task_arn) # BraketResult (blocks until done)result = run_descriptors(
descriptors,
shots=100,
backend="local", # or "device"
)Run tests:
pytestAll tests are:
- offline-safe
- no AWS credentials required
- include mocked cloud execution
rqm-braket does not implement canonical quantum mathematics.
All physics and math operations are delegated to rqm-core:
rqm-core = physics + math
rqm-circuits = public/external circuit schema
rqm-compiler = optimization + internal instruction model
rqm-braket = Braket lowering + execution
The rule: rqm-braket may call math and compiler APIs, but never define them.
rqm-braket is intentionally minimal:
- no duplicated logic
- no second IR
- no math reimplementation
- no redefinition of the public circuit schema
Direct inputs to rqm-braket come from:
rqm-compiler
The full upstream path is:
rqm-circuits (public schema)
↓
rqm-compiler (optimization / internal IR)
↓
rqm-braket (Braket lowering + execution)
This ensures:
- backend independence
- clean separation of concerns
- extensibility to new platforms
rqm-braketnever owns or parses the public wire format
Because the compiler produces a canonical instruction format:
rqm-compiler → rqm-qiskit
rqm-compiler → rqm-braket
rqm-compiler → future backends
Current version: 0.2.0
This release introduces:
- compiler-based architecture
BraketBackendabstraction- clean translation/execution separation
- async execution (
run_device_async,get_task_status,get_task_result) - device discovery (
list_devices) - descriptor-first execution (
run_descriptors) - extended result serialization (
BraketResult.to_dictoptional extras) BraketDeviceErrorfor friendly error handling- backward-compatibility shims (deprecated)
Future improvements may include:
- parameter binding support via Braket
FreeParameter(TODO: propose adding parametric circuit support torqm-coreorrqm-compiler) - batched execution
- hybrid Braket workflows
- richer result analysis
- multi-qubit optimization paths
- S3 result storage managed by
rqm-api
Apache License 2.0
Copyright (c) RQM Technologies