Is it possible to pass a PETSCBaseMatrix from Python into C?

Asked by Patrick Farrell

I'd like to assemble a matrix in Python, and then pass it into my C library as a PETSc Mat type. If in Python I do

from dolfin import *

mesh = UnitInterval(10)
V = FunctionSpace(mesh, "CG", 1)
u = TrialFunction(V)
v = TestFunction(V)

mass = inner(u, v)*dx
M = down_cast(assemble(mass), PETScMatrix)
mat = M.mat()

I get a

In [9]: mat
Out[9]: <Swig Object of type 'boost::shared_ptr< Mat > *' at 0x373a210>

Is there some swig magic I can perform to get the raw pointer to the underlying Mat to pass to a C function (interfaced with ctypes)?

Question information

Language:
English Edit question
Status:
Solved
For:
DOLFIN Edit question
Assignee:
No assignee Edit question
Solved by:
Patrick Farrell
Solved:
Last query:
Last reply:
Revision history for this message
Kent-Andre Mardal (kent-and) said :
#1

I don't think anybody has looked really into this yet. You can do this with
Trilinos since both libraries are
made with swig. There are also some tools in cython (which PETSc uses) that
enables swig objects to be passed,
but my guess is that it will require some work to get into the details.

Kent

On 9 June 2012 13:25, Patrick Farrell
<email address hidden>wrote:

> New question #199926 on DOLFIN:
> https://answers.launchpad.net/dolfin/+question/199926
>
> I'd like to assemble a matrix in Python, and then pass it into my C
> library as a PETSc Mat type. If in Python I do
>
> from dolfin import *
>
> mesh = UnitInterval(10)
> V = FunctionSpace(mesh, "CG", 1)
> u = TrialFunction(V)
> v = TestFunction(V)
>
> mass = inner(u, v)*dx
> M = down_cast(assemble(mass), PETScMatrix)
> mat = M.mat()
>
> I get a
>
> In [9]: mat
> Out[9]: <Swig Object of type 'boost::shared_ptr< Mat > *' at 0x373a210>
>
> Is there some swig magic I can perform to get the raw pointer to the
> underlying Mat to pass to a C function (interfaced with ctypes)?
>
> --
> You received this question notification because you are a member of
> DOLFIN Team, which is an answer contact for DOLFIN.
>

Revision history for this message
Joachim Haga (jobh) said :
#2

See also

https://answers.launchpad.net/dolfin/+question/181985

and

https://blueprints.launchpad.net/dolfin/+spec/add-petsc4py-support

-j.

On 10 June 2012 12:55, Kent-Andre Mardal <
<email address hidden>> wrote:

> Question #199926 on DOLFIN changed:
> https://answers.launchpad.net/dolfin/+question/199926
>
> Status: Open => Answered
>
> Kent-Andre Mardal proposed the following answer:
> I don't think anybody has looked really into this yet. You can do this with
> Trilinos since both libraries are
> made with swig. There are also some tools in cython (which PETSc uses) that
> enables swig objects to be passed,
> but my guess is that it will require some work to get into the details.
>
> Kent
>
> On 9 June 2012 13:25, Patrick Farrell
> <email address hidden>wrote:
>
> > New question #199926 on DOLFIN:
> > https://answers.launchpad.net/dolfin/+question/199926
> >
> > I'd like to assemble a matrix in Python, and then pass it into my C
> > library as a PETSc Mat type. If in Python I do
> >
> > from dolfin import *
> >
> > mesh = UnitInterval(10)
> > V = FunctionSpace(mesh, "CG", 1)
> > u = TrialFunction(V)
> > v = TestFunction(V)
> >
> > mass = inner(u, v)*dx
> > M = down_cast(assemble(mass), PETScMatrix)
> > mat = M.mat()
> >
> > I get a
> >
> > In [9]: mat
> > Out[9]: <Swig Object of type 'boost::shared_ptr< Mat > *' at 0x373a210>
> >
> > Is there some swig magic I can perform to get the raw pointer to the
> > underlying Mat to pass to a C function (interfaced with ctypes)?
> >
> > --
> > You received this question notification because you are a member of
> > DOLFIN Team, which is an answer contact for DOLFIN.
> >
>
> --
> You received this question notification because you are a member of
> DOLFIN Team, which is an answer contact for DOLFIN.
>

Revision history for this message
Johan Hake (johan-hake) said :
#3

In the long run we would like to interface py4petsc and cython, which
should be possible. See the links Joachim provided.

In the meanwhile you are faced with a couple of problems.

   1) The object that is returned by PETScMatrix.mat is a shared_ptr
      wrapped pointer to the underlying Mat object.

   2) We do not wrap that object properly, it is just a SWIG stub.

   3) The PETScMatrix.mat is also removed from the developer
      interface, because its apparent uselessness.

1) and 3) Is easily fixed in the library by dereferencing the
shared_ptr, well knowing that you loose the sweetness of a shared_ptr,
and you can try it out with this little code snippet.

    code = '''
    namespace dolfin {

      Mat* deref_PETSc_mat(boost::shared_ptr<dolfin::PETScMatrix> mat)
      {
        boost::shared_ptr<Mat> A(mat->mat());
        return &(*A);
      }
    }
    '''
    ext_module = compile_extension_module(code,
                 dolfin_module_import=["la"])

    # Keep a reference to M otherwise it will blow up
    m = ext_module.deref_PETSc_mat(M)

a is now a SWIG stub of the PETSc Mat pointer. I do not think you can do
anything with this though. But it is more native than a wrapped
shared_ptr version of it.

It might be possible to highjack the C++ code and return some sort of
PyObject, which is more likable to ctypes. Not sure how to accomplish
this though.

Johan

On 06/10/2012 01:50 PM, Joachim Haga wrote:
> Question #199926 on DOLFIN changed:
> https://answers.launchpad.net/dolfin/+question/199926
>
> Joachim Haga proposed the following answer:
> See also
>
> https://answers.launchpad.net/dolfin/+question/181985
>
> and
>
> https://blueprints.launchpad.net/dolfin/+spec/add-petsc4py-support
>
> -j.
>
>
> On 10 June 2012 12:55, Kent-Andre Mardal<
> <email address hidden>> wrote:
>
>> Question #199926 on DOLFIN changed:
>> https://answers.launchpad.net/dolfin/+question/199926
>>
>> Status: Open => Answered
>>
>> Kent-Andre Mardal proposed the following answer:
>> I don't think anybody has looked really into this yet. You can do this with
>> Trilinos since both libraries are
>> made with swig. There are also some tools in cython (which PETSc uses) that
>> enables swig objects to be passed,
>> but my guess is that it will require some work to get into the details.
>>
>> Kent
>>
>> On 9 June 2012 13:25, Patrick Farrell
>> <email address hidden>wrote:
>>
>>> New question #199926 on DOLFIN:
>>> https://answers.launchpad.net/dolfin/+question/199926
>>>
>>> I'd like to assemble a matrix in Python, and then pass it into my C
>>> library as a PETSc Mat type. If in Python I do
>>>
>>> from dolfin import *
>>>
>>> mesh = UnitInterval(10)
>>> V = FunctionSpace(mesh, "CG", 1)
>>> u = TrialFunction(V)
>>> v = TestFunction(V)
>>>
>>> mass = inner(u, v)*dx
>>> M = down_cast(assemble(mass), PETScMatrix)
>>> mat = M.mat()
>>>
>>> I get a
>>>
>>> In [9]: mat
>>> Out[9]:<Swig Object of type 'boost::shared_ptr< Mat> *' at 0x373a210>
>>>
>>> Is there some swig magic I can perform to get the raw pointer to the
>>> underlying Mat to pass to a C function (interfaced with ctypes)?
>>>
>>> --
>>> You received this question notification because you are a member of
>>> DOLFIN Team, which is an answer contact for DOLFIN.
>>>
>>
>> --
>> You received this question notification because you are a member of
>> DOLFIN Team, which is an answer contact for DOLFIN.
>>
>

Revision history for this message
Patrick Farrell (pefarrell) said :
#4

Great, thanks for the advice. I think I might take a matrix-free approach for now: assemble the matrix in Python, and just use its action opaquely in the C layer. I think that will be easier to code (I can already pass vectors around), although it won't be as fast.
If petsc4py ever happens, I can come back and revisit it again.

Cheers!

Patrick