SYCL: Avoid using no_init read accessor in rocFFT
[alexxy/gromacs.git] / src / gromacs / utility / tests / listoflists.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2018,2019, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 /*! \internal \file
36  * \brief
37  * Tests for the ListOfLists class.
38  *
39  * \author berk Hess <hess@kth.se>
40  * \ingroup module_utility
41  */
42 #include "gmxpre.h"
43
44 #include "gromacs/utility/listoflists.h"
45
46 #include <gmock/gmock.h>
47 #include <gtest/gtest.h>
48
49 #include "testutils/testasserts.h"
50
51 namespace gmx
52 {
53
54 namespace
55 {
56
57 using ::testing::Eq;
58 using ::testing::Pointwise;
59
60 //! Compares all element between two lists of lists
61 template<typename T>
62 void compareLists(const ListOfLists<T>& list, const std::vector<std::vector<T>>& v)
63 {
64     ASSERT_EQ(list.size(), v.size());
65     for (std::size_t i = 0; i < list.size(); i++)
66     {
67         ASSERT_EQ(list[i].size(), v[i].size());
68         EXPECT_THAT(list[i], Pointwise(Eq(), v[i]));
69     }
70 }
71
72 TEST(ListOfLists, EmptyListOfListsWorks)
73 {
74     ListOfLists<char> list;
75
76     EXPECT_EQ(list.size(), 0);
77     EXPECT_EQ(list.empty(), true);
78     EXPECT_EQ(list.numElements(), 0);
79 }
80
81 //! Checks whether append works and stores the data correctly
82 template<typename T>
83 void checkAppend(const std::vector<std::vector<T>> inputLists)
84 {
85     ListOfLists<T> list;
86
87     for (const auto& inputList : inputLists)
88     {
89         list.pushBack(inputList);
90     }
91     EXPECT_EQ(list.size(), 2);
92     compareLists(list, inputLists);
93 }
94
95 TEST(ListOfLists, AppendWorks)
96 {
97     const std::vector<std::vector<char>> v = { { 5, 3 }, { char(-1), 7, 4 } };
98
99     checkAppend(v);
100 }
101
102 TEST(ListOfLists, EmptyListWorks)
103 {
104     ListOfLists<char> list;
105
106     std::vector<char> v = { 5, 3 };
107     list.pushBack(v);
108     list.pushBack({});
109     EXPECT_EQ(list.size(), 2);
110     auto a = list[1];
111     EXPECT_EQ(a.empty(), true);
112 }
113
114 TEST(ListOfLists, AppendAccessWorks)
115 {
116     const std::vector<std::vector<char>> v = { { 5, 3 }, { char(-1), 4 } };
117
118     ListOfLists<char> list;
119     list.pushBack(v[0]);
120     list.pushBackListOfSize(v[1].size());
121     std::copy(v[1].begin(), v[1].end(), list.back().begin());
122     compareLists(list, v);
123 }
124
125 TEST(ListOfLists, ClearWorks)
126 {
127     ListOfLists<char> list;
128
129     std::vector<char> v = { 5, 3 };
130     list.pushBack(v);
131     list.pushBack({});
132     list.clear();
133     EXPECT_EQ(list.empty(), true);
134     EXPECT_EQ(list.numElements(), 0);
135 }
136
137 TEST(ListOfLists, OutOfRangeAccessThrows)
138 {
139     ListOfLists<char> list;
140
141     std::vector<char> v = { 5, 3 };
142     EXPECT_THROW(list.at(1), std::out_of_range);
143 }
144
145 TEST(ListOfLists, FrontAndBackWork)
146 {
147     ListOfLists<char> list1;
148     std::vector<char> v1{ { 3, 4 } };
149     list1.pushBack(v1);
150     EXPECT_THAT(list1.front(), Pointwise(Eq(), v1));
151     EXPECT_THAT(list1.back(), Pointwise(Eq(), v1));
152
153     std::vector<char> v2{ { 12, 63, 1 } };
154     list1.pushBack(v2);
155     EXPECT_THAT(list1.front(), Pointwise(Eq(), v1));
156     EXPECT_THAT(list1.back(), Pointwise(Eq(), v2));
157
158     list1.pushBack({});
159     EXPECT_THAT(list1.front(), Pointwise(Eq(), v1));
160     EXPECT_THAT(list1.back(), Pointwise(Eq(), std::vector<char>{}));
161
162     std::vector<char> v3{ { 99, 0, char(-1) } };
163     list1.pushBack(v3);
164     EXPECT_THAT(list1.front(), Pointwise(Eq(), v1));
165     EXPECT_THAT(list1.back(), Pointwise(Eq(), v3));
166
167     ListOfLists<char> list2;
168     list2.pushBack(v2);
169     EXPECT_THAT(list2.front(), Pointwise(Eq(), v2));
170     EXPECT_THAT(list2.back(), Pointwise(Eq(), v2));
171
172     list2.appendListOfLists(list1);
173     EXPECT_THAT(list2.front(), Pointwise(Eq(), v2));
174     EXPECT_THAT(list2.back(), Pointwise(Eq(), v3));
175     EXPECT_EQ(list2.back().size(), v3.size());
176
177     list2.pushBackListOfSize(1);
178     EXPECT_EQ(list2.back().size(), 1);
179 }
180
181 TEST(ListOfLists, ExtractsAndRestores)
182 {
183     const std::vector<std::vector<char>> v({ { 5, 3 }, {}, { char(-1), 4 } });
184
185     ListOfLists<char> list1;
186     for (const auto& vlist : v)
187     {
188         list1.pushBack(vlist);
189     }
190
191     auto             listRanges = list1.listRangesView();
192     auto             elements   = list1.elementsView();
193     std::vector<int> listRangesVector;
194     listRangesVector.insert(listRangesVector.begin(), listRanges.begin(), listRanges.end());
195     std::vector<char> elementsVector;
196     elementsVector.insert(elementsVector.begin(), elements.begin(), elements.end());
197     ListOfLists<char> list2(std::move(listRangesVector), std::move(elementsVector));
198     compareLists(list2, v);
199 }
200
201 TEST(ListOfLists, AppendsListOfListsWithOffset)
202 {
203     std::vector<std::vector<char>> v = { { 5, 3 }, { 2, char(-1) }, { 4 } };
204
205     ListOfLists<char> list1;
206     ListOfLists<char> list2;
207
208     list1.pushBack(v[0]);
209     list2.pushBack(v[1]);
210     list2.pushBack(v[2]);
211     const char offset = 2;
212     list1.appendListOfLists(list2, offset);
213     for (std::size_t i = 1; i < v.size(); i++)
214     {
215         for (auto& elem : v[i])
216         {
217             elem += offset;
218         }
219     }
220     compareLists(list1, v);
221 }
222
223 } // namespace
224
225 } // namespace gmx