Forum Discussion
FICO
8 years agoCommunity Manager
Is it possible that the XPRESS c-libraries can be called directly from Python using ctypes?
I have successfully called a C dll from Python (using ctypes) that calls XPRMInit, XPRMloadmod etc but it would be nice to avoid the need to create the DLL altogether and call these functions directly.
I have tried this but XPRMload mod is returning an int 0 and I can't see how to represent the XPRMModel reference returned by XPRMloadmod from within Python.
9 Replies
- FICOCommunity Manager
In xprm_rt.h, the XPRMmodel type is defined as follows:
typedef struct Model* XPRMmodel;
This means, that it is a pointer to a struct. In ctypes, use the void pointer c_void_p to represent that pointer. By default, ctypes assumes that the result type of a function is a c_int. You have to change it to c_void_p. Moreover, you have to set the function argument types to the c type that represents "char *": c_char_p.
lib.XPRMloadmod.restype = c_void_p
lib.XPRMloadmod.argtypes = [c_char_p, c_char_p]
Now you can call the function as follows, assuming that bname and intname are normal Python strings:
mod = lib.XPRMloadmod(bname.encode(), intname.encode())
I am preparing an example and will attach it to this thread, when it is finished.
- FICOCommunity Manager
Thanks, this is really good news.
I'm afraid that the next hurdle I am struggling with is the int * arg for
int XPRMrunmod(XPRMmodel model, int *returned, const char *parlist);
I'd tried unsuccessfully with:
mosel.XPRMrunmod.restype = c_int
mosel.XPRMrunmod.argtypes = [c_void_p, POINTER(c_int), c_char_p]
r = mosel.XPRMrunmod(model, result, None)
but get
ctypes.ArgumentError: argument 2: <class 'TypeError'>: expected LP_c_long instance instead of int
- FICOCommunity Manager
The signature for XPRMrunmod is:
lib.XPRMrunmod.restype = c_int
lib.XPRMrunmod.argtypes = [c_void_p, POINTER(c_int), c_char_p]
And the function call is:
def runmod(model, parlist):
returned = c_int()
status = lib.XPRMrunmod(model, byref(returned), parlist.encode())
return status, returned
where model is of type c_void_p, coming from loadmod, and parlist is a normal Python string. The example that I will post will contain both functions and a few more.
- FICOCommunity Manager
Enclosed you find a working example including two example modules for xprm_rt and xprm_mc.
- FICOCommunity Manager
Thanks. That's perfect. It would probably be worth adding this to the libraries documentation as it really helps users in Python who want to keep using Mosel for the modelling.
- FICOCommunity Manager
Hi Johannes, I have been testing your example files and while they work fine in Xpress 8.5, I cannot get them working in Xpress 8.6 nor 8.8.
For example, `lib.XPRMfindident()` always returns `(0, c_void_p(None))`...
Is there some fix to make this work with the latest Xpress?
- FICOCommunity Manager
Hello Michal: The interface example provided by Johannes earlier in this discussion thread does not seem to contain any definition of ‘XPRMfindident’ – would you be willing to share the extension of the code that you are working with?
Besides that, Release 8.6 of Xpress comes with Mosel 5 where we enforce the use of the ‘public’ marker on any entities that you wish to make visible to external programs when using standard compilation of the Mosel model (global, non-public entities will remain visible with debug compilation). I would assume that adding a ‘public’ marker (either onto the whole ‘declarations’ block or for individual entities) will correct the problem that you are reporting.
- FICOCommunity Manager
Hi Susanne, you were right: I have not noticed that 8.6 started enforcing the 'public' marker (I did not even know there was such a marker). Once I added it to the Mosel model, the Python code as expected - thanks!
You are also right that Johannes' example did not use XPRMfindident - I have added support for more functions from C library and have not noticed that this was one of those. The code itself is simple enough:
def findident(model, name): returned = c_void_p() objType = lib.XPRMfindident(model, name.encode(), byref(returned)) return objType, returnedAnd yes, i would be willing to share my extension of the code, with the understanding that it is just an extension of an example (not a full module), written by someone wihtout much experience with Python...
Are you thinking github, or do you have some more suitable place?
- FICOCommunity Manager
Hello Michal, we do not yet have Github repository with this Python interface example: to start with, you could perhaps simply upload your updated version of the code as an attachment to this discussion thread? Please edit the header text to document the additions / revisions that you have made to the original version of the code.
Related Content
Related Content
Hi, Currently we are working with Blaze v7.6, if we want to move to DM, Do we need to migrate to latest blaze(v7.10.) first and then to DM? or directly to DM? If to DM directly, existing DTs, Other templates can we reuse? OR need to create from scratch?
If we can move to DM directly, existing DTs, Other templates in the project can we reuse? OR need to create everything from scratch as per the DM standards?5Views0likes1CommentIs it possible to count all possible Solutions of a Problem?
I wondered wether its possible to either get the number of all possible solutions of a problem or to actually block a solution after an optimization (in my case its minimize an IP) is done to search ...1 year agoPlace FICO® Xpress Optimization ForumFICO® Xpress Optimization Forum3 unread comments3 unread1View0likes3CommentsIs it possible to output the used solving algorithm?
I'm usually working with Xpress Workbench or the optimizer via bash on Linux. Out of curiosity I compared its performances with the Xpress IVE 64bit and there I noticed the statistics tab with detail...1 year agoPlace FICO® Xpress Optimization ForumFICO® Xpress Optimization Forum6 unread comments6 unread0Views0likes6Comments