virtual void
      fetchDims (const multivector_type& A,
		 local_ordinal_type& nrowsLocal, 
		 local_ordinal_type& ncols, 
		 local_ordinal_type& LDA) const
      {
	nrowsLocal = A.getLocalLength();
	ncols = A.getNumVectors();
	if (nrowsLocal < ncols)
	  {
	    std::ostringstream os;
	    os << "The local component of the input matrix has fewer row"
	      "s (" << nrowsLocal << ") than columns (" << ncols << ").  "
	      "TSQR::Trilinos::TpetraRandomizer does not support this case.";
	    throw std::runtime_error (os.str());
	  }
	if (! A.isConstantStride())
	  {
	    // FIXME (mfh 14 June 2010) Storage of A uses nonconstant
	    // stride internally, but that doesn't necessarily mean we
	    // can't run TSQR.  It depends on what get1dViewNonConst()
	    // returns.  If it's copied and packed into a matrix with
	    // constant stride, then we are free to run TSQR.
	    std::ostringstream os;
	    os << "TSQR::Trilinos::TpetraRandomizer does not support "
	      "Tpetra::MultiVector inputs that do not have constant stride.";
	    throw std::runtime_error (os.str());
	  }
	LDA = A.getStride();
      }
      virtual void
      fetchDims (const multivector_type& A,
		 local_ordinal_type& nrowsLocal,
		 local_ordinal_type& ncols,
		 local_ordinal_type& LDA) const
      {
	nrowsLocal = A.MyLength();
	ncols = A.NumVectors();
	if (nrowsLocal < ncols)
	  {
	    std::ostringstream os;
	    os << "TSQR: The local component of the input matrix has fewer row"
	      "s (" << nrowsLocal << ") than columns (" << ncols << ").  TSQR "
	      "does not support this case.";
	    throw std::runtime_error (os.str());
	  }
	if (! A.ConstantStride())
	  {
	    std::ostringstream os;
	    os << "TSQR does not support Epetra_MultiVector inputs that do not"
	      " have constant stride.";
	    throw std::runtime_error (os.str());
	  }
	LDA = A.Stride();
      }
      virtual Teuchos::ArrayRCP< scalar_type > 
      fetchNonConstView (multivector_type& A) const
      {
	// This won't be efficient if the entries of A live in a
	// different memory space (e.g., GPU node), but it will be
	// correct for any Tpetra::MultiVector type.
	return A.get1dViewNonConst();
      }
      virtual void
      fetchMessengers (const multivector_type& mv,
		       scalar_messenger_ptr& pScalarMessenger,
		       ordinal_messenger_ptr& pOrdinalMessenger) const
      {
	typedef TpetraCommFactory< S, LO, GO, NodeType > comm_factory_type;
	comm_ptr pComm = mv.getMap()->getComm();
	comm_factory_type factory;
	factory.makeMessengers (pComm, pScalarMessenger, pOrdinalMessenger);
      }
      virtual Teuchos::ArrayRCP< scalar_type > 
      fetchNonConstView (multivector_type& A) const
      {
	using Teuchos::arcpFromArrayView;
	using Teuchos::arrayView;
	typedef Teuchos::ArrayView< scalar_type >::size_type size_type;

	const size_type nelts = fetchArrayLength (A);
	// The returned ArrayRCP does NOT own A.Values().
	return arcpFromArrayView (arrayView (A.Values(), nelts));
      }
      virtual void
      fetchMessengers (const multivector_type& mv,
		       scalar_messenger_ptr& pScalarMessenger,
		       ordinal_messenger_ptr& pOrdinalMessenger) const
      {
	typedef EpetraCommFactory comm_factory_type;
	// mv.Comm() returns a "const Epetra_Comm&".  rcpFromRef()
	// makes a non-owning (weak) RCP out of it.  This requires
	// that the mv's Epetra_Comm object not fall out of scope,
	// which it shouldn't as long as we are computing with
	// multivectors distributed according to that communicator.
	comm_ptr pComm = Teuchos::rcpFromRef (mv.Comm());
	comm_factory_type factory;
	factory.makeMessengers (pComm, pScalarMessenger, pOrdinalMessenger);
      }
      virtual Teuchos::ArrayRCP< const scalar_type > 
      fetchConstView (const multivector_type& A) const
      {
	using Teuchos::arcpFromArrayView;
	using Teuchos::arrayView;
	using Teuchos::ArrayView;
	typedef ArrayView< scalar_type >::size_type size_type;

	const size_type nelts = fetchArrayLength (A);
	const scalar_type* A_ptr = A.Values();
	ArrayView< const scalar_type > A_view = arrayView (A_ptr, nelts);

	// The returned ArrayRCP does NOT own A.Values().
	return arcpFromArrayView (A_view);
      }
Example #8
0
  static double factorization( const multivector_type Q_ ,
                               const multivector_type R_ )
  {
#if defined( KOKKOS_USING_EXPERIMENTAL_VIEW )
    using Kokkos::Experimental::ALL ;
#else
    const Kokkos::ALL ALL ;
#endif
    const size_type count  = Q_.dimension_1();
    value_view tmp("tmp");
    value_view one("one");

    Kokkos::deep_copy( one , (Scalar) 1 );

    Kokkos::Impl::Timer timer ;

    for ( size_type j = 0 ; j < count ; ++j ) {
      // Reduction   : tmp = dot( Q(:,j) , Q(:,j) );
      // PostProcess : tmp = sqrt( tmp ); R(j,j) = tmp ; tmp = 1 / tmp ;
      const vector_type Qj  = Kokkos::subview( Q_ , ALL , j );
      const value_view  Rjj = Kokkos::subview( R_ , j , j );

      invnorm2( Qj , Rjj , tmp );

      // Q(:,j) *= ( 1 / R(j,j) ); => Q(:,j) *= tmp ;
      Kokkos::scale( tmp , Qj );

      for ( size_t k = j + 1 ; k < count ; ++k ) {
        const vector_type Qk = Kokkos::subview( Q_ , ALL , k );
        const value_view  Rjk = Kokkos::subview( R_ , j , k );

        // Reduction   : R(j,k) = dot( Q(:,j) , Q(:,k) );
        // PostProcess : tmp = - R(j,k);
        dot_neg( Qj , Qk , Rjk , tmp );

        // Q(:,k) -= R(j,k) * Q(:,j); => Q(:,k) += tmp * Q(:,j)
        Kokkos::axpby( tmp , Qj , one , Qk );
      }
    }

    execution_space::fence();

    return timer.seconds();
  }
Example #9
0
  static double factorization( const multivector_type Q ,
                               const multivector_type R )
  {
    const size_type count  = Q.dimension_1();
    value_view tmp("tmp");
    value_view one("one");

    KokkosArray::deep_copy( one , (Scalar) 1 );

    KokkosArray::Impl::Timer timer ;

    for ( size_type j = 0 ; j < count ; ++j ) {
      // Reduction   : tmp = dot( Q(:,j) , Q(:,j) );
      // PostProcess : tmp = sqrt( tmp ); R(j,j) = tmp ; tmp = 1 / tmp ;
      const vector_type Qj( Q , j );
      const value_view  Rjj( R , j , j );

      KokkosArray::dot( Qj , InvNorm2( Rjj , tmp  ) );

      // Q(:,j) *= ( 1 / R(j,j) ); => Q(:,j) *= tmp ;
      KokkosArray::scale( tmp , Qj );

      for ( size_t k = j + 1 ; k < count ; ++k ) {
        const vector_type Qk( Q , k );
        const value_view  Rjk( R , j , k );

        // Reduction   : R(j,k) = dot( Q(:,j) , Q(:,k) );
        // PostProcess : tmp = - R(j,k);
        KokkosArray::dot( Qj , Qk , DotM( Rjk , tmp ) );

        // Q(:,k) -= R(j,k) * Q(:,j); => Q(:,k) += tmp * Q(:,j)
        KokkosArray::axpby( tmp , Qj , one , Qk );
      }
    }

    device_type::fence();

    return timer.seconds();
  }
 /*! 
  * \brief Given a multivector, get a single non-const vector of a given
  * id.
  */
 static Teuchos::RCP<vector_type> getVectorNonConst( 
     multivector_type& multivector, const int id )
 { 
     return multivector.getVectorNonConst( id );
 }