Gromacs  2020.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Macros | Functions | Variables
#include <vector>
#include <gtest/gtest.h>
#include "gromacs/simd/simd.h"
#include "base.h"
#include "data.h"
+ Include dependency graph for simd.h:
+ This graph shows which files directly or indirectly include this file:

Description

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.

Author
Erik Lindahl erik..nosp@m.lind.nosp@m.ahl@s.nosp@m.cili.nosp@m.felab.nosp@m..se

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< realgmx::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.