coin-or / Ipopt

COIN-OR Interior Point Optimizer IPOPT
https://coin-or.github.io/Ipopt
Other
1.4k stars 276 forks source link

Add a pardisomkllib option #654

Open amontoison opened 1 year ago

amontoison commented 1 year ago

Is it possible to add an pardisomkllib like hsllib or pardisolib? It's also not possible to switch to pardisomkl solver dynamically.

Setting: "pardisomkl" is not a valid setting for Option: linear_solver. Check the option documentation.

### linear_solver (String)  ###
Category: Linear Solver
Description: Linear solver used for step computations.
Valid Settings:
    ma27 (load the Harwell routine MA27 from library at runtime)
    ma57 (load the Harwell routine MA57 from library at runtime)
    ma77 (load the Harwell routine HSL_MA77 from library at runtime)
    ma86 (load the Harwell routine MA86 from library at runtime)
    ma97 (load the Harwell routine MA97 from library at runtime)
    pardiso (load the Pardiso package from pardiso-project.org from user-provided library at runtime)
    mumps (use the Mumps package)
    custom (use custom linear solver (expert use))

It should be great to also have a similar option for the Spral solver.

svigerske commented 1 year ago

Probably it is possible, but it is extra effort to implement this.

The reason to do so for HSL and Pardiso (from pardiso-project.org) was that these are codes that one cannot freely redistribute. But MKL and Spral have liberal licenses. So like you have been doing for Mumps, you can just link against these while building Ipopt.

With Pardiso from MKL, I'm also not sure how smooth things will work if one uses a different Blas/Lapack for Ipopt. Loading MKL libs with RTLD_LOCAL seems to be a problem due to the MKL distributing their symbols over different libraries. Loading with RTLD_GLOBAL would load also all the Blas/Lapack symbols into the main namespace, possibly creating new issues.

amontoison commented 1 year ago

If we build Ipopt with Mumps and Spral. Will we be able to switch between Mumps and Spral solvers? If it's the case, it solves the problem for Spral.

For PardisoMKL, I don't think that we can easily solve the problem because we already compile Ipopt with LBT (libblastrampoline) and we don't want to use the symbols of libmkl_rt for BLAS / LAPACK routines. Maybe the order of the flags here is relevant but I never tested. I thought that loading PardisoMKL externally with pardisomkllib will avoid this issue.

svigerske commented 1 year ago

Yes, if you build Ipopt with Spral, the default for the linear solver in Ipopt will change to spral, but you can use Ipopt option linear_solver to select Mumps.

I would just leave this issue open for now as a reminder to add an option to also load MKL's Pardiso at runtime some day.

Btw, the line 45 (https://github.com/JuliaPackaging/Yggdrasil/blob/master/C/Coin-OR/Ipopt/build_tarballs.jl#L45) seems to be missing a $ before {BLAS_LAPACK}.

amontoison commented 1 year ago

Thanks for the typo with {BLAS_LAPACK}! I plan to recompile Ipopt tomorrow, do you have a flag / option to compile Ipopt with -03? I didn't find it in the documentation where we should set the optimization level.

Off-topic: For information, we just released JuliaHSL. :tada: It could be also relevant for users that are using Ipopt without Julia.

svigerske commented 1 year ago

You would have to overwrite or augment the compiler flags that configure is determining. By default, that is -02 -DNDEBUG for C/C++ and -O2 for Fortran.

You should be fine by adding CFLAGS="-O3 -DNDEBUG" CXXFLAGS="-O3 -DNDEBUG" FFLAGS=-O3 FCFLAGS=-O3 to the configure flags.

There are also ADD_XYZFLAGS variables, which you could set to -O3 and then rely on the compiler picking the latter -O compiler flag.

amontoison commented 1 year ago

Yes, if you build Ipopt with Spral, the default for the linear solver in Ipopt will change to spral, but you can use Ipopt option linear_solver to select Mumps.

I would just leave this issue open for now as a reminder to add an option to also load MKL's Pardiso at runtime some day.

Btw, the line 45 (https://github.com/JuliaPackaging/Yggdrasil/blob/master/C/Coin-OR/Ipopt/build_tarballs.jl#L45) seems to be missing a $ before {BLAS_LAPACK}.

@svigerske I recompiled Ipopt with SPRAL but the default solver is still MUMPS and we can't switch to the SPRAL linear solver. It's fine for us to keep MUMPS as the default solver but we would like to switch to the SPRAL solver. https://github.com/JuliaPackaging/Yggdrasil/pull/6836/files

svigerske commented 1 year ago

What you mean you "can't switch to the SPRAL linear solver"? Setting linear_solver spral should do it.

The default is currently still that MUMPS is prefered over SPRAL. I don't really know how good or stable SPRAL it. They didn't have a release for a long time that would have worked with Ipopt, until you pinged them. That they then just tagged immediately whatever there was and don't provide release notes doesn't really build up confidence on their release+test cycle. Some issue I reported is also still unanswered.

If you want to change the default in your link, then you can add a ipopt->Options()->SetStringValue("linear_solver", "spral", true, true) before the users options are set. You can use function IpoptGetAvailableLinearSolvers() to check whether Spral has been linked in, if that is necessary.

amontoison commented 1 year ago

What you mean you "can't switch to the SPRAL linear solver"? Setting linear_solver spral should do it.

I have the following error:

# Use the linear solver SPRAL
julia> set_attribute(model, "linear_solver", "spral")

julia> optimize!(model)
Setting: "spral" is not a valid setting for Option: linear_solver. Check the option documentation.

### linear_solver (String)  ###
Category: Linear Solver
Description: Linear solver used for step computations.
Valid Settings:
    ma27 (load the Harwell routine MA27 from library at runtime)
    ma57 (load the Harwell routine MA57 from library at runtime)
    ma77 (load the Harwell routine HSL_MA77 from library at runtime)
    ma86 (load the Harwell routine MA86 from library at runtime)
    ma97 (load the Harwell routine MA97 from library at runtime)
    pardiso (load the Pardiso package from pardiso-project.org from user-provided library at runtime)
    mumps (use the Mumps package)
    custom (use custom linear solver (expert use))
Default: "mumps"
ERROR: IPOPT: Couldn't set option 'linear_solver' to value 'spral'.
svigerske commented 1 year ago

It seems that Ipopt believes that Spral hasn't been linked in. Check the configure output, then check that IPOPT_HAS_SPRAL is defined in src/Common/config.h and that you indeed use the libraries that you have build.

You could add something like

src/Apps/AmplSolver/ipopt --print-options | grep -A 20 linear_solver

to the build script to show the possible values for the linear_solver option as accepted by the Ipopt (AMPL-)executable.

amontoison commented 1 year ago

Thanks for the help Stefan, an old shared library libipopt.so was used last time.... I just opened a PR #677 to don't use spral as the default linear solver if we have more "stable" linear solvers available.

amontoison commented 1 month ago

@svigerske I worked on a shim library libmkl_pardiso.$dlext today that only contains the symbols for the linear solver "MKL Pardiso". https://github.com/amontoison/MKL_Pardiso It ensures that we can use a different library for BLAS/LAPACK symbols.
This is what we want in Julia, where we rely on libblastrampoline.
My question is: how do I provide libmkl_pardiso to Ipopt?
It seems that we don't have a dedicated option for this linear solver. Should I add -lmkl_pardiso with -lblastrampoline for the BLAS or LAPACK option?

svigerske commented 1 month ago

Yes, currently it is assumed that the MKL-Pardiso comes with Lapack, so configure checks for symbol pardiso in the Lapack library. If you add -lmkl_pardiso to your Lapack flags, that could work.