tket icon indicating copy to clipboard operation
tket copied to clipboard

Segmentation Fault with tket::Circuit::CommandIterator::operator++() for pytket

Open barney54321 opened this issue 2 years ago • 4 comments

When applying a RoutingPass to an RB circuit with more than 5 qubits with pytket, a Segmentation Fault is raised from tket::Circuit::CommandIterator::operator++(). This is consistently occuring with both Windows and Ubuntu (WSL) versions of pytket.

The gdb output is as so:

#0  0x00007fffa537e59f in tket::Circuit::CommandIterator::operator++() ()
   from /home/andrew/.local/lib/python3.8/site-packages/pytket/_tket/../../pytket.libs/libtket-Circuit-8a15d38f.so
#1  0x00007fffd3c54c30 in ?? ()
   from /home/andrew/.local/lib/python3.8/site-packages/pytket/_tket/circuit.cpython-38-x86_64-linux-gnu.so
#2  0x00007fffd3bdc317 in ?? ()
   from /home/andrew/.local/lib/python3.8/site-packages/pytket/_tket/circuit.cpython-38-x86_64-linux-gnu.so
#3  0x00000000005f6929 in PyCFunction_Call ()
#4  0x00000000005f74f6 in _PyObject_MakeTpCall ()
#5  0x000000000050c333 in ?? ()
#6  0x00000000005fe736 in ?? ()
#7  0x00000000005abf99 in ?? ()
#8  0x000000000056be9c in _PyEval_EvalFrameDefault ()
#9  0x0000000000569dba in _PyEval_EvalCodeWithName ()
#10 0x00000000005f6eb3 in _PyFunction_Vectorcall ()
#11 0x000000000056cc1f in _PyEval_EvalFrameDefault ()
#12 0x0000000000569dba in _PyEval_EvalCodeWithName ()
#13 0x00000000005f6eb3 in _PyFunction_Vectorcall ()
#14 0x000000000056bacd in _PyEval_EvalFrameDefault ()
#15 0x00000000005f6cd6 in _PyFunction_Vectorcall ()
#16 0x000000000056bacd in _PyEval_EvalFrameDefault ()
#17 0x0000000000569dba in _PyEval_EvalCodeWithName ()
#18 0x00000000005f6eb3 in _PyFunction_Vectorcall ()
#19 0x000000000056bbfa in _PyEval_EvalFrameDefault ()
#20 0x00000000005f6cd6 in _PyFunction_Vectorcall ()
#21 0x000000000056bbfa in _PyEval_EvalFrameDefault ()
#22 0x00000000005f6cd6 in _PyFunction_Vectorcall ()
#23 0x000000000056bbfa in _PyEval_EvalFrameDefault ()
#24 0x0000000000569dba in _PyEval_EvalCodeWithName ()
#25 0x000000000050bca0 in ?? ()
#26 0x000000000056cc1f in _PyEval_EvalFrameDefault ()
#27 0x0000000000569dba in _PyEval_EvalCodeWithName ()
#28 0x00000000005f6eb3 in _PyFunction_Vectorcall ()
#29 0x000000000056bbfa in _PyEval_EvalFrameDefault ()
#30 0x0000000000569dba in _PyEval_EvalCodeWithName ()
#31 0x00000000005f6eb3 in _PyFunction_Vectorcall ()
#32 0x000000000056bbfa in _PyEval_EvalFrameDefault ()
#33 0x0000000000569dba in _PyEval_EvalCodeWithName ()
#34 0x00000000005f6eb3 in _PyFunction_Vectorcall ()
#35 0x000000000056cc1f in _PyEval_EvalFrameDefault ()
#36 0x0000000000569dba in _PyEval_EvalCodeWithName ()
#37 0x00000000006902a7 in PyEval_EvalCode ()
#38 0x000000000067f951 in ?? ()
#39 0x000000000067f9cf in ?? ()
#40 0x000000000067fa71 in ?? ()
#41 0x0000000000681b97 in PyRun_SimpleFileExFlags ()
#42 0x00000000006b9d32 in Py_RunMain ()
#43 0x00000000006ba0bd in Py_BytesMain ()
#44 0x00007ffff7df2083 in __libc_start_main (main=0x4efd60 <main>, argc=2, argv=0x7fffffffe058, init=<optimized out>,
    fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe048) at ../csu/libc-start.c:308
#45 0x00000000005fc5fe in _start ()

I don't have a specific circuit that is causing this (as Python is hard crashing when the seg fault happens), but I can consistently make it occur when there are 6 qubits and at least 80 gates.

As the quality of the gdb output suggests, I'm not too familiar with C++ and don't really know what I should be looking for or what information is useful, but will happily try out different things if given direction

barney54321 avatar Aug 06 '22 12:08 barney54321

Ran again with valgrind and had the error occur with 30 gates:

==1274== Process terminating with default action of signal 11 (SIGSEGV)
==1274==  Access not within mapped region at address 0x0
==1274==    at 0x5D01459F: tket::Circuit::CommandIterator::operator++() (in /home/andrew/.local/lib/python3.8/site-packages/pytket.libs/libtket-Circuit-8a15d38f.so)
==1274==    by 0x59D69C2F: ??? (in /home/andrew/.local/lib/python3.8/site-packages/pytket/_tket/circuit.cpython-38-x86_64-linux-gnu.so)
==1274==    by 0x59CF1316: ??? (in /home/andrew/.local/lib/python3.8/site-packages/pytket/_tket/circuit.cpython-38-x86_64-linux-gnu.so)
==1274==    by 0x5F6928: PyCFunction_Call (in /usr/bin/python3.8)
==1274==    by 0x5F74F5: _PyObject_MakeTpCall (in /usr/bin/python3.8)
==1274==    by 0x50C332: ??? (in /usr/bin/python3.8)
==1274==    by 0x5FE735: ??? (in /usr/bin/python3.8)
==1274==    by 0x5ABF98: ??? (in /usr/bin/python3.8)
==1274==    by 0x56BE9B: _PyEval_EvalFrameDefault (in /usr/bin/python3.8)
==1274==    by 0x569DB9: _PyEval_EvalCodeWithName (in /usr/bin/python3.8)
==1274==    by 0x5F6EB2: _PyFunction_Vectorcall (in /usr/bin/python3.8)
==1274==    by 0x56CC1E: _PyEval_EvalFrameDefault (in /usr/bin/python3.8)
==1274==  If you believe this happened as a result of a stack
==1274==  overflow in your program's main thread (unlikely but
==1274==  possible), you can try to increase the size of the
==1274==  main thread stack using the --main-stacksize= flag.
==1274==  The main thread stack size used in this run was 8388608.

barney54321 avatar Aug 06 '22 12:08 barney54321

Hi, thanks for reporting this. To help us investigate the cause, please could you let us know the pytket version you are using, and attach a python script that produces the segfault when run?

cqc-alec avatar Aug 06 '22 14:08 cqc-alec

I've been able to reduce it to the bare minimum to get the issue. The seg fault seems to be occuring during the conversion back into qasm. I was also able to reproduce this when using the tk_to_qiskit converter instead of to qasm.

My OS is Windows 10 with Python 3.8.3, but the issue has also occured on Ubuntu and Arch machines running the most recent versions of Python and pytket.

pytket version: 1.5.0

from pytket.passes import RoutingPass
from pytket.transform import Transform
from pytket.qasm import circuit_to_qasm_str, circuit_from_qasm_str
from pytket.architecture import Architecture

qasm = """
OPENQASM 2.0;
include "qelib1.inc";
qreg q[25];
creg c[25];
cx q[2],q[1];
x q[4];
x q[5];
cx q[3],q[7];
cx q[0],q[3];
x q[7];
x q[8];
cx q[6],q[9];
x q[10];
x q[13];
x q[15];
cx q[7],q[15];
x q[15];
x q[15];
x q[7];
cx q[16],q[6];
x q[18];
cx q[18],q[12];
x q[19];
cx q[7],q[19];
cx q[7],q[9];
cx q[20],q[17];
x q[17];
x q[20];
x q[21];
x q[21];
cx q[4],q[21];
cx q[18],q[4];
x q[4];
cx q[23],q[11];
cx q[23],q[19];
x q[19];
cx q[24],q[10];
cx q[10],q[13];
cx q[10],q[20];
cx q[10],q[18];
x q[24];
cx q[17],q[24];
x q[17];
cx q[8],q[13];
barrier q[0],q[1],q[2],q[3],q[4],q[5],q[6],q[7],q[8],q[9],q[10],q[11],q[12],q[13],q[14],q[15],q[16],q[17],q[18],q[19],q[20],q[21],q[22],q[23],q[24];
cx q[0],q[3];
cx q[10],q[18];
cx q[10],q[20];
x q[15];
x q[15];
cx q[16],q[6];
x q[17];
cx q[17],q[24];
x q[17];
x q[19];
cx q[2],q[1];
x q[20];
cx q[20],q[17];
cx q[23],q[19];
cx q[23],q[11];
x q[24];
x q[4];
cx q[18],q[4];
cx q[18],q[12];
x q[18];
cx q[4],q[21];
x q[21];
x q[21];
x q[4];
x q[5];
cx q[7],q[9];
cx q[6],q[9];
cx q[7],q[19];
x q[19];
x q[7];
cx q[7],q[15];
x q[15];
x q[7];
cx q[3],q[7];
cx q[8],q[13];
cx q[10],q[13];
x q[13];
cx q[24],q[10];
x q[10];
x q[8];
barrier q[0],q[1],q[2],q[3],q[4],q[5],q[6],q[7],q[8],q[9],q[10],q[11],q[12],q[13],q[14],q[15],q[16],q[17],q[18],q[19],q[20],q[21],q[22],q[23],q[24];
measure q[0] -> c[0];
measure q[1] -> c[1];
measure q[2] -> c[2];
measure q[3] -> c[3];
measure q[4] -> c[4];
measure q[5] -> c[5];
measure q[6] -> c[6];
measure q[7] -> c[7];
measure q[8] -> c[8];
measure q[9] -> c[9];
measure q[10] -> c[10];
measure q[11] -> c[11];
measure q[12] -> c[12];
measure q[13] -> c[13];
measure q[14] -> c[14];
measure q[15] -> c[15];
measure q[16] -> c[16];
measure q[17] -> c[17];
measure q[18] -> c[18];
measure q[19] -> c[19];
measure q[20] -> c[20];
measure q[21] -> c[21];
measure q[22] -> c[22];
measure q[23] -> c[23];
measure q[24] -> c[24];
"""

tket_circ = circuit_from_qasm_str(qasm)

coupling = [[0, 1], [0, 5], [0, 6], [1, 0], [1, 2], [1, 5], [1, 6], [1, 7], [2, 1], [2, 3], [2, 6], [2, 7], [2, 8], [3, 2], [3, 4], [3, 7], [3, 8], [3, 9], [4, 3], [4, 8], [4, 9], [5, 0], [5, 1], [5, 6], [5, 10], [5, 11], [6, 0], [6, 1], [6, 2], [6, 5], [6, 7], [6, 10], [6, 11], [6, 12], [7, 1], [7, 2], [7, 3], [7, 6], [7, 8], [7, 11], [7, 12], [7, 13], [8, 2], [8, 3], [8, 4], [8, 7], [8, 9], [8, 12], [8, 13], [8, 14], [9, 3], [9, 4], [9, 8], [9, 13], [9, 14], [10, 5], [10, 6], [10, 11], [10, 15], [10, 16], [11, 5], [11, 6], [11, 7], [11, 10], [11, 12], [11, 15], [11, 16], [11, 17], [12, 6], [12, 7], [12, 8], [12, 11], [12, 13], [12, 16], [12, 17], [12, 18], [13, 7], [13, 8], [13, 9], [13, 12], [13, 14], [13, 17], [13, 18], [13, 19], [14, 8], [14, 9], [14, 13], [14, 18], [14, 19], [15, 10], [15, 11], [15, 16], [15, 20], [15, 21], [16, 10], [16, 11], [16, 12], [16, 15], [16, 17], [16, 20], [16, 21], [16, 22], [17, 11], [17, 12], [17, 13], [17, 16], [17, 18], [17, 21], [17, 22], [17, 23], [18, 12], [18, 13], [18, 14], [18, 17], [18, 19], [18, 22], [18, 23], [18, 24], [19, 13], [19, 14], [19, 18], [19, 23], [19, 24], [20, 15], [20, 16], [20, 21], [21, 15], [21, 16], [21, 17], [21, 20], [21, 22], [22, 16], [22, 17], [22, 18], [22, 21], [22, 23], [23, 17], [23, 18], [23, 19], [23, 22], [23, 24], [24, 18], [24, 19], [24, 23]]
arc = Architecture(coupling)

# Route the circuit
cx_pass = RoutingPass(arc)
cx_pass.apply(tket_circ)

# Decompose Bridges into CNOTs
transformer = Transform.DecomposeBRIDGE()

transformer.apply(tket_circ)

new_qasm = circuit_to_qasm_str(tket_circ)

print(new_qasm)

barney54321 avatar Aug 19 '22 08:08 barney54321

Excellent, thank you. Will investigate.

cqc-alec avatar Aug 19 '22 09:08 cqc-alec

Hello @barney54321, this bug has now been fixed with this pull request https://github.com/CQCL/tket/pull/578. The pull request description has an explanation of why this problem occurred if you're interested.

sjdilkes avatar Oct 17 '22 15:10 sjdilkes