Hello,

    I am trying to use a matrix-free linear operator with a matrix-explicit preconditioner, but when I try to do the KSP solve it gives the error:

[0]PETSC ERROR: See http://www.mcs.anl.gov/petsc/documentation/linearsolvertable.html for possible LU and Cholesky solvers [0]PETSC ERROR: Could not locate a solver package. Perhaps you must ./configure with --download-<package> [0]PETSC ERROR: See http://www.mcs.anl.gov/petsc/documentation/faq.html for trouble shooting.
[0]PETSC ERROR: Petsc Release Version 3.8.3, Dec, 09, 2017
[0]PETSC ERROR: ./testcase on a arch-linux2-c-debug named jared-r15 by jared Thu Feb  1 12:40:57 2018
[0]PETSC ERROR: Configure options
[0]PETSC ERROR: #1 MatGetFactor() line 4346 in /home/jared/.julia/v0.4/PETSc2/deps/petsc-3.8.3/src/mat/interface/matrix.c [0]PETSC ERROR: #2 PCSetUp_ILU() line 142 in /home/jared/.julia/v0.4/PETSc2/deps/petsc-3.8.3/src/ksp/pc/impls/factor/ilu/ilu.c [0]PETSC ERROR: #3 PCSetUp() line 924 in /home/jared/.julia/v0.4/PETSc2/deps/petsc-3.8.3/src/ksp/pc/interface/precon.c [0]PETSC ERROR: #4 KSPSetUp() line 381 in /home/jared/.julia/v0.4/PETSc2/deps/petsc-3.8.3/src/ksp/ksp/interface/itfunc.c [0]PETSC ERROR: #5 PCSetUpOnBlocks_BJacobi_Singleblock() line 618 in /home/jared/.julia/v0.4/PETSc2/deps/petsc-3.8.3/src/ksp/pc/impls/bjacobi/bjacobi.c [0]PETSC ERROR: #6 PCSetUpOnBlocks() line 955 in /home/jared/.julia/v0.4/PETSc2/deps/petsc-3.8.3/src/ksp/pc/interface/precon.c [0]PETSC ERROR: #7 KSPSetUpOnBlocks() line 213 in /home/jared/.julia/v0.4/PETSc2/deps/petsc-3.8.3/src/ksp/ksp/interface/itfunc.c [0]PETSC ERROR: #8 KSPSolve() line 613 in /home/jared/.julia/v0.4/PETSc2/deps/petsc-3.8.3/src/ksp/ksp/interface/itfunc.c


  The code to reproduce this error is attached.  The error is present on Petsc 3.7.6 and 3.8.3.  I noticed two things while creating the test case: 1) using a jacobi preconditioner works (using block jacobi with ILU on each block does not), and 2) if I replace the shell matrix with the preconditioner matrix in KSPSetOperators(), there is no error (with the block jacobi ILU preconditioner).

  Is this a bug in Petsc or did I setup the preconditioner incorrectly?

    Jared Crean


static char help[] = "Test using a matrix-free linear operator with a matrix-explicit preconditioner";

#include <petscksp.h>

// use a global constant for the matrix values
const PetscInt N = 4;  // matrix is N x N
const PetscScalar Avals[] = { 1 + 2, 1,     1,      1,
                              1,     1 + 3, 1,      1,
                              1,     1,     1 + 4,  1,
                              1,     1,     1,      1 + 5};

// multiplication function for shell matrix
PetscErrorCode applyLinearOperator(Mat A, Vec x, Vec b);

#undef __FUNCT__
#define __FUNCT__ "main"
int main(int argc,char **args)
{

  PetscInitialize(&argc,&args,(char*)0,help);
  const char* option_keys[] = {"-ksp_monitor",
                               "-pc_type",
                               "-sub_pc_factor_levels",
                               "-sub_pc_type"
                        };
  const char* option_vals[] = {"",
                               "bjacobi",
                               "4",
                               "ilu"
                              };

  int noptions = sizeof(option_keys)/sizeof(option_keys[0]);
  for (int i=0; i < noptions; ++i)
    PetscOptionsSetValue(NULL, option_keys[i], option_vals[i]);


  // create preconditioner matrix
  Mat Ap;
  MatCreate(MPI_COMM_WORLD, &Ap);
  MatSetFromOptions(Ap);
  MatSetType(Ap, MATMPIAIJ);
  MatSetSizes(Ap, N, N, PETSC_DECIDE, PETSC_DECIDE);
  MatMPIAIJSetPreallocation(Ap, N, NULL, 0, NULL);

  // create the shell matrix
  Mat A;
  MatCreateShell(MPI_COMM_WORLD, N, N, PETSC_DECIDE, PETSC_DECIDE, NULL, &A);
  MatSetFromOptions(A);
  MatSetUp(A);
  MatShellSetOperation(A, MATOP_MULT, (void*)(&applyLinearOperator));

  // create the KSP
  KSP ksp;
  KSPCreate(MPI_COMM_WORLD, &ksp);
  KSPSetFromOptions(ksp);
  KSPSetOperators(ksp, A, Ap);

  // create vectors
  Vec x, b;
  VecCreate(MPI_COMM_WORLD, &b);
  VecSetType(b, VECMPI);
  VecSetSizes(b, N, PETSC_DECIDE);

  VecCreate(MPI_COMM_WORLD, &x);
  VecSetType(x, VECMPI);
  VecSetSizes(x, N, PETSC_DECIDE);


  // put values into Ap and b
  PetscInt idx[N];
  PetscScalar bvals[N];

  for (int i=0; i < N; ++i)
  {
    idx[i] = i;
    bvals[i] = 1;
  }

  MatSetValues(Ap, N, idx, N, idx, Avals, ADD_VALUES);
  VecSetValues(b, N, idx, bvals, ADD_VALUES);


  // assemble
  MatAssemblyBegin(Ap, MAT_FINAL_ASSEMBLY);
  VecAssemblyBegin(b);

  MatAssemblyEnd(Ap, MAT_FINAL_ASSEMBLY);
  VecAssemblyEnd(b);

  // solve - this triggers the error
  KSPSolve(ksp, b, x);
  VecView(x, PETSC_VIEWER_STDOUT_WORLD);


  // cleanup
  VecDestroy(&b);
  VecDestroy(&x);
  MatDestroy(&A);
  KSPDestroy(&ksp);

  PetscFinalize();
  return 0;
}


// multiplication function for shell matrix
PetscErrorCode applyLinearOperator(Mat A, Vec x, Vec b)
{

  PetscScalar* btmp;
  const PetscScalar* xtmp;

  VecGetArray(b, &btmp);
  VecGetArrayRead(x, &xtmp);

  // zero out b just in case
  for (int i=0; i < N; ++i)
    btmp[i] = 0;

  // multiply
  for (int i=0; i < N; ++i)
    for (int j=0; j < N; ++j)
      btmp[i] += Avals[j + i*N]*xtmp[j];

  VecRestoreArray(b, &btmp);
  VecRestoreArrayRead(x, &xtmp);

  return 0;
}

Reply via email to