Mattero
Multi-dimensional arrays in Fortran are are a sham. That is, a
multi-dimensional array in fortran is simply a one dimensional array with a
little additional information.
If you have a three dimensional array in Fortran that is
1 3
2 4
5 7
6 8
9 11
10 12
where above I have indicated
A(:,:,1)
A(:,:,2)
A(:,:,3)
it is in actual memory stored in consecutive memory locations as
1 2 3 4 5 6 7 8 9 10 11 12
this is called column major format because the columns are listed in
consecutive memory before rows.
When you call MatCreateMPIBAIJWithArrays() it does not expect the values in
row-major order, it expects them in column major order per block, which, as I
understand it, is exactly what you have already computed.
Please just try what I suggest and see what happens. Send all the output if
it goes wrong, for a tiny problem. The beautiful thing which I love about
programming is no one punishes you for trying something, even it if it is
wrong. As I said before it should just work, if it doesn't then let us know
EXACTLY what goes wrong and we'll see if there is a bug on our end or a
misunderstanding. We are talking too much and not trying enough.
Barry
On Sep 27, 2013, at 8:01 PM, Matteo Parsani <[email protected]> wrote:
> Hi Barry,
> thank you for your feedback. I could be wrong but it seems to me that
> MatSetValuesBlocked has to be called passing a 1D array, as you said.
>
> In fact, From
> http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Mat/MatSetValuesBlocked.html
> Suppose m=n=2 and block size(bs
> ) = 2 The array is
>
> 1 2 | 3 4
>
> 5 6 | 7 8
>
> - - - | - - -
>
> 9 10 | 11 12
>
> 13 14 | 15 16
>
> v[] should be passed in like
>
> v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
>
> If you are not using row oriented storage of v (that is you called
> MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE
> )) then
>
> v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
>
>
>
> So, from above I can see that v[] is a 1D array. My problem or question is
> that my small block are stored in memory as
>
>
> A = [a11, a12 ; a21, a22]
> B = [b11, b12 ; b21, b22]
> etc.
> (My actual blocks are 5x5 as indicated in my first e-mail but here I made
> them smaller to type less)
>
>
> They are actually 2D arrays, i.e with two indices. Therefore before to pass
> them to MatSetValuesBlocked I have to concatenate them in row oriented
> storage or column oriented storage, i.e
>
> v = [a11, a12, b11, b12, a21, a22, b21, b22]
>
> or
>
> v = [a11, a21, a12, a22, b11, b21, b12, b22]
>
> For each element in my mesh I construct N [5x5] blocks (N 2D arrays) which,
> once inserted in the PC matrix, will form the element contribution to the PC
> matrix. The 2D arrays are dense matrix and they are the output of the
> multiplication between a dense matrix and a matrix in CSR which is done
> internally to my Fortran code. Thus I will loop over all elements owned by a
> processor, and each time I will construct the N 2D arrays of 1 element and
> insert them in the PC matrix.
>
> I would like to know if I can avoid to concatenate them in row oriented
> storage or column oriented storage and pass them directly as 2D arrays.
>
>
> Thus, if I am not wrong, it would be nice if the user could have the option
> to pass to MatSetValuesBlocked each block as:
>
> 1- values[bs][bs][1] (e.g. A = [a11, a12 ; a21, a22] )
> values[bs][bs][2] (e.g. B = [b11, b12 ; b21, b22] )
>
> plus the two vectors that complete the CSR format, i.e. global block row and
> column indices (i and j indices). Maybe the last indices that define the
> blocks (i.e. [1] and [2] in the examples can be avoided)
>
> or
>
> 2- values[nblockrows][nblockcols][bs][bs]
>
> Thanks,
>
>
>
> On Fri, Sep 27, 2013 at 5:34 PM, Barry Smith <[email protected]> wrote:
>
> I don't understand the (mild) rant below, the expected format of the
> values is suppose to be EXACTLY what one puts in the double *array for block
> CSR format. That is the values are (formally) a 1 dimensional array)
> containing each block of values (in column oriented storage, that is the
> first column of the values in the first block, followed by the next column in
> the first block, etc etc) in the same order as the j indices. Note that
> this means that in Fortran the values array could be thought of as double
> A(bs,bs,nnz) Note that this is exactly how Matteo has his stuff organized so
> "it should just work". If it does not then please submit a bug report with a
> very small matrix that reproduces the problem.
>
> This function is exactly what it says it is, it takes in exactly a matrix
> in block CSR format.
>
> > wondering if a layout like values[nblockrows][nblockcols][bs][bs]
> > would not be much more convenient for users.
>
> I don't understand this. It is a dense matrix as big as the entire sparse
> matrix.
>
> Barry
>
>
> On Sep 27, 2013, at 4:02 PM, Lisandro Dalcin <[email protected]> wrote:
>
> > On 27 September 2013 21:23, Barry Smith <[email protected]> wrote:
> >> Just use MatCreateMPIBAIJWithArrays() saves thinking and work.
> >
> > BTW, Have you ever thought about how hard to use is this API if you
> > want to provide the matrix values? How are users supposed to fill the
> > "values" array for a matrix with bs>1 ? This API is certainly not
> > Fortran-friendly (and I think it not even C-friendly). Mateo had the
> > CSR indices as well as the block values, but I recommended to use the
> > CSR indices to perform proper matrix preallocation, then loop over
> > cells and call MatSetValuesBlocked(). Otherwise, he would need to
> > create an new intermediate array and fill it the right way for
> > MatCreateMPIBAIJWithArrays() to work as expected.
> >
> > The root of the problem is how MatSetValuesBlocked() expects the array
> > of values to be layout in memory. While I understand that the current
> > convention make it compatible with MatSetValues(), I'm always
> > wondering if a layout like values[nblockrows][nblockcols][bs][bs]
> > would not be much more convenient for users.
> >
> >
> >
> > --
> > Lisandro Dalcin
> > ---------------
> > CIMEC (UNL/CONICET)
> > Predio CONICET-Santa Fe
> > Colectora RN 168 Km 472, Paraje El Pozo
> > 3000 Santa Fe, Argentina
> > Tel: +54-342-4511594 (ext 1016)
> > Tel/Fax: +54-342-4511169
>
>
>
>
> --
> Matteo