CQCL/pytket-phir

Incorrect bitwidth for QASM input with pytket 1.30.0

Closed this issue · 3 comments

Describe the bug
With upgrade to pytket==0.13.1, all tests involving range predicate fail (see here):

FAILED tests/test_api.py::TestApi::test_pytket_to_phir_no_machine_all[QasmFile.cond_1] - UnboundLocalError: cannot access local variable 'cond' where it is not associated with a value
FAILED tests/test_api.py::TestApi::test_pytket_to_phir_no_machine_all[QasmFile.cond_classical] - UnboundLocalError: cannot access local variable 'cond' where it is not associated with a value
FAILED tests/test_api.py::TestApi::test_pytket_to_phir_h1_1_all[QasmFile.cond_1] - UnboundLocalError: cannot access local variable 'cond' where it is not associated with a value
FAILED tests/test_api.py::TestApi::test_pytket_to_phir_h1_1_all[QasmFile.cond_classical] - UnboundLocalError: cannot access local variable 'cond' where it is not associated with a value

I believe this is because the change in #190 makes the value of UINTMAX depend on 64-bits but the pytket translation of QASM circuits is still using 32-bits for the range predicate translation. See

op = RangePredicate([2,4294967295]), cmd = RangePredicate([2,4294967295]) c[0], c[1], tk_SCRATCH_BIT[1];

    def convert_classicalevalop(op: tk.ClassicalEvalOp, cmd: tk.Command) -> JsonDict | None:  # noqa: PLR0912
[...]
            case tk.RangePredicateOp():  # where the condition is a range
                cond: JsonDict
                match op.lower, op.upper:
                    case l, u if l == u:
                        cond = {
                            "cop": "==",
                            "args": [args[0].reg_name, u],
                        }
                    case l, u if u == UINTMAX:
                        cond = {
                            "cop": ">=",
                            "args": [args[0].reg_name, l],
                        }
                    case 0, u:
                        cond = {
                            "cop": "<=",
                            "args": [args[0].reg_name, u],
                        }
                    case l, u:
>                       raise TypeError(f"{l=} {u=} {UINTMAX=}")
E                       TypeError: l=2 u=4294967295 UINTMAX=18446744073709551615

To Reproduce
Upgrade to pytket==0.13.1

Expected behavior
Tests should pass.

Additional context
Changes in #190

@cqc-alec do you think this is a bug in pytket or do we need to treat QASM inputs specially assuming max 32 bits?

cc: @dlucchetti

@cqc-alec do you think this is a bug in pytket or do we need to treat QASM inputs specially assuming max 32 bits?

There is a maxwidth parameter to circuit_from_qasm, which defaults to 32. Would changing this to 64 in the get_qasm_as_circuit() method (or to 64 if pytket.__dict__.get("bit_width_64", False) else 32 as used in the definition of UINTMAX) fix the issue?

Just tested locally and it looks like this does fix the errors.