arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/spqlios/reim4/reim4_fftvec_addmul_ref.c
poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/spqlios/reim4/reim4_fftvec_addmul_ref.cRaw
 1#include <errno.h>
 2#include <memory.h>
 3#include <stdlib.h>
 4#include <string.h>
 5
 6#include "../commons_private.h"
 7#include "reim4_fftvec_internal.h"
 8#include "reim4_fftvec_private.h"
 9
10void* init_reim4_fftvec_addmul_precomp(REIM4_FFTVEC_ADDMUL_PRECOMP* res, uint32_t m) {
11  res->m = m;
12  if (CPU_SUPPORTS("fma")) {
13    if (m >= 2) {
14      res->function = reim4_fftvec_addmul_fma;
15    } else {
16      res->function = reim4_fftvec_addmul_ref;
17    }
18  } else {
19    res->function = reim4_fftvec_addmul_ref;
20  }
21  return res;
22}
23
24EXPORT REIM4_FFTVEC_ADDMUL_PRECOMP* new_reim4_fftvec_addmul_precomp(uint32_t m) {
25  REIM4_FFTVEC_ADDMUL_PRECOMP* res = malloc(sizeof(*res));
26  if (!res) return spqlios_error(strerror(errno));
27  return spqlios_keep_or_free(res, init_reim4_fftvec_addmul_precomp(res, m));
28}
29
30EXPORT void reim4_fftvec_addmul_ref(const REIM4_FFTVEC_ADDMUL_PRECOMP* precomp, double* r, const double* a,
31                                    const double* b) {
32  const uint64_t m = precomp->m;
33  for (uint64_t j = 0; j < m / 4; ++j) {
34    for (uint64_t i = 0; i < 4; ++i) {
35      double re = a[i] * b[i] - a[i + 4] * b[i + 4];
36      double im = a[i] * b[i + 4] + a[i + 4] * b[i];
37      r[i] += re;
38      r[i + 4] += im;
39    }
40    a += 8;
41    b += 8;
42    r += 8;
43  }
44}
45
46EXPORT void reim4_fftvec_addmul_simple(uint32_t m, double* r, const double* a, const double* b) {
47  static REIM4_FFTVEC_ADDMUL_PRECOMP precomp[32];
48  REIM4_FFTVEC_ADDMUL_PRECOMP* p = precomp + log2m(m);
49  if (!p->function) {
50    if (!init_reim4_fftvec_addmul_precomp(p, m)) abort();
51  }
52  p->function(p, r, a, b);
53}
54
55void* init_reim4_fftvec_mul_precomp(REIM4_FFTVEC_MUL_PRECOMP* res, uint32_t m) {
56  res->m = m;
57  if (CPU_SUPPORTS("fma")) {
58    if (m >= 4) {
59      res->function = reim4_fftvec_mul_fma;
60    } else {
61      res->function = reim4_fftvec_mul_ref;
62    }
63  } else {
64    res->function = reim4_fftvec_mul_ref;
65  }
66  return res;
67}
68
69EXPORT REIM4_FFTVEC_MUL_PRECOMP* new_reim4_fftvec_mul_precomp(uint32_t m) {
70  REIM4_FFTVEC_MUL_PRECOMP* res = malloc(sizeof(*res));
71  if (!res) return spqlios_error(strerror(errno));
72  return spqlios_keep_or_free(res, init_reim4_fftvec_mul_precomp(res, m));
73}
74
75EXPORT void reim4_fftvec_mul_ref(const REIM4_FFTVEC_MUL_PRECOMP* precomp, double* r, const double* a, const double* b) {
76  const uint64_t m = precomp->m;
77  for (uint64_t j = 0; j < m / 4; ++j) {
78    for (uint64_t i = 0; i < 4; ++i) {
79      double re = a[i] * b[i] - a[i + 4] * b[i + 4];
80      double im = a[i] * b[i + 4] + a[i + 4] * b[i];
81      r[i] = re;
82      r[i + 4] = im;
83    }
84    a += 8;
85    b += 8;
86    r += 8;
87  }
88}
89
90EXPORT void reim4_fftvec_mul_simple(uint32_t m, double* r, const double* a, const double* b) {
91  static REIM4_FFTVEC_MUL_PRECOMP precomp[32];
92  REIM4_FFTVEC_MUL_PRECOMP* p = precomp + log2m(m);
93  if (!p->function) {
94    if (!init_reim4_fftvec_mul_precomp(p, m)) abort();
95  }
96  p->function(p, r, a, b);
97}