Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error parsing Quilc compilation result #294

Closed
erichulburd opened this issue May 5, 2023 · 2 comments
Closed

Error parsing Quilc compilation result #294

erichulburd opened this issue May 5, 2023 · 2 comments

Comments

@erichulburd
Copy link
Contributor

I've hit an error where a quilc response is not parseable by this SDK. The quilc Docker container logged a successful response. There is a reproducing script below.

Unsure where the issue lies (this program parses fine in pyQuil v3). Regardless as to whether there is a parsing bug in quil-rs, would be nice to have some verbose logging that might print the quilc response.

System Info

% uname -a
Darwin BK-LOSX-WWW5RWR 22.4.0 Darwin Kernel Version 22.4.0: Mon Mar  6 20:59:28 PST 2023; root:xnu-8796.101.5~3/RELEASE_ARM64_T6000 arm64

Quilc Info

% docker run rigetti/quilc --version
1.26.0 [7aef642]

Reproducing Script

import json
from pyquil.api import get_qc
from pyquil.external.rpcq import compiler_isa_to_target_quantum_processor
from pyquil.quil import Program
from qcs_sdk.compiler.quilc import CompilerOpts, TargetDevice, compile_program


quil = """
DEFGATE CRX(%theta):
    1, 0, 0, 0
    0, 1, 0, 0
    0, 0, COS(%theta/2), -i*SIN(%theta/2)
    0, 0, -i*SIN(%theta/2), COS(%theta/2)

DECLARE ro BIT[4]
RESET
H 0
H 1
H 2
H 3
RESET 2
H 0
H 1
H 2
H 3
I 0
X 1
Y 2
Z 3
S 0
T 1
RX(pi) 2
RY(pi/3) 0
RZ(pi) 2
PHASE(pi/6) 3
CZ 0 1
XY(pi/8) 2 3
CPHASE(pi) 0 1
CPHASE00(pi/2) 2 3
CPHASE01(pi/4) 0 1
CPHASE10(pi/8) 2 3
CNOT 0 1
CCNOT 2 3 0
SWAP 1 2
CSWAP 3 0 1
ISWAP 2 3
PSWAP(pi) 0 1
PHASE(2*pi/5) 2
DECLARE phi REAL[3]
RX(phi[0]) 2
RY(phi[1]) 3
RZ(phi[2]) 0
CRX(2*pi/5) 1 2
DECLARE omega REAL[1]
DECLARE psi REAL[2]
CRX(1.23) 3 0
CRX(-14.619) 1 2
DECLARE alpha REAL[3]
DECLARE beta REAL[2]
RX(SIN(3.4)) 3
RX(SQRT(alpha[1]/SQRT(alpha[2])) + pi*COS(beta[1])) 0
XY(SIN(alpha[1])*(EXP(SIN(alpha[0])*COS(beta[0]) + 3.0) + COS(beta[1]))) 1 2
RX(SQRT(alpha[0] + SIN(alpha[1]))) 3
CPHASE(SQRT(9.5)) 0 1
MEASURE 2 ro[0]
MEASURE 3 ro[1]
MEASURE 1 ro[2]
MEASURE 0 ro[3]
"""

def main():
    program = Program(quil)
    qvm = get_qc("4q-qvm", compiler_timeout=300.0, execution_timeout=300.0)
    # qvm.compile(Program(quil), protoquil=False)
    compiler_isa = qvm.quantum_processor.to_compiler_isa()
    target_device_json = json.dumps(compiler_isa_to_target_quantum_processor(compiler_isa).asdict())  # type: ignore
    target_device = TargetDevice.from_json(target_device_json)

    native_quil = compile_program(
        quil=program.out(calibrations=False),
        target=target_device,
        options=CompilerOpts(protoquil=False, timeout=300.0),
    )


if __name__ == "__main__":
    main()

Output:

Traceback (most recent call last):
  File ".../reproduce.py", line 87, in <module>
    main()
  File ".../reproduce.py", line 79, in main
    native_quil = compile_program(
quilc.QuilcError: Problem when trying to parse the compiled program: error while parsing: at line 11, column 18 (LPAREN): expected a command or a gate
@MarquessV
Copy link
Contributor

MarquessV commented May 5, 2023

There are a couple quil-rs issues at play here:

First, quil-rs only supports function calls (sin, cos, etc.) as lowercase strings. I've actually changed this so that casing is ignored, but the fix is tied up in a feature branch for the Python package.

Using that fix, I was able to get a little further, but not all the way. This time, quilc threw an error about being unable to parse the program:

Unexpected terminal :COMPLEX (value #S(CL-QUIL.FRONTEND:CONSTANT
                                       :VALUE #C(0.0d0 1.0d0)
                                       :VALUE-TYPE #.CL-QUIL.FRONTEND:QUIL-REAL)). Expected one of: (NIL                                                                                                     :MINUS                                                                                                     :TIMES                                                                                                     :DIVIDE                                                                                                   :EXPT                                                                                                     :PLUS                                                                                                   :RIGHT-PAREN)                                                                                                

The problem comes down to how quil-rs prints i. For example, quil-rs will parse this quil:

-i*SIN(%theta/2)

and print it as

(-((1i))*SIN((%theta/(2.0))))`

While visually distracting, the extra pairs of parentheses aren't the issue, it's the 1i that quilc can't parse. Per the quil spec, i should be preceded by a floating point number. quil-rs trims the zeroes before printing a floating point number, which is why the lone integer 1 gets printed. After disabling the trimming locally, the reproduce script worked without error.

So, next steps here are to merge my feature branch into quil-rs proper, so that the function call casing is ignored. Then we need to figure out how we want to resolve the float trimming issue. The Expression type up-casts everything to a complex number, meaning that if we just turn off trimming, quil-rs won't be able to print integers in expressions. I can't think of an issue with that off the top of my head, so maybe it's fine, but I would want to explore it a bit more.

quil spec for reference:
image
(note: quil defines a "real" number as a floating point number just above this)

@MarquessV
Copy link
Contributor

This was resolved via the mentioned quil-rs issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants