Gromacs
2024.4
|
#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.