Skip to content

unphysical dialect and separating hardware, emulation, simulation interpreters #382

@jon-wurtz

Description

@jon-wurtz

Continuing discussions of #359 with @weinbe58 on how to extract exact probability distributions. #359 is a blocker for QuEraComputing/bloqade#260 "bloqade circuits" tutorial.

In general, extracting out exact probability distributions is a relatively hard problem that requires some abstract analysis, or at least an interpreter that is able to explore an entire (discrete) decision tree based on postselecting measurements. And, of course, it is impossible for continuous random variables (such as Gaussian random coherent noise). A related challenge is unnecessarily repeatedly calling state-vector evolution to query the same state once per shot, but perhaps that's a caching thing that we'll worry about once performance is an issue.

This also gives some motivation for more strongly distinguishing the three types of interpretation on bloqade kernels:

  • Hardware - This actually executes a task on Gemini or some other device
  • Emulation - A faithful emulator of what running a task on Gemini might be. So, adding circuit noise at the user discretion, as well as not being able to compute exact probability distributions
  • Simulation - A "godmode" of emulation where the user is also able to extract and copy the state vector / RDM, as well as extract exact probability distributions if needed.

Phil and I discussed this at length. The challenge is thinking about "where" postprocessing on bitstring measurements happens: server side next to the QPU, or client side. We settled on proposing adding a new dialect squin.unphysical to squin, which could let the user extract RDMs or probabilities. Further, we concluded post post-processing should occur "outside" of the kernel, on the client side.

probabilities:squin.unphysical.Bitstrings = squin.unphysical.measure([qreg[0],qreg[5],qreg[2],...])

reduced_density_matrix:squin.unphysical.RDM = squin.unphysical.rdm([qreg[0],qreg[5],qreg[2],...])

This unphysical dialect could be appropriately interpreted by simulation, but not by emulation or hardware. The return types could also be rendered uninterpretable to ensure that a user could not use, say, the probability of measuring bitstring 5 to be 0, within that kernel. The only place they could be used is in a return.

It could also be a relatively simple rewrite to convert a squin.unphysical.measure statement into a squin.qubit.measure statement, which would also change the type signature of the returned Bitstrings to list[bool]. One could also automatically write the Python function which could do the averaging/frequentist counting as the client side postprocessing on the returned values. Heck, even the rdm could be rewritten into state tomography/shadows to be run through multiple shots on hardware. Generally speaking, it is a compiler pass that is more explicit about postprocessing pipelines, e.g., with a signature kernel, py_func = rewrite(kernel).

Metadata

Metadata

Assignees

Labels

rfcRequest for Commentstriagerequest for triage. A decision will be made on the issue or PR.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions