Exemplo n.º 1
0
TEST_F(SimdIntegerTest, slli)
{
    GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(4194304), SimdInt32(2) << 21); // 2 << 21 = 4194304
}
Exemplo n.º 2
0
}

TEST_F(SimdIntegerTest, mul)
{
    GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(4, 10, 18), iSimd_1_2_3 * iSimd_4_5_6);            // 2*3=6 (short mul)
    GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(268435456), SimdInt32(16384) * SimdInt32(16384) ); // 16384*16384 = 268435456 (long mul)
}

TEST_F(SimdIntegerTest, slli)
{
    GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(4194304), SimdInt32(2) << 21); // 2 << 21 = 4194304
}

TEST_F(SimdIntegerTest, srli)
{
    GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(4), SimdInt32(4194304) >> 20); // 4194304 >> 20 = 4
}
#endif                                                                     // GMX_SIMD_HAVE_INT32_ARITHMETICS

#if GMX_SIMD_HAVE_INT32_LOGICAL
TEST_F(SimdIntegerTest, and)
{
    GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(0xC0C0C0C0), iSimd_0xF0F0F0F0 & iSimd_0xCCCCCCCC);
}

TEST_F(SimdIntegerTest, andNot)
{
    GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(0x0C0C0C0C), andNot(iSimd_0xF0F0F0F0, iSimd_0xCCCCCCCC));
}

TEST_F(SimdIntegerTest, or)
Exemplo n.º 3
0
TEST_F(SimdIntegerTest, mul)
{
    GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(4, 10, 18), iSimd_1_2_3 * iSimd_4_5_6);            // 2*3=6 (short mul)
    GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(268435456), SimdInt32(16384) * SimdInt32(16384) ); // 16384*16384 = 268435456 (long mul)
}
Exemplo n.º 4
0
namespace test
{

/*! \cond internal */
/*! \addtogroup module_simd */
/*! \{ */

/* Unfortunately we cannot keep static SIMD constants in the test fixture class.
 * The problem is that SIMD memory need to be aligned, and in particular
 * this applies to automatic storage of variables in classes. For SSE registers
 * this means 16-byte alignment (which seems to work), but AVX requires 32-bit
 * alignment. At least both gcc-4.7.3 and Apple clang-5.0 (OS X 10.9) fail to
 * align these variables when they are stored as data in a class.
 *
 * In theory we could set some of these on-the-fly e.g. with setSimdRealFrom3R()
 * instead (although that would mean repeating code between tests), but many of
 * the constants depend on the current precision not to mention they
 * occasionally have many digits that need to be exactly right, and keeping
 * them in a single place makes sure they are consistent.
 */
#ifdef GMX_SIMD_HAVE_REAL
const gmx_simd_real_t rSimd_1_2_3    = setSimdRealFrom3R(1, 2, 3);
const gmx_simd_real_t rSimd_4_5_6    = setSimdRealFrom3R(4, 5, 6);
const gmx_simd_real_t rSimd_7_8_9    = setSimdRealFrom3R(7, 8, 9);
const gmx_simd_real_t rSimd_5_7_9    = setSimdRealFrom3R(5, 7, 9);
const gmx_simd_real_t rSimd_m1_m2_m3 = setSimdRealFrom3R(-1, -2, -3);
const gmx_simd_real_t rSimd_3_1_4    = setSimdRealFrom3R(3, 1, 4);
const gmx_simd_real_t rSimd_m3_m1_m4 = setSimdRealFrom3R(-3, -1, -4);
const gmx_simd_real_t rSimd_2p25     = setSimdRealFrom1R(2.25);
const gmx_simd_real_t rSimd_3p75     = setSimdRealFrom1R(3.75);
const gmx_simd_real_t rSimd_m2p25    = setSimdRealFrom1R(-2.25);
const gmx_simd_real_t rSimd_m3p75    = setSimdRealFrom1R(-3.75);
const gmx_simd_real_t rSimd_Exp      = setSimdRealFrom3R( 1.4055235171027452623914516e+18,
                                                          5.3057102734253445623914516e-13,
                                                          -2.1057102745623934534514516e+16);
#    if (defined GMX_SIMD_HAVE_DOUBLE) && (defined GMX_DOUBLE)
// Make sure we also test exponents outside single precision when we use double
const gmx_simd_real_t rSimd_ExpDouble = setSimdRealFrom3R( 6.287393598732017379054414e+176,
                                                           8.794495252903116023030553e-140,
                                                           -3.637060701570496477655022e+202);
#    endif
#endif  // GMX_SIMD_HAVE_REAL
#ifdef GMX_SIMD_HAVE_INT32
const gmx_simd_int32_t iSimd_1_2_3      = setSimdIntFrom3I(1, 2, 3);
const gmx_simd_int32_t iSimd_4_5_6      = setSimdIntFrom3I(4, 5, 6);
const gmx_simd_int32_t iSimd_7_8_9      = setSimdIntFrom3I(7, 8, 9);
const gmx_simd_int32_t iSimd_5_7_9      = setSimdIntFrom3I(5, 7, 9);
const gmx_simd_int32_t iSimd_1M_2M_3M   = setSimdIntFrom3I(1000000, 2000000, 3000000);
const gmx_simd_int32_t iSimd_4M_5M_6M   = setSimdIntFrom3I(4000000, 5000000, 6000000);
const gmx_simd_int32_t iSimd_5M_7M_9M   = setSimdIntFrom3I(5000000, 7000000, 9000000);
const gmx_simd_int32_t iSimd_0xF0F0F0F0 = setSimdIntFrom1I(0xF0F0F0F0);
const gmx_simd_int32_t iSimd_0xCCCCCCCC = setSimdIntFrom1I(0xCCCCCCCC);
#endif  // GMX_SIMD_HAVE_INT32

#ifdef GMX_SIMD_HAVE_REAL
::std::vector<real>
simdReal2Vector(const gmx_simd_real_t simd)
{
    real                mem[GMX_SIMD_REAL_WIDTH*2];
    real *              p = gmx_simd_align_r(mem);

    gmx_simd_store_r(p, simd);
    std::vector<real>   v(p, p+GMX_SIMD_REAL_WIDTH);

    return v;
}

gmx_simd_real_t
vector2SimdReal(const std::vector<real> &v)
{
    real                mem[GMX_SIMD_REAL_WIDTH*2];
    real *              p = gmx_simd_align_r(mem);

    for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++)
    {
        p[i] = v[i % v.size()];  // repeat vector contents to fill simd width
    }
    return gmx_simd_load_r(p);
}

gmx_simd_real_t
setSimdRealFrom3R(real r0, real r1, real r2)
{
    std::vector<real> v(3);
    v[0] = r0;
    v[1] = r1;
    v[2] = r2;
    return vector2SimdReal(v);
}

gmx_simd_real_t
setSimdRealFrom1R(real value)
{
    std::vector<real> v(GMX_SIMD_REAL_WIDTH);
    for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++)
    {
        v[i] = value;
    }
    return vector2SimdReal(v);
}

testing::AssertionResult
SimdTest::compareSimdRealUlp(const char *  refExpr,     const char *  tstExpr,
                             const gmx_simd_real_t ref, const gmx_simd_real_t tst)
{
    return compareVectorRealUlp(refExpr, tstExpr, simdReal2Vector(ref), simdReal2Vector(tst));
}

testing::AssertionResult
SimdTest::compareSimdRealEq(const char * refExpr, const char * tstExpr,
                            const gmx_simd_real_t ref, const gmx_simd_real_t tst)
{
    return compareVectorEq(refExpr, tstExpr, simdReal2Vector(ref), simdReal2Vector(tst));
}

#endif  // GMX_SIMD_HAVE_REAL

#ifdef GMX_SIMD_HAVE_INT32
std::vector<int>
simdInt2Vector(const gmx_simd_int32_t simd)
{
    int                 mem[GMX_SIMD_INT32_WIDTH*2];
    int *               p = gmx_simd_align_i(mem);

    gmx_simd_store_i(p, simd);
    std::vector<int>    v(p, p+GMX_SIMD_INT32_WIDTH);

    return v;
}

gmx_simd_int32_t
vector2SimdInt(const std::vector<int> &v)
{
    int                 mem[GMX_SIMD_INT32_WIDTH*2];
    int *               p = gmx_simd_align_i(mem);

    for (int i = 0; i < GMX_SIMD_INT32_WIDTH; i++)
    {
        p[i] = v[i % v.size()];  // repeat vector contents to fill simd width
    }
    return gmx_simd_load_i(p);
}

gmx_simd_int32_t
setSimdIntFrom3I(int i0, int i1, int i2)
{
    std::vector<int> v(3);
    v[0] = i0;
    v[1] = i1;
    v[2] = i2;
    return vector2SimdInt(v);
}

gmx_simd_int32_t
setSimdIntFrom1I(int value)
{
    std::vector<int> v(GMX_SIMD_INT32_WIDTH);
    for (int i = 0; i < GMX_SIMD_INT32_WIDTH; i++)
    {
        v[i] = value;
    }
    return vector2SimdInt(v);
}

::testing::AssertionResult
SimdTest::compareSimdInt32(const char *  refExpr,      const char *  tstExpr,
                           const gmx_simd_int32_t ref, const gmx_simd_int32_t tst)
{
    return compareVectorEq(refExpr, tstExpr, simdInt2Vector(ref), simdInt2Vector(tst));
}

#endif  // GMX_SIMD_HAVE_INT32

/*! \} */
/*! \endcond */

}      // namespace