arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/spqlios/lib/test/spqlios_reim_conversions_test.cpp
spqlios/lib/test/spqlios_reim_conversions_test.cppRaw
  1#include <gtest/gtest.h>
  2#include <spqlios/reim/reim_fft_internal.h>
  3
  4#include "testlib/test_commons.h"
  5
  6TEST(reim_conversions, reim_to_tnx) {
  7  for (uint32_t m : {1, 2, 64, 128, 512}) {
  8    for (double divisor : {1, 2, int(m)}) {
  9      for (uint32_t log2overhead : {1, 2, 10, 18, 35, 42}) {
 10        double maxdiff = pow(2., log2overhead - 50);
 11        std::vector<double> data(2 * m);
 12        std::vector<double> dout(2 * m);
 13        for (uint64_t i = 0; i < 2 * m; ++i) {
 14          data[i] = (uniform_f64_01() - 0.5) * pow(2., log2overhead + 1) * divisor;
 15        }
 16        REIM_TO_TNX_PRECOMP* p = new_reim_to_tnx_precomp(m, divisor, 18);
 17        reim_to_tnx_ref(p, dout.data(), data.data());
 18        for (uint64_t i = 0; i < 2 * m; ++i) {
 19          ASSERT_LE(fabs(dout[i]), 0.5);
 20          double diff = dout[i] - data[i] / divisor;
 21          double fracdiff = diff - rint(diff);
 22          ASSERT_LE(fabs(fracdiff), maxdiff);
 23        }
 24        delete_reim_to_tnx_precomp(p);
 25      }
 26    }
 27  }
 28}
 29
 30#ifdef __x86_64__
 31TEST(reim_conversions, reim_to_tnx_ref_vs_avx) {
 32  for (uint32_t m : {8, 16, 64, 128, 512}) {
 33    for (double divisor : {1, 2, int(m)}) {
 34      for (uint32_t log2overhead : {1, 2, 10, 18, 35, 42}) {
 35        // double maxdiff = pow(2., log2overhead - 50);
 36        std::vector<double> data(2 * m);
 37        std::vector<double> dout1(2 * m);
 38        std::vector<double> dout2(2 * m);
 39        for (uint64_t i = 0; i < 2 * m; ++i) {
 40          data[i] = (uniform_f64_01() - 0.5) * pow(2., log2overhead + 1) * divisor;
 41        }
 42        REIM_TO_TNX_PRECOMP* p = new_reim_to_tnx_precomp(m, divisor, 18);
 43        reim_to_tnx_ref(p, dout1.data(), data.data());
 44        reim_to_tnx_avx(p, dout2.data(), data.data());
 45        for (uint64_t i = 0; i < 2 * m; ++i) {
 46          ASSERT_LE(fabs(dout1[i] - dout2[i]), 0.);
 47        }
 48        delete_reim_to_tnx_precomp(p);
 49      }
 50    }
 51  }
 52}
 53#endif
 54
 55typedef typeof(reim_from_znx64_ref) reim_from_znx64_f;
 56
 57void test_reim_from_znx64(reim_from_znx64_f reim_from_znx64, uint64_t maxbnd) {
 58  for (uint32_t m : {4, 8, 16, 64, 16384}) {
 59    REIM_FROM_ZNX64_PRECOMP* p = new_reim_from_znx64_precomp(m, maxbnd);
 60    std::vector<int64_t> data(2 * m);
 61    std::vector<double> dout(2 * m);
 62    for (uint64_t i = 0; i < 2 * m; ++i) {
 63      int64_t magnitude = int64_t(uniform_u64() % (maxbnd + 1));
 64      data[i] = uniform_i64() >> (63 - magnitude);
 65      REQUIRE_DRAMATICALLY(abs(data[i]) <= (INT64_C(1) << magnitude), "pb");
 66    }
 67    reim_from_znx64(p, dout.data(), data.data());
 68    for (uint64_t i = 0; i < 2 * m; ++i) {
 69      ASSERT_EQ(dout[i], double(data[i])) << dout[i] << " " << data[i];
 70    }
 71    delete_reim_from_znx64_precomp(p);
 72  }
 73}
 74
 75TEST(reim_conversions, reim_from_znx64) {
 76  for (uint64_t maxbnd : {50}) {
 77    test_reim_from_znx64(reim_from_znx64, maxbnd);
 78  }
 79}
 80TEST(reim_conversions, reim_from_znx64_ref) { test_reim_from_znx64(reim_from_znx64_ref, 50); }
 81#ifdef __x86_64__
 82TEST(reim_conversions, reim_from_znx64_avx2_bnd50_fma) { test_reim_from_znx64(reim_from_znx64_bnd50_fma, 50); }
 83#endif
 84
 85typedef typeof(reim_to_znx64_ref) reim_to_znx64_f;
 86
 87void test_reim_to_znx64(reim_to_znx64_f reim_to_znx64_fcn, int64_t maxbnd) {
 88  for (uint32_t m : {4, 8, 16, 64, 16384}) {
 89    for (double divisor : {1, 2, int(m)}) {
 90      REIM_TO_ZNX64_PRECOMP* p = new_reim_to_znx64_precomp(m, divisor, maxbnd);
 91      std::vector<double> data(2 * m);
 92      std::vector<int64_t> dout(2 * m);
 93      for (uint64_t i = 0; i < 2 * m; ++i) {
 94        int64_t magnitude = int64_t(uniform_u64() % (maxbnd + 11)) - 10;
 95        data[i] = (uniform_f64_01() - 0.5) * pow(2., magnitude + 1) * divisor;
 96      }
 97      reim_to_znx64_fcn(p, dout.data(), data.data());
 98      for (uint64_t i = 0; i < 2 * m; ++i) {
 99        ASSERT_LE(dout[i] - data[i] / divisor, 0.5) << dout[i] << " " << data[i];
100      }
101      delete_reim_to_znx64_precomp(p);
102    }
103  }
104}
105
106TEST(reim_conversions, reim_to_znx64) {
107  for (uint64_t maxbnd : {63, 50}) {
108    test_reim_to_znx64(reim_to_znx64, maxbnd);
109  }
110}
111TEST(reim_conversions, reim_to_znx64_ref) { test_reim_to_znx64(reim_to_znx64_ref, 63); }
112#ifdef __x86_64__
113TEST(reim_conversions, reim_to_znx64_avx2_bnd63_fma) { test_reim_to_znx64(reim_to_znx64_avx2_bnd63_fma, 63); }
114TEST(reim_conversions, reim_to_znx64_avx2_bnd50_fma) { test_reim_to_znx64(reim_to_znx64_avx2_bnd50_fma, 50); }
115#endif