0

I'm trying to write a Cython wrapper to interface C code from Python.

The C library makes use of Suitesparse's CHOLMOD, so I figured installing scikit-sparse (which uses a cholmod.pyx that contains everything I need) would be a neat way. However, I unsuccessfully looked for solutions to include these definitions of CHOLMOD and I would like to avoid writing "my own" cholmod.pxd with typedefs of the structs that I need.

As a minimal example, let's say I have a foo.h header file that defines a struct which in turn contains some CHOLMOD structs, along with some dummy functions. My Cython definition file looks like this:

cdef extern from "foo.h":
    ctypedef struct foostruct:
        cholmod_common c
        cholmod_factor *f
        cholmod_dense *d

    void initialize_foostruct(foostruct* bar)
    void modify_foostruct(foostruct* bar)

And the implementation could e.g. be:

from libc.stdlib cimport calloc, malloc, free
from foo cimport *

cdef class Foo:
    cdef foostruct* _bar

    def __cinit__(self):
        self._bar = <foostruct*> calloc(1, sizeof(foostruct))
        if self._bar is NULL:
            raise MemoryError()
        initialize_foostruct(self._bar)

    def __dealloc__(self):
        if self._bar is not NULL:
            free(self._bar)
            self._bar = NULL

    def do_something(self):
        modify_foostruct(self._bar)

Obviously this will fail since cholmod_common etc. are not known in the definition file (error reads 'cholmod_common' is not a type identifier). I tried thing like from sksparse.cholmod cimport *, but to no avail...

Is there a way to somehow import those type identifiers (either from scikit-sparse, or another source) to use them in the way described in my definition file?

lz129
  • 21
  • 4
  • I haven't tested it but there is a [`cimport_from_pyx` compiler option](https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#Cython.Compiler.Options.cimport_from_pyx) that you could turn on. You'll need to make sure that the .pyx file is on Python's path. Bear in mind that the pyx file may well not be installed by scikit-sparse (since only the compiled .so files are of use to the user) – DavidW Oct 09 '19 at 08:17
  • Sounds like it's exactly what I need! Unfortunately, I cannot get it to work... I've put the whole scikit-sparse repository (source files) on my python path, added an `Options.cimport_from_pyx = True` in my `setup.py` and tried to import via `from sksparse.cholmod cimport *` but am still getting `'sksparse/cholmod.pxd' not found`. Any clue what I'm missing here? – lz129 Oct 09 '19 at 09:19
  • It looks like pyx files are only looked for locally, it doesn't search on `sys.path`: see https://github.com/cython/cython/blob/074362b47093febfe5273ea7a00f4ba5ded6e73f/Cython/Compiler/Main.py#L246 (look at the passing of `sys_path`). Therefore I'm afraid my suggestion probably isn't useful. – DavidW Oct 09 '19 at 10:05
  • I'm also not succeeding when putting the `sksparse` folder locally (so next to `setup.py`)... – lz129 Oct 09 '19 at 12:36
  • Right - it kind of works.... it only works if the `cimport` is in a .pyx file, not if the `cimport` is in a .pxd file. I'm not sure if that's a deliberate decision or a bug. I don't think this really does what you want I'm afraid - if I were you I'd copy the relevant bits from scikit-sparse into your own pxd file (if the license is suitable for you). However I know that's not really what you're after – DavidW Oct 09 '19 at 12:52

0 Answers0