Decision Optimization

 View Only
  • 1.  Change in .NET API, « Cplex.Param.Threads » obsolete ?

    Posted Fri February 10, 2023 09:12 AM

    Hello dear community !

       For the context, I had made a helper wrapper library around OPL CPLEX .NET API in F#.

       I support CPLEX version from 12.9 up to the latest (22.1.1), it seems we have a change in the API in the latest versions, which is okay if we want CPLEX to evolve, but I'm having a hard time finding what I must do to correct the situation.

       This part of F# code seems to now be broken, as « Cplex.Param.Threads » now seems to be null :

        match maxParallelismeCPLEX with
        | Some n -> cplex.SetParam(Cplex.Param.Threads, n)
        | _ -> ()

       Now « SetParam » seems to complain about it.

       Looking in the specifications for 22.1.1, the parameter still seems to be active and recomended for use in the .NET API :

    https://www.ibm.com/docs/en/icos/22.1.1?topic=parameters-global-thread-count

       If I look at this part of the specification :
    https://www.ibm.com/docs/api/v1/content/SSSA5P_22.1.1/ilog.odms.cplex.help/refdotnetcplex/html/F_ILOG_CPLEX_Cplex_IntParam_Threads.htm

       ... it says obsolete, but to use the « Cplex.Param » hierarchy, which is what I think I'm using.

       Another place to look into would be « Cplex.SetParam » :
    https://www.ibm.com/docs/en/icos/22.1.1?topic=cm-setparam-method-1

       ... but nothing about being obsolete, or any redirection to another kind of method.

       So long intro for my question, sorry about that, but how do I specify the number of threads to be used by the CPLEX engine for a specific instance with the newest version of CPLEX ?

       You guys do an amazing job already in this matter, but I humbly suggest you fix the documentation in the future to help migrating the user code. I can assure you, I'm the living proof, some are really reading it ! ;)

    Thanks !



    ------------------------------
    Luc Charest
    ------------------------------


  • 2.  RE: Change in .NET API, « Cplex.Param.Threads » obsolete ?

    Posted Mon February 13, 2023 08:03 AM

    Dear Luc,

    It is very strange. On our side, when running the AdMIPex5.cs example that uses the Threads parameter using 22.2.1.1 we have no problem setting the threads.

    Could you please try run this example using your installation (using the example project file in C:\Program Files\IBM\ILOG\CPLEX_Studio2211\cplex\examples\x64_windows_msvc14\stat_mda ) and tell us the outcome?

    If it works, please compare the path used by the project file and yours.

    Cheers,



    ------------------------------
    Renaud Dumeur
    ------------------------------



  • 3.  RE: Change in .NET API, « Cplex.Param.Threads » obsolete ?

    Posted Mon February 13, 2023 09:42 AM

    Hello Renaud,

       Ahhh thanks for the hint ! It seems I should look more into the latests versions of the examples ! 

       I tried the example you highlighted, and it works fine. So the difference we can inspect with respect to my situation :

    • I use a reference to oplall.dll; you use a reference to ILOG.Concert.dll and ILOG.CPLEX.dll
    • I use F#; you use C#

       So I included the two other dll, and I tried to change the order of inclusion ("open ILOG.OPL" before/after "open ILOG.CPLEX" in F#)

    When "ILOG.CPLEX" is last (overrides I think the previous shared definitions), I get an error : "Error    FS0041    Aucune surcharge correspondante pour la méthode 'SetParam'"

    So it seems F# sees both definitions of "Threads" as distinct, when I write and debug the following code...

        let a = ILOG.OPL.Cplex.Param.Threads
        let b = ILOG.CPLEX.Cplex.Param.Threads

    a gets "null" assigned

    b gets "{Cplex.Param.Threads}" assigned

    And I guess the error comes from the fact that my "cplex" object is a "ILOG.OPL.Cplex" where yours is a "ILOG.CPLEX.Cplex".

    Bottom line, I guess the question is what have you changed in the definition of Threads for the oplall.dll generation that gets undefined when it used to be defined in the previous versions ?

    Meanwhile I'll see if I can work on something on my side as trying to do some typecast into ILOG.CPLEX namespaces which seems to be working... 

    If nothing works for me, I'll try to reproduce the problem into a toy F# example and send it to you.

    Thanks!



    ------------------------------
    Luc Charest
    ------------------------------



  • 4.  RE: Change in .NET API, « Cplex.Param.Threads » obsolete ?

    Posted Mon February 13, 2023 09:57 AM

    <<some typecast into ILOG.CPLEX namespaces which seems to be working>>

    If it work, it's just luck (I guess it is because a param is just a wrapper on top of an integer id after all). The implementation are totally different. 

    That's one of the reason why we moved the Cplex class in the OPL namespace years ago.

    A safer workaround would be to try 

    ```

    cplex.SetParam(new Cplex.IntParam(1067, null), n);

    ```



    ------------------------------
    Vincent Beraudier
    ------------------------------



  • 5.  RE: Change in .NET API, « Cplex.Param.Threads » obsolete ?

    Posted Mon February 13, 2023 12:13 PM
    Edited by Luc Charest Mon February 13, 2023 12:14 PM

    Hello Vincent,

       You are right F# won't let me typecast, I thought there could be some inheritance involved or some kind of partial class definition, but as you said it seems to be distinct classes.

    I tried what you suggest but it seems I can instantiate a new one of the ...CPLEX namespace, but can't instantiate one from the ...OPL namespace :



    ...so it won't solve my problem, as F# won't let me pass it to the method "SetParam" of the other namespace.

    I also tried to create a CPLEX instance on the ILOG.CPLEX namespace, set the parameter to 4 threads, then create a CPLEX instance using my OplFactory on the ILOG.OPL side (thinking since the documentation says it is a "global" parameter it would the one on the OPL side would inherit the value set on the CPLEX side), it compiled and ran but it did not seem to be taken in account, still running at 12 threads.

    So to be clear, in summary, I failed to find a way the set the number of threads from a CPLEX created with an OplFactory, in the ILOG.OPL namespace. 

    After lunch I will try to reproduce with a plain toy project in C#, using oplall.dll (not the other two DLLs), and then if it works, I'll try setting up a toy project in F#. This would prove or disprove if the langage used is the source of the problem.

    Thanks !



    ------------------------------
    Luc Charest
    ------------------------------



  • 6.  RE: Change in .NET API, « Cplex.Param.Threads » obsolete ?

    Posted Mon February 13, 2023 12:58 PM

    You are right, this does not work in OPL as in the OPL implementation, those objects are not public.

    1 workaround I was able to do in Java is

    ilog.cplex.cppimpl.IloCplex cplex = factory.createCplex().getCplexImpl();
    cplex.setIntParam( new ilog.cplex.cppimpl.IloCplex.IntParam(null, 1067), 5 );

    Can you try it while dev team looks at current public implementation?

    In .NET, you will have to add capital case in all places.



    ------------------------------
    Vincent Beraudier
    ------------------------------



  • 7.  RE: Change in .NET API, « Cplex.Param.Threads » obsolete ?

    Posted Mon February 13, 2023 03:06 PM

    Hello Vincent,

      Thank you, your work around worked :

        let threadParam = new ILOG.CPLEX.Cppimpl.IloCplex.IntParam(null, 1067)
        let cplexImpl = cplex.getCplexImpl()
    
        match maxParallelismeCPLEX with
        | Some n -> 
            cplexImpl.setIntParam(threadParam, n)
        | _ -> ()

       Please let me know if the plan is to bring back the original ILOG.OPL.Cplex.Param.Threads or if the plan is to migrate the code to some other future ways of doing.

    Thanks ! :)



    ------------------------------
    Luc Charest
    ------------------------------