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

Segmentation fault when running LPs repeatedly #8

Open
frogeyedpeas opened this issue Mar 25, 2023 · 4 comments
Open

Segmentation fault when running LPs repeatedly #8

frogeyedpeas opened this issue Mar 25, 2023 · 4 comments

Comments

@frogeyedpeas
Copy link

frogeyedpeas commented Mar 25, 2023

Hello I am using a MAC OS Big Sur Version 11.3.1

When I run the solver multiple times SOMETIMES it segmentation faults, I dont know if this is because of qsopt_ex or because of the cython library. Just copy the code below into a file called reproducing_seg_fault.py and run the program like 20 or so times consecutively. One of the times will result in a segfault (see here)
Screen Shot 2023-03-24 at 8 20 21 PM

Code here:

import qsoptex

import faulthandler
faulthandler.enable()

#import logging
#logging.basicConfig(level=logging.NOTSET)

class Polytope:
    def __init__(self, A, b):
        self.A = A
        self.b = b
        self.status = None
        """
            The status variable carries the status of a most recent solve, if it is set to None then an LP run has not occurred yet 
        """
        self.p = None

    def dimension(self):
        return len(self.A[0])
    
    def inequality_count(self):
        return len(self.A)

    #given an objective array c we attempt to maximize it and return the status, surprising the "c" tells us what the dimension of the problem is 
    def maximize(self, c, flag_integers=True): 
        self.p = qsoptex.ExactProblem()
        for var_number in range(len(c)):
            self.p.add_variable(name='x' + str(var_number), 
                objective=c[var_number], 
                lower=0, upper=1)

        for constraint_number in range(self.inequality_count()):
            self.p.add_linear_constraint(qsoptex.ConstraintSense.LESS, 
                dict(('x' + str(var_number), self.A[constraint_number][var_number]) for var_number in range(len(c))), 
                rhs = self.b[constraint_number], 
                name='c' + str(constraint_number))

        self.p.set_objective_sense(qsoptex.ObjectiveSense.MAXIMIZE)
        self.p.set_param(qsoptex.Parameter.SIMPLEX_DISPLAY, 1)
        print("before seg fault: ")
        self.status = self.p.solve()
        print("after seg fault: ")


    

if __name__ == '__main__':

    #running one at a time never results in a segfault
    #running both of these repeatedly results in a segfault 

 
    A_matrix =  [[1037066, 2074132, 1648264, 796528, 1593056, 686112, 1372224, 244448, 488896, 977792, 1955584, 1411168, 322336, 644672, 1289344, 78688, 157376, 314752, 629504, 1259008], [-1037066, -2074132, -1648264, -796528, -1593056, -686112, -1372224, -244448, -488896, -977792, -1955584, -1411168, -322336, -644672, -1289344, -78688, -157376, -314752, -629504, -1259008]]
    b_matrix =  [2463098, -2463098]
    c_matrix =  [0, -1, 1, -1, 1, -1, 0, 0, 0, 0, -1, 0, -1, -1, 0, 1, 0, 1, 1, -1]

    test_polyhedron = Polytope(A_matrix, b_matrix)
    
    test_polyhedron.maximize( c_matrix)

    A_matrix =  [[1037066, 2074132, 1648264, 796528, 1593056, 686112, 1372224, 244448, 488896, 977792, 1955584, 1411168, 322336, 644672, 1289344, 78688, 157376, 314752, 629504, 1259008], [-1037066, -2074132, -1648264, -796528, -1593056, -686112, -1372224, -244448, -488896, -977792, -1955584, -1411168, -322336, -644672, -1289344, -78688, -157376, -314752, -629504, -1259008]]
    b_matrix =  [2463098, -2463098]
    c_matrix =  [0, -1, 1, -1, 1, -1, 0, 0, 0, 0, -1, 0, -1, -1, 0, 1, 0, 1, 1, -1]

    test_polyhedron = Polytope(A_matrix, b_matrix)

    test_polyhedron.maximize( c_matrix)
@frogeyedpeas frogeyedpeas changed the title Segmentation fault when running identical LPs Segmentation fault when running LPs repeatedly Mar 25, 2023
@frogeyedpeas
Copy link
Author

frogeyedpeas commented Mar 28, 2023

here is my python version Python 3.8.2 (default, Jun 8 2021, 11:59:35) [Clang 12.0.5 (clang-1205.0.22.11)] on darwin and the shell i'm using is zsh

@frogeyedpeas
Copy link
Author

So I have noticed that if I don't have two systems back to back I cannot get the segfault to occur. This suggests to me that some kind of caching routine (maybe reading from a bad cache) is causing the segfaults in the first place.

@frogeyedpeas
Copy link
Author

frogeyedpeas commented Mar 28, 2023

So with some inspection it appears that line 481 in the file qsoptex.pyx is to blame

r = cqsoptex.QSexact_solver(self._c_qsdata, NULL, NULL, NULL, cqsoptex.PRIMAL_SIMPLEX, &status)

I'm out of my depth here but I can follow that line of code the to the file csqoptex.pxd line 96

int QSexact_solver(mpq_QSdata* problem, mpq_t* const x, mpq_t* const y, QSbasis* const basis, int simplexalgo, int* status)

and this basically appears to wrap a direct call to the qsoptex library in exact.h

@frogeyedpeas
Copy link
Author

frogeyedpeas commented Apr 7, 2023

The segfault is caused by line 721 here: https://github.com/jonls/qsopt-ex/blob/master/qsopt_ex/exact.c particulary just accessing the qslp->colnames structure see below:
Screen Shot 2023-04-07 at 1 49 54 PM

It appears that the colnames pointer is being accessed like an array on elements which do not cast like strings

Screen Shot 2023-04-07 at 1 54 06 PM

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

1 participant