I am struggling to refresh the pyEDM (https://github.com/SugiharaLab/pyEDM) package for windows. The package uses pybind11 to wrap the cppEDM (C++ computation engine) which calls LAPACK directly from the C++ code. On Nix systems, no problem. In win I use mingw to build the Py Extension linking to a binary libopenblas.lib, which has worked in the past. This is built on Azure DevOps as I work in Linux.
With the latest libopenblas.lib the build succeeds. However, at load time I see:
Import Error: DLL load failed while importing pyBindEDM: The specified module could not be found.
I see in the wheel there is a pyBindEDM.cp39-win_amd64.pyd file, which I understand is the "dll" of the extension (Windows is a foreign land to me.) pyBindEDM is the name of the module derived via pybind11, vis:
PYBIND11_MODULE( pyBindEDM, pyMod ) {
pyMod.doc() = "Python bindings to cppEDM via pybind11.";
...
}
Attempting to examine the .pyd load dependency with Dependency Walker on a Windows 10 machine, the program just spins endlessly with no feedback.
How does one approach unraveling the Import Error for a pybind11 wrapped c++ extension?
Update: Apologies if editing the original post is poor etiquette, I do not see an option to add an extension.
To reframe the issue:
As above, a pybind11 wrapper of a c++ library libEDM.a API to create the pyEDM package. libEDM.a calls LAPACK dgelss
directly.
Previously, I linked with a static openblas.a using mingw to build the .pyd. No .dll needed at runtime. Now, if this is done with the latest libopenblas.a, the linker complains:
C:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:\a\1\s\cppEDM/lib\openblas.lib(memory.obj):(.text+0x44a): undefined reference to `__imp__cprintf'
I have not been able to resolve this. Static linking is the preferred approach.
A second approach is to build against a .dll (libopenblas.lib), which completes. However, when the pyEDM package is loaded in Python:
Import Error: DLL load failed while importing pyEDMBind: The specified module could not be found.
Using the Dependency application (thank you Mašek), and, if I place libopenblas.dll in the PATH, the unresolved .pyd dependency is python39.dll.
I would prefer not to try and bundle a .dll with the package, and unravel why python39.dll is not found, but in any case, have not been able to deliver a successful build that loads and runs.
Any and all directions are much appreciated. Please forgive my lack of post etiquette if I have transgressed norms.
Although the issue is not resolved as the python extension still fails on Windows, there are two steps along the way which at least partially address the posed questions.
Issue 1: How does one approach unraveling the Import Error for a pybind11 wrapped c++ extension?
On Windows 10 the Dependencies application provides an answer: https://github.com/lucasg/Dependencies
Thank you Mašek.
Issue 2: Linking binary libopenblas.a against pybind11 C++ extension yields:
C:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:\a\1\s\cppEDM/lib\openblas.lib(memory.obj):(.text+0x44a): undefined reference to `__imp__cprintf'
It seems the binary libopenblas.a posted on https://sourceforge.net/projects/openblas/ are built with mingw 9.3, if the extension is built with mingw 9.5, the unresolved references are resolved.