1 /*
2  * Copyright (C) 1998-2018 ALPS Collaboration. See COPYRIGHT.TXT
3  * All rights reserved. Use is subject to license terms. See LICENSE.TXT
4  * For use in publications, see ACKNOWLEDGE.TXT
5  */
6 #include <alps/alea/plugin/stream_serializer.hpp>
7 
8 #include "gtest/gtest.h"
9 #include "dataset.hpp"
10 
11 #include <vector>
12 #include <queue>
13 
14 // Mock class that emulates Boost/HPX serialization archive
15 class mock_archive {
16 
17 public:
18 
mock_archive()19     mock_archive() {}
20 
21     // Store simple types
operator <<(double x)22     mock_archive & operator<<(double x) { store_fundamental(x); return *this; }
operator <<(long x)23     mock_archive & operator<<(long x) { store_fundamental(x); return *this; }
operator <<(unsigned long x)24     mock_archive & operator<<(unsigned long x) { store_fundamental(x); return *this; }
operator <<(std::complex<double> x)25     mock_archive & operator<<(std::complex<double> x)
26     {
27         *this << x.real() << x.imag();
28         return *this;
29     }
30 
31     // Store complex_op<T>
32     template<typename T>
operator <<(const alps::alea::complex_op<T> & x)33     mock_archive & operator<<(const alps::alea::complex_op<T> &x)
34     {
35         *this << x.rere() << x.reim() << x.imre() << x.imim();
36         return *this;
37     }
38 
39     // Store ALEA results
40     template <typename T>
41     typename std::enable_if<alps::alea::is_alea_result<T>::value, mock_archive &>::type
operator <<(const T & result)42     operator<<(const T &result)
43     {
44         save(*this, result, 0);
45         return *this;
46     }
47 
48     // Extract simple types
operator >>(double & x)49     mock_archive & operator>>(double &x) { extract_fundamental(x); return *this; }
operator >>(long & x)50     mock_archive & operator>>(long &x) { extract_fundamental(x); return *this; }
operator >>(unsigned long & x)51     mock_archive & operator>>(unsigned long &x) { extract_fundamental(x); return *this; }
operator >>(std::complex<double> & x)52     mock_archive & operator>>(std::complex<double> &x) {
53       double r, i;
54       extract_fundamental(r);
55       extract_fundamental(i);
56       x = std::complex<double>(r, i);
57       return *this;
58     }
59 
60     // Extract complex_op<T>
61     template<typename T>
operator >>(alps::alea::complex_op<T> & x)62     mock_archive & operator>>(alps::alea::complex_op<T> &x)
63     {
64         *this >> x.rere() >> x.reim() >> x.imre() >> x.imim();
65         return *this;
66     }
67 
68     // Extract ALEA results
69     template <typename T>
70     typename std::enable_if<alps::alea::is_alea_result<T>::value, mock_archive &>::type
operator >>(T & result)71     operator>>(T &result)
72     {
73         load(*this, result, 0);
74         return *this;
75     }
76 
77 private:
78 
79     template<typename T>
store_fundamental(T x)80     void store_fundamental(T x) {
81         unsigned char* p = reinterpret_cast<unsigned char*>(&x);
82         for(size_t n = 0; n < sizeof(T); ++n)
83             buf.push(*(p + n));
84     }
85 
86     template<typename T>
extract_fundamental(T & x)87     void extract_fundamental(T &x) {
88         unsigned char* p = reinterpret_cast<unsigned char*>(&x);
89         for(size_t n = 0; n < sizeof(T); ++n) {
90             *(p + n) = buf.front();
91             buf.pop();
92         }
93     }
94 
95     // FIFO container with raw byte representation of stored values
96     std::queue<unsigned char> buf;
97 };
98 
TEST(twogauss_serialize_case,mock_archive)99 TEST(twogauss_serialize_case, mock_archive) {
100     mock_archive archive;
101 
102     archive << (double)3.14
103             << (long)-123456
104             << (unsigned long)7890
105             << std::complex<double>(0.5,0.75)
106             << alps::alea::complex_op<double>(1, 2, 3, 4);
107 
108     double x = 0;
109     archive >> x;
110     EXPECT_EQ(3.14, x);
111     long l = 0;
112     archive >> l;
113     EXPECT_EQ(-123456, l);
114     unsigned long ul = 0;
115     archive >> ul;
116     EXPECT_EQ(7890U, ul);
117     std::complex<double> c = 0;
118     archive >> c;
119     EXPECT_EQ(std::complex<double>(0.5,0.75), c);
120     alps::alea::complex_op<double> co(0, 0, 0, 0);
121     archive >> co;
122     EXPECT_EQ(alps::alea::complex_op<double>(1, 2, 3, 4), co);
123 }
124 
125 template <typename Acc>
126 class twogauss_serialize_case
127     : public ::testing::Test
128 {
129 public:
130     typedef typename alps::alea::traits<Acc>::value_type value_type;
131     typedef typename alps::alea::traits<Acc>::result_type result_type;
132 
twogauss_serialize_case()133     twogauss_serialize_case() { }
134 
test_result()135     void test_result()
136     {
137         Acc in_acc(2);
138         for (size_t i = 0; i != twogauss_count; ++i)
139             in_acc << std::vector<value_type>{twogauss_data[i][0], twogauss_data[i][1]};
140 
141         auto in = in_acc.result();
142         std::cerr << alps::alea::PRINT_VERBOSE << "\nin\n" << in;
143 
144         mock_archive archive;
145         archive << in; // serialize
146 
147         Acc out_acc(2);
148         auto out = out_acc.result();
149 
150         archive >> out; // deserialize
151 
152         std::cerr << alps::alea::PRINT_VERBOSE << "\nout\n" << out << "\n";
153         EXPECT_EQ(in, out);
154     }
155 };
156 
157 using namespace alps::alea;
158 
159 typedef ::testing::Types<
160         mean_acc<double>
161       , mean_acc<std::complex<double> >
162       , var_acc<double>
163       , var_acc<std::complex<double> >
164       , var_acc<std::complex<double>, elliptic_var>
165       , cov_acc<double>
166       , cov_acc<std::complex<double> >
167       , cov_acc<std::complex<double>, elliptic_var>
168       , autocorr_acc<double>
169       , autocorr_acc<std::complex<double> >
170       , batch_acc<double>
171       , batch_acc<std::complex<double> >
172     > stream_serializable;
173 
174 TYPED_TEST_CASE(twogauss_serialize_case, stream_serializable);
TYPED_TEST(twogauss_serialize_case,test_result)175 TYPED_TEST(twogauss_serialize_case, test_result) { this->test_result(); }
176