Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ifpack2: Error for factory create #4459

Closed
ghtina opened this issue Feb 21, 2019 · 10 comments
Closed

Ifpack2: Error for factory create #4459

ghtina opened this issue Feb 21, 2019 · 10 comments

Comments

@ghtina
Copy link

ghtina commented Feb 21, 2019

I wanted to use the Preconditioner from Ifpack2 for Belos and Tpetra but I got the following error

error: no matching function for call to ‘Ifpack2::Factory::create(const string&, Teuchos::RCP<Tpetra::CrsMatrix<> >&)’
      prec = factory.create (precName, A);

Edit: The following includes the notes:

main.cpp:195:40: error: no matching function for call to ‘Ifpack2::Factory::create(const string&, Teuchos::RCP<Tpetra::CrsMatrix<> >&)’
      prec = factory.create (precName, A);
                                        ^
In file included from /home/freaklovesmango/build-trilinos-tpetra/install/Trilinos/include/Ifpack2_Factory.hpp:1:0,
                 from main.cpp:23:
/home/freaklovesmango/build-trilinos-tpetra/install/Trilinos/include/Ifpack2_Factory_decl.hpp:135:3: note: candidate: template<class MatrixType> static Teuchos::RCP<Ifpack2::Preconditioner<typename MatrixType::scalar_type, typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type> > Ifpack2::Factory::create(const string&, const Teuchos::RCP<const T>&)
   create (const std::string& precType,
   ^
/home/freaklovesmango/build-trilinos-tpetra/install/Trilinos/include/Ifpack2_Factory_decl.hpp:135:3: note:   template argument deduction/substitution failed:
main.cpp:195:40: note:   types ‘const T’ and ‘Tpetra::CrsMatrix<>’ have incompatible cv-qualifiers
      prec = factory.create (precName, A);
                                        ^
main.cpp:195:40: note:   ‘Teuchos::RCP<Tpetra::CrsMatrix<> >’ is not derived from ‘const Teuchos::RCP<const T>’
In file included from /home/freaklovesmango/build-trilinos-tpetra/install/Trilinos/include/Ifpack2_Factory.hpp:1:0,
                 from main.cpp:23:
/home/freaklovesmango/build-trilinos-tpetra/install/Trilinos/include/Ifpack2_Factory_decl.hpp:175:3: note: candidate: template<class MatrixType> static Teuchos::RCP<Ifpack2::Preconditioner<typename MatrixType::scalar_type, typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type> > Ifpack2::Factory::create(const string&, const Teuchos::RCP<const T>&, int)
   create (const std::string& precType,
   ^
/home/freaklovesmango/build-trilinos-tpetra/install/Trilinos/include/Ifpack2_Factory_decl.hpp:175:3: note:   template argument deduction/substitution failed:
main.cpp:195:40: note:   types ‘const T’ and ‘Tpetra::CrsMatrix<>’ have incompatible cv-qualifiers
      prec = factory.create (precName, A);
                                        ^
main.cpp:195:40: note:   ‘Teuchos::RCP<Tpetra::CrsMatrix<> >’ is not derived from ‘const Teuchos::RCP<const T>’

My code is based on this example here: https://trilinos.org/docs/dev/packages/ifpack2/doc/html/classIfpack2_1_1Factory.html#aa19b22421fb0aeebe7a30d025b662aa6

#include "Ifpack2_Factory.hpp"
// ...
using Teuchos::ParameterList;
using Teuchos::RCP;
typedef double Scalar;
typedef Tpetra::CrsMatrix<Scalar> crs_matrix_type;
typedef Ifpack2::Preconditioner<Scalar> prec_type;
// ...
Ifpack2::Factory factory;
RCP<crs_matrix_type> A;
// ... fill A and call fillComplete() ...
// Use ILUT (incomplete LU with thresholding) on each process.
const std::string precType = "ILUT";
RCP<prec_type> prec = factory.create (precType, A);
ParameterList params;
params.set ("fact: ilut level-of-fill", 5.0); // ILUT(fill=5, drop=0)
prec->setParameters (params);
prec->initialize ();
prec->compute ();
// now prec can be used as a preconditioner

This is (basically) my actual code:

#include <Tpetra_MultiVector.hpp>
#include <Tpetra_CrsMatrix.hpp>
#include <Tpetra_Core.hpp>
#include <Tpetra_Version.hpp>
#include <Ifpack2_Factory.hpp>

int main(int argc, char *argv[])
{
 using Teuchos::ParameterList;
  using Teuchos::parameterList;
  using Teuchos::RCP;
  using Teuchos::rcp;

  typedef Tpetra::CrsMatrix<scalar_type, local_ordinal_type, global_ordinal_type, node_type> crs_type;

[...]

RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm ();
const global_ordinal_type indexBase = 0;
int numGlobalElementsMap = 5;

			RCP<map_type> matrixMap = rcp (new map_type(numGlobalElementsMap, numGlobalElementsMap, indexBase, comm));
  			RCP<crs_type> A = 
  				rcp(new crs_type(matrixMap, matrixMap, 0));
A->fillComplete();


// The name of the type of preconditioner to use.
    const std::string precondType ("ILUT");

    // Ifpack2 expects double-precision arguments here.
    const double fillLevel = 2.0;
    const double dropTol = 0.0;
    const double absThreshold = 0.1;
    const bool verbose = true;
    const bool debug = false;
RCP<ParameterList> plist = parameterList ("Preconditioner");
    plist->set ("Ifpack2::Preconditioner", precondType);

    ParameterList precParams ("Ifpack2");
    precParams.set ("fact: ilut level-of-fill", fillLevel);
    precParams.set ("fact: drop tolerance", dropTol);
    precParams.set ("fact: absolute threshold", absThreshold);
plist->set ("Ifpack2", precParams);
RCP<prec_type> prec;
		//ParameterList listPrec;
		ParameterList ifpack2Params;
		//Ifpack Factory;
		Ifpack2::Factory factory;
		// Get the preconditioner type
		const std::string precName = plist->get<std::string> ("Ifpack2::Preconditioner");
prec = factory.create (precName, A);
    	if (plist->isSublist ("Ifpack2"))
        ifpack2Params = plist->sublist ("Ifpack2");
      else
        ifpack2Params.setName ("Ifpack2");
      prec->setParameters (ifpack2Params);
      prec->setParameters (ifpack2Params);
      prec->initialize();
      prec->compute();
@jhux2
Copy link
Member

jhux2 commented Feb 21, 2019

@freaklovesmango Try changing the definition of prec_type to

typedef Ifpack2::Preconditioner<Scalar,LO,GO,Node> prec_type;.

@mhoemmen
Copy link
Contributor

@freaklovesmango Note that if you create the matrix with the row and column Map the same, then you're constraining the matrix to be block diagonal, where each block is an MPI process.

@ghtina
Copy link
Author

ghtina commented Feb 22, 2019

@freaklovesmango Try changing the definition of prec_type to

typedef Ifpack2::Preconditioner<Scalar,LO,GO,Node> prec_type;.

@jhux2 I forgot to show this part of my code but I did include this.

typedef Ifpack2::Preconditioner<scalar_type, local_ordinal_type, global_ordinal_type, node_type> prec_type;

@freaklovesmango Note that if you create the matrix with the row and column Map the >same, then you're constraining the matrix to be block diagonal, where each block is an >MPI process.

@mhoemmen thanks but this was intended because it is symmetric and also I do not use MPI/ only one MPI process.

Any other ideas maybe? I also edited my post with the notes followed by the error message.

@jhux2
Copy link
Member

jhux2 commented Feb 22, 2019

@freaklovesmango What are your LocalOrdinal and GlobalOrdinal types? Can you supply a self-contained example that reproduces the error?

@mhoemmen
Copy link
Contributor

@freaklovesmango wrote:

thanks but this was intended because it is symmetric and also I do not use MPI/ only one MPI process.

Ah, I think I remember that conversation with you on GitHub. It's OK then :-)

@ghtina
Copy link
Author

ghtina commented Feb 23, 2019

@freaklovesmango What are your LocalOrdinal and GlobalOrdinal types? Can you supply a self-contained example that reproduces the error?

@jhux2 I defined them like this:

  typedef Tpetra::Vector<>::local_ordinal_type local_ordinal_type;
  typedef Tpetra::Vector<>::global_ordinal_type global_ordinal_type;

An example should roughly be like this:

#include <Tpetra_MultiVector.hpp>
#include <Tpetra_CrsMatrix.hpp>
#include <Tpetra_Core.hpp>
#include <Tpetra_Version.hpp>

#include <BelosLinearProblem.hpp>
#include <Teuchos_RCP.hpp>
#include <Belos_Tpetra_SolverManager.hpp>
#include <BelosTpetraAdapter.hpp>
#include <Tpetra_Operator.hpp>
#include <Ifpack2_Factory.hpp>

int main(int argc, char *argv[])
{
  using Teuchos::ParameterList;
  using Teuchos::parameterList;
  using Teuchos::RCP;
  using Teuchos::rcp;

  typedef Tpetra::Vector<>::scalar_type scalar_type;
  typedef Tpetra::Vector<>::local_ordinal_type local_ordinal_type;
  typedef Tpetra::Vector<>::global_ordinal_type global_ordinal_type;
  typedef Tpetra::Vector<>::node_type node_type;
  typedef Tpetra::Map<> map_type;
  typedef Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type> mv_type;
  typedef Tpetra::CrsMatrix<scalar_type, local_ordinal_type, global_ordinal_type, node_type> crs_type;
  typedef Tpetra::Operator<scalar_type, local_ordinal_type, global_ordinal_type, node_type> op_type;
  typedef Ifpack2::Preconditioner<scalar_type, local_ordinal_type, global_ordinal_type, node_type> prec_type;

			RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm ();

	  		const int numProcs = comm->getSize(); //1
  			const int myRank = comm->getRank(); //0
			const size_t numGlobalElementsMap = 5;
  			const global_ordinal_type indexBase = 0;
  			RCP<map_type> vectorMap = rcp (new map_type(numGlobalElementsMap, indexBase, comm));
  			RCP<mv_type> b = rcp(new mv_type(vectorMap, 1));
  			b->putScalar(5.0);
  			for (index_t c = 0; c < dim; ++c){
  				b->replaceLocalValue(c,0,rhs[c]);
  			}

  			RCP<mv_type> x = rcp(new mv_type(vectorMap, 1));
  			x->putScalar(0.0);
  			RCP<map_type> matrixMap = rcp (new map_type(numGlobalElementsMap, numGlobalElementsMap, indexBase, comm));
  			RCP<crs_type> A = rcp(new crs_type(matrixMap, matrixMap, 0));
// this is just a random matrix
for( int row = 0 ; row < dim ; ++row )
		{
double val = 1.0;
double col = 1.0;
A->insertLocalValues(row, 1, &val, &col);
	}
A->fillComplete();
const std::string precondType ("ILUT");
    const double fillLevel = 2.0;
    const double dropTol = 0.0;
    const double absThreshold = 0.1;
    const bool verbose = true;
    const bool debug = false;
    RCP<ParameterList> plist = parameterList ("Preconditioner");
    plist->set ("Ifpack2::Preconditioner", precondType);

    ParameterList precParams ("Ifpack2");
    precParams.set ("fact: ilut level-of-fill", fillLevel);
    precParams.set ("fact: drop tolerance", dropTol);
    precParams.set ("fact: absolute threshold", absThreshold);

    plist->set ("Ifpack2", precParams);
RCP<prec_type> prec;
		ParameterList ifpack2Params;
		Ifpack2::Factory factory;
const std::string precName = plist->get<std::string> ("Ifpack2::Preconditioner");
		
prec = rcp(factory.create (precName, A));
    	if (plist->isSublist ("Ifpack2"))
        ifpack2Params = plist->sublist ("Ifpack2");
      else
        ifpack2Params.setName ("Ifpack2");
      prec->setParameters (ifpack2Params);
      prec->setParameters (ifpack2Params);
      prec->initialize();
      prec->compute();
RCP<Belos::LinearProblem<scalar_type, mv_type, op_type>> belosProblem = rcp(new Belos::LinearProblem<scalar_type, mv_type, op_type> (A, x, b));

bool set = belosProblem->setProblem();
}

@mhoemmen
Copy link
Contributor

@freaklovesmango You shouldn't have to call rcp on the result of factory.create (precName, A);; you should just be able to assign it to prec. If that doesn't help, try also casting A to const:

prec = factory.create (precName, Teuchos::rcp_const_cast (A));

@ghtina
Copy link
Author

ghtina commented Feb 24, 2019

@freaklovesmango You shouldn't have to call rcp on the result of factory.create (precName, A);; you should just be able to assign it to prec. If that doesn't help, try also casting A to const:

prec = factory.create (precName, Teuchos::rcp_const_cast (A));

@mhoemmen I tried without rcp which did not work. Also, the cast seems to be inappropriate...
This is the error message I got:

main.cpp:188:65: error: no matching function for call to ‘rcp_const_cast(Teuchos::RCP<Tpetra::CrsMatrix<> >&)’
      prec = factory.create (precName, Teuchos::rcp_const_cast (A));
                                                                 ^
/home/freaklovesmango/build-trilinos-tpetra/install/Trilinos/include/Teuchos_RCP.hpp:752:1: note: candidate: template<class T2, class T1> Teuchos::RCP<T1> Teuchos::rcp_const_cast(const Teuchos::RCP<T2>&)
 Teuchos::rcp_const_cast(const RCP<T1>& p1)
 ^
/home/freaklovesmango/build-trilinos-tpetra/install/Trilinos/include/Teuchos_RCP.hpp:752:1: note:   template argument deduction/substitution failed:
main.cpp:188:65: note:   couldn't deduce template parameter ‘T2’
      prec = factory.create (precName, Teuchos::rcp_const_cast (A));

I am not sure if I use the method properly?
https://trilinos.org/docs/dev/packages/teuchos/doc/html/classTeuchos_1_1RCP.html#a6931e6c2f74c9fa9467e5dc91c6cd983

@mhoemmen
Copy link
Contributor

@freaklovesmango My bad, I forgot about the key detail of the cast:

prec = factory.create (precName, Teuchos::rcp_const_cast<const crs_type> (A));

@ghtina
Copy link
Author

ghtina commented Feb 26, 2019

@freaklovesmango My bad, I forgot about the key detail of the cast:

prec = factory.create (precName, Teuchos::rcp_const_cast<const crs_type> (A));

@mhoemmen It worked! Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants