scikit-umfpack / scikit-umfpack

The umfpack scikit provides wrapper of UMFPACK sparse direct solver to SciPy.
BSD 3-Clause "New" or "Revised" License
45 stars 27 forks source link

TypeError: umfpack_di_symbolic() missing 1 required positional argument: 'Info' #98

Open dahnlund opened 9 months ago

dahnlund commented 9 months ago

First time getting a successful installation with this package after the update 0.4.1, but I get this recurring error when I try to use spsolve. When running "pytest --pyargs scikits.umfpack" I get "TypeError: umfpack_di_symbolic() missing 1 required positional argument: 'Info'" in almost every test. Someone knows what the issue is? This is a subset of the output:

__________________________________________________________________________________ TestSolvers.test_solve_umfpack __________________________________________________________________________________

self = <scikits.umfpack.tests.test_interface.TestSolvers testMethod=test_solve_umfpack>

    def test_solve_umfpack(self):
        # Solve with UMFPACK: double precision
        a = self.a.astype('d')
        b = self.b
>       x = um.spsolve(a, b)

/usr/local/lib/python3.11/site-packages/scikits/umfpack/tests/test_interface.py:62: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/local/lib/python3.11/site-packages/scikits/umfpack/interface.py:62: in spsolve
    x = UmfpackLU(A).solve(b)
/usr/local/lib/python3.11/site-packages/scikits/umfpack/interface.py:206: in __init__
    self.umf.numeric(A)
/usr/local/lib/python3.11/site-packages/scikits/umfpack/umfpack.py:555: in numeric
    self.symbolic(mtx)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <scikits.umfpack.umfpack.UmfpackContext object at 0x114f37f10>, mtx = <5x5 sparse matrix of type '<class 'numpy.float64'>'
        with 9 stored elements in Compressed Sparse Column format>

    def symbolic(self, mtx):
        """
        Perform symbolic object (symbolic LU decomposition) computation for a given
        sparsity pattern.
        """
        self.free_symbolic()

        indx = self._getIndx(mtx)

        if not assumeSortedIndices:
            # row/column indices cannot be assumed to be sorted
            mtx.sort_indices()

        if self.isReal:
            status, self._symbolic\
>                   = self.funs.symbolic(mtx.shape[0], mtx.shape[1],
                                          mtx.indptr,
                                          indx,
                                          mtx.data,
                                          self.control, self.info)
E           TypeError: umfpack_di_symbolic() missing 1 required positional argument: 'Info'

/usr/local/lib/python3.11/site-packages/scikits/umfpack/umfpack.py:522: TypeError
rishi-kulkarni commented 8 months ago

Are you on Mac by any chance? I have the same error on my mac, but I can't reproduce on Linux.

rishi-kulkarni commented 8 months ago

My guess is that you have a much newer version of SuiteSparse installed - I can reproduce this on 7.3.1. Installing an older version, like the one installed in the CI pipeline (v5.10) clears this up. An easy way to install this on Mac is via conda-forge: https://anaconda.org/conda-forge/suitesparse.

CC @rc - it looks like the interface of these functions changed on SuiteSparse 7+. Unfortunately, the versions of SuiteSparse available via package repositories is all over the place - Brew offers 7.3.1, Macports offers 5.13.0, the CI installs 5.10.1 via apt. Might be worth a note in the README about explicitly supported SuiteSparse versions.

dahnlund commented 8 months ago

Yes, I have tried it on both SuiteSparse 7.1.0 and later 7.3.1 (both installed via Brew on Mac). Might have to try an older version by source installation.

DrTimothyAldenDavis commented 8 months ago

I haven't changed the API to umfpack_di_symbolic; it's been the same since at least 2006 and probably earlier. I just checked SuiteSparse v2.1.1 (the oldest copy I have on github) and umfpack_di_symbolic is the same there as it is in the current SuiteSparse 7.4.0.beta12 prerelease.

I have changed how the include files are provided; I used to have a set of files and a single top-level umfpack.h that included them all. I now just have one file. That might account for the difference you're seeing. But the contents have been very stable.

rishi-kulkarni commented 8 months ago

Yes, it's a little challenging to reproduce this, since the meson build file looks in a lot of places before looking in the user-specified nativefile. However, if you delete those other paths in the build file, it's a bit easier to test. This bug did indeed begin after the include file change.

DrTimothyAldenDavis commented 8 months ago

I'm close to releasing a stable SuiteSparse 7.4.0. Its build system is much better now and some of these issues may be resolved when using that version. Let me know if there's anything I can do to revise 7.4.0 to help resolve this issue.

leuraph commented 7 months ago

FYI: I've installed SuiteSparse version 7.4.0 via brew and scikit-umfpack version 0.4.1 via pip. However, I still do encounter the very same issue as stated above. The problem was resolved for me as well, when I installed SuiteSparse version 5.10.1 via conda and reinstalled scikit-umfpack version 0.4.1 via pip. I'm also on a mac.

bnavigator commented 6 months ago

Here is the output of pip/meson-python compiling a wheel on openSUSE Linux with suitesparse 7.5.1 resulting in the same error above:

[   14s] + /usr/bin/python3.9 -mpip wheel --verbose --progress-bar off --disable-pip-version-check --use-pep517 --no-build-isolation --no-deps --wheel-dir ./build .
[   15s] Processing /home/abuild/rpmbuild/BUILD/scikit_umfpack-0.4.1
[   15s]   Preparing metadata (pyproject.toml): started
[   15s]   Running command Preparing metadata (pyproject.toml)
[   15s]   + meson setup /home/abuild/rpmbuild/BUILD/scikit_umfpack-0.4.1 /home/abuild/rpmbuild/BUILD/scikit_umfpack-0.4.1/.mesonpy-l1pyrepj -Dbuildtype=release -Db_ndebug=if-release -Db_vscrt=md --native-file=/home/abuild/rpmbuild/BUILD/scikit_umfpack-0.4.1/.mesonpy-l1pyrepj/meson-python-native-file.ini
[   16s]   The Meson build system
[   16s]   Version: 1.3.2
[   16s]   Source dir: /home/abuild/rpmbuild/BUILD/scikit_umfpack-0.4.1
[   16s]   Build dir: /home/abuild/rpmbuild/BUILD/scikit_umfpack-0.4.1/.mesonpy-l1pyrepj
[   16s]   Build type: native build
[   16s]   Project name: scikits.umfpack
[   16s]   Project version: 0.4.1
[   16s]   C compiler for the host machine: cc (gcc 13.2.1 "cc (SUSE Linux) 13.2.1 20240206 [revision 67ac78caf31f7cb3202177e6428a46d829b70f23]")
[   16s]   C linker for the host machine: cc ld.bfd 2.42.0.20240130-1
[   16s]   Host machine cpu family: x86_64
[   16s]   Host machine cpu: x86_64
[   16s]   Program python found: YES (/usr/bin/python3.9)
[   16s]   Program swig found: YES (/usr/bin/swig)
[   16s]   Found pkg-config: YES (/usr/bin/pkg-config) 2.1.1
[   16s]   Run-time dependency openblas found: YES 0.3.25
[   16s]   Run-time dependency umfpack found: YES 6.3.1
[   16s]   Compiler for C supports arguments -Wno-misleading-indentation: YES
[   16s]   Compiler for C supports arguments -Wno-incompatible-pointer-types: YES
[   16s]   Run-time dependency python found: YES 3.9
[   16s]   Build targets in project: 2
[   16s] 
[   16s]   scikits.umfpack 0.4.1
[   16s] 
[   16s]     User defined options
[   16s]       Native files: /home/abuild/rpmbuild/BUILD/scikit_umfpack-0.4.1/.mesonpy-l1pyrepj/meson-python-native-file.ini
[   16s]       buildtype   : release
[   16s]       b_ndebug    : if-release
[   16s]       b_vscrt     : md
[   16s] 
[   16s]   Found ninja-1.11.1 at /usr/bin/ninja
[   16s]   + /usr/bin/ninja
[   17s]   [1/3] Generating scikits/umfpack/_umfpack_swig with a custom command
[   17s]   /usr/include/suitesparse/umfpack.h:86: Warning 202: Could not evaluate expression '!defined (SUITESPARSE__VERSION) || \
[   17s]       (SUITESPARSE__VERSION < SUITESPARSE__VERCODE(7,5,0))'
[   17s]   /usr/include/suitesparse/umfpack.h:86: Warning 202: Syntax error: expected operator
[   17s]   /usr/include/suitesparse/umfpack.h:91: Warning 202: Could not evaluate expression '!defined (AMD__VERSION) || \
[   17s]       (AMD__VERSION < SUITESPARSE__VERCODE(3,3,1))'
[   17s]   /usr/include/suitesparse/umfpack.h:91: Warning 202: Syntax error: expected operator
...
[   23s] Building wheels for collected packages: scikit-umfpack
[   23s]   Building wheel for scikit-umfpack (pyproject.toml): started
[   23s]   Running command Building wheel for scikit-umfpack (pyproject.toml)
[   23s]   Building wheel for scikit-umfpack (pyproject.toml): finished with status 'done'
[   23s]   Created wheel for scikit-umfpack: filename=scikit_umfpack-0.4.1-cp310-cp310-linux_x86_64.whl size=1586116 sha256=283004e5e9b87b57cf429c9165acc527f584b74920bf540bfb97097d095b6140
[   23s]   Stored in directory: /home/abuild/.cache/pip/wheels/cf/b2/e5/9a16e9a3cbab52c5928e5e83a61d092d7b1026915ba95ba42c
[   23s] Successfully built scikit-umfpack
...
[   35s] + pytest-3.9 --ignore=_build.python39 --ignore=_build.python310 --ignore=_build.python312 --ignore=_build.python311 -v --pyargs scikits.umfpack
[   35s] ============================= test session starts ==============================
[   35s] platform linux -- Python 3.9.18, pytest-7.4.4, pluggy-1.3.0 -- /usr/bin/python3.9
[   35s] cachedir: .pytest_cache
[   35s] rootdir: /home/abuild/rpmbuild/BUILD/scikit_umfpack-0.4.1
[   35s] configfile: pytest.ini
[   35s] collecting ... collected 21 items
...
[   36s] =================================== FAILURES ===================================
[   36s] _________________ TestSolvers.test_solve_complex_int64_umfpack _________________
[   36s] 
[   36s] self = <umfpack.tests.test_interface.TestSolvers testMethod=test_solve_complex_int64_umfpack>
[   36s] 
[   36s]     @unittest.skipIf(_is_32bit_platform, reason="requires 64 bit platform")
[   36s]     def test_solve_complex_int64_umfpack(self):
[   36s]         # Solve with UMFPACK: double precision complex, int64 indices
[   36s]         a = _to_int64(self.a.astype('D'))
[   36s]         b = self.b
[   36s] >       x = um.spsolve(a, b)
[   36s] 
[   36s] ../../BUILDROOT/python-scikit-umfpack-0.4.1-1.2.x86_64/usr/lib64/python3.9/site-packages/scikits/umfpack/tests/test_interface.py:55: 
[   36s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   36s] ../../BUILDROOT/python-scikit-umfpack-0.4.1-1.2.x86_64/usr/lib64/python3.9/site-packages/scikits/umfpack/interface.py:62: in spsolve
[   36s]     x = UmfpackLU(A).solve(b)
[   36s] ../../BUILDROOT/python-scikit-umfpack-0.4.1-1.2.x86_64/usr/lib64/python3.9/site-packages/scikits/umfpack/interface.py:206: in __init__
[   36s]     self.umf.numeric(A)
[   36s] ../../BUILDROOT/python-scikit-umfpack-0.4.1-1.2.x86_64/usr/lib64/python3.9/site-packages/scikits/umfpack/umfpack.py:555: in numeric
[   36s]     self.symbolic(mtx)
[   36s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   36s] 
[   36s] self = <scikits.umfpack.umfpack.UmfpackContext object at 0x7fe39c6b89d0>
[   36s] mtx = <5x5 sparse matrix of type '<class 'numpy.complex128'>'
[   36s]    with 9 stored elements in Compressed Sparse Column format>
[   36s] 
[   36s]     def symbolic(self, mtx):
[   36s]         """
[   36s]         Perform symbolic object (symbolic LU decomposition) computation for a given
[   36s]         sparsity pattern.
[   36s]         """
[   36s]         self.free_symbolic()
[   36s]     
[   36s]         indx = self._getIndx(mtx)
[   36s]     
[   36s]         if not assumeSortedIndices:
[   36s]             # row/column indices cannot be assumed to be sorted
[   36s]             mtx.sort_indices()
[   36s]     
[   36s]         if self.isReal:
[   36s]             status, self._symbolic\
[   36s]                     = self.funs.symbolic(mtx.shape[0], mtx.shape[1],
[   36s]                                           mtx.indptr,
[   36s]                                           indx,
[   36s]                                           mtx.data,
[   36s]                                           self.control, self.info)
[   36s]         else:
[   36s]             real, imag = mtx.data.real.copy(), mtx.data.imag.copy()
[   36s]             status, self._symbolic\
[   36s] >                   = self.funs.symbolic(mtx.shape[0], mtx.shape[1],
[   36s]                                           mtx.indptr,
[   36s]                                           indx,
[   36s]                                           real, imag,
[   36s]                                           self.control, self.info)
[   36s] E           TypeError: umfpack_zl_symbolic() missing 1 required positional argument: 'Info'
[   36s] 
[   36s] ../../BUILDROOT/python-scikit-umfpack-0.4.1-1.2.x86_64/usr/lib64/python3.9/site-packages/scikits/umfpack/umfpack.py:530: TypeError

Haven't tried updating to suitesparse 7.6 yet

j-bowhay commented 5 months ago

I am also experiencing this on error on 7.6.1-1

cmutel commented 3 months ago

@leuraph Could you describe how you got it working? Did you have SuiteSparse in a conda environment and scikit-umfpack in a normal venv? How did pip know where the SuiteSparse libraries were?

leuraph commented 3 months ago

@cmutel Sure! In the end, I did not use conda to get it working. Instead, I compiled a compatible version of SuiteSparse by hand (v5.10.1 works in my case) and pointed pip to it when installing scikit-umfpack (providing nativefile.ini). You can find a more detailed description of what I did to get it working in the Troubleshooting section of the readme in this repo!

minrk commented 2 months ago

just encountered this trying to update the conda-forge package, since conda-forge is now on suitesparse 7.7.

FWIW, the missing argument appears to be Symbolic in the signature:

def umfpack_di_symbolic(n_row, n_col, Ap, Ai, Ax, Symbolic, Control, Info) -> int

where it's called expecting (n_row, n_col, Ap, Ai, Ax, Control, Info) -> (int, Symbolic).

I don't know enough about how swig works, but it seems the **Symbolic/**Numeric output variables aren't detected as output variables, as intended by OPAQUE_ARGOUT here. Given the comment about order being important and interspersed %apply and include, I assume the fact that umfpack.h is now a single header means the OPAQUE_ARGOUT is no longer applied to the expected definitions (or OPAQUE_ARGINOUT is applied more places than expected, I'm not sure).

There also appear to be changes re: SuiteSparse_long -> int64_t that need updating in the swig file, but I'm also not sure about that, since the type is the same, just the declaration.