CQCL/hugr

Can't define a circuit with constant parameters

Closed this issue · 2 comments

The following test case defines a simple circuit:

let mut builder =
    FunctionBuilder::new("f", FunctionType::new(type_row![QB], type_row![QB]).into())?;
let [q] = builder.input_wires_arr();
let angle = builder.add_load_value(ConstF64::new(0.5));
let [q] = builder.add_dataflow_op(rz_f64(), [q, angle])?.outputs_arr();

println!("{}", builder.hugr().mermaid_string());
let res = builder.finish_hugr_with_outputs([q], &FLOAT_OPS_REGISTRY);
assert_matches!(res, Ok(_));

which corresponds to

graph LR
    subgraph 0 ["(0) FuncDefn"]
        direction LR
        1["(1) Input"]
        1--"0:0<br>qubit"-->5
        2["(2) Output"]
        3["(3) const:custom:f64(0.5)"]
        3--"0:0<br>float64"-->4
        4["(4) LoadConstant"]
        4--"0:1<br>float64"-->5
        5["(5) test.quantum.RzF64"]
        5--"0:0<br>qubit"-->2
    end
Loading

However, it fails at validation time with a SrcExceedsTgtExtension error:

InvalidHUGR(
    CantInfer(
        EdgeMismatch(
            SrcExceedsTgtExtensions {
                from: Node(
                    3,
                ),
                from_extensions: ExtensionSet(
                    {
                        IdentList(
                            "arithmetic.float.types",
                        ),
                    },
                ),
                to: Node(
                    2,
                ),
                to_extensions: ExtensionSet(
                    {},
                ),
            },
        ),
    ),
)

I reduced this error from a larger hugr definition of a circuit inside a module, which failed with a MismatchedConcreteWithLocations instead.

If we swap the FunctionBuilder for a DFGBuilder then the validation works.

#1142 fixes this, if we add a .with_extension_delta(float_types::EXTENSION_ID) to the function signature definition.

I would suggest that the error we give the user (in this case, me) for a missing extension delta in the function definition is not helpful. ExtensionError doesn't tell you much:

InvalidHUGR(
    ExtensionError(
        ExtensionError {
            parent: Node(
                1,
            ),
            parent_extensions: ExtensionSet(
                {},
            ),
            child: Node(
                7,
            ),
            child_extensions: ExtensionSet(
                {
                    IdentList(
                        "arithmetic.float.types",
                    ),
                },
            ),
        },
    ),
),