Python SDK
This is the Python-SDK for using the Q-Alchemy API which helps quantum computing researchers to put classical data into the quantum computer. This is all also called: the loading problem, encoding problem, or quantum state preparation. Some people also call it a form of QRAM, or quantum random-access memory.
Under the hood, Q-Alchemy runs on PineXQ, the hypermedia (Siren) API platform of data cybernetics. You do not need to know anything about it to use this SDK; if you want to work with the API directly, see the PineXQ documentation.
pip install q-alchemy-sdk-pypdm add q-alchemy-sdk-pyuv add q-alchemy-sdk-pyFor a complete environment setup, API-key configuration, and a first preparation with local verification, follow the getting-started guide.
The examples below use a fixed two-qubit state and read Q_ALCHEMY_API_KEY from your environment. Install the relevant integration before running them:
python -m pip install "q-alchemy-sdk-py[qiskit]"python -m pip install "q-alchemy-sdk-py[pennylane]"Direct Example
Section titled “Direct Example”import osimport numpy as npfrom q_alchemy.initialize import q_alchemy_as_qasm
state = np.array([1, 0, 0, 1], dtype=complex) / np.sqrt(2)qasm, summary = q_alchemy_as_qasm( state, max_fidelity_loss=0.0, api_key=os.environ["Q_ALCHEMY_API_KEY"], return_summary=True,)print(qasm)print(summary)Qiskit Example
Section titled “Qiskit Example”import osimport numpy as npfrom qiskit.quantum_info import Statevector, state_fidelityfrom q_alchemy.qiskit_integration import QAlchemyInitialize, OptParams
state = np.array([1, 0, 0, 1], dtype=complex) / np.sqrt(2)prep = QAlchemyInitialize( params=state.tolist(), opt_params=OptParams( max_fidelity_loss=0.0, api_key=os.environ["Q_ALCHEMY_API_KEY"], ),).definitionprint(prep.draw(output="text"))fidelity = state_fidelity(Statevector.from_instruction(prep), Statevector(state))print(f"Local simulation fidelity: {fidelity:.6f}")PennyLane Example
Section titled “PennyLane Example”import osimport numpy as npimport pennylane as qmlfrom q_alchemy.pennylane_integration import QAlchemyStatePreparation, OptParams
state = np.array([1, 0, 0, 1], dtype=complex) / np.sqrt(2)dev = qml.device("default.qubit", wires=2)
@qml.qnode(dev)def circuit(): QAlchemyStatePreparation( state, wires=[0, 1], opt_params=OptParams( max_fidelity_loss=0.0, api_key=os.environ["Q_ALCHEMY_API_KEY"], ), ) return qml.probs(wires=[0, 1])
print(circuit()) # Expected approximately [0.5, 0.0, 0.0, 0.5]This example explicitly synthesizes a Q-Alchemy preparation and runs it on a local simulator.
Broadcasting with PennyLane
Section titled “Broadcasting with PennyLane”PennyLane provides native support for broadcasting, which allows quantum nodes to process batches of inputs efficiently. This is particularly useful in machine learning applications where inputs often come in batches. When broadcasting is used in conjunction with Q-Alchemy, each state in the batch is individually prepared using Q-Alchemy’s circuit synthesis capabilities.
Broadcasting Example with qiskit.aer
Section titled “Broadcasting Example with qiskit.aer”This larger example also needs the example dependencies: python -m pip install "q-alchemy-sdk-py[examples]". Set Q_ALCHEMY_API_KEY as in the getting-started guide.
import osimport numpy as npimport pennylane as qmlimport torch
from q_alchemy.pennylane_integration import AmplitudeEmbedding, OptParamsfrom sklearn.datasets import make_moons
# Sample dataX, _ = make_moons(n_samples=5, noise=0.1)X = X / np.linalg.norm(X, axis=1, keepdims=True) # Normalize each row for amplitude embedding
# Create PennyLane devicedev = qml.device("qiskit.aer", wires=1)
@qml.qnode(dev, interface="torch")def circuit(x): AmplitudeEmbedding( x, wires=[0], opt_params=OptParams( max_fidelity_loss=0.0, api_key=os.environ["Q_ALCHEMY_API_KEY"] ) ) return qml.expval(qml.PauliZ(0))
# Run the circuit on a batch of inputsX_tensor = torch.tensor(X, dtype=torch.float64)print(qml.draw(circuit, level="device", max_length=100)(X_tensor))This example demonstrates how batched data can be processed using broadcasting with AmplitudeEmbedding, and how Q-Alchemy is triggered on simulators like qiskit.aer. When moving to real hardware or gate-based backends that lack StatePrep gate, Q-Alchemy will transparently handle the state preparation.
For the method selection and tuning parameters every entry point accepts, see Options.
Verifying circuits with the sparse simulator
Section titled “Verifying circuits with the sparse simulator”Q-Alchemy also hosts a sparse state-vector simulator, so you can check that a preparation circuit really produces your target state. The typical loop is prepare → simulate → verify:
import numpy as npfrom qiskit import QuantumCircuitfrom qiskit.quantum_info import Statevector, state_fidelityfrom q_alchemy import q_alchemy_as_qasm, SparseSimulator
target = np.array([1, 0, 0, 1], dtype=complex) / np.sqrt(2)qasm = q_alchemy_as_qasm(target, max_fidelity_loss=0.0) # prepareprep = QuantumCircuit.from_qasm_str(qasm)
sim = SparseSimulator() # reads Q_ALCHEMY_API_KEY from the envsv = sim.sparse_statevector(prep) # simulateprint("fidelity:", state_fidelity(Statevector(sv.to_dense()), Statevector(target))) # verifySparseSimulator also offers .counts(...) for measurement sampling and .tomography(...) for an exact analysis of the simulated state (not measurement-based): its density matrix and purity, plus the fidelity against a dense reference for small circuits.
The sparse result holds only the non-zero amplitudes (anything below 1e-10 is dropped), so for a sparse state it stays small even where a dense 2**n vector would not fit in memory.
A state that populates most of its basis states is as large as the dense one and can exhaust the simulator. max_nnz=N caps it: after every gate only the N largest amplitudes are kept and renormalised, so the result becomes approximate, and nothing in it marks that it was truncated.
sv.to_coo() feeds a simulated state straight back into q_alchemy_as_qasm.
The free service includes simulator access with 4 MB RAM. For commercial workloads, platform pay-as-you-go access and full-suite OEM licensing are available. See Pricing and access or discuss platform access.
As a Qiskit backend
Section titled “As a Qiskit backend”The same simulator is exposed as a Qiskit BackendV2, so it works with the transpiler, Sampler and the rest of the Qiskit ecosystem:
from qiskit import QuantumCircuit, transpilefrom q_alchemy import QAlchemyBackend
backend = QAlchemyBackend()
qc = QuantumCircuit(2, 2)qc.h(0); qc.cx(0, 1); qc.measure([0, 1], [0, 1])
job = backend.run(transpile(qc, backend), shots=4096)print(job.result().get_counts()) # {'00': ~2048, '11': ~2048}backend.run(...) accepts Aer-style options such as shots, seed_simulator, save_statevector and Q-Alchemy’s own save_sparse_statevector.
Through the PennyLane–Qiskit plugin it also works as a PennyLane device:
qml.device("qiskit.remote", wires=2, backend=QAlchemyBackend(), shots=4096).
The GitHub repository has the full guide and a runnable notebook.
License
Section titled “License”The q-alchemy-sdk-py is free and open source, released under the Apache License, Version 2.0.