Skip to content

Qiskit Integration ​

MENOS integrates with Qiskit through two classes in menos.qiskit:

ClassQiskit interfacePurpose
MENOSBackendBackendV2Run circuits and get counts or a statevector
MENOSEstimatorBaseEstimatorV2Compute expectation values

MENOSJob (a JobV1) is the object run returns. There is no provider class and no SamplerV2 primitive.

Running circuits ​

python
from qiskit import QuantumCircuit

from menos.qiskit import MENOSBackend

backend = MENOSBackend()
qc = QuantumCircuit(3, 3)
qc.h(0)
qc.cx(0, 1)
qc.cx(1, 2)
qc.measure([0, 1, 2], [0, 1, 2])

job = backend.run(qc, shots=500, seed_simulator=3)
print(job.status(), job.result().get_counts())
assert job.result().success

Options are shots (default 1024), seed_simulator (default: a fresh random seed) and want_statevector (default False). Anything else raises AttributeError. See MENOSBackend.

Transpiling ​

MENOSBackend advertises a Target built from exactly the gates it can execute, so Qiskit's transpiler knows how to lower a circuit for it:

python
from qiskit import QuantumCircuit, transpile
from qiskit.circuit.library import QFTGate

from menos.qiskit import MENOSBackend

backend = MENOSBackend()
qc = QuantumCircuit(3)
qc.append(QFTGate(3), [0, 1, 2])
qc.measure_all()

lowered = transpile(qc, backend, seed_transpiler=0)
print(sorted(lowered.count_ops()))
counts = backend.run(lowered, shots=100, seed_simulator=1).result().get_counts()
assert sum(counts.values()) == 100

The backend's target has no fixed qubit count (num_qubits=None), matching Qiskit's own BasicSimulator, because the real limit is memory, not a device size.

What the converter accepts ​

Circuit contentBehaviour
A gate in the supported tableRun natively
Any other gate with a matrix on 1 to 5 qubitsLowered to a dense unitary and run
A gate on more than 5 qubits that is not nativeUnsupportedFeatureError ("try transpile(qc, backend) first")
barrier, id, delayDropped; they do not change the result
measureSupported, but must be terminal for its qubit
reset, classical control (if_test), mid-circuit measurementUnsupportedFeatureError
Unbound ParametersInvalidCircuitError; call assign_parameters first

Global phase is preserved: a circuit's global_phase is part of the statevector MENOS returns.

Estimator ​

python
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp

from menos.qiskit import MENOSEstimator

qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)

estimator = MENOSEstimator()
pub_result = estimator.run([(qc, [SparsePauliOp("ZZ"), SparsePauliOp("XX")])]).result()[0]
print(pub_result.data.evs)

Results are exact, so stds is always zero and any requested precision is recorded in the metadata but never used to add noise. See EstimatorV2.

What the Qiskit layer does not expose ​

The Qiskit classes cover the common path and deliberately nothing more. These are reachable only through the native API:

  • time and memory budgets (time_budget_seconds, memory_budget_bytes)
  • the plan report, explain()
  • arbitrary observables other than through MENOSEstimator

Backend selection (CPU or CUDA) is automatic and is not exposed anywhere in Python.

Released under the Apache-2.0 license. GitHub · PyPI