Closed S-Dafarra closed 5 months ago
Damn it. The dynamic loading of libraries like HSL on Windows is the one thing that changed from 3.14.14 to 3.14.15 (#755).
Can you say more about your setup? Where do you have the HSL DLL located, from where do you run Ipopt, and do you have the path to the HSL DLL in the PATH
environment variable?
do you have the path to the HSL DLL in the
PATH
environment variable?
Yes!
In fact it was puzzling me. The error when it does not find the library is
Exception of type: DYNAMIC_LIBRARY_FAILURE in file "D:\bld\ipopt_1705695044464\work\src\Common\IpLibraryLoader.cpp" at line 59:
Exception message: Error 126 while loading DLL libhsl.dll: The specified module could not be found.
The same error is also thrown when Windows does not find some runtime dependency of libhsl.dll
, while in this case the error code is different.
Where do you have the HSL DLL located, from where do you run Ipopt
ipopt
is installed via conda
, while libhsl.dll
is in a personal path. Both of them are in the PATH
.
The code I was trying to run is a bit complex, involving other dependencies (like casadi
). If necessary I can try to work on a minimal reproducible example.
Hmm, one would think that this setup would work. I have no clue what it means by a parameter being incorrect.
An original suggestion in #755 was to try both LoadLibrary
(as in 3.14.14) and LoadLibraryExA
(as in 3.14.15). I've done this in 9a36a9ed and here are windows DLLs: https://cloud.gams.com/s/PCZY3RnGKZj5bND
If you like, you could try whether these work.
I don't know how the conda libraries are build.
Thanks @svigerske for the quick reply ! I backported the patch in conda binaries for 3.14.15 in https://github.com/conda-forge/ipopt-feedstock/pull/103, I also enable upload of test artifacts (see https://conda-forge.org/docs/maintainer/updating_pkgs/#downloading-prebuilt-packages-from-ci), so @S-Dafarra you can test if that PR solve your problem (just install with conda install <downloaded_package>.conda
the downloaded package).
I don't know how the conda libraries are build.
Unfortunately at the moment we are using a custom CMake script for ipopt mantained at https://github.com/conda-forge/ipopt-feedstock/blob/main/recipe/cmake/CMakeLists.txt . It would be great to be aligned with upstream, but to be honest I never looked into how to make autotools works with the rest of the Windows conda-forge machinery.
For what regards HSL's dll, actually those are built with a fix we did to HSL's upstream meson build system, we actually still need to report that fix upstream.
Actually I had checked https://github.com/coin-or/Ipopt/pull/755 back when it was proposed, and it seemed fine. However, looking into the details of the documentation I noticed that in https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexa it reads that if LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
option is used, "The lpFileName parameter must specify a fully qualified path.". Perhaps this is the problem? @S-Dafarra can you try to pass the absolute path to the libhsl.dll
? If that is the case, I guess it make sense to use https://github.com/coin-or/Ipopt/commit/9a36a9ed0d19900cbc7553209de4d0207c731afa . Or perhaps we should check if libname
is an absolute path, and just use LoadLibraryExA
in that case?
Oh, I read through this documentation several times, and still overlooked that small sentence.
So if libname
is an absolute path ("fully qualified path"), one should use LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
, otherwise use LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
. But one cannot combine both (at least not with the default relative path for libname
).
It should be sufficient to check libname[1] == ':'
to recognize an absolute path (?).
In the next release, LoadLibraryExA
with LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
will only be used if libname
seems to be an absolute path.
Otherwise, it will be as before 3.14.15, i.e., LoadLibraryA
is used.
This seems to work on my system when specifying a library as absolute path or when having it in PATH.
CC @metab0t
Thanks for the fix!
It should be sufficient to check
libname[1] == ':'
to recognize an absolute path (?).
Sorry, I missed that comment. I am not sure how widespread those are, but I guess that check may be fail when using UNC or DOS device path (see https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#unc-paths). Anyhow, I guess those are kind of seldomly used, and anyhow if they are used the normal LoadLibraryA
that was used before 3.14.15 will be used, so I guess this is ok.
@svigerske Sorry for breaking existing code because of the mess of DLL search strategy on Windows. Instead of judging whether the path is absolute, can we just use the initial commit? Search the default paths, if not found, then use LoadLibraryExA
as a possible fix?
Besides, we should use LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIRS
in LoadLibraryExA
instead of LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
because the latter does not search default paths at all. libhsl.dll may have some dependencies in default search paths.
I also make a fix in my own package: https://github.com/metab0t/PyOptInterface/commit/94c6561bbdcf4cd3480166c3af29a2c66b7042d9
I was changing it to LOAD_LIBRARY_SEARCH_DLL_LOAD_DIRS
for the call to LoadLibraryExA
.
The LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
adds some additional directories.
But using LoadLibraryExA
with any non-zero argument prevents it from looking into PATH, which we had before 3.14.15.
So we still need the LoadLibraryA
call.
We can do as in the initial commit, just need to improve error handling. At the moment, the message from the LoadLibrary
call would be lost, if that fails.
Yes, I agree. LoadLibraryA
handles the libhsl.dll
cases and LoadLibraryExA
for the full DLL paths.
@S-Dafarra can you try to pass the absolute path to the
libhsl.dll
?
By passing the absolute path using the hsllib
option, it works
so @S-Dafarra you can test if that PR solve your problem (just install with
conda install <downloaded_package>.conda
the downloaded package).
I have tested the version mentioned in https://github.com/conda-forge/ipopt-feedstock/pull/103#issuecomment-2067222479 and it also works with the default relative setting. Thanks a lot @svigerske and @traversaro for the super quick support!
For what regards HSL's dll, actually those are built with a fix we did to HSL's upstream meson build system, we actually still need to report that fix upstream.
@traversaro Don't hesitate to contact me if you have an issue the new Meson build system of COIN-HSL / libHSL.
For what regards HSL's dll, actually those are built with a fix we did to HSL's upstream meson build system, we actually still need to report that fix upstream.
@traversaro Don't hesitate to contact me if you have an issue the new Meson build system of COIN-HSL / libHSL.
Great! I sent you a mail.
I have installed
ipopt
3.14.15 withconda
on Windows.If I try to use a
hsl
linear solver, I get the following exception:If I use the 3.14.14 version instead it works fine.