Export PETSc Mat to python

Hi There,

I am trying to export a PETSc Mat type to python to continue working on it there. I save the Mat type using

load "PETSc"

Mat A;

... // Filling A

ObjectView(A, format = "binary", name = "A.dat");

Afterwards I copy the file to the working directory of my python script where I try to open the binary data using

from petsc4py import PETSc

viewer = PETSc.Viewer().createBinary('A.dat', 'r')
A = PETSc.Mat().load(viewer)

Unfortunately this does not work. However, if I create the binary in Python, using

viewer = PETSc.Viewer().createBinary('matrix-A.dat', 'w')
viewer(A)

and then load it, it does work.

The error I get is this one:

Traceback (most recent call last):
  File "/home/koen/internship/python_practice/petsc.py", line 4, in <module>
    A = PETSc.Mat().load(viewer)
  File "PETSc/Mat.pyx", line 696, in petsc4py.PETSc.Mat.load
petsc4py.PETSc.Error: error code 66
[0] MatLoad() line 1231 in /home/koen/FreeFem-sources/3rdparty/ff-petsc/petsc-3.14.2/src/mat/interface/matrix.c
[0] MatLoad_SeqAIJ() line 4723 in /home/koen/FreeFem-sources/3rdparty/ff-petsc/petsc-3.14.2/src/mat/impls/aij/seq/aij.c
[0] MatLoad_SeqAIJ_Binary() line 4786 in /home/koen/FreeFem-sources/3rdparty/ff-petsc/petsc-3.14.2/src/mat/impls/aij/seq/aij.c
[0] PetscViewerBinaryRead() line 1002 in /home/koen/FreeFem-sources/3rdparty/ff-petsc/petsc-3.14.2/src/sys/classes/viewer/impls/binary/binv.c
[0] PetscBinarySynchronizedRead() line 633 in /home/koen/FreeFem-sources/3rdparty/ff-petsc/petsc-3.14.2/src/sys/fileio/sysio.c
[0] PetscBinaryRead() line 311 in /home/koen/FreeFem-sources/3rdparty/ff-petsc/petsc-3.14.2/src/sys/fileio/sysio.c
[0] Read from file failed
[0] Read past end of file

I guess there is a difference in how petsc4py and ObjectView write the binary file from the Mat, but I have no clue what this difference is. Any help would be much appreciated!

How did you install petsc4py? Which version are you using?

I installed petsc4py using pip install petsc4py petsc after doing echo PETSC_DIR=FreeFem-sources/3rdparty/ff-petsc/petsc-3.14.2. I have petsc 3.14.5 and petsc4py 3.14.1. I did however install FreeFem in /usr/local/lib and also have the folder /usr/local/ff-petsc/r/lib/petsc in which I found the file PetscBinaryIO.py. Maybe I should somehow configure this to be included in my python packages? I am not sure how to do this though.

Update: This inspired me to do some more research to those packages and here are some of my important conclusions (which made it work eventually):
First of all my PETSC_ARCH was not correct. This should be the directory in your PETSC_DIR in which you can find lib/petsc/conf/petscvariable (in my case PETSC_ARCH=fr).

Next I copied the Petsc python modules of petsc/bin to my python site-packages. (in my case the modules were in /usr/local/ff-petsc/r/lib/petsc/bin. Then I got the script to work using

import PetscBinaryIO

io = PetscBinaryIO.PetscBinaryIO()
obj = open('A.dat')
objecttype = io.readObjectType(obj)
if objecttype == 'Mat':
    A = io.readMat(obj)

Hope this can help anyone else. Thank you for the swift response, somehow it did point me in the right direction!

Wow, that’s a lot of copy/paste’ing. There is probably a cleaner route, but if it’s working alright now, I guess it’s all good. Just FYI, ObjectView() writes exactly as MatView() reads, there is no shenanigan, you can have a look at the sources.

One cleaner solution is to add $PETSC_HOME/lib/petsc/bin to your PYTHONPATH.

By the way, if you have a PETSc installed outside of FreeFEM, you can have FreeFEM use your custom PETSc, see this GitHub issue.

Unfortunately I have come back to this issue. Using the PetscBinaryIO works, but it does not seem like a good way to continue further since the petsc4py.PETSc.Mat class has much more options and is better integrated with the PETSc interface. Now I come back to this issue. If I generate data using petsc4py the method does work, but if I generate data using ObjectView in FreeFEM the method does not work.

I have already stated how I load and import my data and the error is still the same… I have added the full scripts for the FreeFEM part, and copied the full python scripts below.vorticity.edp (2.0 KB)

import petsc4py, sys
petsc4py.init(sys.argv)

from petsc4py import PETSc

viewer = PETSc.Viewer().createBinary('data/A_0.dat', 'r')
A = PETSc.Mat().load(viewer)

Can’t reproduce your error.

$ mpirun -n 1 FreeFem++-mpi vorticity.edp -v 0
[..]
step 195 of 200
step 196 of 200
step 197 of 200
step 198 of 200
step 199 of 200
$ cat vorticity.py
#! /usr/bin/python3

import petsc4py, sys
petsc4py.init(sys.argv)

from petsc4py import PETSc

viewer = PETSc.Viewer().createBinary('vorticity_A_test/A_0.dat', 'r')
A = PETSc.Mat().load(viewer)
$ mpirun -n 2 python3 ./vorticity.py && echo $?
0

But if you have multiple PETSc installations here and there, it could explain why it is failing in your case.

It seems that this was indeed the problem. I reinstalled petsc4py, this time from the src/binding/petsc4py folder instead of using pip install. Now it seems to work. Thanks for the suggestion!