Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Thyra_SpmdMultiVectorSerializer_def.hpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Thyra: Interfaces and Support for Abstract Numerical Algorithms
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Roscoe A. Bartlett (bartlettra@ornl.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef THYRA_SPMD_MULTI_VECTOR_SERIALIZER_HPP
43 #define THYRA_SPMD_MULTI_VECTOR_SERIALIZER_HPP
44 
45 #include "Thyra_SpmdMultiVectorSerializer_decl.hpp"
46 #include "Thyra_SpmdVectorSpaceDefaultBase.hpp"
47 #include "Thyra_MultiVectorBase.hpp"
48 #include "Thyra_DetachedMultiVectorView.hpp"
49 
50 namespace Thyra {
51 
52 template<class Scalar>
54  const bool my_binaryMode
55  )
56  :binaryMode_(my_binaryMode)
57 {}
58 
59 template<class Scalar>
61  const MultiVectorBase<Scalar> &mv
62  ) const
63 {
64  return 0!=dynamic_cast<const SpmdVectorSpaceBase<Scalar>*>(&*mv.range());
65 }
66 
67 template<class Scalar>
69  const MultiVectorBase<Scalar>& mv, std::ostream& out
70  ) const
71 {
73  mpi_vec_spc
74  = Teuchos::rcp_dynamic_cast<const SpmdVectorSpaceBase<Scalar> >(mv.range());
75  std::ios::fmtflags fmt(out.flags());
76  out.precision(std::numeric_limits<Scalar>::digits10+4);
77  if( mpi_vec_spc.get() ) {
78  // This is a mpi-based vector space so let's just write the local
79  // multi-vector elements (row-by-row).
80  const Ordinal
81  localOffset = mpi_vec_spc->localOffset(),
82  localSubDim = mpi_vec_spc->localSubDim();
83  const Range1D localRng( localOffset, localOffset+localSubDim-1 );
84  ConstDetachedMultiVectorView<Scalar> local_mv(mv,localRng,Range1D());
85  out << localSubDim << " " << local_mv.numSubCols() << std::endl;
86  if( binaryMode() ) {
87  // Write column-wise for better cache performance
88  for( Ordinal j = 0; j < local_mv.numSubCols(); ++j )
89  out.write( reinterpret_cast<const char*>(&local_mv(0,j)), sizeof(Scalar)*localSubDim );
90  }
91  else {
92  // Write row-wise for better readability
93  for( Ordinal i = 0; i < localSubDim; ++i ) {
94  out << " " << i;
95  for( Ordinal j = 0; j < local_mv.numSubCols(); ++j ) {
96  out << " " << local_mv(i,j);
97  }
98  out << std::endl;
99  }
100  }
101  }
102  else {
103  // This is a serial (or locally replicated) vector space so
104  // just write all of the multi-vector elements here.
105  TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Does not handle non-SPMD spaces yet" );
106  }
107  out.flags(fmt);
108 }
109 
110 template<class Scalar>
112  std::istream& in, MultiVectorBase<Scalar>* mv
113  ) const
114 {
116  mpi_vec_spc = Teuchos::rcp_dynamic_cast<const SpmdVectorSpaceBase<Scalar> >(mv->range());
117  if( mpi_vec_spc.get() ) {
118  // This is a mpi-based vector space so let's just read the local
119  // multi-vector elements (row-by-row).
120  const Ordinal
121  localOffset = mpi_vec_spc->localOffset(),
122  localSubDim = mpi_vec_spc->localSubDim();
123  const Range1D localRng( localOffset, localOffset+localSubDim-1 );
124  DetachedMultiVectorView<Scalar> local_mv(*mv,localRng,Range1D());
125 #ifdef TEUCHOS_DEBUG
127  !in, std::logic_error
128  ,"Error: The input stream given is empty before any reading has began!\n"
129  "If this stream came from a file, then the file may not exist!"
130  );
131 #endif
132  Ordinal localSubDim_in;
133  in >> localSubDim_in;
134 #ifdef TEUCHOS_DEBUG
136  localSubDim != localSubDim_in, std::logic_error
137  , "Error, localSubDim = "<<localSubDim<<" does not match the read in value of "
138  "localSubDim_in = "<<localSubDim_in<<"!"
139  );
140 #endif
141  Ordinal numSubCols_in;
142  in >> numSubCols_in;
143 #ifdef TEUCHOS_DEBUG
145  local_mv.numSubCols() != numSubCols_in, std::logic_error
146  , "Error, numSubCols = "<<local_mv.numSubCols()<<" does not match the read in value of "
147  "numSubCols_in = "<<numSubCols_in<<"!"
148  );
149 #endif
150  // Get rid of extra newline after first line
151  in >> std::ws;
152  // Get the elements
153  if( binaryMode() ) {
154  // Column-wise
155  for( Ordinal j = 0; j < local_mv.numSubCols(); ++j )
156  in.read( reinterpret_cast<char*>(&local_mv(0,j)), sizeof(Scalar)*localSubDim );
157  }
158  else {
159  // Row-wise
160  for( Ordinal i = 0; i < localSubDim; ++i ) {
161 #ifdef TEUCHOS_DEBUG
162  TEUCHOS_TEST_FOR_EXCEPTION( !in, std::logic_error, "Error, premature end of input!" );
163 #endif
164  Ordinal i_in;
165  in >> i_in;
166 #ifdef TEUCHOS_DEBUG
168  i != i_in, std::logic_error
169  , "Error, i = "<<i<<" does not match the read in value of "
170  "i_in = "<<i_in<<"!"
171  );
172 #endif
173  for( Ordinal j = 0; j < local_mv.numSubCols(); ++j ) {
174 #ifdef TEUCHOS_DEBUG
176  !in, std::logic_error
177  ,"Error: The input stream ran out at j="<<j<<" before"
178  " reaching the promised " << local_mv.numSubCols()
179  << " rows of the (multi)vector!"
180  );
181 #endif
182  in >> local_mv(i,j);
183  }
184  }
185  }
186  }
187  else {
188  // This is a serial (or locally replicated) vector space so
189  // just read all of the multi-vector elements here.
190  TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Does not handle non-SPMD spaces yet" );
191  }
192 }
193 
194 } // end namespace Thyra
195 
196 #endif // THYRA_SPMD_MULTI_VECTOR_SERIALIZER_HPP
void deserialize(std::istream &in, MultiVectorBase< Scalar > *mv) const
Read from a stream.
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