-
Notifications
You must be signed in to change notification settings - Fork 24
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
Python DSP #205
Comments
In case you don't know yet, we have a modeling interface in Julia: https://github.com/kibaekkim/DSPopt.jl With the package, you can simply model problems in algebraic form. If you want/need to use Python, you have to use the C-library functions available in DSP, as you are already trying. I think the problem data is not correctly defined in your example. The problem data should be compatible to the function arguments defined here: Lines 292 to 306 in 6675d30
In particular, these three arguments should represent the constraint matrix in row-wise sparse format: Lines 298 to 300 in 6675d30
What you are trying to do has been coded in Julia like this: |
First, Thanks for you time and your quick response. All my models are written in Python so I would rather implement my own interface with DSP directly rather than going through Julia. I see my mistake in the argument CoinBigIndex * start, I should have passed an int type row there. However, I still get a segfault when I do so. If possible, could you explain with a toy c++ model how you would instanciate a block MILP directly from handwritten vectors and solve it ? Thanks for your help again, MIFTARI B |
@MiftariB I am working on a c++ example, but this will take some time. |
Dear @kibaekkim, Thanks for the answer and sorry for my previous enquiry, it came too early in my using of DSP. However, I made some progress in the python front. This is the current state:
Adding the different blocks seems to work. However, the model printing yields a segfault after printing the "parent/master". I added the corresponding log file python_print.log. I tried not printing and going straight to the solving but the extended form also segfaults (python_de.log), dantzig-wolf yields a more complicated python error that i am yet to figure completely out (python_dw.log). I am not sure to understand where these segfaults could come from. Is there something else that i am using wrongly ? Is the work-flow more or less the correct one now ? Best regards, MIFTARI B |
By quickly looking at your example, I see the example is using I also found one potential issue causing segfault from the print function. I will fix that shortly. |
Hi, I only use the COO form to match the pickle files. CSR matrices are sent to DSP corresponding to the lines :
and the lines
I will definitively have a look at your C++ example. Thanks. Regards, MIFTARI B |
Oh, I see. Thanks for the clarification. I must have overlooked that. I will try to run your example on my side. |
I am not familiar with python. But, this simple code is not running on my mac or linux, returning segfault. from ctypes import *
libDSP = cdll.LoadLibrary("libDsp.dylib")
pointer_to_model = c_void_p(libDSP.createEnv())
# libDSP.freeEnv(byref(pointer_to_model)) # This does not run either.
libDSP.freeEnv(pointer_to_model) But, this simple c++ code is running fine: #include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
int main(int argc, char **argv)
{
void *handle;
char *error;
handle = dlopen ("libDsp.dylib", RTLD_LAZY);
if (!handle) {
fputs (dlerror(), stderr);
exit(1);
}
void* env = NULL;
env = ((void *(*)())dlsym(handle, "createEnv"))();
if (env == NULL) {
printf("Failed to create DSP environment.\n");
} else {
printf("Successfully created DSP environment.\n");
}
if (env != NULL) {
((void (*)(void*&))dlsym(handle, "freeEnv"))(env);
env = NULL;
printf("Successfully freed DSP environment.\n");
}
dlclose(handle);
return 0;
} @MiftariB Any idea from this? |
The following code works perfectly on my end
producing the following output test.log. I ran this code on Windows subsystem Linux Ubuntu 18.04 with python 3.7.5 and DSP installed with Cplex and Gurobi. Can you maybe try the following :
The problem might come from not knowing the return and argument types respectively. Can you tell me whether it's freeing or allocating the model that creates the segfault ? (I guess the freeing does.) |
Yes, giving explicit types fixed the python issue. I have also fixed some bugs in the DSP code. Can you try again with branch |
Thanks. I changed slightly the file by adding the arguments and return types :
I also pulled the branch (and rebuild DSP). The model printing and the extensive method do not segfault anymore. The result from DE is slightly different from the one i get with CPLEX (DE : 154.4 - CPLEX : 146.6000000003857). I still have to figure out why. Might come from the encoding. DW still produces the error :
Here is also the full file, I used linking_test.zip. |
# libDSP.loadBlockProblem(pointer_to_model, b_number+1, c_int(block_nb_col), c_int(block_nb_lines), len(block_val),
# block_row, block_col, block_val, minus_infinity_col, plus_infinity_col, block_coltypes, objective_nul, row_lb, row_up)
libDSP.loadBlockProblem(pointer_to_model, b_number+1, c_int(nb_col), c_int(block_nb_lines), len(block_val),
block_row, block_col, block_val, minus_infinity_col, plus_infinity_col, master_coltypes, master_C, row_lb, row_up) But, it does not seem to give the correct solution. I will look into that more. |
Hi @kibaekkim, I made a few changes. My lower bound in blocks was incorrect (not enough values if master block had less constraints than another block). One of the pickle files was incorrect too. I corrected both issues and now I have the correct objective : 146.6. Thanks for the help ! I still need to figure out what is going on with DW. However, I don't fully understand why do we need the changes referenced in the previous comment : #205 (comment). Regards, MIFTARI B |
Sorry for the double comment. I tried your modifications. I obtain the exact same output for the extensive form python_de.log. However, when trying with DW, I get the following output python_dw.log which ends with a segfault when trying to retrieve the solution (I guess) as it classifies the problem as unfeasible. |
The reason is based on how it should be used, for example:
Yes, the subproblem is infeasible. See sub1.mps.zip. |
There is something I am not getting. In the problem I am trying to solve, I put every variable as free. However in your mps file, they are fixed to 0. And of course, the constraint x49 <= -6.9 becomes unfeasible in that case. |
I found that these need to be added after adding blocks. libDSP.updateBlocks.argtypes = [c_void_p]
libDSP.updateBlocks(pointer_to_model) In future, I will see if I can prevent Known bugAfter adding the lines above, I ran again and found that one of your subproblems becomes unbounded and terminates the algorithm with error. This is a known bug I just found today (#211). WorkaroundFor now you can avoid this by adding some bounds on your variables. For example, I was able to find the objective value of 154.4 with the variable bounds [-20, 20]. |
Thanks for the update. I will keep up with the issue 211 then. Thanks for your help ! I will be implementing a clean-up ( and more general) version of the python linking with DSP. Thanks for your help, Best regards, MIFTARI B |
@MiftariB Awesome! I would really appreciate if you can share your python example with us in this repo. |
Sure ! We will keep in touch ! Thanks again ! |
Dear @kibaekkim, I am writing to follow up on our earlier exchange about a Python interface for DSP. To give some context, @MathiasPBerger and I are researchers at the University of Liège (Belgium) and we have been developing a new optimization modelling language for structured mixed-integer linear programming problems called GBOML. In short, GBOML makes it possible to exploit the underlying problem structure in order to simplify model encoding, enable model re-use, speed up model generation (e.g., by parallelizing matrix generation) and facilitate the application of structure-exploiting algorithms. The GBOML parser is written in Python and we decided to develop an interface to DSP to promote the use of structure-exploiting algorithms. DSP's Extensive Form and Dantzig-Wolfe algorithms have been tested via the Python interface so far, and we plan on testing the dual decomposition algorithm shortly. To learn more about GBOML, here is the documentation. Our understanding is that you were interested in having a look at the Python interface, and we wanted to let you know that we would be happy to share the code with you. We plan on maintaining an interface to DSP as part of GBOML but the code could also be made stand-alone for other people to use. We would love to hear your thoughts on this. Best regards, Miftari B |
@MiftariB Thanks for the update. The package looks very interesting. I am interested in trying your package for some of our examples. Please feel free to let us know if there is anything we can do on the DSP side. I would also like to draw your attention on a Julia package that may be relevant to this direction of your research: https://github.com/zavalab/Plasmo.jl Does your team also have a plan for modeling beyond linear? For example, quadratic, second-order cone, etc..? Given that one of your examples considers power system, it would be great to have some nonlinear supports. |
Dear @kibaekkim, Sorry with the late reply, we were a little overwhelmed by work lately. First, thanks for trying our package, any feedback we can get is very valuable to us. Do not hesitate to ask questions on our gitlab. Thanks for the link, we already knew about Plasmo and were asked about it in a very interesting discussion with one of our reviewers for our JOSS submission. Thank you for offering your help, we will recontact you in a near future to talk about our experimenting of DSP. Concerning modeling beyond linear, it is not in our mid-term goals to do so. We would like to focus our attention to graph partitioning and structure exploiting methods in MILPs. If you have any interesting ideas or references on these subjects, we would love to hear them. Best Regards, Miftari B |
Hi,
I am looking to pass a structured MILP problem to DSP via python ctypes. However, I don't fully understand the workflow that needs to be implemented. I tried to add a single block to the DspApiEnv but I get a SEGFAULT each time.
My python code :
Could you help me understand the different functions I need to call to pass a block structured MILP to DSP ?
Thanks in advance for your help.
Best Regards,
Miftari B
The text was updated successfully, but these errors were encountered: