1 #include "gtest/gtest.h"
2 #include "dpd_varray.hpp"
3 
4 using namespace std;
5 using namespace MArray;
6 
7 static dpd_layout layouts[6] =
8 {
9     PREFIX_ROW_MAJOR,
10     PREFIX_COLUMN_MAJOR,
11     BLOCKED_ROW_MAJOR,
12     BLOCKED_COLUMN_MAJOR,
13     BALANCED_ROW_MAJOR,
14     BALANCED_COLUMN_MAJOR,
15 };
16 
17 static dim_vector perms[6] =
18     {{3,2,1,0}, {0,1,2,3}, {3,2,1,0}, {0,1,2,3}, {3,2,1,0}, {0,1,2,3}};
19 
20 static irrep_vector irreps[8] =
21     {{1,0,0,0}, {0,1,0,0}, {0,0,1,0}, {1,1,1,0},
22      {0,0,0,1}, {1,1,0,1}, {1,0,1,1}, {0,1,1,1}};
23 static len_vector lengths[8] =
24     {{1,2,1,3}, {3,2,1,3}, {3,2,2,3}, {1,2,2,3},
25      {3,2,1,4}, {1,2,1,4}, {1,2,2,4}, {3,2,2,4}};
26 
27 static stride_vector strides[6][8] =
28 {
29     {{42,11, 3, 1}, {42,11, 3, 1}, {42,10, 3, 1}, {42,10, 3, 1},
30      {42,10, 4, 1}, {42,10, 4, 1}, {42,11, 4, 1}, {42,11, 4, 1}},
31     {{ 1, 1, 8,24}, { 1, 3, 8,24}, { 1, 3, 8,24}, { 1, 1, 8,24},
32      { 1, 3, 8,24}, { 1, 1, 8,24}, { 1, 1, 8,24}, { 1, 3, 8,24}},
33     {{ 6, 3, 3, 1}, { 6, 3, 3, 1}, {12, 6, 3, 1}, {12, 6, 3, 1},
34      { 8, 4, 4, 1}, { 8, 4, 4, 1}, {16, 8, 4, 1}, {16, 8, 4, 1}},
35     {{ 1, 1, 2, 2}, { 1, 3, 6, 6}, { 1, 3, 6,12}, { 1, 1, 2, 4},
36      { 1, 3, 6, 6}, { 1, 1, 2, 2}, { 1, 1, 2, 4}, { 1, 3, 6,12}},
37     {{22,11, 3, 1}, {22,11, 3, 1}, {20,10, 3, 1}, {20,10, 3, 1},
38      {20,10, 4, 1}, {20,10, 4, 1}, {22,11, 4, 1}, {22,11, 4, 1}},
39     {{ 1, 1, 8, 8}, { 1, 3, 8, 8}, { 1, 3, 8,16}, { 1, 1, 8,16},
40      { 1, 3, 8, 8}, { 1, 1, 8, 8}, { 1, 1, 8,16}, { 1, 3, 8,16}}
41 };
42 
43 static stride_type offsets[6][8] =
44 {
45      {126, 20,  4,152,  0,148,129, 23},
46      {  0,  2,  8, 14, 72, 78, 80, 82},
47      {162,144, 96,132,  0, 24, 80, 32},
48      {  0, 42,108, 22,144, 34,  6, 60},
49      { 80+66, 80   ,     0+4,  0+60+4,
50         0   ,  0+60, 80+66+3, 80   +3},
51      {  0   ,  0   +2, 88   , 88   +6,
52        88+48, 88+48+6,  0+24,  0+24+2}
53 };
54 
55 #define CHECK_DPD_MARRAY_RESET(v) \
56     EXPECT_EQ(nullptr, v.data()); \
57     EXPECT_EQ(0u, v.irrep()); \
58     EXPECT_EQ(0u, v.num_irreps()); \
59     EXPECT_EQ((dim_vector{}), v.permutation()); \
60     EXPECT_EQ((matrix<len_type>{}), v.lengths());
61 
62 #define CHECK_DPD_MARRAY(v,j) \
63     SCOPED_TRACE(j); \
64     EXPECT_EQ(1u, v.irrep()); \
65     EXPECT_EQ(2u, v.num_irreps()); \
66     EXPECT_EQ(perms[j], v.permutation()); \
67     EXPECT_EQ((matrix<len_type>{{3, 1}, {2, 2}, {1, 2}, {3, 4}}), v.lengths()); \
68     \
69     { \
70         auto vs = v(1,0,0,0); \
71         EXPECT_EQ(v.data() + offsets[j][0], vs.data()); \
72         for (unsigned k = 0;k < 4;k++) \
73         { \
74             EXPECT_EQ(lengths[0][k], vs.length(k)); \
75             EXPECT_EQ(strides[j][0][k], vs.stride(k)); \
76         } \
77     } \
78     \
79     { \
80         auto vs = v({0,1,0,0}); \
81         EXPECT_EQ(v.data() + offsets[j][1], vs.data()); \
82         EXPECT_EQ(lengths[1], vs.lengths()); \
83         EXPECT_EQ(strides[j][1], vs.strides()); \
84     } \
85     \
86     for (unsigned i = 2;i < 8;i++) \
87     { \
88         SCOPED_TRACE(i); \
89         auto vs = v(irreps[i]); \
90         EXPECT_EQ(v.data() + offsets[j][i], vs.data()); \
91         EXPECT_EQ(lengths[i], vs.lengths()); \
92         EXPECT_EQ(strides[j][i], vs.strides()); \
93     }
94 
TEST(dpd_varray,constructor)95 TEST(dpd_varray, constructor)
96 {
97     double data[168];
98     for (len_type i = 0;i < 168;i++) data[i] = i;
99 
100     dpd_varray<double> v0(1, 2, {{3, 1}, {2, 2}, {1, 2}, {3, 4}}, layouts[0]);
101     dpd_varray_view<double> v00(1, 2, {{3, 1}, {2, 2}, {1, 2}, {3, 4}}, data, layouts[0]);
102 
103     dpd_varray<double> v1;
104     CHECK_DPD_MARRAY_RESET(v1)
105 
106     dpd_varray<double> v2(1, 2, {{3, 1}, {2, 2}, {1, 2}, {3, 4}}, layouts[0]);
107     CHECK_DPD_MARRAY(v2, 0)
108 
109     for (unsigned j = 1;j < 6;j++)
110     {
111         dpd_varray<double> v3(1, 2, {{3, 1}, {2, 2}, {1, 2}, {3, 4}}, layouts[j]);
112         CHECK_DPD_MARRAY(v3, j)
113     }
114 
115     dpd_varray<double> v5(v2);
116     CHECK_DPD_MARRAY(v5, 0)
117 
118     dpd_varray<double> v51(v0);
119     CHECK_DPD_MARRAY(v51, 0)
120     for (len_type i = 0;i < 168;i++) EXPECT_EQ(v51.data()[i], 0.0);
121 
122     dpd_varray<double> v52(v00);
123     CHECK_DPD_MARRAY(v51, 0)
124     for (len_type i = 0;i < 168;i++) EXPECT_EQ(v52.data()[i], i);
125 
126     dpd_varray<double> v6(dpd_varray_view<double>(1, 2, {{3, 1}, {2, 2}, {1, 2}, {3, 4}}, data, layouts[0]));
127     CHECK_DPD_MARRAY(v6, 0)
128     for (len_type i = 0;i < 168;i++) EXPECT_EQ(v52.data()[i], i);
129 }
130 
TEST(dpd_varray,reset)131 TEST(dpd_varray, reset)
132 {
133     double data[168];
134     for (len_type i = 0;i < 168;i++) data[i] = i;
135 
136     dpd_varray<double> v1;
137     dpd_varray_view<double> v3(1, 2, {{3, 1}, {2, 2}, {1, 2}, {3, 4}}, data, layouts[0]);
138     dpd_varray_view<const double> v4(1, 2, {{3, 1}, {2, 2}, {1, 2}, {3, 4}}, data, layouts[0]);
139     dpd_varray<double> v0(1, 2, {{3, 1}, {2, 2}, {1, 2}, {3, 4}}, layouts[0]);
140 
141     CHECK_DPD_MARRAY_RESET(v1)
142 
143     for (unsigned j = 0;j < 6;j++)
144     {
145         v1.reset(1, 2, {{3, 1}, {2, 2}, {1, 2}, {3, 4}}, uninitialized, layouts[j]);
146         CHECK_DPD_MARRAY(v1, j)
147     }
148 
149     v1.reset(v3);
150     CHECK_DPD_MARRAY(v1, 0)
151     for (len_type i = 0;i < 168;i++) EXPECT_EQ(v1.data()[i], i);
152 
153     v1.reset(v4);
154     CHECK_DPD_MARRAY(v1, 0)
155     for (len_type i = 0;i < 168;i++) EXPECT_EQ(v1.data()[i], i);
156 
157     v1.reset(v0);
158     CHECK_DPD_MARRAY(v1, 0)
159     for (len_type i = 0;i < 168;i++) EXPECT_EQ(v1.data()[i], 0.0);
160 
161     v1.reset(dpd_varray_view<double>(1, 2, {{3, 1}, {2, 2}, {1, 2}, {3, 4}}, data, layouts[0]));
162     CHECK_DPD_MARRAY(v1, 0)
163     for (len_type i = 0;i < 168;i++) EXPECT_EQ(v1.data()[i], i);
164 
165     v1.reset(dpd_varray_view<const double>(1, 2, {{3, 1}, {2, 2}, {1, 2}, {3, 4}}, data, layouts[0]));
166     CHECK_DPD_MARRAY(v1, 0)
167     for (len_type i = 0;i < 168;i++) EXPECT_EQ(v1.data()[i], i);
168 
169     v1.reset();
170     CHECK_DPD_MARRAY_RESET(v1)
171 }
172 
TEST(dpd_varray,permute)173 TEST(dpd_varray, permute)
174 {
175     unsigned perm_irreps[8] = {1, 0, 2, 3, 4, 5, 7, 6};
176 
177     dim_vector perms2[6] =
178         {{2,3,1,0}, {1,0,2,3}, {2,3,1,0}, {1,0,2,3}, {2,3,1,0}, {1,0,2,3}};
179 
180     for (unsigned j = 0;j < 6;j++)
181     {
182         SCOPED_TRACE(j);
183 
184         dpd_varray<double> v1(1, 2, {{3, 1}, {2, 2}, {1, 2}, {3, 4}}, layouts[j]);
185 
186         auto v2 = v1.permuted({1, 0, 2, 3});
187         EXPECT_EQ(v1.data(), v2.data());
188         EXPECT_EQ(1u, v2.irrep());
189         EXPECT_EQ(2u, v2.num_irreps());
190         EXPECT_EQ(perms2[j], v2.permutation());
191         EXPECT_EQ((matrix<len_type>{{2, 2}, {3, 1}, {1, 2}, {3, 4}}), v2.lengths());
192 
193         for (unsigned i = 0;i < 8;i++)
194         {
195             SCOPED_TRACE(i);
196             len_vector len(4);
197             stride_vector stride(4);
198             for (unsigned k = 0;k < 4;k++)
199             {
200                 len[k] = lengths[i][perms2[1][k]];
201                 stride[k] = strides[j][i][perms2[1][k]];
202             }
203             auto vs = v2(irreps[perm_irreps[i]]);
204             EXPECT_EQ(v1.data() + offsets[j][i], vs.data());
205             EXPECT_EQ(len, vs.lengths());
206             EXPECT_EQ(stride, vs.strides());
207         }
208     }
209 }
210 
TEST(dpd_varray,block_iteration)211 TEST(dpd_varray, block_iteration)
212 {
213     array<array<int,2>,2> visited;
214 
215     for (int l = 0;l < 6;l++)
216     {
217         SCOPED_TRACE(l);
218 
219         dpd_varray<double> v1(0, 2, {{2, 3}, {1, 2}, {3, 1}}, layouts[l]);
220 
221         visited = {};
222         v1.for_each_block(
223         [&](varray_view<double>&& v3, const irrep_vector& irreps)
224         {
225             EXPECT_EQ(irreps.size(), 3u);
226             unsigned i = irreps[0];
227             unsigned j = irreps[1];
228             unsigned k = irreps[2];
229             EXPECT_LT(i, 2u);
230             EXPECT_LT(j, 2u);
231             EXPECT_LT(k, 2u);
232             EXPECT_EQ(i^j^k, 0u);
233             auto v4 = v1({i, j, k});
234             EXPECT_EQ(v3.data(), v4.data());
235             EXPECT_EQ(v3.lengths(), v4.lengths());
236             EXPECT_EQ(v3.strides(), v4.strides());
237             visited[i][j]++;
238         });
239 
240         for (len_type i = 0;i < 2;i++)
241         {
242             for (len_type j = 0;j < 2;j++)
243             {
244                 EXPECT_EQ(visited[i][j], 1);
245             }
246         }
247 
248         visited = {};
249         v1.for_each_block<3>(
250         [&](marray_view<double,3>&& v3, unsigned i, unsigned j, unsigned k)
251         {
252             EXPECT_LT(i, 2u);
253             EXPECT_LT(j, 2u);
254             EXPECT_LT(k, 2u);
255             EXPECT_EQ(i^j^k, 0u);
256             auto v4 = v1(i, j, k);
257             EXPECT_EQ(v3.data(), v4.data());
258             EXPECT_EQ(v3.lengths(), v4.lengths());
259             EXPECT_EQ(v3.strides(), v4.strides());
260             visited[i][j]++;
261         });
262 
263         for (len_type i = 0;i < 2;i++)
264         {
265             for (len_type j = 0;j < 2;j++)
266             {
267                 EXPECT_EQ(visited[i][j], 1);
268             }
269         }
270     }
271 }
272 
TEST(dpd_varray,element_iteration)273 TEST(dpd_varray, element_iteration)
274 {
275     array<int,31> visited;
276     array<len_vector,3> len = {{{2, 3}, {1, 2}, {3, 1}}};
277 
278     for (int l = 0;l < 6;l++)
279     {
280         SCOPED_TRACE(l);
281 
282         dpd_varray<double> v1(0, 2, len, layouts[l]);
283 
284         visited = {};
285         v1.for_each_element(
286         [&](double& v, const irrep_vector& irreps, const len_vector& pos)
287         {
288             EXPECT_EQ(irreps.size(), 3u);
289             EXPECT_EQ(pos.size(), 3u);
290             unsigned i = irreps[0];
291             unsigned j = irreps[1];
292             unsigned k = irreps[2];
293             len_type a = pos[0];
294             len_type b = pos[1];
295             len_type c = pos[2];
296             EXPECT_LT(i, 2u);
297             EXPECT_LT(j, 2u);
298             EXPECT_LT(k, 2u);
299             EXPECT_GE(a, 0);
300             EXPECT_LT(a, len[0][i]);
301             EXPECT_GE(b, 0);
302             EXPECT_LT(b, len[1][j]);
303             EXPECT_GE(c, 0);
304             EXPECT_LT(c, len[2][k]);
305             EXPECT_EQ(i^j^k, 0u);
306             auto v3 = v1(i, j, k);
307             EXPECT_EQ(&v, &v3(a, b, c));
308             visited[&v - v1.data()]++;
309         });
310 
311         for (unsigned i = 0;i < 31;i++)
312         {
313             EXPECT_EQ(visited[i], 1);
314         }
315 
316         visited = {};
317         v1.for_each_element<3>(
318         [&](double& v, unsigned i, unsigned j, unsigned k, len_type a, len_type b, len_type c)
319         {
320             EXPECT_LT(i, 2u);
321             EXPECT_LT(j, 2u);
322             EXPECT_LT(k, 2u);
323             EXPECT_GE(a, 0);
324             EXPECT_LT(a, len[0][i]);
325             EXPECT_GE(b, 0);
326             EXPECT_LT(b, len[1][j]);
327             EXPECT_GE(c, 0);
328             EXPECT_LT(c, len[2][k]);
329             EXPECT_EQ(i^j^k, 0u);
330             auto v3 = v1(i, j, k);
331             EXPECT_EQ(&v, &v3(a, b, c));
332             visited[&v - v1.data()]++;
333         });
334 
335         for (unsigned i = 0;i < 31;i++)
336         {
337             EXPECT_EQ(visited[i], 1);
338         }
339     }
340 }
341 
TEST(dpd_varray,swap)342 TEST(dpd_varray, swap)
343 {
344     dpd_varray<double> v1(1, 2, {{2, 3}, {2, 1}, {5, 3}}, PREFIX_ROW_MAJOR);
345     dpd_varray<double> v2(0, 2, {{1, 1}, {6, 3}, {2, 4}}, PREFIX_COLUMN_MAJOR);
346 
347     double* data1 = v1.data();
348     double* data2 = v2.data();
349 
350     v1.swap(v2);
351 
352     EXPECT_EQ(data2, v1.data());
353     EXPECT_EQ(0u, v1.irrep());
354     EXPECT_EQ(2u, v1.num_irreps());
355     EXPECT_EQ((dim_vector{0, 1, 2}), v1.permutation());
356     EXPECT_EQ((matrix<len_type>{{1, 1}, {6, 3}, {2, 4}}), v1.lengths());
357 
358     EXPECT_EQ(data1, v2.data());
359     EXPECT_EQ(1u, v2.irrep());
360     EXPECT_EQ(2u, v2.num_irreps());
361     EXPECT_EQ((dim_vector{2, 1, 0}), v2.permutation());
362     EXPECT_EQ((matrix<len_type>{{2, 3}, {2, 1}, {5, 3}}), v2.lengths());
363 
364     swap(v2, v1);
365 
366     EXPECT_EQ(data1, v1.data());
367     EXPECT_EQ(1u, v1.irrep());
368     EXPECT_EQ(2u, v1.num_irreps());
369     EXPECT_EQ((dim_vector{2, 1, 0}), v1.permutation());
370     EXPECT_EQ((matrix<len_type>{{2, 3}, {2, 1}, {5, 3}}), v1.lengths());
371 
372     EXPECT_EQ(data2, v2.data());
373     EXPECT_EQ(0u, v2.irrep());
374     EXPECT_EQ(2u, v2.num_irreps());
375     EXPECT_EQ((dim_vector{0, 1, 2}), v2.permutation());
376     EXPECT_EQ((matrix<len_type>{{1, 1}, {6, 3}, {2, 4}}), v2.lengths());
377 }
378