Thyra Version of the Day
Loading...
Searching...
No Matches
Thyra_SpmdMultiVectorSerializer_def.hpp
1// @HEADER
2// *****************************************************************************
3// Thyra: Interfaces and Support for Abstract Numerical Algorithms
4//
5// Copyright 2004 NTESS and the Thyra contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
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
18namespace Thyra {
19
20template<class Scalar>
22 const bool my_binaryMode
23 )
24 :binaryMode_(my_binaryMode)
25{}
26
27template<class Scalar>
30 ) const
31{
32 return 0!=dynamic_cast<const SpmdVectorSpaceBase<Scalar>*>(&*mv.range());
33}
34
35template<class Scalar>
37 const MultiVectorBase<Scalar>& mv, std::ostream& out
38 ) const
39{
41 mpi_vec_spc
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
78template<class Scalar>
80 std::istream& in, MultiVectorBase<Scalar>* mv
81 ) const
82{
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 )
124 in.read( reinterpret_cast<char*>(&local_mv(0,j)), sizeof(Scalar)*localSubDim );
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
T * get() const
Create an explicit non-mutable (const) view of a MultiVectorBase object.
Create an explicit mutable (non-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.
Interface for a collection of column vectors called a multi-vector.
bool isCompatible(const MultiVectorBase< Scalar > &mv) const
Determine if the multi-vector is compatible or not.
void serialize(const MultiVectorBase< Scalar > &mv, std::ostream &out) const
Write to a stream.
void deserialize(std::istream &in, MultiVectorBase< Scalar > *mv) const
Read from a stream.
Base abstract VectorSpaceBase class for all SPMD-based vector spaces.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
Teuchos::Range1D Range1D
T_To & dyn_cast(T_From &from)