Thyra Package Browser (Single Doxygen Collection) Version of the Day
Thyra_SpmdMultiVectorSerializer_def.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //    Thyra: Interfaces and Support for Abstract Numerical Algorithms
00005 //                 Copyright (2004) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #ifndef THYRA_SPMD_MULTI_VECTOR_SERIALIZER_HPP
00030 #define THYRA_SPMD_MULTI_VECTOR_SERIALIZER_HPP
00031 
00032 #include "Thyra_SpmdMultiVectorSerializer_decl.hpp"
00033 #include "Thyra_SpmdVectorSpaceDefaultBase.hpp"
00034 #include "Thyra_MultiVectorBase.hpp"
00035 #include "Thyra_DetachedMultiVectorView.hpp"
00036 
00037 namespace Thyra {
00038 
00039 template<class Scalar>
00040 SpmdMultiVectorSerializer<Scalar>::SpmdMultiVectorSerializer(
00041   const bool  my_binaryMode
00042   )
00043   :binaryMode_(my_binaryMode)
00044 {}
00045 
00046 template<class Scalar>
00047 bool SpmdMultiVectorSerializer<Scalar>::isCompatible(
00048   const MultiVectorBase<Scalar> &mv
00049   ) const
00050 {
00051   return 0!=dynamic_cast<const SpmdVectorSpaceBase<Scalar>*>(&*mv.range());
00052 }
00053 
00054 template<class Scalar>
00055 void SpmdMultiVectorSerializer<Scalar>::serialize(
00056   const MultiVectorBase<Scalar>& mv, std::ostream& out
00057   ) const
00058 {
00059   Teuchos::RCP<const SpmdVectorSpaceBase<Scalar> >
00060     mpi_vec_spc
00061     = Teuchos::rcp_dynamic_cast<const SpmdVectorSpaceBase<Scalar> >(mv.range());
00062   out.precision(std::numeric_limits<Scalar>::digits10+4);
00063   if( mpi_vec_spc.get() ) {
00064     // This is a mpi-based vector space so let's just write the local
00065     // multi-vector elements (row-by-row).
00066     const Ordinal
00067       localOffset = mpi_vec_spc->localOffset(),
00068       localSubDim = mpi_vec_spc->localSubDim();
00069     const Range1D localRng( localOffset, localOffset+localSubDim-1 ); 
00070     ConstDetachedMultiVectorView<Scalar> local_mv(mv,localRng,Range1D());
00071     out << localSubDim << " " << local_mv.numSubCols() << std::endl;
00072     if( binaryMode() ) {
00073       // Write column-wise for better cache performance
00074       for( Ordinal j = 0; j < local_mv.numSubCols(); ++j )
00075         out.write( reinterpret_cast<const char*>(&local_mv(0,j)), sizeof(Scalar)*localSubDim );
00076     }
00077     else {
00078       // Write row-wise for better readability
00079       for( Ordinal i = 0; i < localSubDim; ++i ) {
00080         out << " " << i;
00081         for( Ordinal j = 0; j < local_mv.numSubCols(); ++j ) {
00082           out << " " << local_mv(i,j);
00083         }
00084         out << std::endl;
00085       }
00086     }
00087   }
00088   else {
00089     //  This is a serial (or locally replicated) vector space so
00090     // just write all of the multi-vector elements here.
00091     TEST_FOR_EXCEPTION( true, std::logic_error, "Does not handle non-SPMD spaces yet" );
00092   }
00093 }
00094 
00095 template<class Scalar>
00096 void SpmdMultiVectorSerializer<Scalar>::deserialize(
00097   std::istream& in, MultiVectorBase<Scalar>* mv
00098   ) const
00099 {
00100   Teuchos::RCP<const SpmdVectorSpaceBase<Scalar> >
00101     mpi_vec_spc = Teuchos::rcp_dynamic_cast<const SpmdVectorSpaceBase<Scalar> >(mv->range());
00102   if( mpi_vec_spc.get() ) {
00103     // This is a mpi-based vector space so let's just read the local
00104     // multi-vector elements (row-by-row).
00105     const Ordinal
00106       localOffset = mpi_vec_spc->localOffset(),
00107       localSubDim = mpi_vec_spc->localSubDim();
00108     const Range1D localRng( localOffset, localOffset+localSubDim-1 ); 
00109     DetachedMultiVectorView<Scalar> local_mv(*mv,localRng,Range1D());
00110 #ifdef TEUCHOS_DEBUG
00111     TEST_FOR_EXCEPTION(
00112       !in, std::logic_error
00113       ,"Error: The input stream given is empty before any reading has began!\n"
00114       "If this stream came from a file, then the file may not exist!"
00115       );
00116 #endif
00117     Ordinal localSubDim_in;
00118     in >> localSubDim_in;
00119 #ifdef TEUCHOS_DEBUG
00120     TEST_FOR_EXCEPTION(
00121       localSubDim != localSubDim_in, std::logic_error
00122       , "Error, localSubDim = "<<localSubDim<<" does not match the read in value of "
00123       "localSubDim_in = "<<localSubDim_in<<"!"
00124       );
00125 #endif
00126     Ordinal numSubCols_in;
00127     in >> numSubCols_in;
00128 #ifdef TEUCHOS_DEBUG
00129     TEST_FOR_EXCEPTION(
00130       local_mv.numSubCols() != numSubCols_in, std::logic_error
00131       , "Error, numSubCols = "<<local_mv.numSubCols()<<" does not match the read in value of "
00132       "numSubCols_in = "<<numSubCols_in<<"!"
00133       );
00134 #endif
00135     // Get rid of extra newline after first line
00136     in >> std::ws;
00137     // Get the elements
00138     if( binaryMode() ) {
00139       // Column-wise
00140       for( Ordinal j = 0; j < local_mv.numSubCols(); ++j )
00141         in.read( reinterpret_cast<char*>(&local_mv(0,j)), sizeof(Scalar)*localSubDim );
00142     }
00143     else {
00144       // Row-wise
00145       for( Ordinal i = 0; i < localSubDim; ++i ) {
00146 #ifdef TEUCHOS_DEBUG
00147         TEST_FOR_EXCEPTION( !in, std::logic_error, "Error, premature end of input!" );
00148 #endif
00149         Ordinal i_in;
00150         in >> i_in;
00151 #ifdef TEUCHOS_DEBUG
00152         TEST_FOR_EXCEPTION(
00153           i != i_in, std::logic_error
00154           , "Error, i = "<<i<<" does not match the read in value of "
00155           "i_in = "<<i_in<<"!"
00156           );
00157 #endif
00158         for( Ordinal j = 0; j < local_mv.numSubCols(); ++j ) {
00159 #ifdef TEUCHOS_DEBUG
00160           TEST_FOR_EXCEPTION(
00161             !in, std::logic_error
00162             ,"Error: The input stream ran out at j="<<j<<" before"
00163             " reaching the promised " << local_mv.numSubCols()
00164             << " rows of the (multi)vector!"
00165             );
00166 #endif
00167           in >> local_mv(i,j);
00168         }
00169       }
00170     }
00171   }
00172   else {
00173     //  This is a serial (or locally replicated) vector space so
00174     // just read all of the multi-vector elements here.
00175     TEST_FOR_EXCEPTION( true, std::logic_error, "Does not handle non-SPMD spaces yet" );
00176   }
00177 }
00178 
00179 } // end namespace Thyra
00180 
00181 #endif // THYRA_SPMD_MULTI_VECTOR_SERIALIZER_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines