microsoft / qsharp

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

Hack around recursive operations calls #1586

Open orpuente-MS opened 6 months ago

orpuente-MS commented 6 months ago

Describe the bug

When calling recursive operations in Base profile you get an error (this the correct behavior).

But you can get around it using the following hack. And it runs.

namespace TopLevel {
    @EntryPoint()
    operation Main() : Unit {
        RecursiveOperation(0);
    }

    operation RecursiveOperation(x: Int) : Unit {
        use q = Qubit();
        Message($"Depth {x}");

        let hack = [RecursiveOperation];
        hack[0](x + 1);
    }
}

To Reproduce

Steps to reproduce the behavior:

  1. Open the playground on the latest main branch.
  2. Paste the source code provided above.
  3. Change the profile to Base.
  4. Click on Run.
  5. You will see that the code runs and prints some Messages.
  6. Now go to the QIR tab, you will see "Error: memory access out of bounds".

Expected behavior

Describe what you expect to happen, versus what actually happened.

Screenshots Correct behavior image

Hack image

System information

swernli commented 6 months ago

This one is tricky to address... RCA doesn't see this as recursive because there is a use of a runtime-resolved callable. Then at partial eval it will try to evaluate the call, get stuck in the infinite recursion, and fail with out of memory. On the one hand, it would be great if it could recognize and avoid this. On the other hand, it's no different than a classical infinite loop or other program that fails to terminate for classical reasons. The cycle check in RCA is best effort, but at the end of the day this seems to reduce to yet another version of the halting problem.