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