lukpank / go-glpk

Go bindings for GLPK (GNU Linear Programming Kit)
GNU General Public License v3.0
36 stars 18 forks source link

Fails go test_glpk suite! #6

Open PYCChan opened 6 years ago

PYCChan commented 6 years ago

I have succeeded in installing and building your go-glpk package, linking to libglpk.a This static library is recompiled afresh using gcc and recent glpk version 4-64, and the check was successful: "OPTIMAL LP SOLUTION FOUND" on examples\plan.mps and examples\murtagh.mps and

Unfortunately, the (very thorough) test_glpk didn't succeed:

$ go test glp_free: ptr = 0000000000982D10; invalid pointer Error detected in file ..\src\env\alloc.c at line 59 exit status 3 FAIL github.com/lukpank/go-glpk/glpk 13.750s

I probably have to ask glpk specialists...

lukpank commented 6 years ago

Please try adding

func init() {
    runtime.LockOSThread()
}

to go-glpk/glpk/glpk_test.go and rerun the test and let me know if this solves your problem.

The problem (if the answer is yes) is that some recent versions of glpk use (by default) thread local memory for faster allocation and dealocation of memory but this does not play nice with Go which may run the same goroutine on different threads which leads to similar deallocation problems as described above. There are four possible solutions:

  1. Adding the above init function to your program and allocating/dealocating glpk problems only in the main goroutine.

  2. Disabling the use of thread local storage in glpk by recompiling glpk with:

$ ./configure --disable-reentrant
$ make
  1. I could allocate/deallocate problems on a single thread in go-glpk but this would slow down programs allocating many glpk problems compared to solution 1.

  2. I could try to convince glpk team to allow for runtime configuration of "disable-reentrant" (but this solution might not be backward compatible in used glpk API). At this point I could only check with glp_config("TLS") if tread local storage is used and make some action based on that.

PYCChan commented 6 years ago

After adding the init func and importing "runtime", go test gave the same error ;-(. Further notes 1) the two examples on the go-glpk home page (creating a pb with individual instructions for a 3x3 matrix and reading sample.lp) also gave the same error. 2) When building libglpk.a, the \src\misc\wclique1.c on lines 121 and 123 issued the warning: 'memset' specified size between 18446744071562067968 and 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Wstringop-overflow=]. Seems to be a problem with the O2 option. I tried O1, but then I got another pair of same warnings on \src\misc\keller.c on lines 109 & 114.

And many thanks for your plugin. I need it for my job. I will ASAP detail how I got to compile everything and build the glpk module on my Windows PC.

nskondratev commented 4 years ago

I suffered from the same issue and tried the suggestion with init function, but it also didn't help.

The working solution was to add the following code before lp := glpk.New():

runtime.LockOSThread()
defer runtime.UnlockOSThread()

lp := glpk.New()
defer lp.Delete()
// ...

I created repo with the working example: https://github.com/nskondratev/go-glpk-bench-example.