rsimd

Make SIMD instruction sets easier to use
git clone git://git.meso-star.fr/rsimd.git
Log | Files | Refs | README | LICENSE

test_math8.c (6612B)


      1 /* Copyright (C) 2013-2021 Vincent Forest (vaplv@free.fr)
      2  *
      3  * The RSIMD library is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published
      5  * by the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * The RSIMD library is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with the RSIMD library. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #define _POSIX_C_SOURCE 200112L
     17 
     18 #include "rsimd.h"
     19 #include "math.h"
     20 
     21 #include <math.h>
     22 
     23 #define LOG2E 1.4426950408889634074 /* log_2 e */
     24 #define LN10 2.30258509299404568402 /* log_e 10 */
     25 
     26 #define CHKV8_EPS(V, Ref, Eps) {                                               \
     27   CHK(eq_eps(v4f_x(v8f_abcd(V)), Ref[0], fabsf(Ref[0]) * Eps));                \
     28   CHK(eq_eps(v4f_y(v8f_abcd(V)), Ref[1], fabsf(Ref[1]) * Eps));                \
     29   CHK(eq_eps(v4f_z(v8f_abcd(V)), Ref[2], fabsf(Ref[2]) * Eps));                \
     30   CHK(eq_eps(v4f_w(v8f_abcd(V)), Ref[3], fabsf(Ref[3]) * Eps));                \
     31   CHK(eq_eps(v4f_x(v8f_efgh(V)), Ref[4], fabsf(Ref[4]) * Eps));                \
     32   CHK(eq_eps(v4f_y(v8f_efgh(V)), Ref[5], fabsf(Ref[5]) * Eps));                \
     33   CHK(eq_eps(v4f_z(v8f_efgh(V)), Ref[6], fabsf(Ref[6]) * Eps));                \
     34   CHK(eq_eps(v4f_w(v8f_efgh(V)), Ref[7], fabsf(Ref[7]) * Eps));                \
     35 } (void)0
     36 
     37 #define CHKV8_FUNC_EPS(V, Func, Eps) {                                         \
     38   const v8f_T r__ = v8f_##Func(V);                                             \
     39   float ref__[8];                                                              \
     40   ref__[0] = (float)Func(v4f_x(v8f_abcd(V)));                                  \
     41   ref__[1] = (float)Func(v4f_y(v8f_abcd(V)));                                  \
     42   ref__[2] = (float)Func(v4f_z(v8f_abcd(V)));                                  \
     43   ref__[3] = (float)Func(v4f_w(v8f_abcd(V)));                                  \
     44   ref__[4] = (float)Func(v4f_x(v8f_efgh(V)));                                  \
     45   ref__[5] = (float)Func(v4f_y(v8f_efgh(V)));                                  \
     46   ref__[6] = (float)Func(v4f_z(v8f_efgh(V)));                                  \
     47   ref__[7] = (float)Func(v4f_w(v8f_efgh(V)));                                  \
     48   CHKV8_EPS(r__, ref__, Eps);                                                  \
     49 } (void)0
     50 
     51 static void
     52 test_trigo(void)
     53 {
     54   v8f_T i, j, k;
     55   float ref[8];
     56 
     57   i = v8f_set
     58     ((float)PI/2.f, (float)PI/3.f, (float)PI/4.f, (float)PI/6.f,
     59      (float)PI/8.f, (float)PI/7.f, (float)PI/16.f, (float)PI/9.f);
     60 
     61   CHKV8_FUNC_EPS(i, cos, 1.e-6f);
     62   CHKV8_FUNC_EPS(i, sin, 1.e-6f);
     63 
     64   v8f_sincos(i, &k, &j);
     65   ref[0] = (float)sin(v4f_x(v8f_abcd(i)));
     66   ref[1] = (float)sin(v4f_y(v8f_abcd(i)));
     67   ref[2] = (float)sin(v4f_z(v8f_abcd(i)));
     68   ref[3] = (float)sin(v4f_w(v8f_abcd(i)));
     69   ref[4] = (float)sin(v4f_x(v8f_efgh(i)));
     70   ref[5] = (float)sin(v4f_y(v8f_efgh(i)));
     71   ref[6] = (float)sin(v4f_z(v8f_efgh(i)));
     72   ref[7] = (float)sin(v4f_w(v8f_efgh(i)));
     73   CHKV8_EPS(k, ref, 1.e-6f);
     74   ref[0] = (float)cos(v4f_x(v8f_abcd(i)));
     75   ref[1] = (float)cos(v4f_y(v8f_abcd(i)));
     76   ref[2] = (float)cos(v4f_z(v8f_abcd(i)));
     77   ref[3] = (float)cos(v4f_w(v8f_abcd(i)));
     78   ref[4] = (float)cos(v4f_x(v8f_efgh(i)));
     79   ref[5] = (float)cos(v4f_y(v8f_efgh(i)));
     80   ref[6] = (float)cos(v4f_z(v8f_efgh(i)));
     81   ref[7] = (float)cos(v4f_w(v8f_efgh(i)));
     82   CHKV8_EPS(j, ref, 1.e-6f);
     83 
     84   i = v8f_set
     85     ((float)PI/2.2f, (float)PI/3.f, (float)PI/4.f, (float)PI/6.f,
     86      (float)PI/8.f, (float)PI/7.f, (float)PI/16.f, (float)PI/9.f);
     87 
     88   CHKV8_FUNC_EPS(i, tan, 1.e-6);
     89   CHKV8_FUNC_EPS(v8f_cos(i), acos, 1.e-6f);
     90   CHKV8_FUNC_EPS(v8f_sin(i), asin, 1.e-6f);
     91   CHKV8_FUNC_EPS(v8f_tan(i), atan, 1.e-6f);
     92 }
     93 
     94 static void
     95 test_exp(void)
     96 {
     97   const v8f_T i = v8f_set
     98     (1.f, -1.234f, 0.f, 3.14156f, 0.9187f, 7.9f, 3.333f, 2.387e-7f);
     99   v8f_T j;
    100   float ref[8];
    101 
    102   CHKV8_FUNC_EPS(i, exp, 1.e-6f);
    103   CHKV8_FUNC_EPS(i, exp2, 1.e-6f);
    104 
    105   j = v8f_exp10(i);
    106   ref[0] = (float)exp2(LOG2E * LN10 * v4f_x(v8f_abcd(i)));
    107   ref[1] = (float)exp2(LOG2E * LN10 * v4f_y(v8f_abcd(i)));
    108   ref[2] = (float)exp2(LOG2E * LN10 * v4f_z(v8f_abcd(i)));
    109   ref[3] = (float)exp2(LOG2E * LN10 * v4f_w(v8f_abcd(i)));
    110   ref[4] = (float)exp2(LOG2E * LN10 * v4f_x(v8f_efgh(i)));
    111   ref[5] = (float)exp2(LOG2E * LN10 * v4f_y(v8f_efgh(i)));
    112   ref[6] = (float)exp2(LOG2E * LN10 * v4f_z(v8f_efgh(i)));
    113   ref[7] = (float)exp2(LOG2E * LN10 * v4f_w(v8f_efgh(i)));
    114   CHKV8_EPS(j, ref, 1.e-6f);
    115 }
    116 
    117 static void
    118 test_log(void)
    119 {
    120   const v8f_T i = v8f_set
    121     (4.675f, 3.14f, 9.99999f, 1.234e-13f, 3.33e-3f, 0.98f, 8.f, 9.87654f);
    122   CHKV8_FUNC_EPS(i, log, 1.e-6f);
    123   CHKV8_FUNC_EPS(i, log2, 1.e-6f);
    124   CHKV8_FUNC_EPS(i, log10, 1.e-6f);
    125 }
    126 
    127 static void
    128 test_misc(void)
    129 {
    130   v8f_T i, j, k;
    131   float ref[8];
    132 
    133   i = v8f_set(-1.2345f, 9.3e-7f, 3.879e9f, -10.56f, 9.9f, -3.1f, 0.33e-6f, 1.f);
    134   j = v8f_set(7.89e-9f, 0.12f, -4.9e10f, 3.14f, 5.f, 0.1e-19f, 1.234f, -0.45f);
    135   k = v8f_copysign(i, j);
    136   ref[0] = (float)copysign(v4f_x(v8f_abcd(i)), v4f_x(v8f_abcd(j)));
    137   ref[1] = (float)copysign(v4f_y(v8f_abcd(i)), v4f_y(v8f_abcd(j)));
    138   ref[2] = (float)copysign(v4f_z(v8f_abcd(i)), v4f_z(v8f_abcd(j)));
    139   ref[3] = (float)copysign(v4f_w(v8f_abcd(i)), v4f_w(v8f_abcd(j)));
    140   ref[4] = (float)copysign(v4f_x(v8f_efgh(i)), v4f_x(v8f_efgh(j)));
    141   ref[5] = (float)copysign(v4f_y(v8f_efgh(i)), v4f_y(v8f_efgh(j)));
    142   ref[6] = (float)copysign(v4f_z(v8f_efgh(i)), v4f_z(v8f_efgh(j)));
    143   ref[7] = (float)copysign(v4f_w(v8f_efgh(i)), v4f_w(v8f_efgh(j)));
    144   CHKV8_EPS(k, ref, 1.e-6f);
    145 
    146   CHKV8_FUNC_EPS(i, floor, 1.e-6f);
    147 
    148   k = v8f_pow(v8f_abs(i), j);
    149   ref[0] = (float)pow(fabsf(v4f_x(v8f_abcd(i))), v4f_x(v8f_abcd(j)));
    150   ref[1] = (float)pow(fabsf(v4f_y(v8f_abcd(i))), v4f_y(v8f_abcd(j)));
    151   ref[2] = (float)pow(fabsf(v4f_z(v8f_abcd(i))), v4f_z(v8f_abcd(j)));
    152   ref[3] = (float)pow(fabsf(v4f_w(v8f_abcd(i))), v4f_w(v8f_abcd(j)));
    153   ref[4] = (float)pow(fabsf(v4f_x(v8f_efgh(i))), v4f_x(v8f_efgh(j)));
    154   ref[5] = (float)pow(fabsf(v4f_y(v8f_efgh(i))), v4f_y(v8f_efgh(j)));
    155   ref[6] = (float)pow(fabsf(v4f_z(v8f_efgh(i))), v4f_z(v8f_efgh(j)));
    156   ref[7] = (float)pow(fabsf(v4f_w(v8f_efgh(i))), v4f_w(v8f_efgh(j)));
    157   CHKV8_EPS(k, ref, 1.e-6f);
    158 }
    159 
    160 int
    161 main(int argc, char** argv)
    162 {
    163   (void)argc, (void)argv;
    164 
    165   test_trigo();
    166   test_exp();
    167   test_log();
    168   test_misc();
    169 
    170   return 0;
    171 }
    172