All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MatrixSerializer.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_SERIALIZATION_MATRIXSERIALIZER_H_
23 #define _BLAZE_MATH_SERIALIZATION_MATRIXSERIALIZER_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <stdexcept>
42 #include <blaze/util/Assert.h>
43 #include <blaze/util/DisableIf.h>
44 #include <blaze/util/EnableIf.h>
45 #include <blaze/util/Types.h>
47 
48 
49 namespace blaze {
50 
51 //=================================================================================================
52 //
53 // CLASS DEFINITION
54 //
55 //=================================================================================================
56 
57 //*************************************************************************************************
146 {
147  private:
148  //**Private class MatrixValueMappingHelper******************************************************
162  template< bool IsDenseMatrix, bool IsRowMajorMatrix >
163  struct MatrixValueMappingHelper;
165  //**********************************************************************************************
166 
167  //**Private class MatrixValueMapping************************************************************
175  template< typename T >
176  struct MatrixValueMapping
177  {
178  enum { value = MatrixValueMappingHelper< IsDenseMatrix<T>::value, IsRowMajorMatrix<T>::value >::value };
180  };
182  //**********************************************************************************************
183 
184  public:
185  //**Constructor*********************************************************************************
188  explicit inline MatrixSerializer();
189  // No explicitly declared copy constructor.
191  //**********************************************************************************************
192 
193  //**Destructor**********************************************************************************
194  // No explicitly declared destructor.
195  //**********************************************************************************************
196 
197  //**Assignment operators************************************************************************
198  // No explicitly declared copy assignment operator.
199  //**********************************************************************************************
200 
201  //**Serialization functions*********************************************************************
204  template< typename Archive, typename MT, bool SO >
205  void serialize( Archive& archive, const Matrix<MT,SO>& mat );
207  //**********************************************************************************************
208 
209  //**Deserialization functions*******************************************************************
212  template< typename Archive, typename MT, bool SO >
213  void deserialize( Archive& archive, Matrix<MT,SO>& mat );
215  //**********************************************************************************************
216 
217  private:
218  //**Serialization functions*********************************************************************
221  template< typename Archive, typename MT >
222  void serializeHeader( Archive& archive, const MT& mat );
223 
224  template< typename Archive, typename MT, bool SO >
225  void serializeMatrix( Archive& archive, const DenseMatrix<MT,SO>& mat );
226 
227  template< typename Archive, typename MT, bool SO >
228  void serializeMatrix( Archive& archive, const SparseMatrix<MT,SO>& mat );
230  //**********************************************************************************************
231 
232  //**Deserialization functions*******************************************************************
235  template< typename Archive, typename MT >
236  void deserializeHeader( Archive& archive, const MT& mat );
237 
238  template< typename MT >
239  typename DisableIf< IsResizable<MT> >::Type prepareMatrix( MT& mat );
240 
241  template< typename MT >
242  typename EnableIf< IsResizable<MT> >::Type prepareMatrix( MT& mat );
243 
244  template< typename Archive, typename MT >
245  void deserializeMatrix( Archive& archive, MT& mat );
246 
247  template< typename Archive, typename MT >
250 
251  template< typename Archive, typename MT, bool SO >
253 
254  template< typename Archive, typename MT, bool SO >
257 
258  template< typename Archive, typename MT, bool SO >
261 
262  template< typename Archive, typename MT >
265 
266  template< typename Archive, typename MT, bool SO >
268 
269  template< typename Archive, typename MT, bool SO >
272 
273  template< typename Archive, typename MT, bool SO >
276 
277  template< typename Archive, typename MT, bool SO >
279 
280  template< typename Archive, typename MT >
282 
283  template< typename Archive, typename MT >
285 
286  template< typename Archive, typename MT, bool SO >
288 
289  template< typename Archive, typename MT >
291 
292  template< typename Archive, typename MT >
295  //**********************************************************************************************
296 
297  //**Member variables****************************************************************************
307 
308  //**********************************************************************************************
309 };
310 //*************************************************************************************************
311 
312 
313 
314 
315 //=================================================================================================
316 //
317 // CONSTRUCTOR
318 //
319 //=================================================================================================
320 
321 //*************************************************************************************************
325  : version_ ( 0U ) // The version of the archive
326  , type_ ( 0U ) // The type of the matrix
327  , elementType_( 0U ) // The type of an element
328  , elementSize_( 0U ) // The size in bytes of a single element of the matrix
329  , rows_ ( 0UL ) // The number of rows of the matrix
330  , columns_ ( 0UL ) // The number of columns of the matrix
331  , number_ ( 0UL ) // The total number of elements contained in the matrix
332 {}
333 //*************************************************************************************************
334 
335 
336 
337 
338 //=================================================================================================
339 //
340 // SERIALIZATION FUNCTIONS
341 //
342 //=================================================================================================
343 
344 //*************************************************************************************************
352 template< typename Archive // Type of the archive
353  , typename MT // Type of the matrix
354  , bool SO > // Storage order
356 {
357  if( !archive ) {
358  throw std::runtime_error( "Faulty archive detected" );
359  }
360 
361  serializeHeader( archive, ~mat );
362  serializeMatrix( archive, ~mat );
363 }
364 //*************************************************************************************************
365 
366 
367 //*************************************************************************************************
375 template< typename Archive // Type of the archive
376  , typename MT > // Type of the matrix
377 void MatrixSerializer::serializeHeader( Archive& archive, const MT& mat )
378 {
379  typedef typename MT::ElementType ET;
380 
381  archive << uint8_t ( 1U );
382  archive << uint8_t ( MatrixValueMapping<MT>::value );
383  archive << uint8_t ( TypeValueMapping<ET>::value );
384  archive << uint8_t ( sizeof( ET ) );
385  archive << uint64_t( mat.rows() );
386  archive << uint64_t( mat.columns() );
387  archive << uint64_t( ( IsDenseMatrix<MT>::value ) ? ( mat.rows()*mat.columns() ) : ( mat.nonZeros() ) );
388 
389  if( !archive ) {
390  throw std::runtime_error( "File header could not be serialized" );
391  }
392 }
393 //*************************************************************************************************
394 
395 
396 //*************************************************************************************************
404 template< typename Archive // Type of the archive
405  , typename MT // Type of the matrix
406  , bool SO > // Storage order
408 {
410  for( size_t i=0UL; i<(~mat).rows(); ++i ) {
411  for( size_t j=0UL; j<(~mat).columns(); ++j ) {
412  archive << (~mat)(i,j);
413  }
414  }
415  }
416  else {
417  for( size_t j=0UL; j<(~mat).columns(); ++j ) {
418  for( size_t i=0UL; i<(~mat).rows(); ++i ) {
419  archive << (~mat)(i,j);
420  }
421  }
422  }
423 
424  if( !archive ) {
425  throw std::runtime_error( "Dense matrix could not be serialized" );
426  }
427 }
428 //*************************************************************************************************
429 
430 
431 //*************************************************************************************************
439 template< typename Archive // Type of the archive
440  , typename MT // Type of the matrix
441  , bool SO > // Storage order
443 {
444  typedef typename MT::ConstIterator ConstIterator;
445 
447  for( size_t i=0UL; i<(~mat).rows(); ++i ) {
448  archive << uint64_t( (~mat).nonZeros( i ) );
449  for( ConstIterator element=(~mat).begin(i); element!=(~mat).end(i); ++element ) {
450  archive << element->index() << element->value();
451  }
452  }
453  }
454  else {
455  for( size_t j=0UL; j<(~mat).columns(); ++j ) {
456  archive << uint64_t( (~mat).nonZeros( j ) );
457  for( ConstIterator element=(~mat).begin(j); element!=(~mat).end(j); ++element ) {
458  archive << element->index() << element->value();
459  }
460  }
461  }
462 
463  if( !archive ) {
464  throw std::runtime_error( "Sparse matrix could not be serialized" );
465  }
466 }
467 //*************************************************************************************************
468 
469 
470 
471 
472 //=================================================================================================
473 //
474 // DESERIALIZATION FUNCTIONS
475 //
476 //=================================================================================================
477 
478 //*************************************************************************************************
486 template< typename Archive // Type of the archive
487  , typename MT // Type of the matrix
488  , bool SO > // Storage order
490 {
492 
493  if( !archive ) {
494  throw std::invalid_argument( "Faulty archive detected" );
495  }
496 
497  deserializeHeader( archive, ~mat );
498  prepareMatrix( ~mat );
499  deserializeMatrix( archive, ~mat );
500 }
501 //*************************************************************************************************
502 
503 
504 //*************************************************************************************************
512 template< typename Archive // Type of the archive
513  , typename MT > // Type of the matrix
514 void MatrixSerializer::deserializeHeader( Archive& archive, const MT& mat )
515 {
516  typedef typename MT::ElementType ET;
517 
518  if( !( archive >> version_ >> type_ >> elementType_ >> elementSize_ >> rows_ >> columns_ >> number_ ) ) {
519  throw std::runtime_error( "Corrupt archive detected" );
520  }
521  else if( version_ != 1UL ) {
522  throw std::runtime_error( "Invalid version detected" );
523  }
524  else if( ( type_ & 1U ) != 1U || ( type_ & (~7U) ) != 0U ) {
525  throw std::runtime_error( "Invalid matrix type detected" );
526  }
528  throw std::runtime_error( "Invalid element type detected" );
529  }
530  else if( elementSize_ != sizeof( ET ) ) {
531  throw std::runtime_error( "Invalid element size detected" );
532  }
533  else if( !IsResizable<MT>::value && ( rows_ != mat.rows() || columns_ != mat.columns() ) ) {
534  throw std::runtime_error( "Invalid matrix size detected" );
535  }
536  else if( number_ > rows_*columns_ ) {
537  throw std::runtime_error( "Invalid number of elements detected" );
538  }
539 }
540 //*************************************************************************************************
541 
542 
543 //*************************************************************************************************
549 template< typename MT > // Type of the matrix
551 {
552  reset( mat );
553 }
554 //*************************************************************************************************
555 
556 
557 //*************************************************************************************************
563 template< typename MT > // Type of the matrix
565 {
566  mat.resize ( rows_, columns_, false );
567  mat.reserve( number_ );
568  reset( mat );
569 }
570 //*************************************************************************************************
571 
572 
573 //*************************************************************************************************
584 template< typename Archive // Type of the archive
585  , typename MT > // Type of the matrix
587 {
588  if( type_ == 1U ) {
589  deserializeDenseRowMatrix( archive, ~mat );
590  }
591  else if( type_ == 5UL ) {
592  deserializeDenseColumnMatrix( archive, ~mat );
593  }
594  else if( type_ == 3UL ) {
595  deserializeSparseRowMatrix( archive, ~mat );
596  }
597  else if( type_ == 7UL ) {
598  deserializeSparseColumnMatrix( archive, ~mat );
599  }
600  else {
601  BLAZE_INTERNAL_ASSERT( false, "Undefined type flag" );
602  }
603 }
604 //*************************************************************************************************
605 
606 
607 //*************************************************************************************************
619 template< typename Archive // Type of the archive
620  , typename MT > // Type of the matrix
623 {
624  if( columns_ == 0UL ) return;
625 
626  for( size_t i=0UL; i<rows_; ++i ) {
627  archive.read( &(~mat)(i,0), columns_ );
628  }
629 
630  if( !archive ) {
631  throw std::runtime_error( "Dense matrix could not be deserialized" );
632  }
633 }
634 //*************************************************************************************************
635 
636 
637 //*************************************************************************************************
649 template< typename Archive // Type of the archive
650  , typename MT // Type of the matrix
651  , bool SO > // Storage order
653 {
654  typedef typename MT::ElementType ET;
655 
656  ET value = ET();
657 
658  for( size_t i=0UL; i<rows_; ++i ) {
659  size_t j( 0UL );
660  while( ( j != columns_ ) && ( archive >> value ) ) {
661  (~mat)(i,j) = value;
662  ++j;
663  }
664  }
665 
666  if( !archive ) {
667  throw std::runtime_error( "Dense matrix could not be deserialized" );
668  }
669 }
670 //*************************************************************************************************
671 
672 
673 //*************************************************************************************************
685 template< typename Archive // Type of the archive
686  , typename MT // Type of the matrix
687  , bool SO > // Storage order
690 {
692  deserializeDenseRowMatrix( archive, tmp );
693  (~mat) = tmp;
694 
695  if( !archive ) {
696  throw std::runtime_error( "Sparse matrix could not be deserialized" );
697  }
698 }
699 //*************************************************************************************************
700 
701 
702 //*************************************************************************************************
714 template< typename Archive // Type of the archive
715  , typename MT // Type of the matrix
716  , bool SO > // Storage order
719 {
720  typedef typename MT::ElementType ET;
721 
722  ET value = ET();
723 
724  const size_t dim1( ( SO == rowMajor )?( rows_ ):( columns_ ) );
725  const size_t dim2( ( SO != rowMajor )?( rows_ ):( columns_ ) );
726 
727  for( size_t i=0UL; i<dim1; ++i ) {
728  (~mat).reserve( i, dim2 );
729  }
730 
731  for( size_t i=0UL; i<rows_; ++i ) {
732  size_t j( 0UL );
733  while( ( j != columns_ ) && ( archive >> value ) ) {
734  (~mat).append( i, j, value, false );
735  ++j;
736  }
737  }
738 
739  if( !archive ) {
740  throw std::runtime_error( "Sparse matrix could not be deserialized" );
741  }
742 }
743 //*************************************************************************************************
744 
745 
746 //*************************************************************************************************
758 template< typename Archive // Type of the archive
759  , typename MT > // Type of the matrix
762 {
763  if( rows_ == 0UL ) return;
764 
765  for( size_t j=0UL; j<columns_; ++j ) {
766  archive.read( &(~mat)(0,j), rows_ );
767  }
768 
769  if( !archive ) {
770  throw std::runtime_error( "Dense matrix could not be deserialized" );
771  }
772 }
773 //*************************************************************************************************
774 
775 
776 //*************************************************************************************************
788 template< typename Archive // Type of the archive
789  , typename MT // Type of the matrix
790  , bool SO > // Storage order
792 {
793  typedef typename MT::ElementType ET;
794 
795  ET value = ET();
796 
797  for( size_t j=0UL; j<columns_; ++j ) {
798  size_t i( 0UL );
799  while( ( i != rows_ ) && ( archive >> value ) ) {
800  (~mat)(i,j) = value;
801  ++i;
802  }
803  }
804 
805  if( !archive ) {
806  throw std::runtime_error( "Dense matrix could not be deserialized" );
807  }
808 }
809 //*************************************************************************************************
810 
811 
812 //*************************************************************************************************
824 template< typename Archive // Type of the archive
825  , typename MT // Type of the matrix
826  , bool SO > // Storage order
829 {
831  deserializeDenseColumnMatrix( archive, tmp );
832  (~mat) = tmp;
833 
834  if( !archive ) {
835  throw std::runtime_error( "Sparse matrix could not be deserialized" );
836  }
837 }
838 //*************************************************************************************************
839 
840 
841 //*************************************************************************************************
853 template< typename Archive // Type of the archive
854  , typename MT // Type of the matrix
855  , bool SO > // Storage order
858 {
859  typedef typename MT::ElementType ET;
860 
861  ET value = ET();
862 
863  const size_t dim1( ( SO == rowMajor )?( rows_ ):( columns_ ) );
864  const size_t dim2( ( SO != rowMajor )?( rows_ ):( columns_ ) );
865 
866  for( size_t i=0UL; i<dim1; ++i ) {
867  (~mat).reserve( i, dim2 );
868  }
869 
870  for( size_t j=0UL; j<columns_; ++j ) {
871  size_t i( 0UL );
872  while( ( i != rows_ ) && ( archive >> value ) ) {
873  (~mat).append( i, j, value, false );
874  ++i;
875  }
876  }
877 
878  if( !archive ) {
879  throw std::runtime_error( "Sparse matrix could not be deserialized" );
880  }
881 }
882 //*************************************************************************************************
883 
884 
885 //*************************************************************************************************
897 template< typename Archive // Type of the archive
898  , typename MT // Type of the matrix
899  , bool SO > // Storage order
901 {
902  typedef typename MT::ElementType ET;
903 
904  uint64_t number( 0UL );
905  size_t index ( 0UL );
906  ET value = ET();
907 
908  for( size_t i=0UL; i<rows_; ++i ) {
909  archive >> number;
910  size_t j( 0UL );
911  while( ( j != number ) && ( archive >> index >> value ) ) {
912  (~mat)(i,index) = value;
913  ++j;
914  }
915  }
916 
917  if( !archive ) {
918  throw std::runtime_error( "Dense matrix could not be deserialized" );
919  }
920 }
921 //*************************************************************************************************
922 
923 
924 //*************************************************************************************************
936 template< typename Archive // Type of the archive
937  , typename MT > // Type of the matrix
939 {
940  typedef typename MT::ElementType ET;
941 
942  uint64_t number( 0UL );
943  size_t index ( 0UL );
944  ET value = ET();
945 
946  for( size_t i=0UL; i<rows_; ++i )
947  {
948  archive >> number;
949  (~mat).reserve( i, number );
950 
951  size_t j( 0UL );
952  while( ( j != number ) && ( archive >> index >> value ) ) {
953  (~mat).append( i, index, value, false );
954  ++j;
955  }
956  }
957 
958  if( !archive ) {
959  throw std::runtime_error( "Sparse matrix could not be deserialized" );
960  }
961 }
962 //*************************************************************************************************
963 
964 
965 //*************************************************************************************************
977 template< typename Archive // Type of the archive
978  , typename MT > // Type of the matrix
980 {
982  deserializeSparseRowMatrix( archive, tmp );
983  (~mat) = tmp;
984 
985  if( !archive ) {
986  throw std::runtime_error( "Sparse matrix could not be deserialized" );
987  }
988 }
989 //*************************************************************************************************
990 
991 
992 //*************************************************************************************************
1004 template< typename Archive // Type of the archive
1005  , typename MT // Type of the matrix
1006  , bool SO > // Storage order
1008 {
1009  typedef typename MT::ElementType ET;
1010 
1011  uint64_t number( 0UL );
1012  size_t index ( 0UL );
1013  ET value = ET();
1014 
1015  for( size_t j=0UL; j<columns_; ++j ) {
1016  archive >> number;
1017  size_t i( 0UL );
1018  while( ( i != number ) && ( archive >> index >> value ) ) {
1019  (~mat)(index,j) = value;
1020  ++i;
1021  }
1022  }
1023 
1024  if( !archive ) {
1025  throw std::runtime_error( "Dense matrix could not be deserialized" );
1026  }
1027 }
1028 //*************************************************************************************************
1029 
1030 
1031 //*************************************************************************************************
1043 template< typename Archive // Type of the archive
1044  , typename MT > // Type of the matrix
1046 {
1048  deserializeSparseColumnMatrix( archive, tmp );
1049  (~mat) = tmp;
1050 
1051  if( !archive ) {
1052  throw std::runtime_error( "Sparse matrix could not be deserialized" );
1053  }
1054 }
1055 //*************************************************************************************************
1056 
1057 
1058 //*************************************************************************************************
1070 template< typename Archive // Type of the archive
1071  , typename MT > // Type of the matrix
1073 {
1074  typedef typename MT::ElementType ET;
1075 
1076  uint64_t number( 0UL );
1077  size_t index ( 0UL );
1078  ET value = ET();
1079 
1080  for( size_t j=0UL; j<columns_; ++j )
1081  {
1082  archive >> number;
1083  (~mat).reserve( j, number );
1084 
1085  size_t i( 0UL );
1086  while( ( i != number ) && ( archive >> index >> value ) ) {
1087  (~mat).append( index, j, value, false );
1088  ++i;
1089  }
1090  }
1091 
1092  if( !archive ) {
1093  throw std::runtime_error( "Sparse matrix could not be deserialized" );
1094  }
1095 }
1096 //*************************************************************************************************
1097 
1098 
1099 
1100 
1101 //=================================================================================================
1102 //
1103 // MATRIXVALUEMAPPINGHELPER SPECIALIZATIONS
1104 //
1105 //=================================================================================================
1106 
1107 //*************************************************************************************************
1111 template<>
1112 struct MatrixSerializer::MatrixValueMappingHelper<true,true>
1113 {
1114  enum { value = 1 };
1115 };
1117 //*************************************************************************************************
1118 
1119 
1120 //*************************************************************************************************
1124 template<>
1125 struct MatrixSerializer::MatrixValueMappingHelper<true,false>
1126 {
1127  enum { value = 5 };
1128 };
1130 //*************************************************************************************************
1131 
1132 
1133 //*************************************************************************************************
1137 template<>
1138 struct MatrixSerializer::MatrixValueMappingHelper<false,true>
1139 {
1140  enum { value = 3 };
1141 };
1143 //*************************************************************************************************
1144 
1145 
1146 //*************************************************************************************************
1150 template<>
1151 struct MatrixSerializer::MatrixValueMappingHelper<false,false>
1152 {
1153  enum { value = 7 };
1154 };
1156 //*************************************************************************************************
1157 
1158 
1159 
1160 
1161 //=================================================================================================
1162 //
1163 // GLOBAL FUNCTIONS
1164 //
1165 //=================================================================================================
1166 
1167 //*************************************************************************************************
1232 template< typename Archive // Type of the archive
1233  , typename MT // Type of the matrix
1234  , bool SO > // Storage order
1235 void serialize( Archive& archive, const Matrix<MT,SO>& mat )
1236 {
1237  MatrixSerializer().serialize( archive, ~mat );
1238 }
1239 //*************************************************************************************************
1240 
1241 
1242 //*************************************************************************************************
1254 template< typename Archive // Type of the archive
1255  , typename MT // Type of the matrix
1256  , bool SO > // Storage order
1257 void deserialize( Archive& archive, Matrix<MT,SO>& mat )
1258 {
1259  MatrixSerializer().deserialize( archive, ~mat );
1260 }
1261 //*************************************************************************************************
1262 
1263 } // namespace blaze
1264 
1265 #endif