quil-lang / qvm

The high-performance and featureful Quil simulator.
Other
411 stars 57 forks source link

Don't clobber persistent qvm classical memory between program runs #194

Open appleby opened 4 years ago

appleby commented 4 years ago

THE CLOBBERING CLASSICAL MEMORY CONUNDRUM

Running a program on a persistent QVM causes the existing classical memory subsystem to be clobbered since we tell QVM:LOAD-PROGRAM to :SUPERSEDE-MEMORY-SUBSYSTEM. This ensures things are consistent within a single call to the run-program endpoint, but violates the user's expectations of "persistence". We should allow classical memory registers to persist across runs.

Here are some ideas for how we could support persistent classical memory:

  1. Require the user to specify the classical memory hierarchy at the time the persistent QVM is allocated, and don't supersede when running a new program. This is probably the easiest option to implement, but also the least convenient and most error prone for the user, since they have to decide up front what classical memory registers they will need and then have to make sure all their quil programs are compatible. This option requires thinking about how the user would specify their desired memory hierarchy. A quil program? A JSON object?

  2. Merge the existing classical memory subsystem of the persistent QVM with the one extracted from the new program the user wants to run in the run-program API call. This would entail checking to make sure the definitions of the two memory subsystems are compatible. I haven't thought through exactly what "compatible" would mean here, but a first pass might mean allowing only new memory regions to be declared, or else requiring that re-declarations be identical to their previous declaration. I have a vague suspicion that doing the merging correctly will be ~harder~ finickier than it sounds.

  3. Allow the user to explicitly reconfigure the classical memory of the persistent QVM via an API call, just as we plan to do for things like noise model, simulation method, etc.

  4. Some combination of (1) (2) and/or (3).

appleby commented 4 years ago

Maybe there is another "option 1.5" sort of halfway between (1) and (2) that mimics the existing QVM API by allowing the caller to specify a classical memory model at allocation time, then giving them the option to supersede (or not) when they call the run-program RPC method.

@stylewarning any thoughts / preferences?

stylewarning commented 4 years ago

Maybe memory can always be "added" (new names can be generated), but no names can be reset. That's sort of like #2. But I'd also be happy with a "declare once" situation, and any incompatible memory is an error.

appleby commented 4 years ago

I'm warming up to the "declare once" model. It may have limitations, but at least it's simple and easy for the user to understand what went wrong and how to fix it.