Manual Memory-Compute qubits#3204
Conversation
ae9b0d8 to
0ea1346
Compare
|
Change in memory usage detected by benchmark. Memory Report for b86379f
|
|
Change in memory usage detected by benchmark. Memory Report for fbb998b
|
swernli
left a comment
There was a problem hiding this comment.
Resource estimation updates and general infrastructure changes look good. I left a few comments on some things that should be updated and one thought for the future, but I think this is almost ready to go!
| /// of maximum capacity: 0 = LRU (least recently used), 1 = LFU (least | ||
| /// frequently used) | ||
| /// frequently used), 2 = Manual. | ||
| function EnableMemoryComputeArchitecture(computeCapacity : Int, strategy : Int) : Unit { |
There was a problem hiding this comment.
Would it be possible to expose this to the Python layer, for example through the QRE inputs?
One use case I imagine is that we build up a Q# file with Store and Load operations, and then run multiple resource estimation from Python while toggling memory-compute layout on or off and varying the compute capacity. We can also error out if the load size exceeds the compute capacity.
It would be painful if we needed to add another input parameter to every Q# circuit that might potentially use the memory-compute layout, and then modify the circuit parameters every time we want to resource-estimate the same circuit under different compute capacities.
There was a problem hiding this comment.
This would be tricky. This information needs to be known during logical resource estimation, so it needs to be an input to logical_counts. Interpreter::logical_counts currently only takes callable and arguments, it doesn't take any "resource estimation parameters".
It's debatable whether using memory-compute architecture is purely resource estimation feature (and therefore using memory-compute should be considered QRE setting). It is now, but in the future when we support error-correcting codes, enabling memory-compute will results in different generated QIR.
I understand that it's inconvenient to declare extra boolean argument in Q# operation. But if this operation expresses two different quantum algorithms based on that argument, extra parameter is the best way to represent that.
There was a problem hiding this comment.
I know this is not perfect solution, but in my Shor's implementation I added a boolean field "use_memory_compute" to ShorsConfig, so at least we don't have to add a new parameter in function signature. It looks like this:
operation PeriodFindingIteration(
modexp_j_params : ModExpParams,
modexp_k_params : ModExpParams,
config : ShorsConfig,
num_output_qubits : Int
) : (BigInt, BigInt) {
if (config.use_memory_compute) {
Std.ResourceEstimation.EnableMemoryComputeArchitecture(0, 2);
}
...
}
Co-authored-by: Stefan J. Wernli <swernli@microsoft.com>
|
Change in memory usage detected by benchmark. Memory Report for 6e3b3c4
|
|
Change in memory usage detected by benchmark. Memory Report for 12e091f
|
|
Change in memory usage detected by benchmark. Memory Report for caa2c79
|
This PR introduces a new way to manually manage Memory qubits. It adds two new operations
Std.Memory.MemoryQubitLoadandStd.Memory.MemoryQubitStorethat operate on a single qubit and instruct runtime to "load" qubit (move from memory to compute) or "save" it (move from compute to memory).Example:
Conventions:
Qubitis the "quantum value" rather than a location on a physical device. When it is moved between locations (e.g. from "hot" to "cold" area of quantum computer), in Q# it's still the same Q# object. This is why Load and Store act on single qubit and mutate its "type" (compute/memory) rather than action between 2 qubits. At some point Load and Store is translated to 2-qubit operation between memory and compute qubit, but this is hidden from the programmer.swap_idcan be performet only between 2 compute qubits.Reseton memory qubit is allowed.Notes on implementing these operations in backends:
Std.ResourceEstimation.EnableMemoryComputeArchitecturewas called withstrategy=2(which corresponds to manual strategy). They are no-ops in any other backend.Std.Memory, notStd.ResourceEstimation. They describe operations that make sense outside resource estimation, even though currently they are only implemented in resource estimation.Notes on interaction with existing "automatic" memory-compute architecture:
MemoryComputeInfoimplementing automatic memory-compute is untouched, I just wrapped it into enumMemoryCompute. By being enum, it forces mutual exlcusivity of memory and compute architecture.