SYCL: Avoid using no_init read accessor in rocFFT
[alexxy/gromacs.git] / src / gromacs / simd / tests / simd4.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2014,2015,2017,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 #ifndef GMX_SIMD_TESTS_SIMD4_H
36 #define GMX_SIMD_TESTS_SIMD4_H
37
38 /*! \internal \file
39  * \brief
40  * Declares fixture for testing of SIMD4 functionality.
41  *
42  * This files specializes the common base test utilities to be used
43  * for SIMD4 variables. For detailed documentation, check out the normal
44  * SIMD test classes and files.
45  *
46  * \author Erik Lindahl <erik.lindahl@scilifelab.se>
47  * \ingroup module_simd
48  */
49
50 #include <vector>
51
52 #include <gtest/gtest.h>
53
54 #include "gromacs/simd/simd.h"
55
56 #include "base.h"
57 #include "data.h"
58
59 #if GMX_SIMD
60
61 namespace gmx
62 {
63 namespace test
64 {
65
66 /*! \cond internal */
67 /*! \addtogroup module_simd */
68 /*! \{ */
69
70 #    if GMX_SIMD4_HAVE_REAL
71 extern const Simd4Real rSimd4_c0c1c2; //!< c0,c1,c2 repeated
72 extern const Simd4Real rSimd4_c3c4c5; //!< c3,c4,c5 repeated
73 extern const Simd4Real rSimd4_c6c7c8; //!< c6,c7,c8 repeated
74 extern const Simd4Real rSimd4_c3c0c4; //!< c3,c0,c4 repeated
75 extern const Simd4Real rSimd4_c4c6c8; //!< c4,c6,c8 repeated
76 extern const Simd4Real rSimd4_c7c2c3; //!< c7,c2,c3 repeated
77 extern const Simd4Real rSimd4_m0m1m2; //!< -c0,-c1,-c2 repeated
78 extern const Simd4Real rSimd4_m3m0m4; //!< -c3,-c0,-c4 repeated
79 extern const Simd4Real rSimd4_2p25;   //!< Value that rounds down.
80 extern const Simd4Real rSimd4_3p75;   //!< Value that rounds up.
81 extern const Simd4Real rSimd4_m2p25;  //!< Negative value that rounds up.
82 extern const Simd4Real rSimd4_m3p75;  //!< Negative value that rounds down.
83 //! Three large floating-point values whose exponents are >32.
84 extern const Simd4Real rSimd4_Exp;
85
86 #        if GMX_SIMD_HAVE_LOGICAL
87 extern const Simd4Real rSimd4_logicalA;         //!< Bit pattern to test logical ops
88 extern const Simd4Real rSimd4_logicalB;         //!< Bit pattern to test logical ops
89 extern const Simd4Real rSimd4_logicalResultOr;  //!< Result or bitwise 'or' of A and B
90 extern const Simd4Real rSimd4_logicalResultAnd; //!< Result or bitwise 'and' of A and B
91 #        endif                                  // GMX_SIMD_HAVE_LOGICAL
92
93 extern const Simd4Real rSimd4_Bits1; //!< Pattern F0 repeated to fill single/double.
94 extern const Simd4Real rSimd4_Bits2; //!< Pattern CC repeated to fill single/double.
95 extern const Simd4Real rSimd4_Bits3; //!< Pattern C0 repeated to fill single/double.
96 extern const Simd4Real rSimd4_Bits4; //!< Pattern 0C repeated to fill single/double.
97 extern const Simd4Real rSimd4_Bits5; //!< Pattern FC repeated to fill single/double.
98 extern const Simd4Real rSimd4_Bits6; //!< Pattern 3C repeated to fill single/double.
99
100 /*! \internal
101  * \brief
102  * Test fixture for SIMD4 tests - contains test settings.
103  *
104  * This is a very simple test fixture that basically just takes the common
105  * SIMD/SIMD4 functionality from SimdBaseTest and creates wrapper routines
106  * specific for SIMD4 functionality.
107  */
108 class Simd4Test : public SimdBaseTest
109 {
110 public:
111     /*! \brief Compare two real SIMD4 variables for approximate equality.
112      *
113      * This is an internal implementation routine. YOu should always use
114      * GMX_EXPECT_SIMD4_REAL_NEAR() instead.
115      *
116      * This routine is designed according to the Google test specs, so the char
117      * strings will describe the arguments to the macro.
118      *
119      * The comparison is applied to each element, and it returns true if each element
120      * in the SIMD4 test variable is within the class tolerances of the corresponding
121      * reference element.
122      */
123     ::testing::AssertionResult
124     compareSimd4RealUlp(const char* refExpr, const char* tstExpr, Simd4Real ref, Simd4Real tst);
125
126     /*! \brief Compare two real SIMD4 variables for exact equality.
127      *
128      * This is an internal implementation routine. YOu should always use
129      * GMX_EXPECT_SIMD4_REAL_NEAR() instead.
130      *
131      * This routine is designed according to the Google test specs, so the char
132      * strings will describe the arguments to the macro.
133      *
134      * The comparison is applied to each element, and it returns true if each element
135      * in the SIMD4 test variable is within the class tolerances of the corresponding
136      * reference element.
137      */
138     ::testing::AssertionResult
139     compareSimd4RealEq(const char* refExpr, const char* tstExpr, Simd4Real ref, Simd4Real tst);
140 };
141
142 /*! \brief Convert SIMD4 real to std::vector<real>.
143  *
144  * The returned vector will have the same length as the SIMD4 width.
145  */
146 std::vector<real> simd4Real2Vector(Simd4Real simd4);
147
148 /*! \brief Return floating-point SIMD4 value from std::vector<real>.
149  *
150  * If the vector is longer than SIMD4 width, only the first elements will be used.
151  * If it is shorter, the contents will be repeated to fill the SIMD4 register.
152  */
153 Simd4Real vector2Simd4Real(const std::vector<real>& v);
154
155 /*! \brief Set SIMD4 register contents from three real values.
156  *
157  * It might seem stupid to use three values when we know that the SIMD4 width
158  * is 4, but it simplifies the test organization when the SIMD and SIMD4 tests
159  * are completely symmetric.
160  */
161 Simd4Real setSimd4RealFrom3R(real r0, real r1, real r2);
162
163 /*! \brief Set SIMD4 register contents from single real value.
164  *
165  * All elements is set from the given value. This is effectively the same
166  * operation as simd4Set1(), but is implemented using only load/store
167  * operations that have been tested separately in the bootstrapping tests.
168  */
169 Simd4Real setSimd4RealFrom1R(real value);
170
171 /*! \brief Test if a SIMD4 real is bitwise identical to reference SIMD4 value. */
172 #        define GMX_EXPECT_SIMD4_REAL_EQ(ref, tst) EXPECT_PRED_FORMAT2(compareSimd4RealEq, ref, tst)
173
174 /*! \brief Test if a SIMD4 real is within tolerance of reference SIMD4 value. */
175 #        define GMX_EXPECT_SIMD4_REAL_NEAR(ref, tst) \
176             EXPECT_PRED_FORMAT2(compareSimd4RealUlp, ref, tst)
177
178 #    endif // GMX_SIMD4_HAVE_REAL
179
180 /*! \} */
181 /*! \endcond */
182
183 } // namespace test
184 } // namespace gmx
185
186 #endif // GMX_SIMD
187
188 #endif // GMX_SIMD_TESTS_SIMD4_H