On Wed, Mar 3, 2010 at 1:55 PM, Lisandro Dalcin <[email protected]> wrote:
> On 3 March 2010 17:22, Ondrej Certik <[email protected]> wrote:
>> Hi,
>>
>> I am using the C API Declarations[0], which generate the file
>> _hermes_common_api.h, that I include in my C++ files. I am having
>> problems with initializing the module properly.
>>
>> Here is an example of my C++ function, that internally calls scipy's
>> sparse solver to solve the system:
>>
>> void solve_linear_system_scipy_cg(CooMatrix *mat, double *res)
>> {
>>    if (import__hermes_common())
>>        throw std::runtime_error("hermes_common failed to import.");
>>    CSRMatrix M(mat);
>>    insert_object("m", c2py_CSRMatrix(&M));
>>    insert_object("rhs", c2numpy_double_inplace(res, mat->get_size()));
>>    cmd("A = m.to_scipy_csr()");
>>    cmd("from scipy.sparse.linalg import cg");
>>    cmd("x, res = cg(A, rhs)");
>>    double *x;
>>    int n;
>>    numpy2c_double_inplace(get_object("x"), &x, &n);
>>    memcpy(res, x, n*sizeof(double));
>> }
>>
>> the functions insert_object(), cmd(), c2numpy_double_inplace() etc.
>> are declared in my .pyx file to ease C++ and Python integration (the
>> whole code is at [1]). Everything works, as long as I call the
>> "import__hermes_common()" function. Since I call Python things all
>> over my C++ code, it's kind of annoying to always call this by hand.
>> Also, doesn't it slow things down?
>>
>> What is the best way to do this?
>>
>> It occurred to me that I could create a "Python" C++ class, whose
>> constructor would import the module if needed, and it would be used
>> like this:
>>
>> Python p;
>> p.insert_object(...)
>> p.cmd(...)
>> p.get_object(...)
>>
>
> That's the way I would do it... Moreover, all C++ -- Python
> interactions should go via this object, so you should wrap the C API
> calls of your module as methos of the "Python" class.
>
>> Another annoying thing is that I currently need to have the following
>> at the beginning of my C++ main() function:
>>
>>        // This is a hack, this should be set somewhere else:
>>        putenv((char *)"PYTHONPATH=../..");
>>        Py_Initialize();
>>        PySys_SetArgv(argc, argv);
>>
>> I would like this to be handled automatically somehow, probably in the
>> constructor of the C++ class "Python".
>>
>
> Yep..
>
>> The problem that I am having is that it seems to me, that I need to
>> call import__hermes_common() in every single .cpp file that I have,
>> even though that I link all of them into a shared library. It
>> segfaults if I don't do it. This confuses me. Here is a part of the
>> code in _hermes_common_api.h:
>>
>> static PyObject *(*c2py_CooMatrix)(struct CooMatrix *);
>> static PyObject *(*c2py_CSRMatrix)(struct CSRMatrix *);
>> static void (*cmd)(const char*);
>> static void (*set_verbose_cmd)(int);
>> static void (*insert_object)(const char*, PyObject *);
>>
>> those have to be initalized by calling import__hermes_common(), that
>> is clear, but why isn't it enough to call it once per the
>> project/shared lib?
>
> Because these are "static" ... and these are not visible outside
> compilation units (i.e. outside each C source)

Ah --- that explains everything. I am still learning C++. :)

>
>> I call it in matrix.cpp, but if I don't call it in
>> python_solvers.cpp as well, it seems it won't get initialized and it
>> segfaults.
>
> Of course. Each source has it's own copy of these pointers, then you
> have to init them at each source...
>
> Again, if you route stuff using an globally accessible instance of a
> "Python" class, this is no longer an issue.

In this case, that'd be cool. It'd be a bit tedious to repeat all the
functions in the Python class, but maybe I'll figure out some
shortcut.

>
>> Maybe it has something to do with how C++ header files
>> work, but I thought that symbols are shared in the whole
>> program/library.
>>
>
> Yes. Symbols are shared, as long as then are not "static" :-) ...

Got it --- everything is clear now.

>
> Cython could grow support for your use case... If you really feel you
> will need this (as opposed to implementing the "Python" class),
> perhaps I could take a look at it and implement something...

Do you have some ideas how Cython could be improved to make my use case easier?

I can try to write something too --- I am still in the stage of
figuring things out, not sure yet what I really want in details. I
only know my general goal --- it should be easy for C++ users to use
it, should be robust (no segfaults) and Python internals should not be
visible at all. I am half way there already.

Thanks for the help,
Ondrej
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to