quil-lang / quilc

The optimizing Quil compiler.
Apache License 2.0
460 stars 72 forks source link

quilc test-faithfulness fails assertion in cl-quil::scale-out-matrix-phases: Matrices do not lie in the same projective class #199

Closed appleby closed 5 years ago

appleby commented 5 years ago

The faithfulness tests that were recently enabled in #189 are failing an assertion in cl-quil::scale-out-matrix-phases. The test failure appears to be a result of changes made in #159. At least, if I rebase and drop that commit, the test passes again. Note that #159 was merged just before #189, so @ecpeterson wouldn't have known.

Probably related to @karalekas comment here: https://github.com/rigetti/quilc/pull/197#issuecomment-483434459

Here is the backtrace:

Backtrace:
  0: (SB-KERNEL:ASSERT-ERROR (CL-QUIL::DOUBLE~ (ABS (MAGICL:REF CL-QUIL::MAT CL-QUIL::J 0)) (ABS (MAGICL:REF CL-QUIL::REF-MAT CL-QUIL::J 0))) (((ABS #) 2.1628161436138797d-16) ((ABS #) 0.7071067811865475d0..
      Locals:
        ARGS-AND-VALUES = (((ABS (MAGICL:REF CL-QUIL::MAT CL-QUIL::J 0)) 2.1628161436138797d-16) ((ABS (MAGICL:REF CL-QUIL::REF-MAT CL-QUIL::J 0)) 0.7071067811865475d0))
        ASSERTION = (CL-QUIL::DOUBLE~ (ABS (MAGICL:REF CL-QUIL::MAT CL-QUIL::J 0)) (ABS (MAGICL:REF CL-QUIL::REF-MAT CL-QUIL::J 0)))
        DATUM = "Matrices do not lie in the same projective class."
        PLACES = NIL
        SB-DEBUG::MORE = NIL
  1: (CL-QUIL::SCALE-OUT-MATRIX-PHASES #S(MAGICL:MATRIX :ROWS 64 :COLS 64 :DATA-TYPE MAGICL:Z :STORAGE-TYPE MAGICL::GE :DATA #(#C(0.1186426678685776d0 -0.6970824322567777d0) #C(1.0302206828327032d-16 -1.90..
      Locals:
        GOODNESS-VALUE = 0.7071067811865466d0
        J = 1
        MAT = #S(MAGICL:MATRIX ..)
        REF-MAT = #S(MAGICL:MATRIX ..)
        RESCALE-VALUE = #C(0.7071067811865475d0 0.7071067811865491d0)
  2: (QUILC::PROCESS-PROGRAM #<CL-QUIL:PARSED-PROGRAM {10042C2D33}> #<CL-QUIL::CHIP-SPECIFICATION of 8:8 objects>)
      Locals:
        CHIP-SPECIFICATION = #<CL-QUIL::CHIP-SPECIFICATION of 8:8 objects>
        ORIGINAL-MATRIX = #S(MAGICL:MATRIX ..)
        PROGRAM = #<CL-QUIL:PARSED-PROGRAM {10042C2D33}>
  3: (QUILC::PROCESS-OPTIONS :PREFER-GATE-LADDERS NIL :COMPUTE-GATE-DEPTH NIL :COMPUTE-GATE-VOLUME NIL :COMPUTE-RUNTIME NIL :COMPUTE-FIDELITY NIL :COMPUTE-MATRIX-REPS T :COMPUTE-2Q-GATE-DEPTH NIL :COMPUTE-..
  4: ((LABELS QUILC-TESTS::TEST-FAITHFULNESS :IN QUILC-TESTS::TEST-FAITHFULNESS))
...
appleby commented 5 years ago

I will look into this later tonight, but being new to quilc it might take me a bit. If someone wants to unbreak the build on my behalf before then, please be my guest :).

ecpeterson commented 5 years ago

I’ll look at this tomorrow morning. It’s very likely a problem with the new comments not being read by whatever the quilc test is doing, and so the two matrices it’s trying to compare are only equivalent up to a qubit permutation it doesn’t know about. Similarly intended tests in the CL-QUIL test suite work OK, so I don’t expect something is fundamentally broken, and users can probably rest easy.

We’ll see, though!

appleby commented 5 years ago

I don't know a qubit from a cucumber so take this with a grain of salt, but I noticed that prior to this change, a CURRENT_REWIRING pragma appears at the end of code, just before the HALT:

$ ./quilc.before < app/tests/faithfulness-test-files/CCNOTs.quil | tail -3
RZ(-2.5480657262161737) 4
PRAGMA CURRENT_REWIRING "#(2 4 0 3 5 1 6 7)"
HALT

Whereas after, the rewiring is attached to the HALT as comment.

$ ./quilc < app/tests/faithfulness-test-files/CCNOTs.quil | tail -3
RX(-pi/2) 4
RZ(-2.5480657262161737) 4
HALT                                    # Exiting rewiring: #(2 4 0 3 5 1 6 7)

When quilc is invoked with the "--protoquil" flag, then the HALT instruction is stripped. In the former case the rewiring pragma remains and the single CURRENT_REWIRING turns into a sequence of 3 pragmas with an EXPECTED_REWIRING in the middle:

$ ./quilc.before -P < app/tests/faithfulness-test-files/CCNOTs.quil | tail -4
RZ(-2.5480657262161737) 4
PRAGMA CURRENT_REWIRING "#(2 4 0 3 5 1 6 7)"
PRAGMA EXPECTED_REWIRING "#(2 4 0 3 5 1 6 7)"
PRAGMA CURRENT_REWIRING "#(2 4 0 3 5 1 6 7)"

But since the rewiring is now "attached" to HALT, it gets dropped.

$ ./quilc -P < app/tests/faithfulness-test-files/CCNOTs.quil | tail -4
RX(pi/2) 4
RZ(1.760797612472632) 4
RX(-pi/2) 4
RZ(-2.5480657262161737) 4

I noticed that in quil::parsed-program-to-logical-matrix it does some twiddling of resultant matrix based on the rewiring pragmas/comments, but I have no idea what any of this means, so apologies if this is expected / irrelevant.

My next idea was to try replacing the HALT with a no-op stealing the rewiring comment and see if that fixes it, but I won't have time to try before @ecpeterson looks into it this morning, so posting this speculation now in case it's relevant.