[petsc-users] Malloc error with 'correct' preallocation?

Appel, Thibaut t.appel17 at imperial.ac.uk
Tue Feb 27 19:05:41 CST 2018


Dear PETSc developers and users,

I am forming a sparse matrix in complex, double precision arithmetic and can’t understand why I have «PETSC ERROR: Argument out of range - New nonzero at (X,X) caused a malloc» during the assembly of the matrix.

This matrix discretizes a PDE in 2D using a finite difference method in both spatial directions and, in short, here is the ensemble of routines I call:

    CALL MatCreate(PETSC_COMM_WORLD,MatA,ierr)
    CALL MatSetType(MatA,MATAIJ,ierr)
    CALL MatSetSizes(MatA,PETSC_DECIDE,PETSC_DECIDE,leading_dimension,leading_dimension,ierr)
    CALL MatSeqAIJSetPreallocation(MatA,0,PETSC_NULL_INTEGER,ierr)
    CALL MatMPIAIJSetPreallocation(MatA,0,PETSC_NULL_INTEGER,0,PETSC_NULL_INTEGER,ierr)
    CALL MatGetOwnershipRange(MatA,istart,iend,ierr)

Then I preallocate my matrix doing tests on the derivative coefficient arrays like

    ALLOCATE(nnz(istart:iend-1), dnz(istart:iend-1), onz(istart:iend-1))
    nnz = 0
    dnz = 0
    onz = 0
    DO row= istart, iend-1

	*detect the nonzero elements*
        IF (ABS(this_derivative_coef) > 0.D0) THEN 
          nnz(row) = nnz(row) + corresponding_stencil_size
          DO *elements in stencil*
              *compute corresponding column*
              IF ((col >= istart) .AND. (col <= (iend-1))) THEN
                dnz(row) = dnz(row) + 1
              ELSE
                onz(row) = onz(row) + 1
              END IF
          END DO
	END IF

   END DO
   CALL MatSeqAIJSetPreallocation(MatA,PETSC_DEFAULT_INTEGER,nnz,ierr)
   CALL MatMPIAIJSetPreallocation(MatA,PETSC_DEFAULT_INTEGER,dnz,PETSC_DEFAULT_INTEGER,onz,ierr)
   CALL MatSetOption(MatA,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE,ierr)

And assemble the matrix, at each row, with the different derivatives terms (pure x derivative, pure y derivative, cross xy derivative…)

    DO row = istart, iend-1

        cols(0) = *compute corresponding column*
        vals(0) = no_derivative_coef
        CALL MatSetValues(MatA,1,row,1,cols,vals,ADD_VALUES,ierr)

        DO m=0,x_order
          cols(m) = *compute corresponding column*
          vals(m) = x_derivative_coef
        END DO
        CALL MatSetValues(MatA,1,row,x_order+1,cols,vals,ADD_VALUES,ierr)

        DO m=0,y_order
          cols(m) = *compute corresponding column*
          vals(m) = y_derivative_coef
        END DO
        CALL MatSetValues(MatA,1,row,y_order+1,cols,vals,ADD_VALUES,ierr)

        DO n=0,y_order
          DO m=0,x_order
            cols(..) =  *compute corresponding column*
            vals(..)= xy_derivative_coef
          END DO
        END DO
        CALL MatSetValues(MatA,1,row,(x_order+1)*(y_order+1),cols,vals,ADD_VALUES,ierr)

    END DO

    CALL MatAssemblyBegin(MatA,MAT_FINAL_ASSEMBLY,ierr)
    CALL MatAssemblyEnd(MatA,MAT_FINAL_ASSEMBLY,ierr)

I am using ADD_VALUES as the different loops here-above can contribute to the same column.

The approach I chose is therefore preallocating without overestimating the non-zero elements and hope that the MAT_IGNORE_ZERO_ENTRIES option discards the 'vals(…)' who are exactly zero during the assembly (I read that the criteria PETSc uses to do so is ‘== 0.0’) so with the test I used everything should work fine.

However, when testing with 1 MPI process, I have this malloc problem appearing at a certain row.

I print the corresponding nnz(row) I allocated for this row, say NZ.
I print for each (cols, vals) computed in the loops above the test (vals /= zero) to number the non-zero elements and notice that the malloc error appears when I insert a block of non-zero elements in which the last one is the NZth!

In other words, why a malloc if the 'correct' number of elements is allocated? Is there something wrong with my understanding of ADD_VALUES?

I read somewhere that it is good to call both MatSeqAIJSetPreallocation and MatMPIAIJSetPreallocation as PETSc will automatically call the right one whether it is a serial or parallel computation. Is it better to use MatXAIJSetPreallocation?

Thank you in advance for any advice that could put me on the trail to correctness, and I would appreciate any correction should I do something that looks silly. 

Kind regards,


Thibaut



More information about the petsc-users mailing list