bnaecker / pygsvd

Python and NumPy extension module implementing the generalized signular value decomposition (GSVD).
Other
31 stars 13 forks source link

Unable to setup with python 3 #10

Open joshuakortje opened 2 weeks ago

joshuakortje commented 2 weeks ago

Hello, I am trying to set up this wrapper, but am getting errors when I run the setup.py command. Below is my output.

I ran the command

python setup.py build_ext --include-dirs="C:\lapack-3.12.0\LAPACKE\include" --library-dirs="C:\lapack-3.12.0\LAPACKE\src"

the output was

running build_ext
building '_gsvd' extension
"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\bin\HostX86\x64\cl.exe" /c /nologo /O2 /W3 /GL /DNDEBUG /MD -DUSE_LAPACK=1 -IC:\Users\jkort\AppData\L
ocal\Programs\Python\Python311\Lib\site-packages\numpy\core\include -I/usr/local/include -IC:\lapack-3.12.0\LAPACKE\include -IC:\Users\jkort\AppData\Local\Programs\Python\Python311\inc
lude -IC:\Users\jkort\AppData\Local\Programs\Python\Python311\Include "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\include" "-IC:\Program Files\
Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\ATLMFC\include" "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\include" "-IC:\Program Files
 (x86)\Windows Kits\10\include\10.0.22621.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\um" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\
shared" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\winrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\cppwinrt" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" /Tcsrc/_gsvd.c /Fobuild\temp.win-amd64-cpython-311\Release\src/_gsvd.obj -DBUILD_WITH_PYTHON3
_gsvd.c
C:\lapack-3.12.0\LAPACKE\include\lapack.h(11): fatal error C1083: Cannot open include file: 'lapacke_mangling.h': No such file or directory
error: command 'C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.41.34120\\bin\\HostX86\\x64\\cl.exe' failed with exit code 2
PS C:\Users\jkort\Desktop\Thesis\CodeSubmission\libs\pygsvd> 
PS C:\Users\jkort\Desktop\Thesis\CodeSubmission\libs\pygsvd>
PS C:\Users\jkort\Desktop\Thesis\CodeSubmission\libs\pygsvd>
PS C:\Users\jkort\Desktop\Thesis\CodeSubmission\libs\pygsvd>
PS C:\Users\jkort\Desktop\Thesis\CodeSubmission\libs\pygsvd>
PS C:\Users\jkort\Desktop\Thesis\CodeSubmission\libs\pygsvd> python setup.py build_ext --include-dirs="C:\lapack-3.8.0\LAPACKE\include" --library-dirs="C:\lapack-3.8.0\LAPACKE\src"  
running build_ext
building '_gsvd' extension
"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\bin\HostX86\x64\cl.exe" /c /nologo /O2 /W3 /GL /DNDEBUG /MD -DUSE_LAPACK=1 -IC:\Users\jkort\AppData\L
ocal\Programs\Python\Python311\Lib\site-packages\numpy\core\include -I/usr/local/include -IC:\lapack-3.8.0\LAPACKE\include -IC:\Users\jkort\AppData\Local\Programs\Python\Python311\incl
ude -IC:\Users\jkort\AppData\Local\Programs\Python\Python311\Include "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\include" "-IC:\Program Files\M
icrosoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\ATLMFC\include" "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\include" "-IC:\Program Files 
(x86)\Windows Kits\10\include\10.0.22621.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\um" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\s
hared" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\winrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\cppwinrt" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" /Tcsrc/_gsvd.c /Fobuild\temp.win-amd64-cpython-311\Release\src/_gsvd.obj -DBUILD_WITH_PYTHON3
_gsvd.c
C:\lapack-3.8.0\LAPACKE\include\lapacke.h(85): error C2061: syntax error: identifier 'lapack_make_complex_float'
C:\lapack-3.8.0\LAPACKE\include\lapacke.h(85): error C2059: syntax error: ';'
C:\lapack-3.8.0\LAPACKE\include\lapacke.h(85): error C2059: syntax error: '<parameter-list>'
C:\lapack-3.8.0\LAPACKE\include\lapacke.h(101): error C2061: syntax error: identifier 'lapack_make_complex_double'
C:\lapack-3.8.0\LAPACKE\include\lapacke.h(101): error C2059: syntax error: ';'
C:\lapack-3.8.0\LAPACKE\include\lapacke.h(101): error C2059: syntax error: '<parameter-list>'
C:\lapack-3.8.0\LAPACKE\include\lapacke.h(136): error C2143: syntax error: missing ')' before '*'
C:\lapack-3.8.0\LAPACKE\include\lapacke.h(136): error C2143: syntax error: missing '{' before '*'
C:\lapack-3.8.0\LAPACKE\include\lapacke.h(136): error C2059: syntax error: ')'
C:\lapack-3.8.0\LAPACKE\include\lapacke.h(136): error C2059: syntax error: ';'
C:\lapack-3.8.0\LAPACKE\include\lapacke.h(138): error C2143: syntax error: missing ')' before '*'

and it continues with more of the same. It appears that the lapacke.h file is not being read in correctly, but I'm not sure.

Thanks for your help!

bnaecker commented 2 weeks ago

Hi @joshuakortje. I see a few issues in the output you've posted, but it's not immediately obvious what the solution is.

The first error is this:

C:\lapack-3.12.0\LAPACKE\include\lapack.h(11): fatal error C1083: Cannot open include file: 'lapacke_mangling.h': No such file or directory

It appears that the directory C:\lapack-3.12.0\LAPACKE\include is on the compiler's include search path, but it doesn't seem to include lapacke_mangling.h. That is supposed to be part of the normal LAPACK distribution. Does that file exist somewhere else on your system? For me, on macOS or Linux, it's located directly in the same include path as lapacke.h, so I'm not sure why it's in the same location on your system. How did you install LAPACK? If you can find the file, and include it in the list of include directories for the compiler, that should resolve this particular error.

The second error is a bit confusing, but we might be able to understand it. The syntax error is from your C compiler failing to parse lapacke.h, specifically this line:

lapack_complex_float lapack_make_complex_float( float re, float im );

That appears to fail because lapack_complex_float isn't defined. That should be defined in lapack.h, for example, on my installation I see this:

/* Complex type (single precision) */
#ifndef lapack_complex_float
#ifndef __cplusplus
#include <complex.h>
#else
#include <complex>
#endif
#define lapack_complex_float    float _Complex
#endif

Based on how you're building this, I expect that last ifdef to be chosen, in which case it should be float _Complex. That's only available if <complex.h> is also available. Is that true for your system? I'd be pretty surprised if it were not, since that was standardized in C99, but it's possible.

There's one other potential problem I see. Im not sure it's causing this particular issue, but it appears you have two version of LAPACK installed: 3.12.0 and 3.8.0. The first invocation that fails is using 3.12.0, and the latter (with the parsing error) is using 3.8.0. Either of those should work fine, but you definitely want to make sure you're consistently using the same version throughout the whole build. For example, you want to make sure you compile and link with the same version, to avoid any kind of ABI issue.

Finally, you may want to try to get a self-contained LAPACK C program compiled and linked. Something very simple, which you can just use to prove your toolchain and LAPACK installation are working as you expect. Then you can use the version information and install directories to help build this package. Hope that helps, but please reach out with other questions.

joshuakortje commented 2 weeks ago

My lapacke_mangling.h file is not in that directory and I don't see one actually. I did eventually come to the conclusion that LAPACK is not installed correctly and I'm having some trouble with that. I tried to install it by running the CMake GUI on the source code while specifying the Fortran compiler by following the instructions here: https://icl.utk.edu/lapack-for-windows/lapack/ under "Build Instructions for LAPACK 3.5.0 for Windows with Visual Studio". However, I keep running into an error where CMake says the Fortran compiler "is not able to compile a simple test program." I get the issue using ifx.exe and gfortran.exe with MinGW. Is there a better way to install LAPACK on Windows?

bnaecker commented 2 weeks ago

Is there a better way to install LAPACK on Windows?

I really don't know, sorry about that. I'm not a Windows user myself.

However, I keep running into an error where CMake says the Fortran compiler "is not able to compile a simple test program."

I might investigate this. If you can get more verbose output, it might show you how the Fortran compiler is failing. Is it missing some include files or other configuration? Is the compiler out-of-date, and just can't work with the version of LAPACK you're building?

joshuakortje commented 2 weeks ago

Ok. I think I have gotten LAPACK installed correctly now. I eventually figured out that I had to configure CMake to generate a makefile for MinGW instead of for Visual Studio (I'm not sure why it would not work for VS...). I was able to verify with the built in tests that everything seemed to be working (ie running make test). This appears to have cleared up the error for why lapacke_mangling.h was missing earlier.

However, I still get the other error about 'lapack_make_complex_float' not being defined. How do I check that complex.h is on my system?

bnaecker commented 1 week ago

I think I have gotten LAPACK installed correctly now.

That's great!

However, I still get the other error about 'lapack_make_complex_float' not being defined. How do I check that complex.h is on my system?

After a bit of reading, it seems like Visual Studio's support for C99's complex numeric types is quite weak. This article indicates that types like float _Complex are just not at all supported. The C99 functions operating on complex data are available, but they're designed to work on a hand-rolled type, I think, something like a C struct with real and imaginary fields for the components. This SO answer seems to show someone having similar issues on Windows, and the workaround they implemented to get it to compile. As far as I can tell, they define a preprocessor directive that tells LAPACK to use a custom type definition, and then implement that themselves in a manner similar to the C struct I describe above.

It seems possible that most folks using the LAPACK C-interface on Windows are actually writing C++ code, which defines a separate set of types and functions in the <complex> C++ STL header. I have never tested building the pygsvd package as a C++ extension, so I can't make any guarantees that it would build, let alone work correctly. Python extensions certainly can use C++, but I've never done that myself.

I wish there were better news for you on this front. Let me know if I can help more.

joshuakortje commented 1 week ago

Thank you for your continued support. I am trying to go the route of the Stack Overflow post that you linked, but that appears to still give errors. I think it is because in that user's application, he is compiling with C++ whereas I am using a C compiler. (not super familiar with C so kind of stumbling through this a bit)

I added the middle section of the below code to my copy of _gsvd.c:

#include <complex.h>
#include <stdio.h>

#include "Python.h"

#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include "numpy/arrayobject.h"

#ifndef LAPACK_COMPLEX_CUSTOM
#define LAPACK_COMPLEX_CUSTOM

#define lapack_complex_float std::complex<float>
#define lapack_complex_double std::complex<double>

#endif

#ifdef USE_LAPACK
# include "lapacke.h"
#elif defined USE_MKL
# include "mkl.h"
#else
# error "Cannot find a LAPACK header, define either USE_MKL or USE_LAPACK"
#endif 

The errors I get in the compilation are:

C:\lapack-3.12.0\LAPACKE\new_include\lapack.h(126): error C2143: syntax error: missing ')' before ':'
C:\lapack-3.12.0\LAPACKE\new_include\lapack.h(126): error C2143: syntax error: missing '{' before ':'
C:\lapack-3.12.0\LAPACKE\new_include\lapack.h(126): error C2059: syntax error: ':'
C:\lapack-3.12.0\LAPACKE\new_include\lapack.h(126): error C2059: syntax error: ')'
C:\lapack-3.12.0\LAPACKE\new_include\lapack.h(128): error C2143: syntax error: missing ')' before ':'
C:\lapack-3.12.0\LAPACKE\new_include\lapack.h(128): error C2143: syntax error: missing '{' before ':'
C:\lapack-3.12.0\LAPACKE\new_include\lapack.h(128): error C2059: syntax error: ':'
C:\lapack-3.12.0\LAPACKE\new_include\lapack.h(128): error C2059: syntax error: ')'

These point to the same place in the header that the SO post had an issue with:

typedef lapack_logical (*LAPACK_C_SELECT1) ( const lapack_complex_float* );
typedef lapack_logical (*LAPACK_C_SELECT2)
    ( const lapack_complex_float*, const lapack_complex_float* );
typedef lapack_logical (*LAPACK_Z_SELECT1) ( const lapack_complex_double* );
typedef lapack_logical (*LAPACK_Z_SELECT2)
    ( const lapack_complex_double*, const lapack_complex_double* );

I suspect (although it is not very clear in the error) that the issue is due to std::complex not really being valid in C. Do you know what the appropriate analog in C would be?

bnaecker commented 1 week ago

std::complex is definitely not valid C, that's a C++ construct, part of the C++ standard library. The C compiler being used to build this extension will balk at that.

If you'd like to try to define your own complex type, I would probably start by making a C struct that looks like this:

typedef struct lapack_complex_float {
    float real; // Real part
    float imag; // Imaginary part
} lapack_complex_float;

with a similar type for double-precision. I would then try to define the functions for constructing those like this:

lapack_complex_float make_lapack_complex_float(float re, float im) {
    lapack_complex_float out = { .real = re, .imag = im };
    return out;
}

I'm not entirely sure how one would direct LAPACK to use those definitions you provide, but I might look at where they are currently defined (not their declarations, the actual definitions), and see if you can #ifdef those out in favor of your custom definitions.

I might first look at the Microsoft post I linked above in more detail. From my initial reading, that's exactly how the Visual Studio code implements the complex types, with structs that probably look similar to the one I wrote above. You might try to use those definitions yourself, rather than writing your own. I don't know how one would do that, though, since I have almost no Visual Studio experience myself. Let me know if that helps!

joshuakortje commented 1 week ago

That article makes it seem like I should actually be able to just replace std::complex<float> with _Fcomplex (and similarly for the double type). So I replaced those lines with

#define lapack_complex_float _Fcomplex
#define lapack_complex_double _Dcomplex

Now, This is the output from the compiler:

PS C:\Users\jkort\Desktop\Thesis\CodeSubmission\libs\pygsvd> python setup.py build_ext --include-dirs="C:\lapack-3.12.0_2\build\include" --library-dirs="C:\lapack-3.12.0_2\build\lib"  
running build_ext
building '_gsvd' extension
"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\bin\HostX86\x64\cl.exe" /c /nologo /O2 /W3 /GL /DNDEBUG /MD -DUSE_LAPACK=1 -IC:\Users\jkort\AppData\L
ocal\Programs\Python\Python311\Lib\site-packages\numpy\core\include -I/usr/local/include -IC:\lapack-3.12.0_2\build\include -IC:\Users\jkort\AppData\Local\Programs\Python\Python311\inc
lude -IC:\Users\jkort\AppData\Local\Programs\Python\Python311\Include "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\include" "-IC:\Program Files\
Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\ATLMFC\include" "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\include" "-IC:\Program Files
 (x86)\Windows Kits\10\include\10.0.22621.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\um" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\
shared" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\winrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\cppwinrt" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" /Tcsrc/_gsvd.c /Fobuild\temp.win-amd64-cpython-311\Release\src/_gsvd.obj -DBUILD_WITH_PYTHON3
_gsvd.c
src/_gsvd.c(122): warning C4244: '=': conversion from 'npy_intp' to 'int', possible loss of data
src/_gsvd.c(123): warning C4244: '=': conversion from 'npy_intp' to 'int', possible loss of data
src/_gsvd.c(124): warning C4244: '=': conversion from 'npy_intp' to 'int', possible loss of data
src/_gsvd.c(125): warning C4244: '=': conversion from 'npy_intp' to 'int', possible loss of data
src/_gsvd.c(126): warning C4244: '=': conversion from 'npy_intp' to 'int', possible loss of data
"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\bin\HostX86\x64\link.exe" /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LI
BPATH:/usr/local/lib /LIBPATH:C:\lapack-3.12.0_2\build\lib /LIBPATH:C:\Users\jkort\AppData\Local\Programs\Python\Python311\libs /LIBPATH:C:\Users\jkort\AppData\Local\Programs\Python\Py
thon311 /LIBPATH:C:\Users\jkort\AppData\Local\Programs\Python\Python311\PCbuild\amd64 "/LIBPATH:C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\ATLMFC
\lib\x64" "/LIBPATH:C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\lib\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x64" "/
LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.22621.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64" lapacke.lib /EXPORT:PyInit__gsvd b
uild\temp.win-amd64-cpython-311\Release\src/_gsvd.obj /OUT:build\lib.win-amd64-cpython-311\_gsvd.cp311-win_amd64.pyd /IMPLIB:build\temp.win-amd64-cpython-311\Release\src\_gsvd.cp311-win_amd64.lib
LINK : fatal error LNK1181: cannot open input file 'lapacke.lib'
error: command 'C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.41.34120\\bin\\HostX86\\x64\\link.exe' failed with exit code 1181

From what I can tell, the warnings look benign. However, the linking error is failing to find lapacke.lib. I looked around in the area where I installed LAPACK and that file does not exist. There was a file named liblapacke.lib, but I'm not sure if that is the same thing. Where do you get this file from or am I missing something in my LAPACK installation? I did go through the process of running all of the tests that are generated as part of the install and they all appear to pass so I think my install is fine but maybe things are named slightly different?

Note that I am having to install/build/make LAPACK with MinGW. Not sure if that makes a difference. I have not been able to get it to work with VS Code for the install.

bnaecker commented 1 week ago

From what I can tell, the warnings look benign

I'm not sure, I tend not to treat any warning like this as benign in C. This indicates we're implicitly casting between types that might not be wide enough, which loses precision. Could you show which lines those are in your modified version of the source file?

However, the linking error is failing to find lapacke.lib. I looked around in the area where I installed LAPACK and that file does not exist. There was a file named liblapacke.lib, but I'm not sure if that is the same thing. Where do you get this file from or am I missing something in my LAPACK installation?

When passing libraries to a linker, the convention is to use arguments like -l name, where the library itself is called libname.so or similar. So in this case, on a Unix-like system, I would expect to see an argument like -l lapacke, which would search in one of several places for a library named liblapacke.so. On Unix-like systems, one can add directories to search with the -L flag. So in total, we might see something like -L/path/to/lapack/lib -llapacke.

I'm not very familiar with Visual Studio's linker, but I see something that's basically the same. There is a flag /LIBPATH:C:\lapack-3.12.0_2\build\lib -- does that contain the file liblapacke.lib? It's possible that Windows works differently, and that the convention of dropping the lib-prefix from the library name is not honored. That is, it's possible we should be specifiying libraries = ['liblapacke'] on this line for Windows builds. If you change that line, does your build work?

Also, to be clear, this library is pretty old at this point. When I wrote it, using setup.py to distribute packages was already a bit out-dated, and I used it in the interest of simplicity and portability. It may be better to use a more modern distribution system now, something like Poetry or the bleeding-edge uv project.

joshuakortje commented 1 week ago

The warnings are pointing to the following lines. It is the 5 lines that are assigning the m, lda, p, ldb, and n variables. I assumed that it was simply an intentional cast from a numpy type to a C int type.

    /* Get and verify input array sizes. */
    if ( (PyArray_NDIM(A) != 2) || (PyArray_NDIM(B) != 2) ) {
        PyErr_SetString(PyExc_ValueError, 
                "Arrays must be 2-dimensional");
        return NULL;
    }
    npy_intp *a_dims = PyArray_DIMS(A);
    npy_intp *b_dims = PyArray_DIMS(B);
    m = a_dims[0];
    lda = a_dims[1];
    p = b_dims[0];
    ldb = b_dims[1];
    n = a_dims[1];
    if (n != b_dims[1]) {
        PyErr_SetString(PyExc_ValueError, 
                "Arrays must have the same number of columns");
        return NULL;
    }

Well, switching the library did get past that error. However apparently there is now an undefined symbol error. It appears to be the ggsvd3 functions which seems a little strange since I don't see how those wouldn't be compiled when I installed LAPACK.

_gsvd.obj : error LNK2001: unresolved external symbol LAPACKE_zggsvd3
_gsvd.obj : error LNK2001: unresolved external symbol LAPACKE_dggsvd3

These are the settings I used in MinGW to install LAPACK. Is there anything not included that looks like it should be included? image

bnaecker commented 1 week ago

The warnings are pointing to the following lines. It is the 5 lines that are assigning the m, lda, p, ldb, and n variables. I assumed that it was simply an intentional cast from a numpy type to a C int type.

Thanks for the source here. It is indeed intentionally casting from npy_intp to an int, but I would have expected those to be the same width (64-bits, both signed). If sizeof(int) == sizeof(npy_intp), then it should be fine, and this is a red-herring. If those are not the same, then I'd have to think more carefully about what to do. The LAPACK interface requires an int, so we would probably want a run-time check that the provided dimensions won't overflow that type.

Well, switching the library did get past that error. However apparently there is now an undefined symbol error. It appears to be the ggsvd3 functions which seems a little strange since I don't see how those wouldn't be compiled when I installed LAPACK.

Great! But that's annoying we're at a different problem. You can use the dumpbin.exe executable to check that your LAPACK library does in fact include those symbols. Search the output of dumpbin.exe /SYMBOLS C:\lapack-3.12.0_2\build\lib\liblapacke.lib for those strings, and they "should" be there. If they are not, then the installation doesn't contain them for some reason. If they are there, then we need to figure out why the linker doesn't seem to consider them defined. In my experience, this is usually that the object naming the symbols appears on the command-line after the file providing those symbols. For example, on my machine I see this:

clang -bundle -undefined dynamic_lookup build/temp.macosx-14.0-arm64-cpython-312/src/_gsvd.o -L/usr/local/lib -L/opt/homebrew/opt/lapack/lib -llapacke -o build/lib.macosx-14.0-arm64-cpython-312/_gsvd.cpython-312-darwin.so

Here, the file build/temp.macosx-14.0-arm64-cpython-312/src/_gsvd.o refers to the symbols LAPACKE_dggsvd3. The file liblapacke.dylib contains those symbols, which the linker resolves when it sees the CLI argument -llapacke. Again, my Windows ignorance rears its head, but it's possible that the Windows linker resolves things in different orders.

joshuakortje commented 1 week ago

Ok. Maybe I can try to throw in a simple runtime check and when it is running we'll see if the types are compatible.

I ran dumpbin.exe on the lib and got a rather underwhelming output:

Microsoft (R) COFF/PE Dumper Version 14.41.34120.0
Copyright (C) Microsoft Corporation.  All rights reserved.

Dump of file C:\lapack-3.12.0_2\build\lib\liblapacke.lib

File Type: LIBRARY

COFF SYMBOL TABLE
000 01018548 ABS    notype       Static       | @comp.id
001 00000000 SECT2  notype       External     | __IMPORT_DESCRIPTOR_liblapacke
002 C0000040 SECT2  notype       Section      | .idata$2
003 00000000 SECT3  notype       Static       | .idata$6
004 C0000040 UNDEF  notype       Section      | .idata$4
005 C0000040 UNDEF  notype       Section      | .idata$5
006 00000000 UNDEF  notype       External     | __NULL_IMPORT_DESCRIPTOR
007 00000000 UNDEF  notype       External     | liblapacke_NULL_THUNK_DATA

String Table Size = 0x58 bytes

COFF SYMBOL TABLE
000 01018548 ABS    notype       Static       | @comp.id
001 00000000 SECT2  notype       External     | __NULL_IMPORT_DESCRIPTOR

String Table Size = 0x1D bytes

COFF SYMBOL TABLE
000 01018548 ABS    notype       Static       | @comp.id
001 00000000 SECT2  notype       External     | liblapacke_NULL_THUNK_DATA

String Table Size = 0x20 bytes

  Summary

          CC .debug$S
          14 .idata$2
          14 .idata$3
           4 .idata$4
           4 .idata$5
          10 .idata$6

I also trying running it on the dll file (since the make command outputted a liblapacke.dll.a file as well) and that one had a much larger output. Here is the output of dumpbin.exe case you want to check that I am interpreting correctly, but it looks like those functions are in fact in the dll file.

Do I perhaps need a way of including the dll.a file instead?

Also, I was able to install and test the LAPACK examples for windows that are referenced here. (search: Using LAPACKE subroutines in a Visual Studio C/C++ Project). They include a preinstalled version of lapack (not sure which version). I was able to build and run in VS just by opening the project and building it. However, I also tried using the setup.py to build it as well and it failed (unable to find LAPACKE_zgesv). I did this pointing to the same pre-built libraries that came with the example. This makes me think that it is something about how it is being compiled/linked. Below is the link command that the example appears to use (I think anyway, I had to dig it out of a log). There are quite a few more libraries. I did already try adding the libraries and while they did not cause any errors, they didn't fix the problem.

^C:\USERS\JKORT\DOWNLOADS\LAPACKE_EXAMPLES\LAPACKE_EXAMPLES\EXAMPLE_DGESV_ROWMAJOR\RELEASE\EXAMPLE_DGESV_ROWMAJOR.OBJ
/OUT:"C:\USERS\JKORT\DOWNLOADS\LAPACKE_EXAMPLES\LAPACKE_EXAMPLES\RELEASE\EXAMPLE_DGESV_ROWMAJOR.EXE" /INCREMENTAL:NO /NOLOGO /LIBPATH:C:\USERS\JKORT\DOWNLOADS\LAPACKE_EXAMPLES\LAPACKE_EXAMPLES\/LIB LIBLAPACKE.LIB LIBLAPACK.LIB LIBBLAS.LIB KERNEL32.LIB USER32.LIB GDI32.LIB WINSPOOL.LIB COMDLG32.LIB ADVAPI32.LIB SHELL32.LIB OLE32.LIB OLEAUT32.LIB UUID.LIB ODBC32.LIB ODBCCP32.LIB KERNEL32.LIB USER32.LIB GDI32.LIB WINSPOOL.LIB COMDLG32.LIB ADVAPI32.LIB SHELL32.LIB OLE32.LIB OLEAUT32.LIB UUID.LIB ODBC32.LIB ODBCCP32.LIB /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:\USERS\JKORT\DOWNLOADS\LAPACKE_EXAMPLES\LAPACKE_EXAMPLES\RELEASE\EXAMPLE_DGESV_ROWMAJOR.PDB" /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /LTCG:incremental /LTCGOUT:"RELEASE\EXAMPLE_DGESV_ROWMAJOR.IOBJ" /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:\USERS\JKORT\DOWNLOADS\LAPACKE_EXAMPLES\LAPACKE_EXAMPLES\RELEASE\EXAMPLE_DGESV_ROWMAJOR.LIB" /MACHINE:X86 /SAFESEH RELEASE\EXAMPLE_DGESV_ROWMAJOR.OBJ
joshuakortje commented 1 week ago

Doing a little more digging, I found this thread: https://stackoverflow.com/questions/6422478/linking-a-lib-and-def-files/6480464#6480464

I notice that for my case the dll.a seems to work (find the correct functions) whereas the .lib does not. I'm not sure why the .lib does not appear to be a working static library but since the .dll.a seems to accomplish the same function it seems to me like I would want to include that instead. I was trying to see if there is a way to modify the setup.py to use the dll.a file but haven't come up with anything yet since the .lib extension is automatically added to the end of each library in the Extension object.