microsoft / qsharp

Azure Quantum Development Kit, including the Q# programming language, resource estimator, and Quantum Katas
https://microsoft.github.io/qsharp/
MIT License
387 stars 80 forks source link

Make it easier to implement circuits described using mutable arrays #485

Open bamarsha opened 1 year ago

bamarsha commented 1 year ago

From microsoft/qsharp-language#59:

I was trying to implement the carry lookahead adder from https://arxiv.org/pdf/2004.01826.pdf . it has a step described like this:

image

As you can see, their description involves storing a reference to an initialized qubit into an array, which will be used during later steps.

Currently, it is difficult to implement this in Q# because:

  1. The syntax for mutating an array-of-arrays is extremely verbose.
  2. set lines prevent the creation of an automatic adjoint.
  3. Qubits need to be allocated outside the nested loop, requiring you to separately calculate the total number you need to allocate instead of just relying on the loop to do it.

I'm not exactly sure how to fix this, but it's something that I've run into more than once.

Here are some ideas:

  1. Have a concept of a "qubit pool", which you can iteratively ask for more qubits from and where all the qubits are deallocated when the pool goes away. Using a pool would prevent the automatic creation of an adjoint:
using (pool = QubitPool()) {
    for (...complicated...) {
        let q = pool.allocate_another();
    }
}
  1. Add support for mutable arrays, and/or multi-dimensional arrays, and/or hash maps. Support syntax like set map[(i, j)] = x.
  2. Allow the use of set statements inside of auto-adjoint operations as long as they invoke no operation that returns a value (except perhaps for some whitelisted special case operations like allocation). Implement these methods by executing them forwards, with all operations replaced by no-ops, recording the historical state of mutable variables. Then rewind while applying the inverses of the operations.
nirajvenkat commented 2 months ago

Nudging this issue as this point was mentioned in a discussion:

The syntax for mutating an array-of-arrays is extremely verbose.

Also, IIRC @swernli mentioned that copy-update syntax incurs a copy of the entire array. Wondering if there is a workaround that instead mutates just the single element. Can spin this off into a separate issue if needed.