Skip to content

quilc crashes with SBCL heap exhaustion during quil_to_native_quil compilation #932

@lichkim

Description

@lichkim

Description

While compiling a Quil program targeting a QPU(Ankaa-3) through pyQuil, quilc crashes during the quil_to_native_quil stage with an SBCL heap exhaustion error. Instead of returning a compilation failure or diagnostic message, the compiler terminates with a fatal SBCL garbage collection error.

A pyQuil maintainer suggested reporting this issue directly to the quilc maintainers.

Environment

  • pyQuil: 4.17
  • quilc: 1.20.0 [7db3c19]
  • Target QPU: Ankaa-3
  • OS: Debian GNU/Linux 13 (trixie)

Reproducible Example

from pyquil import Program, get_qc
from pyquil.gates import *
from pyquil.quilbase import Declare
from pyquil.quilatom import Label
from qcs_sdk.qpu.translation import get_quilt_calibrations

QPU_NAME = "Ankaa-3"
SHOT_COUNT = 10

qubits_by_readout_line = [
    # Get the qubits from each `DEFFRAME [...] "ro_rx"` instruction
    [q.index for q in frame.qubits]
    for frame in Program(get_quilt_calibrations(QPU_NAME)).frames
    if frame.name == "ro_rx"
]

AS_QVM = False

qc = get_qc(QPU_NAME, as_qvm=AS_QVM)

qubits_readout1 = qubits_by_readout_line[0]
qubits_readout2 = qubits_by_readout_line[1]

q0 = qubits_readout1[0]
q1 = qubits_readout2[0]

program = Program()

ro_0 = program.declare('ro_0', 'BIT', 1)
ro_1 = program.declare('ro_1', 'BIT', 1) 
test_register = program.declare('test_register', 'BIT', 2)

program += H(q0)
program += CNOT(q0, q1)

program += MEASURE(q0, ro_0)
program += MEASURE(q1, ro_1)
program += X(q0)
program += MEASURE(q0, test_register[0])

if AS_QVM:
    program = program.wrap_in_numshots_loop(SHOT_COUNT)
else:
    # Live QPU requires manual shot count loop with 'with_loop'
    shot_count = program.declare('shot_count', 'INTEGER', 1)
    memory_map = {"shot_count": [SHOT_COUNT]}
    program = program.with_loop(SHOT_COUNT, shot_count, Label("start-loop"), Label("end-loop"))

# Resolve labels
program.resolve_label_placeholders()
print(program)

compiled_program = qc.compiler.quil_to_native_quil(program, protoquil=False)

executable = qc.compiler.native_quil_to_executable(compiled_program)

result = qc.run(executable, memory_map)

Expected Behavior

The compiler should either:

  • successfully compile the program, or
  • return a structured compilation error explaining why the program cannot be compiled

Actual Behavior

quilc crashes with a fatal SBCL error during compilation

quilc Error log

Heap exhausted during garbage collection: 48 bytes available, 80 requested.

fatal error encountered in SBCL:
GC invariant lost, file "gencgc.c", line 472

Stack trace excerpt:

CL-QUIL::ACTIVE-STATE-APPLY 
CL-QUIL::SEARCH-REWIRING 
CL-QUIL::SELECT-SWAPS-FOR-REWIRING 
CL-QUIL::MOVE-TO-EXPECTED-REWIRING 
CL-QUIL::DEQUEUE-GATE-APPLICATION 
CL-QUIL::DO-GREEDY-ADDRESSING 
CL-QUIL::COMPILER-HOOK 
QUILC::PROCESS-PROGRAM

Question

Is this a known limitation related to memory usage during the routing/rewiring stage?
If so, are there recommended configuration options (e.g., --dynamic-space-size) or compiler flags that should be used when compiling such programs?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions