1 //=================================================================================================
2 /*!
3 // \file blaze/math/serialization/MatrixSerializer.h
4 // \brief Serialization of dense and sparse matrices
5 //
6 // Copyright (C) 2012-2020 Klaus Iglberger - All Rights Reserved
7 //
8 // This file is part of the Blaze library. You can redistribute it and/or modify it under
9 // the terms of the New (Revised) BSD License. Redistribution and use in source and binary
10 // forms, with or without modification, are permitted provided that the following conditions
11 // are met:
12 //
13 // 1. Redistributions of source code must retain the above copyright notice, this list of
14 // conditions and the following disclaimer.
15 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
16 // of conditions and the following disclaimer in the documentation and/or other materials
17 // provided with the distribution.
18 // 3. Neither the names of the Blaze development group nor the names of its contributors
19 // may be used to endorse or promote products derived from this software without specific
20 // prior written permission.
21 //
22 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
23 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25 // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 // BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 // DAMAGE.
32 */
33 //=================================================================================================
34
35 #ifndef _BLAZE_MATH_SERIALIZATION_MATRIXSERIALIZER_H_
36 #define _BLAZE_MATH_SERIALIZATION_MATRIXSERIALIZER_H_
37
38
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42
43 #include <blaze/math/Aliases.h>
44 #include <blaze/math/constraints/Matrix.h>
45 #include <blaze/math/dense/DynamicMatrix.h>
46 #include <blaze/math/Exception.h>
47 #include <blaze/math/expressions/DenseMatrix.h>
48 #include <blaze/math/expressions/SparseMatrix.h>
49 #include <blaze/math/expressions/Matrix.h>
50 #include <blaze/math/serialization/TypeValueMapping.h>
51 #include <blaze/math/sparse/CompressedMatrix.h>
52 #include <blaze/math/typetraits/IsDenseMatrix.h>
53 #include <blaze/math/typetraits/IsResizable.h>
54 #include <blaze/math/typetraits/IsRowMajorMatrix.h>
55 #include <blaze/util/Assert.h>
56 #include <blaze/util/EnableIf.h>
57 #include <blaze/util/Types.h>
58 #include <blaze/util/typetraits/IsNumeric.h>
59
60
61 namespace blaze {
62
63 //=================================================================================================
64 //
65 // CLASS DEFINITION
66 //
67 //=================================================================================================
68
69 //*************************************************************************************************
70 /*!\brief Serializer for dense and sparse matrices.
71 // \ingroup math_serialization
72 //
73 // The MatrixSerializer implements the necessary logic to serialize dense and sparse matrices,
74 // i.e. to convert them into a portable, binary representation. The following example demonstrates
75 // the (de-)serialization process of matrices:
76
77 \code
78 using blaze::rowMajor;
79 using blaze::columnMajor;
80
81 // Serialization of both matrices
82 {
83 blaze::StaticMatrix<double,3UL,5UL,rowMajor> D;
84 blaze::CompressedMatrix<int,columnMajor> S;
85
86 // ... Resizing and initialization
87
88 // Creating an archive that writes into a the file "matrices.blaze"
89 blaze::Archive<std::ofstream> archive( "matrices.blaze" );
90
91 // Serialization of both matrices into the same archive. Note that D lies before S!
92 archive << D << S;
93 }
94
95 // Reconstitution of both matrices
96 {
97 blaze::DynamicMatrix<double,rowMajor> D1;
98 blaze::DynamicMatrix<int,rowMajor> D2;
99
100 // Creating an archive that reads from the file "matrices.blaze"
101 blaze::Archive<std::ofstream> archive( "matrices.blaze" );
102
103 // Reconstituting the former D matrix into D1. Note that it is possible to reconstitute
104 // the matrix into a differrent kind of matrix (StaticMatrix -> DynamicMatrix), but that
105 // the type of elements has to be the same.
106 archive >> D1;
107
108 // Reconstituting the former S matrix into D2. Note that is is even possible to reconstitute
109 // a sparse matrix as a dense matrix (also the reverse is possible) and that a column-major
110 // matrix can be reconstituted as row-major matrix (and vice versa). Note however that also
111 // in this case the type of elements is the same!
112 archive >> D2
113 }
114 \endcode
115
116 // Note that it is even possible to (de-)serialize matrices with vector or matrix elements:
117
118 \code
119 // Serialization
120 {
121 blaze::CompressedMatrix< blaze::DynamicMatrix< blaze::complex<double> > > mat;
122
123 // ... Resizing and initialization
124
125 // Creating an archive that writes into a the file "matrix.blaze"
126 blaze::Archive<std::ofstream> archive( "matrix.blaze" );
127
128 // Serialization of the matrix into the archive
129 archive << mat;
130 }
131
132 // Deserialization
133 {
134 blaze::CompressedMatrix< blaze::DynamicMatrix< blaze::complex<double> > > mat;
135
136 // Creating an archive that reads from the file "matrix.blaze"
137 blaze::Archive<std::ofstream> archive( "matrix.blaze" );
138
139 // Reconstitution of the matrix from the archive
140 archive >> mat;
141 }
142 \endcode
143
144 // As the examples demonstrates, the matrix serialization offers an enormous flexibility. However,
145 // several actions result in errors:
146 //
147 // - matrices cannot be reconstituted as vectors (and vice versa)
148 // - the element type of the serialized and reconstituted matrix must match, which means
149 // that on the source and destination platform the general type (signed/unsigned integral
150 // or floating point) and the size of the type must be exactly the same
151 // - when reconstituting a StaticMatrix, the number of rows and columns must match those of
152 // the serialized matrix
153 //
154 // In case an error is encountered during (de-)serialization, a \a std::runtime_exception is
155 // thrown.
156 */
157 class MatrixSerializer
158 {
159 private:
160 //**Private class MatrixValueMappingHelper******************************************************
161 /*! \cond BLAZE_INTERNAL */
162 /*!\brief Auxiliary helper class for the MatrixValueMapping class template.
163 //
164 // The MatrixValueMapping class template is an auxiliary class for the MatrixSerializer. It
165 // maps a matrix type into an integral representation. For the mapping, the following bit
166 // mapping is used:
167
168 \code
169 0x01 - Vector/Matrix flag
170 0x02 - Dense/Sparse flag
171 0x04 - Row-/Column-major flag
172 \endcode
173 */
174 template< bool IsDenseMatrix, bool IsRowMajorMatrix >
175 struct MatrixValueMappingHelper;
176 /*! \endcond */
177 //**********************************************************************************************
178
179 //**Private class MatrixValueMapping************************************************************
180 /*! \cond BLAZE_INTERNAL */
181 /*!\brief Serialization of the type of a matrix.
182 //
183 // This class template converts the given matrix type into an integral representation suited
184 // for serialization. Depending on the given matrix type, the \a value member enumeration is
185 // set to the according integral representation.
186 */
187 template< typename T >
188 struct MatrixValueMapping
189 {
190 enum { value = MatrixValueMappingHelper< IsDenseMatrix_v<T>, IsRowMajorMatrix_v<T> >::value };
191 BLAZE_CONSTRAINT_MUST_BE_MATRIX_TYPE( T );
192 };
193 /*! \endcond */
194 //**********************************************************************************************
195
196 public:
197 //**Constructors********************************************************************************
198 /*!\name Constructors */
199 //@{
200 inline MatrixSerializer();
201 //@}
202 //**********************************************************************************************
203
204 //**Serialization functions*********************************************************************
205 /*!\name Serialization functions */
206 //@{
207 template< typename Archive, typename MT, bool SO >
208 void serialize( Archive& archive, const Matrix<MT,SO>& mat );
209 //@}
210 //**********************************************************************************************
211
212 //**Deserialization functions*******************************************************************
213 /*!\name Deserialization functions */
214 //@{
215 template< typename Archive, typename MT, bool SO >
216 void deserialize( Archive& archive, Matrix<MT,SO>& mat );
217 //@}
218 //**********************************************************************************************
219
220 private:
221 //**Serialization functions*********************************************************************
222 /*!\name Serialization functions */
223 //@{
224 template< typename Archive, typename MT >
225 void serializeHeader( Archive& archive, const MT& mat );
226
227 template< typename Archive, typename MT, bool SO >
228 void serializeMatrix( Archive& archive, const DenseMatrix<MT,SO>& mat );
229
230 template< typename Archive, typename MT, bool SO >
231 void serializeMatrix( Archive& archive, const SparseMatrix<MT,SO>& mat );
232 //@}
233 //**********************************************************************************************
234
235 //**Deserialization functions*******************************************************************
236 /*!\name Deserialization functions */
237 //@{
238 template< typename Archive, typename MT >
239 void deserializeHeader( Archive& archive, const MT& mat );
240
241 template< typename MT, bool SO >
242 DisableIf_t< IsResizable_v<MT> > prepareMatrix( DenseMatrix<MT,SO>& mat );
243
244 template< typename MT, bool SO >
245 DisableIf_t< IsResizable_v<MT> > prepareMatrix( SparseMatrix<MT,SO>& mat );
246
247 template< typename MT >
248 EnableIf_t< IsResizable_v<MT> > prepareMatrix( MT& mat );
249
250 template< typename Archive, typename MT >
251 void deserializeMatrix( Archive& archive, MT& mat );
252
253 template< typename Archive, typename MT >
254 EnableIf_t< MT::simdEnabled >
255 deserializeDenseRowMatrix( Archive& archive, DenseMatrix<MT,rowMajor>& mat );
256
257 template< typename Archive, typename MT, bool SO >
258 void deserializeDenseRowMatrix( Archive& archive, DenseMatrix<MT,SO>& mat );
259
260 template< typename Archive, typename MT, bool SO >
261 DisableIf_t< IsNumeric_v< ElementType_t<MT> > >
262 deserializeDenseRowMatrix( Archive& archive, SparseMatrix<MT,SO>& mat );
263
264 template< typename Archive, typename MT, bool SO >
265 EnableIf_t< IsNumeric_v< ElementType_t<MT> > >
266 deserializeDenseRowMatrix( Archive& archive, SparseMatrix<MT,SO>& mat );
267
268 template< typename Archive, typename MT >
269 EnableIf_t< MT::simdEnabled>
270 deserializeDenseColumnMatrix( Archive& archive, DenseMatrix<MT,columnMajor>& mat );
271
272 template< typename Archive, typename MT, bool SO >
273 void deserializeDenseColumnMatrix( Archive& archive, DenseMatrix<MT,SO>& mat );
274
275 template< typename Archive, typename MT, bool SO >
276 DisableIf_t< IsNumeric_v< ElementType_t<MT> > >
277 deserializeDenseColumnMatrix( Archive& archive, SparseMatrix<MT,SO>& mat );
278
279 template< typename Archive, typename MT, bool SO >
280 EnableIf_t< IsNumeric_v< ElementType_t<MT> > >
281 deserializeDenseColumnMatrix( Archive& archive, SparseMatrix<MT,SO>& mat );
282
283 template< typename Archive, typename MT, bool SO >
284 void deserializeSparseRowMatrix( Archive& archive, DenseMatrix<MT,SO>& mat );
285
286 template< typename Archive, typename MT >
287 void deserializeSparseRowMatrix( Archive& archive, SparseMatrix<MT,rowMajor>& mat );
288
289 template< typename Archive, typename MT >
290 void deserializeSparseRowMatrix( Archive& archive, SparseMatrix<MT,columnMajor>& mat );
291
292 template< typename Archive, typename MT, bool SO >
293 void deserializeSparseColumnMatrix( Archive& archive, DenseMatrix<MT,SO>& mat );
294
295 template< typename Archive, typename MT >
296 void deserializeSparseColumnMatrix( Archive& archive, SparseMatrix<MT,rowMajor>& mat );
297
298 template< typename Archive, typename MT >
299 void deserializeSparseColumnMatrix( Archive& archive, SparseMatrix<MT,columnMajor>& mat );
300 //@}
301 //**********************************************************************************************
302
303 //**Member variables****************************************************************************
304 /*!\name Member variables */
305 //@{
306 uint8_t version_; //!< The version of the archive.
307 uint8_t type_; //!< The type of the matrix.
308 uint8_t elementType_; //!< The type of an element.
309 uint8_t elementSize_; //!< The size in bytes of a single element of the matrix.
310 uint64_t rows_; //!< The number of rows of the matrix.
311 uint64_t columns_; //!< The number of columns of the matrix.
312 uint64_t number_; //!< The total number of elements contained in the matrix.
313 //@}
314 //**********************************************************************************************
315 };
316 //*************************************************************************************************
317
318
319
320
321 //=================================================================================================
322 //
323 // CONSTRUCTORS
324 //
325 //=================================================================================================
326
327 //*************************************************************************************************
328 /*!\brief The default constructor of the MatrixSerializer class.
329 */
MatrixSerializer()330 MatrixSerializer::MatrixSerializer()
331 : version_ ( 0U ) // The version of the archive
332 , type_ ( 0U ) // The type of the matrix
333 , elementType_( 0U ) // The type of an element
334 , elementSize_( 0U ) // The size in bytes of a single element of the matrix
335 , rows_ ( 0UL ) // The number of rows of the matrix
336 , columns_ ( 0UL ) // The number of columns of the matrix
337 , number_ ( 0UL ) // The total number of elements contained in the matrix
338 {}
339 //*************************************************************************************************
340
341
342
343
344 //=================================================================================================
345 //
346 // SERIALIZATION FUNCTIONS
347 //
348 //=================================================================================================
349
350 //*************************************************************************************************
351 /*!\brief Serializes the given matrix and writes it to the archive.
352 //
353 // \param archive The archive to be written.
354 // \param mat The matrix to be serialized.
355 // \return void
356 // \exception std::runtime_error Error during serialization.
357 */
358 template< typename Archive // Type of the archive
359 , typename MT // Type of the matrix
360 , bool SO > // Storage order
serialize(Archive & archive,const Matrix<MT,SO> & mat)361 void MatrixSerializer::serialize( Archive& archive, const Matrix<MT,SO>& mat )
362 {
363 if( !archive ) {
364 BLAZE_THROW_RUNTIME_ERROR( "Faulty archive detected" );
365 }
366
367 serializeHeader( archive, *mat );
368 serializeMatrix( archive, *mat );
369 }
370 //*************************************************************************************************
371
372
373 //*************************************************************************************************
374 /*!\brief Serializes all meta information about the given matrix.
375 //
376 // \param archive The archive to be written.
377 // \param mat The matrix to be serialized.
378 // \return void
379 // \exception std::runtime_error File header could not be serialized.
380 */
381 template< typename Archive // Type of the archive
382 , typename MT > // Type of the matrix
serializeHeader(Archive & archive,const MT & mat)383 void MatrixSerializer::serializeHeader( Archive& archive, const MT& mat )
384 {
385 using ET = ElementType_t<MT>;
386
387 archive << uint8_t ( 1U );
388 archive << uint8_t ( MatrixValueMapping<MT>::value );
389 archive << uint8_t ( TypeValueMapping<ET>::value );
390 archive << uint8_t ( sizeof( ET ) );
391 archive << uint64_t( mat.rows() );
392 archive << uint64_t( mat.columns() );
393 archive << uint64_t( ( IsDenseMatrix_v<MT> ) ? ( mat.rows()*mat.columns() ) : ( mat.nonZeros() ) );
394
395 if( !archive ) {
396 BLAZE_THROW_RUNTIME_ERROR( "File header could not be serialized" );
397 }
398 }
399 //*************************************************************************************************
400
401
402 //*************************************************************************************************
403 /*!\brief Serializes the elements of a dense matrix.
404 //
405 // \param archive The archive to be written.
406 // \param mat The matrix to be serialized.
407 // \return void
408 // \exception std::runtime_error Dense matrix could not be serialized.
409 */
410 template< typename Archive // Type of the archive
411 , typename MT // Type of the matrix
412 , bool SO > // Storage order
serializeMatrix(Archive & archive,const DenseMatrix<MT,SO> & mat)413 void MatrixSerializer::serializeMatrix( Archive& archive, const DenseMatrix<MT,SO>& mat )
414 {
415 if( IsRowMajorMatrix_v<MT> ) {
416 for( size_t i=0UL; i<(*mat).rows(); ++i ) {
417 for( size_t j=0UL; j<(*mat).columns(); ++j ) {
418 archive << (*mat)(i,j);
419 }
420 }
421 }
422 else {
423 for( size_t j=0UL; j<(*mat).columns(); ++j ) {
424 for( size_t i=0UL; i<(*mat).rows(); ++i ) {
425 archive << (*mat)(i,j);
426 }
427 }
428 }
429
430 if( !archive ) {
431 BLAZE_THROW_RUNTIME_ERROR( "Dense matrix could not be serialized" );
432 }
433 }
434 //*************************************************************************************************
435
436
437 //*************************************************************************************************
438 /*!\brief Serializes the elements of a sparse matrix.
439 //
440 // \param archive The archive to be written.
441 // \param mat The matrix to be serialized.
442 // \return void
443 // \exception std::runtime_error Sparse matrix could not be serialized.
444 */
445 template< typename Archive // Type of the archive
446 , typename MT // Type of the matrix
447 , bool SO > // Storage order
serializeMatrix(Archive & archive,const SparseMatrix<MT,SO> & mat)448 void MatrixSerializer::serializeMatrix( Archive& archive, const SparseMatrix<MT,SO>& mat )
449 {
450 if( IsRowMajorMatrix_v<MT> ) {
451 for( size_t i=0UL; i<(*mat).rows(); ++i ) {
452 archive << uint64_t( (*mat).nonZeros( i ) );
453 for( auto element=(*mat).begin(i); element!=(*mat).end(i); ++element ) {
454 archive << element->index() << element->value();
455 }
456 }
457 }
458 else {
459 for( size_t j=0UL; j<(*mat).columns(); ++j ) {
460 archive << uint64_t( (*mat).nonZeros( j ) );
461 for( auto element=(*mat).begin(j); element!=(*mat).end(j); ++element ) {
462 archive << element->index() << element->value();
463 }
464 }
465 }
466
467 if( !archive ) {
468 BLAZE_THROW_RUNTIME_ERROR( "Sparse matrix could not be serialized" );
469 }
470 }
471 //*************************************************************************************************
472
473
474
475
476 //=================================================================================================
477 //
478 // DESERIALIZATION FUNCTIONS
479 //
480 //=================================================================================================
481
482 //*************************************************************************************************
483 /*!\brief Deserializes a matrix from the given archive.
484 //
485 // \param archive The archive to be read from.
486 // \param mat The matrix to be deserialized.
487 // \return void
488 // \exception std::runtime_error Error during deserialization.
489 */
490 template< typename Archive // Type of the archive
491 , typename MT // Type of the matrix
492 , bool SO > // Storage order
deserialize(Archive & archive,Matrix<MT,SO> & mat)493 void MatrixSerializer::deserialize( Archive& archive, Matrix<MT,SO>& mat )
494 {
495 if( !archive ) {
496 BLAZE_THROW_INVALID_ARGUMENT( "Faulty archive detected" );
497 }
498
499 deserializeHeader( archive, *mat );
500 prepareMatrix( *mat );
501 deserializeMatrix( archive, *mat );
502 }
503 //*************************************************************************************************
504
505
506 //*************************************************************************************************
507 /*!\brief Deserializes all meta information about the given matrix.
508 //
509 // \param archive The archive to be read from.
510 // \param mat The matrix to be deserialized.
511 // \return void
512 // \exception std::runtime_error Error during deserialization.
513 */
514 template< typename Archive // Type of the archive
515 , typename MT > // Type of the matrix
deserializeHeader(Archive & archive,const MT & mat)516 void MatrixSerializer::deserializeHeader( Archive& archive, const MT& mat )
517 {
518 using ET = ElementType_t<MT>;
519
520 if( !( archive >> version_ >> type_ >> elementType_ >> elementSize_ >> rows_ >> columns_ >> number_ ) ) {
521 BLAZE_THROW_RUNTIME_ERROR( "Corrupt archive detected" );
522 }
523 else if( version_ != 1UL ) {
524 BLAZE_THROW_RUNTIME_ERROR( "Invalid version detected" );
525 }
526 else if( ( type_ & 1U ) != 1U || ( type_ & (~7U) ) != 0U ) {
527 BLAZE_THROW_RUNTIME_ERROR( "Invalid matrix type detected" );
528 }
529 else if( elementType_ != TypeValueMapping<ET>::value ) {
530 BLAZE_THROW_RUNTIME_ERROR( "Invalid element type detected" );
531 }
532 else if( elementSize_ != sizeof( ET ) ) {
533 BLAZE_THROW_RUNTIME_ERROR( "Invalid element size detected" );
534 }
535 else if( !IsResizable_v<MT> && ( rows_ != mat.rows() || columns_ != mat.columns() ) ) {
536 BLAZE_THROW_RUNTIME_ERROR( "Invalid matrix size detected" );
537 }
538 else if( number_ > rows_*columns_ ) {
539 BLAZE_THROW_RUNTIME_ERROR( "Invalid number of elements detected" );
540 }
541 }
542 //*************************************************************************************************
543
544
545 //*************************************************************************************************
546 /*!\brief Prepares the given non-resizable dense matrix for the deserialization process.
547 //
548 // \param mat The dense matrix to be prepared.
549 // \return void
550 */
551 template< typename MT // Type of the dense matrix
552 , bool SO > // Storage order
prepareMatrix(DenseMatrix<MT,SO> & mat)553 DisableIf_t< IsResizable_v<MT> > MatrixSerializer::prepareMatrix( DenseMatrix<MT,SO>& mat )
554 {
555 reset( *mat );
556 }
557 //*************************************************************************************************
558
559
560 //*************************************************************************************************
561 /*!\brief Prepares the given non-resizable sparse matrix for the deserialization process.
562 //
563 // \param mat The sparse matrix to be prepared.
564 // \return void
565 */
566 template< typename MT // Type of the sparse matrix
567 , bool SO > // Storage order
prepareMatrix(SparseMatrix<MT,SO> & mat)568 DisableIf_t< IsResizable_v<MT> > MatrixSerializer::prepareMatrix( SparseMatrix<MT,SO>& mat )
569 {
570 (*mat).reserve( number_ );
571 reset( *mat );
572 }
573 //*************************************************************************************************
574
575
576 //*************************************************************************************************
577 /*!\brief Prepares the given resizable matrix for the deserialization process.
578 //
579 // \param mat The matrix to be prepared.
580 // \return void
581 */
582 template< typename MT > // Type of the matrix
prepareMatrix(MT & mat)583 EnableIf_t< IsResizable_v<MT> > MatrixSerializer::prepareMatrix( MT& mat )
584 {
585 mat.resize ( rows_, columns_, false );
586 mat.reserve( number_ );
587 reset( mat );
588 }
589 //*************************************************************************************************
590
591
592 //*************************************************************************************************
593 /*!\brief Deserializes a matrix from the archive.
594 //
595 // \param archive The archive to be read from.
596 // \param mat The matrix to be reconstituted.
597 // \return void
598 // \exception std::runtime_error Error during deserialization.
599 //
600 // This function deserializes the contents of the matrix from the archive and reconstitutes the
601 // given matrix.
602 */
603 template< typename Archive // Type of the archive
604 , typename MT > // Type of the matrix
deserializeMatrix(Archive & archive,MT & mat)605 void MatrixSerializer::deserializeMatrix( Archive& archive, MT& mat )
606 {
607 if( type_ == 1U ) {
608 deserializeDenseRowMatrix( archive, *mat );
609 }
610 else if( type_ == 5UL ) {
611 deserializeDenseColumnMatrix( archive, *mat );
612 }
613 else if( type_ == 3UL ) {
614 deserializeSparseRowMatrix( archive, *mat );
615 }
616 else if( type_ == 7UL ) {
617 deserializeSparseColumnMatrix( archive, *mat );
618 }
619 else {
620 BLAZE_INTERNAL_ASSERT( false, "Undefined type flag" );
621 }
622 }
623 //*************************************************************************************************
624
625
626 //*************************************************************************************************
627 /*!\brief Deserializes a row-major dense matrix from the archive.
628 //
629 // \param archive The archive to be read from.
630 // \param mat The dense matrix to be reconstituted.
631 // \return void
632 // \exception std::runtime_error Dense matrix could not be deserialized.
633 //
634 // This function deserializes a row-major dense matrix from the archive and reconstitutes
635 // the given row-major dense matrix. In case any error is detected during the deserialization
636 // process, a \a std::runtime_error is thrown.
637 */
638 template< typename Archive // Type of the archive
639 , typename MT > // Type of the matrix
640 EnableIf_t< MT::simdEnabled >
deserializeDenseRowMatrix(Archive & archive,DenseMatrix<MT,rowMajor> & mat)641 MatrixSerializer::deserializeDenseRowMatrix( Archive& archive, DenseMatrix<MT,rowMajor>& mat )
642 {
643 if( columns_ == 0UL ) return;
644
645 for( size_t i=0UL; i<rows_; ++i ) {
646 archive.read( &(*mat)(i,0), columns_ );
647 }
648
649 if( !archive ) {
650 BLAZE_THROW_RUNTIME_ERROR( "Dense matrix could not be deserialized" );
651 }
652 }
653 //*************************************************************************************************
654
655
656 //*************************************************************************************************
657 /*!\brief Deserializes a row-major dense matrix from the archive.
658 //
659 // \param archive The archive to be read from.
660 // \param mat The dense matrix to be reconstituted.
661 // \return void
662 // \exception std::runtime_error Dense matrix could not be deserialized.
663 //
664 // This function deserializes a row-major dense matrix from the archive and reconstitutes
665 // the given dense matrix. In case any error is detected during the deserialization process,
666 // a \a std::runtime_error is thrown.
667 */
668 template< typename Archive // Type of the archive
669 , typename MT // Type of the matrix
670 , bool SO > // Storage order
deserializeDenseRowMatrix(Archive & archive,DenseMatrix<MT,SO> & mat)671 void MatrixSerializer::deserializeDenseRowMatrix( Archive& archive, DenseMatrix<MT,SO>& mat )
672 {
673 using ET = ElementType_t<MT>;
674
675 ET value{};
676
677 for( size_t i=0UL; i<rows_; ++i ) {
678 size_t j( 0UL );
679 while( ( j != columns_ ) && ( archive >> value ) ) {
680 (*mat)(i,j) = value;
681 ++j;
682 }
683 }
684
685 if( !archive ) {
686 BLAZE_THROW_RUNTIME_ERROR( "Dense matrix could not be deserialized" );
687 }
688 }
689 //*************************************************************************************************
690
691
692 //*************************************************************************************************
693 /*!\brief Deserializes a row-major dense matrix from the archive.
694 //
695 // \param archive The archive to be read from.
696 // \param mat The dense matrix to be reconstituted.
697 // \return void
698 // \exception std::runtime_error Sparse matrix could not be deserialized.
699 //
700 // This function deserializes a row-major dense matrix from the archive and reconstitutes
701 // the given sparse matrix. In case any error is detected during the deserialization
702 // process, a \a std::runtime_error is thrown.
703 */
704 template< typename Archive // Type of the archive
705 , typename MT // Type of the matrix
706 , bool SO > // Storage order
707 EnableIf_t< IsNumeric_v< ElementType_t<MT> > >
deserializeDenseRowMatrix(Archive & archive,SparseMatrix<MT,SO> & mat)708 MatrixSerializer::deserializeDenseRowMatrix( Archive& archive, SparseMatrix<MT,SO>& mat )
709 {
710 DynamicMatrix< ElementType_t<MT>, rowMajor > tmp( rows_, columns_ );
711 deserializeDenseRowMatrix( archive, tmp );
712 (*mat) = tmp;
713
714 if( !archive ) {
715 BLAZE_THROW_RUNTIME_ERROR( "Sparse matrix could not be deserialized" );
716 }
717 }
718 //*************************************************************************************************
719
720
721 //*************************************************************************************************
722 /*!\brief Deserializes a row-major dense matrix from the archive.
723 //
724 // \param archive The archive to be read from.
725 // \param mat The dense matrix to be reconstituted.
726 // \return void
727 // \exception std::runtime_error Sparse matrix could not be deserialized.
728 //
729 // This function deserializes a row-major dense matrix from the archive and reconstitutes
730 // the given sparse matrix. In case any error is detected during the deserialization
731 // process, a \a std::runtime_error is thrown.
732 */
733 template< typename Archive // Type of the archive
734 , typename MT // Type of the matrix
735 , bool SO > // Storage order
736 DisableIf_t< IsNumeric_v< ElementType_t<MT> > >
deserializeDenseRowMatrix(Archive & archive,SparseMatrix<MT,SO> & mat)737 MatrixSerializer::deserializeDenseRowMatrix( Archive& archive, SparseMatrix<MT,SO>& mat )
738 {
739 using ET = ElementType_t<MT>;
740
741 ET value{};
742
743 const size_t dim1( ( SO == rowMajor )?( rows_ ):( columns_ ) );
744 const size_t dim2( ( SO != rowMajor )?( rows_ ):( columns_ ) );
745
746 for( size_t i=0UL; i<dim1; ++i ) {
747 (*mat).reserve( i, dim2 );
748 }
749
750 for( size_t i=0UL; i<rows_; ++i ) {
751 size_t j( 0UL );
752 while( ( j != columns_ ) && ( archive >> value ) ) {
753 (*mat).append( i, j, value, false );
754 ++j;
755 }
756 }
757
758 if( !archive ) {
759 BLAZE_THROW_RUNTIME_ERROR( "Sparse matrix could not be deserialized" );
760 }
761 }
762 //*************************************************************************************************
763
764
765 //*************************************************************************************************
766 /*!\brief Deserializes a column-major dense matrix from the archive.
767 //
768 // \param archive The archive to be read from.
769 // \param mat The dense matrix to be reconstituted.
770 // \return void
771 // \exception std::runtime_error Dense matrix could not be deserialized.
772 //
773 // This function deserializes a column-major dense matrix from the archive and reconstitutes
774 // the given column-major dense matrix. In case any error is detected during the deserialization
775 // process, a \a std::runtime_error is thrown.
776 */
777 template< typename Archive // Type of the archive
778 , typename MT > // Type of the matrix
779 EnableIf_t< MT::simdEnabled >
deserializeDenseColumnMatrix(Archive & archive,DenseMatrix<MT,columnMajor> & mat)780 MatrixSerializer::deserializeDenseColumnMatrix( Archive& archive, DenseMatrix<MT,columnMajor>& mat )
781 {
782 if( rows_ == 0UL ) return;
783
784 for( size_t j=0UL; j<columns_; ++j ) {
785 archive.read( &(*mat)(0,j), rows_ );
786 }
787
788 if( !archive ) {
789 BLAZE_THROW_RUNTIME_ERROR( "Dense matrix could not be deserialized" );
790 }
791 }
792 //*************************************************************************************************
793
794
795 //*************************************************************************************************
796 /*!\brief Deserializes a column-major dense matrix from the archive.
797 //
798 // \param archive The archive to be read from.
799 // \param mat The dense matrix to be reconstituted.
800 // \return void
801 // \exception std::runtime_error Dense matrix could not be deserialized.
802 //
803 // This function deserializes a column-major dense matrix from the archive and reconstitutes
804 // the given dense matrix. In case any error is detected during the deserialization process,
805 // a \a std::runtime_error is thrown.
806 */
807 template< typename Archive // Type of the archive
808 , typename MT // Type of the matrix
809 , bool SO > // Storage order
deserializeDenseColumnMatrix(Archive & archive,DenseMatrix<MT,SO> & mat)810 void MatrixSerializer::deserializeDenseColumnMatrix( Archive& archive, DenseMatrix<MT,SO>& mat )
811 {
812 using ET = ElementType_t<MT>;
813
814 ET value{};
815
816 for( size_t j=0UL; j<columns_; ++j ) {
817 size_t i( 0UL );
818 while( ( i != rows_ ) && ( archive >> value ) ) {
819 (*mat)(i,j) = value;
820 ++i;
821 }
822 }
823
824 if( !archive ) {
825 BLAZE_THROW_RUNTIME_ERROR( "Dense matrix could not be deserialized" );
826 }
827 }
828 //*************************************************************************************************
829
830
831 //*************************************************************************************************
832 /*!\brief Deserializes a column-major dense matrix from the archive.
833 //
834 // \param archive The archive to be read from.
835 // \param mat The sparse matrix to be reconstituted.
836 // \return void
837 // \exception std::runtime_error Sparse matrix could not be deserialized.
838 //
839 // This function deserializes a column-major dense matrix from the archive and reconstitutes
840 // the given sparse matrix. In case any error is detected during the deserialization process,
841 // a \a std::runtime_error is thrown.
842 */
843 template< typename Archive // Type of the archive
844 , typename MT // Type of the matrix
845 , bool SO > // Storage order
846 EnableIf_t< IsNumeric_v< ElementType_t<MT> > >
deserializeDenseColumnMatrix(Archive & archive,SparseMatrix<MT,SO> & mat)847 MatrixSerializer::deserializeDenseColumnMatrix( Archive& archive, SparseMatrix<MT,SO>& mat )
848 {
849 DynamicMatrix< ElementType_t<MT>, columnMajor > tmp( rows_, columns_ );
850 deserializeDenseColumnMatrix( archive, tmp );
851 (*mat) = tmp;
852
853 if( !archive ) {
854 BLAZE_THROW_RUNTIME_ERROR( "Sparse matrix could not be deserialized" );
855 }
856 }
857 //*************************************************************************************************
858
859
860 //*************************************************************************************************
861 /*!\brief Deserializes a column-major dense matrix from the archive.
862 //
863 // \param archive The archive to be read from.
864 // \param mat The sparse matrix to be reconstituted.
865 // \return void
866 // \exception std::runtime_error Sparse matrix could not be deserialized.
867 //
868 // This function deserializes a column-major dense matrix from the archive and reconstitutes
869 // the given sparse matrix. In case any error is detected during the deserialization process,
870 // a \a std::runtime_error is thrown.
871 */
872 template< typename Archive // Type of the archive
873 , typename MT // Type of the matrix
874 , bool SO > // Storage order
875 DisableIf_t< IsNumeric_v< ElementType_t<MT> > >
deserializeDenseColumnMatrix(Archive & archive,SparseMatrix<MT,SO> & mat)876 MatrixSerializer::deserializeDenseColumnMatrix( Archive& archive, SparseMatrix<MT,SO>& mat )
877 {
878 using ET = ElementType_t<MT>;
879
880 ET value{};
881
882 const size_t dim1( ( SO == rowMajor )?( rows_ ):( columns_ ) );
883 const size_t dim2( ( SO != rowMajor )?( rows_ ):( columns_ ) );
884
885 for( size_t i=0UL; i<dim1; ++i ) {
886 (*mat).reserve( i, dim2 );
887 }
888
889 for( size_t j=0UL; j<columns_; ++j ) {
890 size_t i( 0UL );
891 while( ( i != rows_ ) && ( archive >> value ) ) {
892 (*mat).append( i, j, value, false );
893 ++i;
894 }
895 }
896
897 if( !archive ) {
898 BLAZE_THROW_RUNTIME_ERROR( "Sparse matrix could not be deserialized" );
899 }
900 }
901 //*************************************************************************************************
902
903
904 //*************************************************************************************************
905 /*!\brief Deserializes a row-major sparse matrix from the archive.
906 //
907 // \param archive The archive to be read from.
908 // \param mat The matrix to be reconstituted.
909 // \return void
910 // \exception std::runtime_error Dense matrix could not be deserialized.
911 //
912 // This function deserializes a row-major sparse matrix from the archive and reconstitutes
913 // the given dense matrix. In case any error is detected during the deserialization process,
914 // a \a std::runtime_error is thrown.
915 */
916 template< typename Archive // Type of the archive
917 , typename MT // Type of the matrix
918 , bool SO > // Storage order
deserializeSparseRowMatrix(Archive & archive,DenseMatrix<MT,SO> & mat)919 void MatrixSerializer::deserializeSparseRowMatrix( Archive& archive, DenseMatrix<MT,SO>& mat )
920 {
921 using ET = ElementType_t<MT>;
922
923 uint64_t number( 0UL );
924 size_t index ( 0UL );
925 ET value {};
926
927 for( size_t i=0UL; i<rows_; ++i ) {
928 archive >> number;
929 size_t j( 0UL );
930 while( ( j != number ) && ( archive >> index >> value ) ) {
931 (*mat)(i,index) = value;
932 ++j;
933 }
934 }
935
936 if( !archive ) {
937 BLAZE_THROW_RUNTIME_ERROR( "Dense matrix could not be deserialized" );
938 }
939 }
940 //*************************************************************************************************
941
942
943 //*************************************************************************************************
944 /*!\brief Deserializes a row-major sparse matrix from the archive.
945 //
946 // \param archive The archive to be read from.
947 // \param mat The matrix to be reconstituted.
948 // \return void
949 // \exception std::runtime_error Sparse matrix could not be deserialized.
950 //
951 // This function deserializes a row-major sparse matrix from the archive and reconstitutes
952 // the given row-major sparse matrix. In case any error is detected during the deserialization
953 // process, a \a std::runtime_error is thrown.
954 */
955 template< typename Archive // Type of the archive
956 , typename MT > // Type of the matrix
deserializeSparseRowMatrix(Archive & archive,SparseMatrix<MT,rowMajor> & mat)957 void MatrixSerializer::deserializeSparseRowMatrix( Archive& archive, SparseMatrix<MT,rowMajor>& mat )
958 {
959 using ET = ElementType_t<MT>;
960
961 uint64_t number( 0UL );
962 size_t index ( 0UL );
963 ET value {};
964
965 for( size_t i=0UL; i<rows_; ++i )
966 {
967 archive >> number;
968
969 size_t j( 0UL );
970 while( ( j != number ) && ( archive >> index >> value ) ) {
971 (*mat).append( i, index, value, false );
972 ++j;
973 }
974
975 (*mat).finalize( i );
976 }
977
978 if( !archive ) {
979 BLAZE_THROW_RUNTIME_ERROR( "Sparse matrix could not be deserialized" );
980 }
981 }
982 //*************************************************************************************************
983
984
985 //*************************************************************************************************
986 /*!\brief Deserializes a row-major sparse matrix from the archive.
987 //
988 // \param archive The archive to be read from.
989 // \param mat The matrix to be reconstituted.
990 // \return void
991 // \exception std::runtime_error Sparse matrix could not be deserialized.
992 //
993 // This function deserializes a row-major sparse matrix from the archive and reconstitutes
994 // the given column-major sparse matrix. In case any error is detected during the deserialization
995 // process, a \a std::runtime_error is thrown.
996 */
997 template< typename Archive // Type of the archive
998 , typename MT > // Type of the matrix
deserializeSparseRowMatrix(Archive & archive,SparseMatrix<MT,columnMajor> & mat)999 void MatrixSerializer::deserializeSparseRowMatrix( Archive& archive, SparseMatrix<MT,columnMajor>& mat )
1000 {
1001 CompressedMatrix< ElementType_t<MT>, rowMajor > tmp( rows_, columns_, number_ );
1002 deserializeSparseRowMatrix( archive, tmp );
1003 (*mat) = tmp;
1004
1005 if( !archive ) {
1006 BLAZE_THROW_RUNTIME_ERROR( "Sparse matrix could not be deserialized" );
1007 }
1008 }
1009 //*************************************************************************************************
1010
1011
1012 //*************************************************************************************************
1013 /*!\brief Deserializes a column-major sparse matrix from the archive.
1014 //
1015 // \param archive The archive to be read from.
1016 // \param mat The matrix to be reconstituted.
1017 // \return void
1018 // \exception std::runtime_error Dense matrix could not be deserialized.
1019 //
1020 // This function deserializes a column-major sparse matrix from the archive and reconstitutes
1021 // the given dense matrix. In case any error is detected during the deserialization process,
1022 // a \a std::runtime_error is thrown.
1023 */
1024 template< typename Archive // Type of the archive
1025 , typename MT // Type of the matrix
1026 , bool SO > // Storage order
deserializeSparseColumnMatrix(Archive & archive,DenseMatrix<MT,SO> & mat)1027 void MatrixSerializer::deserializeSparseColumnMatrix( Archive& archive, DenseMatrix<MT,SO>& mat )
1028 {
1029 using ET = ElementType_t<MT>;
1030
1031 uint64_t number( 0UL );
1032 size_t index ( 0UL );
1033 ET value {};
1034
1035 for( size_t j=0UL; j<columns_; ++j ) {
1036 archive >> number;
1037 size_t i( 0UL );
1038 while( ( i != number ) && ( archive >> index >> value ) ) {
1039 (*mat)(index,j) = value;
1040 ++i;
1041 }
1042 }
1043
1044 if( !archive ) {
1045 BLAZE_THROW_RUNTIME_ERROR( "Dense matrix could not be deserialized" );
1046 }
1047 }
1048 //*************************************************************************************************
1049
1050
1051 //*************************************************************************************************
1052 /*!\brief Deserializes a column-major sparse matrix from the archive.
1053 //
1054 // \param archive The archive to be read from.
1055 // \param mat The matrix to be reconstituted.
1056 // \return void
1057 // \exception std::runtime_error Sparse matrix could not be deserialized.
1058 //
1059 // This function deserializes a column-major sparse matrix from the archive and reconstitutes
1060 // the given row-major sparse matrix. In case any error is detected during the deserialization
1061 // process, a \a std::runtime_error is thrown.
1062 */
1063 template< typename Archive // Type of the archive
1064 , typename MT > // Type of the matrix
deserializeSparseColumnMatrix(Archive & archive,SparseMatrix<MT,rowMajor> & mat)1065 void MatrixSerializer::deserializeSparseColumnMatrix( Archive& archive, SparseMatrix<MT,rowMajor>& mat )
1066 {
1067 CompressedMatrix< ElementType_t<MT>, columnMajor > tmp( rows_, columns_, number_ );
1068 deserializeSparseColumnMatrix( archive, tmp );
1069 (*mat) = tmp;
1070
1071 if( !archive ) {
1072 BLAZE_THROW_RUNTIME_ERROR( "Sparse matrix could not be deserialized" );
1073 }
1074 }
1075 //*************************************************************************************************
1076
1077
1078 //*************************************************************************************************
1079 /*!\brief Deserializes a column-major sparse matrix from the archive.
1080 //
1081 // \param archive The archive to be read from.
1082 // \param mat The matrix to be reconstituted.
1083 // \return void
1084 // \exception std::runtime_error Sparse matrix could not be deserialized.
1085 //
1086 // This function deserializes a column-major sparse matrix from the archive and reconstitutes
1087 // the given column-major sparse matrix. In case any error is detected during the deserialization
1088 // process, a \a std::runtime_error is thrown.
1089 */
1090 template< typename Archive // Type of the archive
1091 , typename MT > // Type of the matrix
deserializeSparseColumnMatrix(Archive & archive,SparseMatrix<MT,columnMajor> & mat)1092 void MatrixSerializer::deserializeSparseColumnMatrix( Archive& archive, SparseMatrix<MT,columnMajor>& mat )
1093 {
1094 using ET = ElementType_t<MT>;
1095
1096 uint64_t number( 0UL );
1097 size_t index ( 0UL );
1098 ET value {};
1099
1100 for( size_t j=0UL; j<columns_; ++j )
1101 {
1102 archive >> number;
1103
1104 size_t i( 0UL );
1105 while( ( i != number ) && ( archive >> index >> value ) ) {
1106 (*mat).append( index, j, value, false );
1107 ++i;
1108 }
1109
1110 (*mat).finalize( j );
1111 }
1112
1113 if( !archive ) {
1114 BLAZE_THROW_RUNTIME_ERROR( "Sparse matrix could not be deserialized" );
1115 }
1116 }
1117 //*************************************************************************************************
1118
1119
1120
1121
1122 //=================================================================================================
1123 //
1124 // MATRIXVALUEMAPPINGHELPER SPECIALIZATIONS
1125 //
1126 //=================================================================================================
1127
1128 //*************************************************************************************************
1129 /*! \cond BLAZE_INTERNAL */
1130 /*!\brief Specialization of the MatrixValueMappingHelper class template for row-major dense matrices.
1131 */
1132 template<>
1133 struct MatrixSerializer::MatrixValueMappingHelper<true,true>
1134 {
1135 enum { value = 1 };
1136 };
1137 /*! \endcond */
1138 //*************************************************************************************************
1139
1140
1141 //*************************************************************************************************
1142 /*! \cond BLAZE_INTERNAL */
1143 /*!\brief Specialization of the MatrixValueMappingHelper class template for column-major dense matrices.
1144 */
1145 template<>
1146 struct MatrixSerializer::MatrixValueMappingHelper<true,false>
1147 {
1148 enum { value = 5 };
1149 };
1150 /*! \endcond */
1151 //*************************************************************************************************
1152
1153
1154 //*************************************************************************************************
1155 /*! \cond BLAZE_INTERNAL */
1156 /*!\brief Specialization of the MatrixValueMappingHelper class template for row-major sparse matrices.
1157 */
1158 template<>
1159 struct MatrixSerializer::MatrixValueMappingHelper<false,true>
1160 {
1161 enum { value = 3 };
1162 };
1163 /*! \endcond */
1164 //*************************************************************************************************
1165
1166
1167 //*************************************************************************************************
1168 /*! \cond BLAZE_INTERNAL */
1169 /*!\brief Specialization of the MatrixValueMappingHelper class template for column-major sparse matrices.
1170 */
1171 template<>
1172 struct MatrixSerializer::MatrixValueMappingHelper<false,false>
1173 {
1174 enum { value = 7 };
1175 };
1176 /*! \endcond */
1177 //*************************************************************************************************
1178
1179
1180
1181
1182 //=================================================================================================
1183 //
1184 // GLOBAL FUNCTIONS
1185 //
1186 //=================================================================================================
1187
1188 //*************************************************************************************************
1189 /*!\brief Serializes the given matrix and writes it to the archive.
1190 //
1191 // \param archive The archive to be written.
1192 // \param mat The matrix to be serialized.
1193 // \return void
1194 // \exception std::runtime_error Matrix could not be serialized.
1195 //
1196 // The serialize() function converts the given matrix into a portable, binary representation.
1197 // The following example demonstrates the (de-)serialization process of matrices:
1198
1199 \code
1200 using blaze::rowMajor;
1201 using blaze::columnMajor;
1202
1203 // Serialization of both matrices
1204 {
1205 blaze::StaticMatrix<double,3UL,5UL,rowMajor> D;
1206 blaze::CompressedMatrix<int,columnMajor> S;
1207
1208 // ... Resizing and initialization
1209
1210 // Creating an archive that writes into a the file "matrices.blaze"
1211 blaze::Archive<std::ofstream> archive( "matrices.blaze" );
1212
1213 // Serialization of both matrices into the same archive. Note that D lies before S!
1214 archive << D << S;
1215 }
1216
1217 // Reconstitution of both matrices
1218 {
1219 blaze::DynamicMatrix<double,rowMajor> D1;
1220 blaze::DynamicMatrix<int,rowMajor> D2;
1221
1222 // ... Resizing and initialization
1223
1224 // Creating an archive that reads from the file "matrices.blaze"
1225 blaze::Archive<std::ofstream> archive( "matrices.blaze" );
1226
1227 // Reconstituting the former D matrix into D1. Note that it is possible to reconstitute
1228 // the matrix into a differrent kind of matrix (StaticMatrix -> DynamicMatrix), but that
1229 // the type of elements has to be the same.
1230 archive >> D1;
1231
1232 // Reconstituting the former S matrix into D2. Note that is is even possible to reconstitute
1233 // a sparse matrix as a dense matrix (also the reverse is possible) and that a column-major
1234 // matrix can be reconstituted as row-major matrix (and vice versa). Note however that also
1235 // in this case the type of elements is the same!
1236 archive >> D2
1237 }
1238 \endcode
1239
1240 // As the example demonstrates, the matrix serialization offers an enormous flexibility. However,
1241 // several actions result in errors:
1242 //
1243 // - matrices cannot be reconstituted as vectors (and vice versa)
1244 // - the element type of the serialized and reconstituted matrix must match, which means
1245 // that on the source and destination platform the general type (signed/unsigned integral
1246 // or floating point) and the size of the type must be exactly the same
1247 // - when reconstituting a StaticMatrix, the number of rows and columns must match those of
1248 // the serialized matrix
1249 //
1250 // In case an error is encountered during (de-)serialization, a \a std::runtime_exception is
1251 // thrown.
1252 */
1253 template< typename Archive // Type of the archive
1254 , typename MT // Type of the matrix
1255 , bool SO > // Storage order
1256 void serialize( Archive& archive, const Matrix<MT,SO>& mat )
1257 {
1258 MatrixSerializer().serialize( archive, *mat );
1259 }
1260 //*************************************************************************************************
1261
1262
1263 //*************************************************************************************************
1264 /*!\brief Deserializes a matrix from the given archive.
1265 //
1266 // \param archive The archive to be read from.
1267 // \param mat The matrix to be deserialized.
1268 // \return void
1269 // \exception std::runtime_error Matrix could not be deserialized.
1270 //
1271 // The deserialize() function converts the portable, binary representation contained in the
1272 // given archive into the given matrix type. For a detailed example that demonstrates the
1273 // (de-)serialization process of matrices, see the serialize() function.
1274 */
1275 template< typename Archive // Type of the archive
1276 , typename MT // Type of the matrix
1277 , bool SO > // Storage order
1278 void deserialize( Archive& archive, Matrix<MT,SO>& mat )
1279 {
1280 MatrixSerializer().deserialize( archive, *mat );
1281 }
1282 //*************************************************************************************************
1283
1284 } // namespace blaze
1285
1286 #endif
1287