# Strange behavior with MatLoad

**URL:** https://community.freefem.org/t/strange-behavior-with-matload/2270
**Category:** General Discussion
**Created:** [February 8, 2023, 9:11am UTC](https://community.freefem.org/t/strange-behavior-with-matload/2270 "2023-02-08T09:11:59Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![aszaboa](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/aszaboa/32/2918_2.png) [@aszaboa](https://community.freefem.org/u/aszaboa)
#### Post date: [February 8, 2023, 9:11am UTC](https://community.freefem.org/t/strange-behavior-with-matload/2270/1 "2023-02-08T09:11:59Z")

</div>

Dear FreeFem users,

I would like to use `ObjectView` and `MatLoad` for saving the PETSc numbering solution (vectors) in binary, possible to dome post-processing in Matlab, etc. However, when I am loading the results back in FreeFem, I get a very stange behavior: the unknown numbering change per process. The following MWE demonstrates this behavior:

```auto
load "PETSc"

{
int n=1000;
real[int] rhs(n+mpirank*n*0.1);

real[int, int] rhsView(rhs.n,1);
rhsView(:,0) = rhs;
ObjectView(rhsView, format = "binary", name = "rhsout");
cout << "writing: rank " << mpirank << "/" << mpisize << ", rhsView.n=" << rhsView.n << ", rhs.n=" << rhs.n << endl;
}

{
real[int, int] rhsView(1, 1);
MatLoad(rhsView, format = "binary", name = "rhsout");
real[int] rhs = rhsView.asarray;  
cout << "reading: rank " << mpirank << "/" << mpisize << ", rhsView.n=" << rhsView.n << ", rhs.n=" << rhs.n << endl;
}

```

The resulting output is the following:

> writing: rank 1/2, rhsView.n=1100, rhs.n=1100  
> writing: rank 0/2, rhsView.n=1000, rhs.n=1000  
> reading: rank 1/2, rhsView.n=1050, rhs.n=1050  
> reading: rank 0/2, rhsView.n=1050, rhs.n=1050

I would expect the numerings to be the same. Is this a bug, or am I misunderstanding something?

---

<div class="post-metadata">

### Author: ![prj](https://avatars.discourse-cdn.com/v4/letter/p/ecae2f/32.png) [@prj](https://community.freefem.org/u/prj)
#### Post date: [February 8, 2023, 12:37pm UTC](https://community.freefem.org/t/strange-behavior-with-matload/2270/2 "2023-02-08T12:37:05Z")

</div>

PETSc does not store the partitioning. This has the big advantage that you can save with, e.g., 1 process, and then load with, e.g., 4 processes. In plain PETSc, you can force the local dimension before loading a `Mat` so that the partitioning suits your needs, but this is not implemented in the FreeFEM plugin. I could add that if you want, though, I’m not sure when (probably not before the end of this weekend).

---

<div class="post-metadata">

### Author: ![aszaboa](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/aszaboa/32/2918_2.png) [@aszaboa](https://community.freefem.org/u/aszaboa)
#### Post date: [February 8, 2023, 1:25pm UTC](https://community.freefem.org/t/strange-behavior-with-matload/2270/3 "2023-02-08T13:25:14Z")

</div>

Thanks for the quick reply, this makes complete sense.

I think there is no need for you implement additional features, I think I can just (i) save the vector, (ii) save the numbering accessed via `GlobalNumbering` (along with the corresponding ranks), (iii) load the vector and and the numbering on rank 0, and (iv) distribute the vector myself among the processes. Please correct me if I am wrong.

A note: the example [FreeFem-sources/diffusion-substructuring-2d-PETSc.edp at master · FreeFem/FreeFem-sources · GitHub](https://github.com/FreeFem/FreeFem-sources/blob/master/examples/hpddm/diffusion-substructuring-2d-PETSc.edp) throws me an error at line 45 I think due to incorrect indexing of `numbering[i]`. I am not sure what the example exactly does, so I cannot propose a fix unfortunately.

---

<div class="post-metadata">

### Author: ![aszaboa](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/aszaboa/32/2918_2.png) [@aszaboa](https://community.freefem.org/u/aszaboa)
#### Post date: [February 8, 2023, 10:33pm UTC](https://community.freefem.org/t/strange-behavior-with-matload/2270/4 "2023-02-08T22:33:22Z")

</div>

I was trying to implement what I described above, however, it did not work. The error can be reproduced in the MWE I posted initially: I would expect it to work with reading only on a single core:

```auto
if(mpirank==0){
real[int, int] rhsView(1, 1);
MatLoad(rhsView, format = "binary", name = "rhsout");
real[int] rhs = rhsView.asarray;  
cout << "reading: rank " << mpirank << "/" << mpisize << ", rhsView.n=" << rhsView.n << ", rhs.n=" << rhs.n << endl;
}

```

However, at `MatLoad` the script seems to freeze. Is this behavior intended, or is this a bug?  
(Again, I think I can circumvent this, I am just curious and I would like to understand the behavior)

---

<div class="post-metadata">

### Author: ![prj](https://avatars.discourse-cdn.com/v4/letter/p/ecae2f/32.png) [@prj](https://community.freefem.org/u/prj)
#### Post date: [February 9, 2023, 6:30am UTC](https://community.freefem.org/t/strange-behavior-with-matload/2270/5 "2023-02-09T06:30:27Z")

</div>

You probably need to specify `communicator = mpiCommSelf` in the `MatLoad()`.

---

<div class="post-metadata">

### Author: ![aszaboa](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/aszaboa/32/2918_2.png) [@aszaboa](https://community.freefem.org/u/aszaboa)
#### Post date: [February 9, 2023, 8:43am UTC](https://community.freefem.org/t/strange-behavior-with-matload/2270/6 "2023-02-09T08:43:59Z")

</div>

Thanks, now it works perfectly!

---

<div class="post-metadata">

### Author: ![RYP](https://avatars.discourse-cdn.com/v4/letter/r/b9e5f3/32.png) [@RYP](https://community.freefem.org/u/RYP)
#### Post date: [July 26, 2026, 2:08pm UTC](https://community.freefem.org/t/strange-behavior-with-matload/2270/7 "2026-07-26T14:08:07Z")

</div>

Hi, @aszaboa

I have recently been learning parallel programming with FreeFEM. Could you elaborate on how the method you mentioned actually works? Do you have any script code for the implementation examples of your (i)-(iv)? I would like to learn from it.

Best regards.

---

<div class="post-metadata">

### Author: ![aszaboa](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/aszaboa/32/2918_2.png) [@aszaboa](https://community.freefem.org/u/aszaboa)
#### Post date: [July 26, 2026, 11:49pm UTC](https://community.freefem.org/t/strange-behavior-with-matload/2270/8 "2026-07-26T23:49:10Z")

</div>

Hi,

This is the macro I use to save the numbering of the processes:

```auto
    macro saveGlobal2LocalNumbering(infespace, inMat, inmeshName){

        /* just a dummy vector */
        real[int] tempPETSc;
        infespace gendef(uTemp);
        ChangeNumbering(inMat, uTemp[], tempPETSc);
        /* for some reason PETSc can only export (n,1) matrices ... */
        real[int, int] numExport(tempPETSc.n, 1);
        real[int, int] numExportFF(uTemp[].n, 1);

        /* mpiranks for the global indices */
        int[int] index2mpirank(tempPETSc.n);
        index2mpirank = mpirank;
        /* exporting ranks */
        for [i, ranki : index2mpirank] numExport(i,0) = ranki;
        ObjectView(numExport, format = "binary", name = (wdir + "/" + inmeshName + "_mpiranks_PETSc"));

        /* exporting vector space index 2 rank */
        uTemp[] = mpirank;
        numExportFF(:,0)= uTemp[];
        ObjectView(numExportFF, format = "binary", name = (wdir + "/" + inmeshName + "_mpiranks_FE"));

    }//EOM 

```

This is the macro to load the numbering:

```auto
    macro loadGlobal2LocalNumbering(vLocal2Global,inName,nGlobal){
        int[int] rankNumbering;
        /* loading the data */
        if(mpirank==0) {
            real[int, int] vecView(1, 1);
            MatLoad(vecView, format = "binary", name = inName, communicator = mpiCommSelf);
            nGlobal = vecView.n;
            rankNumbering.resize(nGlobal);
            for [i, numi:rankNumbering] numi = vecView(i,0);
        }
        
        /* broadcast and resize numbering */
        broadcast(processor(0),nGlobal);
        if(mpirank!=0) 
            rankNumbering.resize(nGlobal);
        mpiBarrier(mpiCommWorld);
        broadcast(processor(0),rankNumbering);
        
        /* gettig the sizes of the local numberings */
        int nLocal = 0;
        for(int i=0; i<nGlobal; i++) {
            if(rankNumbering[i] == mpirank)
                nLocal++;
        }

        /* saving the actual global2local numberings */
        vLocal2Global.resize(nLocal);
        nLocal=-1;
        for(int i=0; i<nGlobal; i++) {
            if(rankNumbering[i] == mpirank)
                vLocal2Global[++nLocal] = i;
        }
            
        mpiBarrier(mpiCommWorld);
    } //EOM 

```

These are the macros for writing and reading vectors:

```auto
    macro exportPETScBinary(vecPETSc, outputFileName) {
        real[int, int] solallView(vecPETSc.n, 1);
        solallView(:, 0) = vecPETSc;
        ObjectView(solallView, format = "binary", name = outputFileName);
    } //EOM

    macro loadPETScBinary(vec,loc2GlobNum,nGlob,fname){

        real[int] vecGlobIn(nGlob);
        if(mpirank==0) {
            real[int, int] vecGlobView(1, 1);
            MatLoad(vecGlobView, format = "binary", name = fname, communicator = mpiCommSelf);
            vecGlobIn = vecGlobView.asarray;
        }

        broadcast(processor(0), vecGlobIn);
            for(int i=0; i<loc2GlobNum.n; i++)
                vec[i] = vecGlobIn[loc2GlobNum[i]];

    } //EOM 

```

I hope that these are helpful. Let me know if you have questions!

---

<div class="post-metadata">

### Author: ![RYP](https://avatars.discourse-cdn.com/v4/letter/r/b9e5f3/32.png) [@RYP](https://community.freefem.org/u/RYP)
#### Post date: [July 27, 2026, 6:45am UTC](https://community.freefem.org/t/strange-behavior-with-matload/2270/9 "2026-07-27T06:45:02Z")

</div>

Hi @aszaboa , Thank you!  
That’s an excellent idea and the logic is very clear, it has been a great help to me.

By the way, I’d like to ask if you know whether there is a way to convert a PETSc `Mat` to a FreeFEM `matrix`. I know the reverse conversion is easy—simply use `Mat A(B)`.

---

<div class="post-metadata">

### Author: ![aszaboa](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/aszaboa/32/2918_2.png) [@aszaboa](https://community.freefem.org/u/aszaboa)
#### Post date: [July 27, 2026, 3:33pm UTC](https://community.freefem.org/t/strange-behavior-with-matload/2270/10 "2026-07-27T15:33:24Z")

</div>

I am happy to hear that the scripts are helpful. I have no idea if there is a simple method to convert a PETSc Mat into a FreeFEM matrix. I guess you could approach a PETSc mat as a bundle of vectors, and do the conversion that way - I believe PETSc partitions the matrices like that, i.e., each process get a certain number of rows of a matrix. I am not sure whether the sparse matrix structure complicates the approach.

---

<div class="post-metadata">

### Author: ![RYP](https://avatars.discourse-cdn.com/v4/letter/r/b9e5f3/32.png) [@RYP](https://community.freefem.org/u/RYP)
#### Post date: [July 28, 2026, 2:24am UTC](https://community.freefem.org/t/strange-behavior-with-matload/2270/11 "2026-07-28T02:24:25Z")

</div>

I greatly appreciate your detailed reply. I will continue to follow any progress in this regard and will share my feedback here as appropriate.
