1 //=================================================================================================
2 /*!
3 // \file blaze/math/serialization/VectorSerializer.h
4 // \brief Serialization of dense and sparse vectors
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_VECTORSERIALIZER_H_
36 #define _BLAZE_MATH_SERIALIZATION_VECTORSERIALIZER_H_
37
38
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42
43 #include <blaze/math/Aliases.h>
44 #include <blaze/math/constraints/Vector.h>
45 #include <blaze/math/Exception.h>
46 #include <blaze/math/expressions/DenseVector.h>
47 #include <blaze/math/expressions/SparseVector.h>
48 #include <blaze/math/expressions/Vector.h>
49 #include <blaze/math/serialization/TypeValueMapping.h>
50 #include <blaze/math/typetraits/IsDenseVector.h>
51 #include <blaze/math/typetraits/IsResizable.h>
52 #include <blaze/util/Assert.h>
53 #include <blaze/util/EnableIf.h>
54 #include <blaze/util/Types.h>
55
56
57 namespace blaze {
58
59 //=================================================================================================
60 //
61 // CLASS DEFINITION
62 //
63 //=================================================================================================
64
65 //*************************************************************************************************
66 /*!\brief Serializer for dense and sparse vectors.
67 // \ingroup math_serialization
68 //
69 // The VectorSerializer implements the necessary logic to serialize dense and sparse vectors, i.e.
70 // to convert them into a portable, binary representation. The following example demonstrates the
71 // (de-)serialization process of vectors:
72
73 \code
74 using blaze::columnVector;
75 using blaze::rowVector;
76
77 // Serialization of both vectors
78 {
79 blaze::StaticVector<double,5UL,rowVector> d;
80 blaze::CompressedVector<int,columnVector> s;
81
82 // ... Resizing and initialization
83
84 // Creating an archive that writes into a the file "vectors.blaze"
85 blaze::Archive<std::ofstream> archive( "vectors.blaze" );
86
87 // Serialization of both vectors into the same archive. Note that d lies before s!
88 archive << d << s;
89 }
90
91 // Reconstitution of both vectors
92 {
93 blaze::DynamicVector<double,rowVector> d1;
94 blaze::DynamicVector<int,rowVector> d2;
95
96 // Creating an archive that reads from the file "vectors.blaze"
97 blaze::Archive<std::ofstream> archive( "vectors.blaze" );
98
99 // Reconstituting the former d vector into d1. Note that it is possible to reconstitute
100 // the vector into a differrent kind of vector (StaticVector -> DynamicVector), but that
101 // the type of elements has to be the same.
102 archive >> d1;
103
104 // Reconstituting the former s vector into d2. Note that is is even possible to reconstitute
105 // a sparse vector as a dense vector (also the reverse is possible) and that a column vector
106 // can be reconstituted as row vector (and vice versa). Note however that also in this case
107 // the type of elements is the same!
108 archive >> d2
109 }
110 \endcode
111
112 // Note that it is even possible to (de-)serialize vectors with vector or matrix elements:
113
114 \code
115 // Serialization
116 {
117 blaze::CompressedVector< blaze::DynamicVector< blaze::complex<double> > > vec;
118
119 // ... Resizing and initialization
120
121 // Creating an archive that writes into a the file "vector.blaze"
122 blaze::Archive<std::ofstream> archive( "vector.blaze" );
123
124 // Serialization of the vector into the archive
125 archive << vec;
126 }
127
128 // Deserialization
129 {
130 blaze::CompressedVector< blaze::DynamicVector< blaze::complex<double> > > vec;
131
132 // Creating an archive that reads from the file "vector.blaze"
133 blaze::Archive<std::ofstream> archive( "vector.blaze" );
134
135 // Reconstitution of the vector from the archive
136 archive >> vec;
137 }
138 \endcode
139
140 // As the examples demonstrates, the vector serialization offers an enormous flexibility. However,
141 // several actions result in errors:
142 //
143 // - vectors cannot be reconstituted as matrices (and vice versa)
144 // - the element type of the serialized and reconstituted vector must match, which means
145 // that on the source and destination platform the general type (signed/unsigned integral
146 // or floating point) and the size of the type must be exactly the same
147 // - when reconstituting a StaticVector, its size must match the size of the serialized vector
148 //
149 // In case an error is encountered during (de-)serialization, a \a std::runtime_exception is
150 // thrown.
151 */
152 class VectorSerializer
153 {
154 private:
155 //**Private class VectorValueMappingHelper******************************************************
156 /*! \cond BLAZE_INTERNAL */
157 /*!\brief Auxiliary helper class for the VectorValueMapping class template.
158 //
159 // The VectorValueMapping class template is an auxiliary class for the VectorSerializer. It
160 // maps a vector type into an integral representation. For the mapping, the following bit
161 // mapping is used:
162
163 \code
164 0x01 - Vector/Matrix flag
165 0x02 - Dense/Sparse flag
166 0x04 - Row-/Column-major flag
167 \endcode
168 */
169 template< bool IsDenseVector >
170 struct VectorValueMappingHelper;
171 /*! \endcond */
172 //**********************************************************************************************
173
174 //**Private class VectorValueMapping************************************************************
175 /*! \cond BLAZE_INTERNAL */
176 /*!\brief Serialization of the type of a vector.
177 //
178 // This class template converts the given vector type into an integral representation suited
179 // for serialization. Depending on the given vector type, the \a value member enumeration is
180 // set to the according integral representation.
181 */
182 template< typename T >
183 struct VectorValueMapping
184 {
185 enum { value = VectorValueMappingHelper< IsDenseVector_v<T> >::value };
186 BLAZE_CONSTRAINT_MUST_BE_VECTOR_TYPE( T );
187 };
188 /*! \endcond */
189 //**********************************************************************************************
190
191 public:
192 //**Constructor*********************************************************************************
193 /*!\name Constructor */
194 //@{
195 inline VectorSerializer();
196 //@}
197 //**********************************************************************************************
198
199 //**Serialization functions*********************************************************************
200 /*!\name Serialization functions */
201 //@{
202 template< typename Archive, typename VT, bool TF >
203 void serialize( Archive& archive, const Vector<VT,TF>& vec );
204 //@}
205 //**********************************************************************************************
206
207 //**Deserialization functions*********************************************************************
208 /*!\name Deserialization functions */
209 //@{
210 template< typename Archive, typename VT, bool TF >
211 void deserialize( Archive& archive, Vector<VT,TF>& vec );
212 //@}
213 //**********************************************************************************************
214
215 private:
216 //**Serialization functions*********************************************************************
217 /*!\name Serialization functions */
218 //@{
219 template< typename Archive, typename VT >
220 void serializeHeader( Archive& archive, const VT& vec );
221
222 template< typename Archive, typename VT, bool TF >
223 void serializeVector( Archive& archive, const DenseVector<VT,TF>& vec );
224
225 template< typename Archive, typename VT, bool TF >
226 void serializeVector( Archive& archive, const SparseVector<VT,TF>& vec );
227 //@}
228 //**********************************************************************************************
229
230 //**Deserialization functions*******************************************************************
231 /*!\name Deserialization functions */
232 //@{
233 template< typename Archive, typename VT >
234 void deserializeHeader( Archive& archive, const VT& vec );
235
236 template< typename VT, bool TF >
237 DisableIf_t< IsResizable_v<VT> > prepareVector( DenseVector<VT,TF>& vec );
238
239 template< typename VT, bool TF >
240 DisableIf_t< IsResizable_v<VT> > prepareVector( SparseVector<VT,TF>& vec );
241
242 template< typename VT >
243 EnableIf_t< IsResizable_v<VT> > prepareVector( VT& vec );
244
245 template< typename Archive, typename VT >
246 void deserializeVector( Archive& archive, VT& vec );
247
248 template< typename Archive, typename VT, bool TF >
249 DisableIf_t< VT::simdEnabled >
250 deserializeDenseVector( Archive& archive, DenseVector<VT,TF>& vec );
251
252 template< typename Archive, typename VT, bool TF >
253 EnableIf_t< VT::simdEnabled >
254 deserializeDenseVector( Archive& archive, DenseVector<VT,TF>& vec );
255
256 template< typename Archive, typename VT, bool TF >
257 void deserializeDenseVector( Archive& archive, SparseVector<VT,TF>& vec );
258
259 template< typename Archive, typename VT, bool TF >
260 void deserializeSparseVector( Archive& archive, DenseVector<VT,TF>& vec );
261
262 template< typename Archive, typename VT, bool TF >
263 void deserializeSparseVector( Archive& archive, SparseVector<VT,TF>& vec );
264 //@}
265 //**********************************************************************************************
266
267 //**Member variables****************************************************************************
268 /*!\name Member variables */
269 //@{
270 uint8_t version_; //!< The version of the archive.
271 uint8_t type_; //!< The type of the vector.
272 uint8_t elementType_; //!< The type of an element.
273 uint8_t elementSize_; //!< The size in bytes of a single element of the vector.
274 uint64_t size_; //!< The size of the vector.
275 uint64_t number_; //!< The total number of elements contained in the vector.
276 //@}
277 //**********************************************************************************************
278 };
279 //*************************************************************************************************
280
281
282
283
284 //=================================================================================================
285 //
286 // CONSTRUCTOR
287 //
288 //=================================================================================================
289
290 //*************************************************************************************************
291 /*!\brief The default constructor of the VectorSerializer class.
292 */
VectorSerializer()293 VectorSerializer::VectorSerializer()
294 : version_ ( 0U ) // The version of the archive
295 , type_ ( 0U ) // The type of the vector
296 , elementType_( 0U ) // The type of an element
297 , elementSize_( 0U ) // The size in bytes of a single element of the vector
298 , size_ ( 0UL ) // The size of the vector
299 , number_ ( 0UL ) // The total number of elements contained in the vector
300 {}
301 //*************************************************************************************************
302
303
304
305
306 //=================================================================================================
307 //
308 // SERIALIZATION FUNCTIONS
309 //
310 //=================================================================================================
311
312 //*************************************************************************************************
313 /*!\brief Serializes the given vector and writes it to the archive.
314 //
315 // \param archive The archive to be written.
316 // \param vec The vector to be serialized.
317 // \return void
318 // \exception std::runtime_error Error during serialization.
319 //
320 // This function serializes the given vector and writes it to the given archive. In case any
321 // error is detected during the serialization, a \a std::runtime_error is thrown.
322 */
323 template< typename Archive // Type of the archive
324 , typename VT // Type of the vector
325 , bool TF > // Transpose flag
serialize(Archive & archive,const Vector<VT,TF> & vec)326 void VectorSerializer::serialize( Archive& archive, const Vector<VT,TF>& vec )
327 {
328 if( !archive ) {
329 BLAZE_THROW_RUNTIME_ERROR( "Faulty archive detected" );
330 }
331
332 serializeHeader( archive, *vec );
333 serializeVector( archive, *vec );
334 }
335 //*************************************************************************************************
336
337
338 //*************************************************************************************************
339 /*!\brief Serializes all meta information about the given vector.
340 //
341 // \param archive The archive to be written.
342 // \param vec The vector to be serialized.
343 // \return void
344 // \exception std::runtime_error File header could not be serialized.
345 */
346 template< typename Archive // Type of the archive
347 , typename VT > // Type of the vector
serializeHeader(Archive & archive,const VT & vec)348 void VectorSerializer::serializeHeader( Archive& archive, const VT& vec )
349 {
350 using ET = ElementType_t<VT>;
351
352 archive << uint8_t ( 1U );
353 archive << uint8_t ( VectorValueMapping<VT>::value );
354 archive << uint8_t ( TypeValueMapping<ET>::value );
355 archive << uint8_t ( sizeof( ET ) );
356 archive << uint64_t( vec.size() );
357 archive << uint64_t( IsDenseVector_v<VT> ? vec.size() : vec.nonZeros() );
358
359 if( !archive ) {
360 BLAZE_THROW_RUNTIME_ERROR( "File header could not be serialized" );
361 }
362 }
363 //*************************************************************************************************
364
365
366 //*************************************************************************************************
367 /*!\brief Serializes the elements of a dense vector.
368 //
369 // \param archive The archive to be written.
370 // \param vec The vector to be serialized.
371 // \return void
372 // \exception std::runtime_error Dense vector could not be serialized.
373 */
374 template< typename Archive // Type of the archive
375 , typename VT // Type of the vector
376 , bool TF > // Transpose flag
serializeVector(Archive & archive,const DenseVector<VT,TF> & vec)377 void VectorSerializer::serializeVector( Archive& archive, const DenseVector<VT,TF>& vec )
378 {
379 size_t i( 0UL );
380 while( ( i < (*vec).size() ) && ( archive << (*vec)[i] ) ) {
381 ++i;
382 }
383
384 if( !archive ) {
385 BLAZE_THROW_RUNTIME_ERROR( "Dense vector could not be serialized" );
386 }
387 }
388 //*************************************************************************************************
389
390
391 //*************************************************************************************************
392 /*!\brief Serializes the elements of a sparse vector.
393 //
394 // \param archive The archive to be written.
395 // \param vec The vector to be serialized.
396 // \return void
397 // \exception std::runtime_error Sparse vector could not be serialized.
398 */
399 template< typename Archive // Type of the archive
400 , typename VT // Type of the vector
401 , bool TF > // Transpose flag
serializeVector(Archive & archive,const SparseVector<VT,TF> & vec)402 void VectorSerializer::serializeVector( Archive& archive, const SparseVector<VT,TF>& vec )
403 {
404 using ConstIterator = ConstIterator_t<VT>;
405
406 ConstIterator element( (*vec).begin() );
407 while( ( element != (*vec).end() ) &&
408 ( archive << element->index() << element->value() ) ) {
409 ++element;
410 }
411
412 if( !archive ) {
413 BLAZE_THROW_RUNTIME_ERROR( "Sparse vector could not be serialized" );
414 }
415 }
416 //*************************************************************************************************
417
418
419
420
421 //=================================================================================================
422 //
423 // DESERIALIZATION FUNCTIONS
424 //
425 //=================================================================================================
426
427 //*************************************************************************************************
428 /*!\brief Deserializes a vector from the given archive.
429 //
430 // \param archive The archive to be read from.
431 // \param vec The vector to be deserialized.
432 // \return void
433 // \exception std::runtime_error Error during deserialization.
434 */
435 template< typename Archive // Type of the archive
436 , typename VT // Type of the vector
437 , bool TF > // Transpose flag
deserialize(Archive & archive,Vector<VT,TF> & vec)438 void VectorSerializer::deserialize( Archive& archive, Vector<VT,TF>& vec )
439 {
440 if( !archive ) {
441 BLAZE_THROW_INVALID_ARGUMENT( "Faulty archive detected" );
442 }
443
444 deserializeHeader( archive, *vec );
445 prepareVector( *vec );
446 deserializeVector( archive, *vec );
447 }
448 //*************************************************************************************************
449
450
451 //*************************************************************************************************
452 /*!\brief Deserializes all meta information about the given vector.
453 //
454 // \param archive The archive to be read from.
455 // \param vec The vector to be deserialized.
456 // \return void
457 // \exception std::runtime_error Error during deserialization.
458 //
459 // This function deserializes all meta information about the given vector contained in the
460 // header of the given archive. In case any error is detected during the deserialization
461 // process (for instance an invalid type of vector, element type, element size, or vector
462 // size) a \a std::runtime_error is thrown.
463 */
464 template< typename Archive // Type of the archive
465 , typename VT > // Type of the vector
deserializeHeader(Archive & archive,const VT & vec)466 void VectorSerializer::deserializeHeader( Archive& archive, const VT& vec )
467 {
468 using ET = ElementType_t<VT>;
469
470 if( !( archive >> version_ >> type_ >> elementType_ >> elementSize_ >> size_ >> number_ ) ) {
471 BLAZE_THROW_RUNTIME_ERROR( "Corrupt archive detected" );
472 }
473 else if( version_ != 1UL ) {
474 BLAZE_THROW_RUNTIME_ERROR( "Invalid version detected" );
475 }
476 else if( ( type_ & 1U ) != 0U || ( type_ & (~3U) ) != 0U ) {
477 BLAZE_THROW_RUNTIME_ERROR( "Invalid vector type detected" );
478 }
479 else if( elementType_ != TypeValueMapping<ET>::value ) {
480 BLAZE_THROW_RUNTIME_ERROR( "Invalid element type detected" );
481 }
482 else if( elementSize_ != sizeof( ET ) ) {
483 BLAZE_THROW_RUNTIME_ERROR( "Invalid element size detected" );
484 }
485 else if( !IsResizable_v<VT> && size_ != vec.size() ) {
486 BLAZE_THROW_RUNTIME_ERROR( "Invalid vector size detected" );
487 }
488 else if( number_ > size_ ) {
489 BLAZE_THROW_RUNTIME_ERROR( "Invalid number of elements detected" );
490 }
491 }
492 //*************************************************************************************************
493
494
495 //*************************************************************************************************
496 /*!\brief Prepares the given non-resizable dense vector for the deserialization process.
497 //
498 // \param vec The dense vector to be prepared.
499 // \return void
500 */
501 template< typename VT // Type of the dense vector
502 , bool TF > // Transpose flag
prepareVector(DenseVector<VT,TF> & vec)503 DisableIf_t< IsResizable_v<VT> > VectorSerializer::prepareVector( DenseVector<VT,TF>& vec )
504 {
505 reset( *vec );
506 }
507 //*************************************************************************************************
508
509
510 //*************************************************************************************************
511 /*!\brief Prepares the given non-resizable sparse vector for the deserialization process.
512 //
513 // \param vec The sparse vector to be prepared.
514 // \return void
515 */
516 template< typename VT // Type of the sparse vector
517 , bool TF > // Transpose flag
prepareVector(SparseVector<VT,TF> & vec)518 DisableIf_t< IsResizable_v<VT> > VectorSerializer::prepareVector( SparseVector<VT,TF>& vec )
519 {
520 (*vec).reserve( number_ );
521 reset( *vec );
522 }
523 //*************************************************************************************************
524
525
526 //*************************************************************************************************
527 /*!\brief Prepares the given resizable vector for the deserialization process.
528 //
529 // \param vec The vector to be prepared.
530 // \return void
531 */
532 template< typename VT > // Type of the vector
prepareVector(VT & vec)533 EnableIf_t< IsResizable_v<VT> > VectorSerializer::prepareVector( VT& vec )
534 {
535 vec.resize ( size_, false );
536 vec.reserve( number_ );
537 reset( vec );
538 }
539 //*************************************************************************************************
540
541
542 //*************************************************************************************************
543 /*!\brief Deserializes a vector from the archive.
544 //
545 // \param archive The archive to be read from.
546 // \param vec The vector to be reconstituted.
547 // \return void
548 // \exception std::runtime_error Error during deserialization.
549 //
550 // This function deserializes the contents of the vector from the archive and reconstitutes the
551 // given vector.
552 */
553 template< typename Archive // Type of the archive
554 , typename VT > // Type of the vector
deserializeVector(Archive & archive,VT & vec)555 void VectorSerializer::deserializeVector( Archive& archive, VT& vec )
556 {
557 if( type_ == 0U ) {
558 deserializeDenseVector( archive, vec );
559 }
560 else if( type_ == 2U ) {
561 deserializeSparseVector( archive, vec );
562 }
563 else {
564 BLAZE_INTERNAL_ASSERT( false, "Undefined type flag" );
565 }
566 }
567 //*************************************************************************************************
568
569
570 //*************************************************************************************************
571 /*!\brief Deserializes a dense vector from the archive.
572 //
573 // \param archive The archive to be read from.
574 // \param vec The dense vector to be reconstituted.
575 // \return void
576 // \exception std::runtime_error Dense vector could not be deserialized.
577 //
578 // This function deserializes a dense vector from the archive and reconstitutes the given
579 // dense vector. In case any error is detected during the deserialization process, a
580 // \a std::runtime_error is thrown.
581 */
582 template< typename Archive // Type of the archive
583 , typename VT // Type of the vector
584 , bool TF > // Transpose flag
585 DisableIf_t< VT::simdEnabled >
deserializeDenseVector(Archive & archive,DenseVector<VT,TF> & vec)586 VectorSerializer::deserializeDenseVector( Archive& archive, DenseVector<VT,TF>& vec )
587 {
588 using ET = ElementType_t<VT>;
589
590 size_t i( 0UL );
591 ET value{};
592
593 while( ( i != size_ ) && ( archive >> value ) ) {
594 (*vec)[i] = value;
595 ++i;
596 }
597
598 if( !archive ) {
599 BLAZE_THROW_RUNTIME_ERROR( "Dense vector could not be deserialized" );
600 }
601 }
602 //*************************************************************************************************
603
604
605 //*************************************************************************************************
606 /*!\brief Deserializes a dense vector from the archive.
607 //
608 // \param archive The archive to be read from.
609 // \param vec The dense vector to be reconstituted.
610 // \return void
611 // \exception std::runtime_error Dense vector could not be deserialized.
612 //
613 // This function deserializes a dense vector from the archive and reconstitutes the given
614 // dense vector. In case any error is detected during the deserialization process, a
615 // \a std::runtime_error is thrown.
616 */
617 template< typename Archive // Type of the archive
618 , typename VT // Type of the vector
619 , bool TF > // Transpose flag
620 EnableIf_t< VT::simdEnabled >
deserializeDenseVector(Archive & archive,DenseVector<VT,TF> & vec)621 VectorSerializer::deserializeDenseVector( Archive& archive, DenseVector<VT,TF>& vec )
622 {
623 if( size_ == 0UL ) return;
624 archive.read( &(*vec)[0], size_ );
625
626 if( !archive ) {
627 BLAZE_THROW_RUNTIME_ERROR( "Dense vector could not be deserialized" );
628 }
629 }
630 //*************************************************************************************************
631
632
633 //*************************************************************************************************
634 /*!\brief Deserializes a dense vector from the archive.
635 //
636 // \param archive The archive to be read from.
637 // \param vec The sparse vector to be reconstituted.
638 // \return void
639 // \exception std::runtime_error Sparse vector could not be deserialized.
640 //
641 // This function deserializes a dense vector from the archive and reconstitutes the given
642 // sparse vector. In case any error is detected during the deserialization process, a
643 // \a std::runtime_error is thrown.
644 */
645 template< typename Archive // Type of the archive
646 , typename VT // Type of the vector
647 , bool TF > // Transpose flag
deserializeDenseVector(Archive & archive,SparseVector<VT,TF> & vec)648 void VectorSerializer::deserializeDenseVector( Archive& archive, SparseVector<VT,TF>& vec )
649 {
650 using ET = ElementType_t<VT>;
651
652 size_t i( 0UL );
653 ET value{};
654
655 while( ( i != size_ ) && ( archive >> value ) ) {
656 (*vec)[i] = value;
657 ++i;
658 }
659
660 if( !archive ) {
661 BLAZE_THROW_RUNTIME_ERROR( "Sparse vector could not be deserialized" );
662 }
663 }
664 //*************************************************************************************************
665
666
667 //*************************************************************************************************
668 /*!\brief Deserializes a sparse vector from the archive.
669 //
670 // \param archive The archive to be read from.
671 // \param vec The dense vector to be reconstituted.
672 // \return void
673 // \exception std::runtime_error Dense vector could not be deserialized.
674 //
675 // This function deserializes a sparse vector from the archive and reconstitutes the given
676 // dense vector. In case any error is detected during the deserialization process, a
677 // \a std::runtime_error is thrown.
678 */
679 template< typename Archive // Type of the archive
680 , typename VT // Type of the vector
681 , bool TF > // Transpose flag
deserializeSparseVector(Archive & archive,DenseVector<VT,TF> & vec)682 void VectorSerializer::deserializeSparseVector( Archive& archive, DenseVector<VT,TF>& vec )
683 {
684 using ET = ElementType_t<VT>;
685
686 size_t i ( 0UL );
687 size_t index( 0UL );
688 ET value{};
689
690 while( ( i != number_ ) && ( archive >> index >> value ) ) {
691 (*vec)[index] = value;
692 ++i;
693 }
694
695 if( !archive ) {
696 BLAZE_THROW_RUNTIME_ERROR( "Dense vector could not be deserialized" );
697 }
698 }
699 //*************************************************************************************************
700
701
702 //*************************************************************************************************
703 /*!\brief Deserializes a sparse vector from the archive.
704 //
705 // \param archive The archive to be read from.
706 // \param vec The sparse vector to be reconstituted.
707 // \return void
708 // \exception std::runtime_error Sparse vector could not be deserialized.
709 //
710 // This function deserializes a sparse vector from the archive and reconstitutes the given
711 // sparse vector. In case any error is detected during the deserialization process, a
712 // \a std::runtime_error is thrown.
713 */
714 template< typename Archive // Type of the archive
715 , typename VT // Type of the vector
716 , bool TF > // Transpose flag
deserializeSparseVector(Archive & archive,SparseVector<VT,TF> & vec)717 void VectorSerializer::deserializeSparseVector( Archive& archive, SparseVector<VT,TF>& vec )
718 {
719 using ET = ElementType_t<VT>;
720
721 size_t i ( 0UL );
722 size_t index( 0UL );
723 ET value{};
724
725 while( ( i != number_ ) && ( archive >> index >> value ) ) {
726 (*vec).append( index, value, false );
727 ++i;
728 }
729
730 if( !archive ) {
731 BLAZE_THROW_RUNTIME_ERROR( "Sparse vector could not be deserialized" );
732 }
733 }
734 //*************************************************************************************************
735
736
737
738
739 //=================================================================================================
740 //
741 // VECTORVALUEMAPPINGHELPER SPECIALIZATIONS
742 //
743 //=================================================================================================
744
745 //*************************************************************************************************
746 /*! \cond BLAZE_INTERNAL */
747 /*!\brief Specialization of the VectorValueMappingHelper class template for dense vectors.
748 */
749 template<>
750 struct VectorSerializer::VectorValueMappingHelper<true>
751 {
752 enum { value = 0 };
753 };
754 /*! \endcond */
755 //*************************************************************************************************
756
757
758 //*************************************************************************************************
759 /*! \cond BLAZE_INTERNAL */
760 /*!\brief Specialization of the VectorValueMappingHelper class template for sparse vectors.
761 */
762 template<>
763 struct VectorSerializer::VectorValueMappingHelper<false>
764 {
765 enum { value = 2 };
766 };
767 /*! \endcond */
768 //*************************************************************************************************
769
770
771
772
773 //=================================================================================================
774 //
775 // GLOBAL FUNCTIONS
776 //
777 //=================================================================================================
778
779 //*************************************************************************************************
780 /*!\brief Serializes the given vector and writes it to the archive.
781 //
782 // \param archive The archive to be written.
783 // \param vec The vector to be serialized.
784 // \return void
785 // \exception std::runtime_error Error during serialization.
786 //
787 // The serialize() function converts the given vector into a portable, binary representation.
788 // The following example demonstrates the (de-)serialization process of vectors:
789
790 \code
791 using blaze::columnVector;
792 using blaze::rowVector;
793
794 // Serialization of both vectors
795 {
796 blaze::StaticVector<double,5UL,rowVector> d;
797 blaze::CompressedVector<int,columnVector> s;
798
799 // ... Resizing and initialization
800
801 // Creating an archive that writes into a the file "vectors.blaze"
802 blaze::Archive<std::ofstream> archive( "vectors.blaze" );
803
804 // Serialization of both vectors into the same archive. Note that d lies before s!
805 archive << d << s;
806 }
807
808 // Reconstitution of both vectors
809 {
810 blaze::DynamicVector<double,rowVector> d1;
811 blaze::DynamicVector<int,rowVector> d2;
812
813 // ... Resizing and initialization
814
815 // Creating an archive that reads from the file "vectors.blaze"
816 blaze::Archive<std::ofstream> archive( "vectors.blaze" );
817
818 // Reconstituting the former d vector into d1. Note that it is possible to reconstitute
819 // the vector into a differrent kind of vector (StaticVector -> DynamicVector), but that
820 // the type of elements has to be the same.
821 archive >> d1;
822
823 // Reconstituting the former s vector into d2. Note that is is even possible to reconstitute
824 // a sparse vector as a dense vector (also the reverse is possible) and that a column vector
825 // can be reconstituted as row vector (and vice versa). Note however that also in this case
826 // the type of elements is the same!
827 archive >> d2
828 }
829 \endcode
830
831 // As the example demonstrates, the vector serialization offers an enormous flexibility. However,
832 // several actions result in errors:
833 //
834 // - vectors cannot be reconstituted as matrices (and vice versa)
835 // - the element type of the serialized and reconstituted vector must match, which means
836 // that on the source and destination platform the general type (signed/unsigned integral
837 // or floating point) and the size of the type must be exactly the same
838 // - when reconstituting a StaticVector, its size must match the size of the serialized vector
839 //
840 // In case an error is encountered during (de-)serialization, a \a std::runtime_exception is
841 // thrown.
842 */
843 template< typename Archive // Type of the archive
844 , typename VT // Type of the vector
845 , bool TF > // Transpose flag
846 void serialize( Archive& archive, const Vector<VT,TF>& vec )
847 {
848 VectorSerializer().serialize( archive, *vec );
849 }
850 //*************************************************************************************************
851
852
853 //*************************************************************************************************
854 /*!\brief Deserializes a vector from the given archive.
855 //
856 // \param archive The archive to be read from.
857 // \param vec The vector to be deserialized.
858 // \return void
859 // \exception std::runtime_error Vector could not be deserialized.
860 //
861 // The deserialize() function converts the portable, binary representation contained in
862 // the given archive into the given vector type. For a detailed example that demonstrates
863 // the (de-)serialization process of vectors, see the serialize() function.
864 */
865 template< typename Archive // Type of the archive
866 , typename VT // Type of the vector
867 , bool TF > // Transpose flag
868 void deserialize( Archive& archive, Vector<VT,TF>& vec )
869 {
870 VectorSerializer().deserialize( archive, *vec );
871 }
872 //*************************************************************************************************
873
874 } // namespace blaze
875
876 #endif
877