Tpetra: Use of ETI macros should not require enclosing them in Tpetra namespace
Created by: mhoemmen
@trilinos/tpetra
Tpetra currently requires that its explicit template instantiation (ETI) macros be used inside the Tpetra namespace. For example:
namespace Tpetra {
SOME_ETI_MACRO_GOES_HERE(...); // just a representation
};
This hinders moving Tpetra classes around and hiding this from users with aliases.
Motivation and Context
I'm working on #2548 and #57. As part of that, I've been applying the following procedure to Tpetra classes:
For all Tpetra classes CLASS
that take 3 or 4 template parameters:
- Move Tpetra class
${CLASS}
fromTpetra
namespace toTpetra::Classes
namespace. - Add forward declaration header file
Tpetra_${CLASS}_fwd.hpp
, that forward-declaresTpetra::Class::${CLASS}
, and adds a template alias to that class in theTpetra
namespace. - Change ETI macro for
${CLASS}
, to put the instantiation in the Classes namespace (Tpetra expects the macros to be used in the Tpetra namespace). - Fix any forward declarations in downstream classes.
This was going fine, until I got to Tpetra::CrsMatrix
. The problem is that Stokhos actually specializes CrsMatrix for various Scalar types. That was working fine for MultiVector, but not for CrsMatrix. As I looked through Stokhos' ETI macros for its specializations of Tpetra classes (for its own Scalar types, specifically UQ PCE), I noticed that they all had to be used inside the Tpetra namespace. Some macros actually needed to be used in the Tpetra::Classes namespace, and others just in the Tpetra namespace. It was a mess that I eventually was able to work around, but it showed how requiring macros to be used in a particular namespace was leading to trouble.
Possible Solution
Put the namespaces themselves in the macro definition:
#define TPETRA_FOO_INST(SC, LO, GO, NT) \
namespace Tpetra { namespace Classes { template class Foo<SC, LO, GO, NT>; } }