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