Gromacs
2022.2
|
#include <vector>
#include <gtest/gtest.h>
#include "gromacs/simd/simd.h"
#include "base.h"
#include "data.h"
Declares fixture for testing of normal SIMD (not SIMD4) functionality.
The SIMD tests are both simple and complicated. The actual testing logic is very straightforward since we just need to test single values against the math library, and for some math functions we need to do it in a loop. This could have been achieved in minutes with the default Google Test tools, if it wasn't for the problem that we cannot access or compare SIMD contents directly without using lots of other SIMD functionality. For this reason we have separate the basic testing of load/store operations into a separate bootstrapping test. Once this works, we use a set of utility routines to convert SIMD contents to/from std:vector<> and perform the rest of the tests, which then can farmed out to the base class SimdBaseTest that is common to SIMD and SIMD4.
Another complication is that the width of the SIMD implementation will depend on the hardware and precision. For some simple operations it is sufficient to set all SIMD elements to the same value, and check that the result is present in all elements. However, for a few more complex instructions that might rely on shuffling under-the-hood it is important that we can test operations with different elements. We achieve this by having test code that can initialize a SIMD variable from an std::vector of arbitrary length; the vector is simply repeated to fill all elements in the SIMD variable. We also have similar routines to compare a SIMD result with values in a vector, which returns true iff all elements match.
This way we can write simple tests that use different values for all SIMD elements. Personally I like using vectors of length 3, since this means there are no simple repeated patterns in low/high halves of SIMD variables that are 2,4,8,or 16 elements wide, and we still don't have to care about the exact SIMD width of the underlying implementation.
Note that this utility uses a few SIMD load/store instructions internally - those have been tested separately in the bootstrap_loadstore.cpp file.
Classes | |
class | gmx::test::SimdTest |
Test fixture for SIMD tests. More... | |
Macros | |
#define | GMX_EXPECT_SIMD_REAL_EQ(ref, tst) EXPECT_PRED_FORMAT2(compareSimdEq, ref, tst) |
Test if a SIMD real is bitwise identical to reference SIMD value. | |
#define | GMX_EXPECT_SIMD_EQ(ref, tst) EXPECT_PRED_FORMAT2(compareSimdEq, ref, tst) |
Test if a SIMD is bitwise identical to reference SIMD value. | |
#define | GMX_EXPECT_SIMD_REAL_NEAR(ref, tst) EXPECT_PRED_FORMAT2(compareSimdRealUlp, ref, tst) |
Test if a SIMD real is within tolerance of reference SIMD value. | |
#define | GMX_EXPECT_SIMD_INT_EQ(ref, tst) EXPECT_PRED_FORMAT2(compareSimdEq, ref, tst) |
Macro that checks SIMD integer expression against SIMD or reference int. More... | |
Functions | |
::std::vector< real > | gmx::test::simdReal2Vector (SimdReal simd) |
Convert SIMD real to std::vector<real>. More... | |
SimdReal | gmx::test::vector2SimdReal (const std::vector< real > &v) |
Return floating-point SIMD value from std::vector<real>. More... | |
SimdReal | gmx::test::setSimdRealFrom3R (real r0, real r1, real r2) |
Set SIMD register contents from three real values. More... | |
SimdReal | gmx::test::setSimdRealFrom1R (real value) |
Set SIMD register contents from single real value. More... | |
std::vector< std::int32_t > | gmx::test::simdInt2Vector (SimdInt32 simd) |
Convert SIMD integer to std::vector<int>. More... | |
SimdInt32 | gmx::test::vector2SimdInt (const std::vector< std::int32_t > &v) |
Return 32-bit integer SIMD value from std::vector<int>. More... | |
SimdInt32 | gmx::test::setSimdIntFrom3I (int i0, int i1, int i2) |
Set SIMD register contents from three int values. More... | |
SimdInt32 | gmx::test::setSimdIntFrom1I (int value) |
Set SIMD register contents from single integer value. More... | |
Variables | |
const SimdReal | gmx::test::rSimd_Bits1 |
Pattern F0 repeated to fill single/double. | |
const SimdReal | gmx::test::rSimd_Bits2 |
Pattern CC repeated to fill single/double. | |
const SimdReal | gmx::test::rSimd_Bits3 |
Pattern C0 repeated to fill single/double. | |
const SimdReal | gmx::test::rSimd_Bits4 |
Pattern 0C repeated to fill single/double. | |
const SimdReal | gmx::test::rSimd_Bits5 |
Pattern FC repeated to fill single/double. | |
const SimdReal | gmx::test::rSimd_Bits6 |
Pattern 3C repeated to fill single/double. | |