Quantum Computing Tool avatar

Quantum Computing Tool

Pricing

Pay per usage

Go to Apify Store
Quantum Computing Tool

Quantum Computing Tool

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Jiri Spitalsky

Jiri Spitalsky

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

8 days ago

Last modified

Categories

Share

Quantum Computing Tool for Apify

A small provider-independent Apify Actor for AI agents that need to validate OpenQASM, simulate circuits with Qiskit Aer, or manage asynchronous jobs on a real quantum provider.

AI agent / MCP client
|
v
Apify Quantum Computing Actor
|-- SIM -> local Qiskit Aer
|-- IBM -> IBM Quantum Runtime Sampler V2
`-- VLQ -> explicit adapter skeleton

The Actor reads one JSON request and writes one stable JSON envelope to both:

  • the OUTPUT record in the default key-value store;
  • one item in the default dataset, which is convenient for Apify's MCP server.

Operations

OperationTargetsBehavior
validate_circuitSIM, IBM, VLQParses and inspects QASM without execution.
simulate_circuitSIMRuns a measured circuit synchronously with Aer.
run_quantum_jobIBM, VLQSubmits and immediately returns a persistent provider job ID.
get_quantum_jobIBM, VLQRetrieves normalized status and completed results.
list_backendsSIM, IBM, VLQDiscovers reliable backend capabilities.

The current POC implements SIM and IBM. VLQ is an intentional interface skeleton: because no authoritative VLQ submission contract was supplied, it returns VLQ_ADAPTER_NOT_IMPLEMENTED and never guesses an endpoint or sends a placeholder request.

GHZ simulation

Input:

{
"operation": "simulate_circuit",
"target": "SIM",
"qasm": "OPENQASM 2.0; include \"qelib1.inc\"; qreg q[3]; creg c[3]; h q[0]; cx q[0],q[1]; cx q[1],q[2]; measure q -> c;",
"shots": 10000,
"seed": 42
}

Representative response (counts vary without a seed):

{
"ok": true,
"operation": "simulate_circuit",
"target": "SIM",
"status": "COMPLETED",
"backend": "aer_simulator",
"result": {
"shots": 10000,
"counts": {"000": 5017, "111": 4983}
},
"metadata": {
"memory_estimate": {
"statevector_bytes": 128,
"safe_to_simulate": true
}
},
"warnings": []
}

The complete example is in examples/simulate-ghz.json.

Memory safety

The Actor definition requests 4608 MiB by default, enforces a 4096 MiB minimum, and caps runs at 4608 MiB (4.5 GiB). Before every simulation, the Actor computes:

statevector_bytes = 16 * 2^num_qubits
method_state_bytes = statevector_bytes
estimated_peak_bytes = 1.5 GiB runtime reserve + 2 * method_state_bytes

The reserve covers Python, Qiskit, Aer, loaded libraries, circuit storage, and Actor SDK overhead. The factor of two allows for simulator working buffers. A simulation is rejected with SIMULATION_MEMORY_LIMIT when the peak estimate exceeds 4.5 GiB. Under this policy the generic statevector ceiling is 26 qubits; 27 qubits is rejected. The same conservative gate is applied even if a more memory-efficient Aer method was requested, so a method-selection mistake cannot bypass the Actor's safety contract.

For explicit density_matrix, method_state_bytes is instead 16 * 4^num_qubits; its conservative ceiling is 13 qubits. This closes the otherwise dangerous gap between statevector and density-matrix scaling. SIM backend discovery reports the ceiling per method.

Validation still accepts circuits above the simulation ceiling (up to a separate 128-qubit parser safety cap) and reports safe_to_execute_under_actor_limit: false without executing them. The parser cap prevents pathological register declarations from allocating enormous objects before validation.

IBM asynchronous workflow

First discover backend names:

{
"operation": "list_backends",
"target": "IBM",
"ibm_token": "<Apify secret input>"
}

Then submit. A backend is deliberately required so an agent cannot accidentally select or pay for a device it did not name:

{
"operation": "run_quantum_job",
"target": "IBM",
"backend": "<backend from list_backends>",
"qasm": "OPENQASM 2.0; include \"qelib1.inc\"; qreg q[3]; creg c[3]; h q[0]; cx q[0],q[1]; cx q[1],q[2]; measure q -> c;",
"shots": 1000,
"ibm_token": "<Apify secret input>"
}

The adapter transpiles to the selected backend's ISA, invokes IBM Runtime Sampler V2 in job mode, and returns SUBMITTED with job_id. The Actor does not wait in the QPU queue.

Retrieve later:

{
"operation": "get_quantum_job",
"target": "IBM",
"job_id": "<returned job ID>",
"ibm_token": "<Apify secret input>"
}

Provider states are normalized to SUBMITTED, QUEUED, RUNNING, COMPLETED, FAILED, or CANCELLED. Completed Sampler V2 bit-array results become ordinary integer counts.

ibm_channel defaults to ibm_quantum_platform; ibm_cloud and an optional ibm_instance are also accepted. The token field is marked isSecret in the Apify input schema, represented as a Pydantic SecretStr, never logged, never stored by this code, and removed from validation/provider error text.

OpenQASM and validation

OpenQASM 2.0 uses Qiskit's built-in qasm2.loads. OpenQASM 3.x uses qasm3.loads with the official optional importer package. Validation returns:

  • qubits, classical bits, depth, and total operation count;
  • operation breakdown and measurement presence/count;
  • exact statevector and conservative peak-memory estimates;
  • the safe-to-simulate decision, errors, and warnings.

Shot-based simulation and QPU submission require at least one measurement. The input model also rejects invalid combinations before circuit parsing, including simulate_circuit + IBM, run_quantum_job + SIM, and get_quantum_job without job_id.

Local development (without Docker)

Python 3.11-3.13 and uv are supported:

uv sync
uv run pytest
uv run ruff check .
uv run quantum-tool examples/simulate-ghz.json

Or stream JSON:

$printf '%s' '{"operation":"list_backends","target":"SIM"}' | uv run quantum-tool -

The Dockerfile is supplied for Apify deployment, but Docker is not needed for local testing. It uses Apify's Python 3.12 base image and sets BLAS/OpenMP thread counts to one to reduce uncontrolled memory/CPU amplification. Production dependencies are installed from the hash-checked requirements.lock exported from uv.lock.

Apify and MCP

The .actor directory contains explicit input, output, and dataset schemas. Deploy with the Apify CLI, then expose the deployed Actor through the hosted Apify MCP server as a specific Actor tool or call it through call-actor. The input schema becomes the tool contract and the single dataset item supplies structured output inference/retrieval.

Do not put credentials in example files, source control, QASM, or logs. Supply IBM/VLQ values through fields marked as Apify secret inputs.

Repository layout

.actor/ Actor definition and discovery schemas
examples/ GHZ and IBM request examples
src/quantum_tool/
circuit.py QASM parsing, analysis, and memory policy
models.py Strict request schema and combination checks
service.py Stable operation dispatch/envelopes
main.py Apify lifecycle and storage output
providers/
base.py Provider interface
sim.py Qiskit Aer adapter
ibm.py IBM Runtime Sampler V2 adapter
vlq.py Non-invented VLQ boundary
tests/ Unit, Aer integration, safety, and adapter tests

POC limitations

  • VLQ needs documented authentication, discovery, submission, and retrieval semantics.
  • Real IBM calls require a user token, service access, and available backend; automated tests mock the provider boundary and never submit paid QPU work.
  • This is shot/count oriented. It does not return statevectors and does not yet accept QPY or structured Qiskit JSON.
  • The memory estimate is intentionally conservative rather than a promise of maximum Aer capacity.

License

Apache-2.0.