Thyra  Version of the Day
Thyra_SpmdMultiVectorSerializer_def.hpp
2 // *****************************************************************************
3 // Thyra: Interfaces and Support for Abstract Numerical Algorithms
4 //
5 // Copyright 2004 NTESS and the Thyra contributors.
7 // *****************************************************************************
9
10 #ifndef THYRA_SPMD_MULTI_VECTOR_SERIALIZER_HPP
11 #define THYRA_SPMD_MULTI_VECTOR_SERIALIZER_HPP
12
13 #include "Thyra_SpmdMultiVectorSerializer_decl.hpp"
14 #include "Thyra_SpmdVectorSpaceDefaultBase.hpp"
15 #include "Thyra_MultiVectorBase.hpp"
16 #include "Thyra_DetachedMultiVectorView.hpp"
17
18 namespace Thyra {
19
20 template<class Scalar>
22  const bool my_binaryMode
23  )
24  :binaryMode_(my_binaryMode)
25 {}
26
27 template<class Scalar>
29  const MultiVectorBase<Scalar> &mv
30  ) const
31 {
32  return 0!=dynamic_cast<const SpmdVectorSpaceBase<Scalar>*>(&*mv.range());
33 }
34
35 template<class Scalar>
37  const MultiVectorBase<Scalar>& mv, std::ostream& out
38  ) const
39 {
41  mpi_vec_spc
42  = Teuchos::rcp_dynamic_cast<const SpmdVectorSpaceBase<Scalar> >(mv.range());
43  std::ios::fmtflags fmt(out.flags());
44  out.precision(std::numeric_limits<Scalar>::digits10+4);
45  if( mpi_vec_spc.get() ) {
46  // This is a mpi-based vector space so let's just write the local
47  // multi-vector elements (row-by-row).
48  const Ordinal
49  localOffset = mpi_vec_spc->localOffset(),
50  localSubDim = mpi_vec_spc->localSubDim();
51  const Range1D localRng( localOffset, localOffset+localSubDim-1 );
52  ConstDetachedMultiVectorView<Scalar> local_mv(mv,localRng,Range1D());
53  out << localSubDim << " " << local_mv.numSubCols() << std::endl;
54  if( binaryMode() ) {
55  // Write column-wise for better cache performance
56  for( Ordinal j = 0; j < local_mv.numSubCols(); ++j )
57  out.write( reinterpret_cast<const char*>(&local_mv(0,j)), sizeof(Scalar)*localSubDim );
58  }
59  else {
60  // Write row-wise for better readability
61  for( Ordinal i = 0; i < localSubDim; ++i ) {
62  out << " " << i;
63  for( Ordinal j = 0; j < local_mv.numSubCols(); ++j ) {
64  out << " " << local_mv(i,j);
65  }
66  out << std::endl;
67  }
68  }
69  }
70  else {
71  // This is a serial (or locally replicated) vector space so
72  // just write all of the multi-vector elements here.
73  TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Does not handle non-SPMD spaces yet" );
74  }
75  out.flags(fmt);
76 }
77
78 template<class Scalar>
80  std::istream& in, MultiVectorBase<Scalar>* mv
81  ) const
82 {
84  mpi_vec_spc = Teuchos::rcp_dynamic_cast<const SpmdVectorSpaceBase<Scalar> >(mv->range());
85  if( mpi_vec_spc.get() ) {
86  // This is a mpi-based vector space so let's just read the local
87  // multi-vector elements (row-by-row).
88  const Ordinal
89  localOffset = mpi_vec_spc->localOffset(),
90  localSubDim = mpi_vec_spc->localSubDim();
91  const Range1D localRng( localOffset, localOffset+localSubDim-1 );
92  DetachedMultiVectorView<Scalar> local_mv(*mv,localRng,Range1D());
93 #ifdef TEUCHOS_DEBUG
95  !in, std::logic_error
96  ,"Error: The input stream given is empty before any reading has began!\n"
97  "If this stream came from a file, then the file may not exist!"
98  );
99 #endif
100  Ordinal localSubDim_in;
101  in >> localSubDim_in;
102 #ifdef TEUCHOS_DEBUG
104  localSubDim != localSubDim_in, std::logic_error
105  , "Error, localSubDim = "<<localSubDim<<" does not match the read in value of "
106  "localSubDim_in = "<<localSubDim_in<<"!"
107  );
108 #endif
109  Ordinal numSubCols_in;
110  in >> numSubCols_in;
111 #ifdef TEUCHOS_DEBUG
113  local_mv.numSubCols() != numSubCols_in, std::logic_error
114  , "Error, numSubCols = "<<local_mv.numSubCols()<<" does not match the read in value of "
115  "numSubCols_in = "<<numSubCols_in<<"!"
116  );
117 #endif
118  // Get rid of extra newline after first line
119  in >> std::ws;
120  // Get the elements
121  if( binaryMode() ) {
122  // Column-wise
123  for( Ordinal j = 0; j < local_mv.numSubCols(); ++j )
125  }
126  else {
127  // Row-wise
128  for( Ordinal i = 0; i < localSubDim; ++i ) {
129 #ifdef TEUCHOS_DEBUG
130  TEUCHOS_TEST_FOR_EXCEPTION( !in, std::logic_error, "Error, premature end of input!" );
131 #endif
132  Ordinal i_in;
133  in >> i_in;
134 #ifdef TEUCHOS_DEBUG
136  i != i_in, std::logic_error
137  , "Error, i = "<<i<<" does not match the read in value of "
138  "i_in = "<<i_in<<"!"
139  );
140 #endif
141  for( Ordinal j = 0; j < local_mv.numSubCols(); ++j ) {
142 #ifdef TEUCHOS_DEBUG
144  !in, std::logic_error
145  ,"Error: The input stream ran out at j="<<j<<" before"
146  " reaching the promised " << local_mv.numSubCols()
147  << " rows of the (multi)vector!"
148  );
149 #endif
150  in >> local_mv(i,j);
151  }
152  }
153  }
154  }
155  else {
156  // This is a serial (or locally replicated) vector space so
157  // just read all of the multi-vector elements here.
158  TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Does not handle non-SPMD spaces yet" );
159  }
160 }
161
162 } // end namespace Thyra
163
164 #endif // THYRA_SPMD_MULTI_VECTOR_SERIALIZER_HPP
void deserialize(std::istream &in, MultiVectorBase< Scalar > *mv) const
Create an explicit non-mutable (const) view of a MultiVectorBase object.
virtual RCP< const VectorSpaceBase< Scalar > > range() const =0
Return a smart pointer for the range space for this operator.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
T * get() const
bool isCompatible(const MultiVectorBase< Scalar > &mv) const
Determine if the multi-vector is compatible or not.
Create an explicit mutable (non-const) view of a MultiVectorBase object.
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
Interface for a collection of column vectors called a multi-vector.
void serialize(const MultiVectorBase< Scalar > &mv, std::ostream &out) const
Write to a stream.
Base abstract VectorSpaceBase class for all SPMD-based vector spaces.
Teuchos::Range1D Range1D