Skip to content

Arguments that are "Dynamic Constant" treated as "Static" across callable boundaries #3283

@swernli

Description

@swernli

(Note this repro depends on the bug in #3282, so if that is fixed first then a different repro may be needed)

When RCA determines the runtime capabilities of a callable invocation it uses the callable's application generator set and checks the dynamism of each argument to know wich capabiltiies to aggregate. However, only arguments that are "Dynamic Variable" are checked, the rest are assumed to be "Static" arguments. Internally, we effectively have three categories of values: Static, Dynamic Constant, or Dynamic Variable. By effectively promoting Dynamic Constant values into Static values, we lose some information across function calls. Using a specific repro, we can see that Q# expressions that generates an error if used directly is accepted if it is instead put in a function:

import Std.Arrays.IsEmpty;
@EntryPoint(Base)
operation Main() : Unit {
    use qs = Qubit[2];
    while IsEmpty(qs) {}
    LoopOnArray(qs);
}

function LoopOnArray(arr : Qubit[]) : Unit {
    while IsEmpty(arr) {}
}
Image

Commenting out the explicit while in the body of Main will avoid errors and successfully generate QIR (as explained in #3282, the capabilities error is incorrect). This shows that code in a callable is treated different than code across callables, which can cause problems if things like classical loops are supposed to be emitted based on Dynamic Constant values.

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions