Thyra::MPILinearOpBase< Scalar > Class Template Reference
[Thyra Operator/Vector Base Support Subclasses for MPI-based SPMD Thyra Implementations]

Base subclass for simplistic MPI SPMD linear operators. More...

#include <Thyra_MPILinearOpBaseDecl.hpp>

Inheritance diagram for Thyra::MPILinearOpBase< Scalar >:

[legend]
List of all members.

Overridden from EuclideanLinearOpBase

Teuchos::RefCountPtr< const
ScalarProdVectorSpaceBase<
Scalar > > 
rangeScalarProdVecSpc () const
 
Teuchos::RefCountPtr< const
ScalarProdVectorSpaceBase<
Scalar > > 
domainScalarProdVecSpc () const
 
void euclideanApply (const ETransp M_trans, const MultiVectorBase< Scalar > &X, MultiVectorBase< Scalar > *Y, const Scalar alpha, const Scalar beta) const
 Calls protected euclideanApply() function.

Protected constructors/initializers/accessors

 MPILinearOpBase ()
virtual void setSpaces (const Teuchos::RefCountPtr< const MPIVectorSpaceBase< Scalar > > &range, const Teuchos::RefCountPtr< const MPIVectorSpaceBase< Scalar > > &domain)
 Initialize vector spaces using pre-formed MPIVectorSpaceBase objects.
virtual void setLocalDimensions (MPI_Comm mpiComm, const Index localDimRange, const Index localDimDomain)
 Initialize vector spaces given local dimensions (uses MPIVectorSpaceStd).
void forceUnitStride (const bool &forceUnitStride)
 Set if unit stride is forced for vector data views or not.

Protected virtual functions to be overridden by subclasses

virtual void euclideanApply (const ETransp M_trans, const RTOpPack::SubVectorT< Scalar > &local_x, const RTOpPack::MutableSubVectorT< Scalar > *local_y, const Scalar alpha, const Scalar beta) const =0
 Apply the operator to explicit vector data.
virtual void euclideanApply (const ETransp M_trans, const RTOpPack::SubMultiVectorT< Scalar > &local_X, const RTOpPack::MutableSubMultiVectorT< Scalar > *local_Y, const Scalar alpha, const Scalar beta) const
 Apply the operator to explicit multi-vector data.

Detailed Description

template<class Scalar>
class Thyra::MPILinearOpBase< Scalar >

Base subclass for simplistic MPI SPMD linear operators.

This subclass defines machinery for developing concrete LinearOpBase subclasses for MPI SPMD vectors where it is assumed that all of the local elements in associated vectors and multi-vectors are immediately and cheaply available on each processor.

This base subclass derives from EuclideanLinearOpBase and therefore any application-specific scalar products can easily be incorporated.

Notes to subclass developers

The only function that a subclass must override in order to provide a concrete implementation is the explicit single-vector version euclideanApply().

This function is called on the subclass implementation passing in views of explicit data. The raw pointers to the local input and input/output arrays are passed in simple templated classes RTOpPack::SubVectorT and RTOpPack::MutableSubVectorT. Getting raw pointers out of these objects is easy.

It is very easy to create concrete subclasses of MPILinearOpBase (see MPITridiagLinearOp for a concrete example). All one has to do is to create a derived base class (MyMPILinearOp for example) of the form:

template<class Scalar>
class MyMPILinearOp : public MPILinearOpBase<Scalar> {
private:
  // Declare your classes private data
  ...
public:
  // Declare you classes constructors, destructor and other initialization functions
  ...
protected:
  // Override the version of euclideanApply() that takes explicit data
  void euclideanApply(
    const ETransp                                M_trans
    ,const RTOpPack::SubVectorT<Scalar>          &local_x_in
    ,const RTOpPack::MutableSubVectorT<Scalar>   *local_y_out
    ,const Scalar                                alpha
    ,const Scalar                                beta
    ) const
    {
      // Get raw pointers to local vector data to make me feel better!
      const Scalar *local_x     = local_x_in.values();
      const Index  local_x_dim  = local_x_in.subDim();
      Scalar       *local_y     = local_y_out->values();
      const Index  local_y_dim  = local_y_out->subDim();
      // Perform operation the operation
      if( real_trans(M_trans) == ::Thyra::NOTRANS ) {
        // Perform the non-transposed operator: y = alpha*M*x + beta*y
        ...
      }
      else {
        // Perform the transposed operation: y = alpha*M'*x + beta*y
        ...
      }
  };

Of course the above function will have to perform some type of processor-to-processor communication in order to apply any non-trivial distributed-memory linear operator but that is always the case.

If you do not need to handle arbitrary scalar data types then you do not have to support them. For example, to define a subclass that only supports double you would declare a non-templated version of the form:

class MyMPILinearOp : public MPILinearOpBase<double> {
private:
  // Declare your classes private data
  ...
public:
  // Declare you classes constructors, destructor and other initialization functions
  ...
protected:
  // Override the version of euclideanApply() that takes explicit data
  void euclideanApply(
    const ETransp                                M_trans
    ,const RTOpPack::SubVectorT<double>          &local_x_in
    ,const RTOpPack::MutableSubVectorT<double>   *local_y_out
    ,const double                                alpha
    ,const double                                beta
    ) const
    {
      // Get raw pointers to vector data to make me feel better!
      const double *local_x     = local_x_in.values();
      const Index  local_x_dim  = local_x_in.subDim();
      double       *local_y     = local_y_out->values();
      const Index  local_y_dim  = local_y_out->subDim();
      // Perform operation the operation
      if( real_trans(M_trans) == ::Thyra::NOTRANS ) {
        // Perform the non-transposed operator: y = alpha*M*x + beta*y
        ...
      }
      else {
        // Perform the transposed operation: y = alpha*M'*x + beta*y
        ...
      }
  };

By default, pointers to explicit data returned from local_x.values() and local_y->values() above are forced to have unit stride to simplify things. However, if your subclass can efficiently handle non-unit stride vector data (as the BLAS can for example) then you can allow this by calling the function this->forceUnitStride() and passing in false. The function this->forceUnitStride() can only be called by your subclasses as it is declared protected so do not worry about silly users messing with this, it is none of their business.

The explicit multi-vector version of euclideanApply() has a default implementation that calls the explicit single-vector version (that a subclass must supply) one column at a time. A subclass should only override this default multi-vector version if it can do something more efficient.

Examples:

MPITridiagLinearOp.hpp.

Definition at line 170 of file Thyra_MPILinearOpBaseDecl.hpp.


Constructor & Destructor Documentation

template<class Scalar>
Thyra::MPILinearOpBase< Scalar >::MPILinearOpBase  ) 
 

Construct to uninitialized

Postconditions:

Definition at line 86 of file Thyra_MPILinearOpBase.hpp.


Member Function Documentation

template<class Scalar>
Teuchos::RefCountPtr< const ScalarProdVectorSpaceBase< Scalar > > Thyra::MPILinearOpBase< Scalar >::rangeScalarProdVecSpc  )  const [virtual]
 

Implements Thyra::EuclideanLinearOpBase< Scalar >.

Definition at line 44 of file Thyra_MPILinearOpBase.hpp.

template<class Scalar>
Teuchos::RefCountPtr< const ScalarProdVectorSpaceBase< Scalar > > Thyra::MPILinearOpBase< Scalar >::domainScalarProdVecSpc  )  const [virtual]
 

Implements Thyra::EuclideanLinearOpBase< Scalar >.

Definition at line 51 of file Thyra_MPILinearOpBase.hpp.

template<class Scalar>
void Thyra::MPILinearOpBase< Scalar >::euclideanApply const ETransp  M_trans,
const MultiVectorBase< Scalar > &  X,
MultiVectorBase< Scalar > *  Y,
const Scalar  alpha,
const Scalar  beta
const [virtual]
 

Calls protected euclideanApply() function.

Implements Thyra::SingleScalarEuclideanLinearOpBase< Scalar >.

Definition at line 57 of file Thyra_MPILinearOpBase.hpp.

template<class Scalar>
void Thyra::MPILinearOpBase< Scalar >::forceUnitStride const bool &  forceUnitStride  )  [inline, protected]
 

Set if unit stride is forced for vector data views or not.

Parameters:
forceUnitStride [in]
Postconditions:

Definition at line 208 of file Thyra_MPILinearOpBaseDecl.hpp.

template<class Scalar>
void Thyra::MPILinearOpBase< Scalar >::setSpaces const Teuchos::RefCountPtr< const MPIVectorSpaceBase< Scalar > > &  range,
const Teuchos::RefCountPtr< const MPIVectorSpaceBase< Scalar > > &  domain
[virtual]
 

Initialize vector spaces using pre-formed MPIVectorSpaceBase objects.

Parameters:
domain [in] Smart pointer to domain space
range [in] Smart pointer to range space
Precondition:
  • domain.get() != NULL
  • range.get() != NULL

Postcondition:

Definition at line 91 of file Thyra_MPILinearOpBase.hpp.

template<class Scalar>
void Thyra::MPILinearOpBase< Scalar >::setLocalDimensions MPI_Comm  mpiComm,
const Index  localDimRange,
const Index  localDimDomain
[virtual]
 

Initialize vector spaces given local dimensions (uses MPIVectorSpaceStd).

Parameters:
mpiComm [in] MPI Communicator
localDimRange [in] The local number of vector elements in the domain space.
localDimDomain [in] The local number of vector elements in the domain space.
Precondition:
  • localDimRange > 0
  • localDimDomain > 0

Postcondition:

  • dynamic_cast<MPIVectorSpace<Scalar>&>(*this->range()).localSubDim() == localDimRange
  • dynamic_cast<MPIVectorSpace<Scalar>&>(*this->domain()).localSubDim() == localDimDomain
  • dynamic_cast<const MPIVectorSpaceStd<Scalar>*>(this->range().get()) != NULL
  • dynamic_cast<const MPIVectorSpaceStd<Scalar>*>(this->domain().get()) != NULL

Definition at line 105 of file Thyra_MPILinearOpBase.hpp.

template<class Scalar>
virtual void Thyra::MPILinearOpBase< Scalar >::euclideanApply const ETransp  M_trans,
const RTOpPack::SubVectorT< Scalar > &  local_x,
const RTOpPack::MutableSubVectorT< Scalar > *  local_y,
const Scalar  alpha,
const Scalar  beta
const [pure virtual]
 

Apply the operator to explicit vector data.

See LinearOpBase::euclideanApply() for a discussion of the arguments to this function. What differentiates this function is that local_x and local_y are passed as objects with explicit pointers to local vector data.

Since this function is protected and does not get directly called by a client. Instead, this function is called by the vector version of euclideanApply().

template<class Scalar>
void Thyra::MPILinearOpBase< Scalar >::euclideanApply const ETransp  M_trans,
const RTOpPack::SubMultiVectorT< Scalar > &  local_X,
const RTOpPack::MutableSubMultiVectorT< Scalar > *  local_Y,
const Scalar  alpha,
const Scalar  beta
const [virtual]
 

Apply the operator to explicit multi-vector data.

See LinearOpBase::euclideanApply() for a discussion of the arguments to this function. What differentiates this function is that local_X and local_Y are passed as objects with explicit pointers to local multi-vector data.

Since this function is protected and does not get directly called by a client. Instead, this function is called by the multi-vector version of euclideanApply().

The default implementation just calls the above vector version one column at a time. A subclass should only override this function if it can provide a cache-smart version. At any rate, one can get up and going very quickly by just providing an override for the simpler single-vector version. Then latter, if profiling data justifies it, one can provide a specialized override for this function in an attempt to improve performance.

Definition at line 122 of file Thyra_MPILinearOpBase.hpp.


The documentation for this class was generated from the following files:
Generated on Thu Sep 18 12:39:53 2008 for Thyra ANA Operator/VectorBase Interfaces and Related Software by doxygen 1.3.9.1