| Filename | Latest commit message | Latest commit date |
|---|---|---|
quantum_cutrank_metal (feature quantum_cutrank_metal, macOS) runs the cut-rank walk's passes on the platform's GPU: - each shot's table is 2^cut single-precision entries in one shared buffer, at most 2^31 a table, so every index fits in 32 bits; - each pass is one dispatch over (entry, shot), in the walk's order and with its arithmetic, done in f32; the passes are the same for every shot, and only each shot's weights (set by the outcomes it drew) differ, read from a small per-shot array; an amplitude is every pass encoded into one command buffer; - a sample's sums are reduced per threadgroup on the device (a SIMD-group sum, then the groups in order) and added on the host in f64, in order, for each shot; the outcome is drawn as the host's walk draws it (outcome_norm and draw, now shared by both); - a batch of shots is sampled side by side, so a qubit is one command buffer for the batch: the previous qubit's passes for each shot's outcome, then this qubit's sums; - each shot draws from a stream of its own, so a seed's samples are the same at any batch size. The kernels are compiled in the platform's safe math mode, so a run is the same bits on one device. Tests hold it to the double-precision walk on states of 10 to 34 qubits: amplitudes within 1e-5 of each amplitude's size and the same bits run to run; samples whose probabilities are their own and whose counts follow them; and the same samples one at a time and seven side by side. Without a device the tests skip; WAI_QUANTUM_CUTRANK_METAL_EXPECT makes that a failure, and the service workflow's macOS job sets it and checks both GPU tests by name. The engine's cutrank_single method runs a cutrank job on that table where the build has the feature and the host a GPU; auto never picks it. It samples up to 32 shots a batch, as many as 2 GiB beside its first table holds within the job's memory, and the plan counts them. Its amplitudes carry the circuit's global phase, found on the same table (catalog::cutrank_phase_with takes the amplitude function). The job service, the command line's metal feature and the desktop app's metal feature build it in. The service's schemas list it, and it marks the method's energy figure partial, since the counter does not read the GPU. examples/cutrank_gpu times one state's amplitudes and samples on the host's tables and on the GPU, and each kernel's pass alone. On a shared desktop machine, each device at its quietest (either side ran up to five times slower under other work), seconds for one amplitude of a random graph state: widest cut host, double host, single GPU 23 bits 0.027 0.024 0.005 25 bits 0.057 0.045 0.019 27 bits 0.18 0.17 0.046 29 bits 1.03 0.54 0.34 and for 64 samples, 16 a batch, the host at about half its quietest speed: widest cut host, single GPU, one at a time GPU, 16 a batch 16 bits 0.52 0.62 0.036 20 bits 1.97 0.73 0.067 23 bits 3.87 0.91 0.34 25 bits 7.48 1.82 1.20 A pass runs at about 550 GB/s on an idle device. Co-Authored-By: Claude Opus 5.5 <[email protected]> (cherry picked from commit f7c7160a9ab5a6255c28d34af57ee2fbc017b055) |
||
| .. | ||
| src | ||
| test | ||
| .gitignore | ||
| build.mjs | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
Quantum Studio
An editor for OpenQASM programs, with three places to run them:
- this browser, through the quantum job service's engine compiled to WebAssembly, in a worker;
- this computer, through the same engine built natively, in the desktop app;
- the job service, over HTTP.
Every place returns the same job: the request, the method and why it was chosen, the result, and its receipt. The Studio shows them the same way and checks every receipt on the machine it runs on. The same request with the same seed gives the same counts in each place.
The editor:
- highlights OpenQASM;
- completes the standard gates and the program's own registers;
- marks the engine's diagnostics on their lines;
- draws the circuit and shows the plan as you type.
Ctrl+Enter (⌘+Enter on macOS) runs the program, and Escape cancels a run. The program and the history of runs are kept on the device. "Copy link" puts the program in a URL fragment, which no server sees.
The assistant
The Assistant pane talks to a language model on this machine: any server with the chat-completions interface and tool calls, such as the JouleClaw runtime or a llama.cpp server. The address goes under "Model…" and is http://127.0.0.1:8080/v1 by default. Nothing leaves the machine unless the address points elsewhere. In the desktop app the app makes the call itself, so no browser origin rule stands in the way.
The engine is the model's tool, not an afterthought:
- Its tools are the Studio's engine: read the program, lint, draw, plan and run. Its first turn must call one of them, so every answer starts from the engine.
- Every program it proposes is checked before it is offered. The engine reads it here. One that does not parse goes back to the model once, with the engine's reason, to be corrected. One that parses is run, with the settings the model used, so the counts it quoted are the counts shown. Then "Apply" puts it in the editor.
- It may state only figures the engine returned. A figure in its prose that no tool returned is marked "Not from a run".
- Answers are plain text. LaTeX a model writes anyway is shown as Unicode.
node test/assistant-live.mjs URL drives the assistant against a real model server and prints what it did. It is not part of CI, which has no model.
Hosting it
Build it with npm ci && node build.mjs. That writes dist/:
| File | What it is |
|---|---|
studio.js |
the interface, bundled |
worker.js |
the engine's worker |
studio.css |
the Studio's styles |
tokens.css |
the site's design tokens, for when it stands alone |
index.html |
the page that stands alone |
A host mounts the Studio on an element:
<div id="studio"
data-engine-pkg="/quantum-ide/pkg/wai_quantum_ide.js"
data-worker="/quantum-studio/worker.js"
data-service="/quantum-jobs"></div>
<script type="module" src="/quantum-studio/studio.js"></script>
data-embedded tells the Studio the host page has its own heading, so the Studio's name is not a second h1. data-engine-pkg names the engine's browser package: wai-web built with the feature quantum_engine. node build.mjs --pkg DIR copies such a package into dist/pkg/ for index.html. On the desktop, window.__TAURI__ is present and the Studio uses the native engine instead.
Testing it
node build.mjs --pkg PATH/TO/PKG && node test/studio.test.mjs
The test runs the Studio in the installed browser:
- lint, draw and plan as the program is typed;
- a run in the browser, with its receipt checked there;
- an error marked on its line;
- a rotation run on the state vector;
- the same job on the live service giving the counts run here, shot for shot;
- Ctrl+Enter;
- the program and the history surviving a reload;
- the assistant, against a scripted model server: a tool call run on the engine, a proposal the engine cannot read sent back with its reason, the corrected one checked and run before it is offered, and Apply;
- the layout at a phone's width.
STUDIO_SKIP_SERVICE=1 leaves the service step out. It saves screenshots of both colour schemes in test/screenshots/.