arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/spqlios/reim/reim_fftvec_fma.c
poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/spqlios/reim/reim_fftvec_fma.cRaw
  1#include <assert.h>
  2#include <immintrin.h>
  3#include <stdint.h>
  4
  5#include "reim_fft_private.h"
  6
  7EXPORT void reim_fftvec_addmul_fma(const REIM_FFTVEC_ADDMUL_PRECOMP* precomp, double* r, const double* a,
  8                                   const double* b) {
  9  const uint64_t m = precomp->m;
 10  double* rr_ptr = r;
 11  double* ri_ptr = r + m;
 12  const double* ar_ptr = a;
 13  const double* ai_ptr = a + m;
 14  const double* br_ptr = b;
 15  const double* bi_ptr = b + m;
 16
 17  const double* const rend_ptr = ri_ptr;
 18  while (rr_ptr != rend_ptr) {
 19    __m256d rr = _mm256_loadu_pd(rr_ptr);
 20    __m256d ri = _mm256_loadu_pd(ri_ptr);
 21    const __m256d ar = _mm256_loadu_pd(ar_ptr);
 22    const __m256d ai = _mm256_loadu_pd(ai_ptr);
 23    const __m256d br = _mm256_loadu_pd(br_ptr);
 24    const __m256d bi = _mm256_loadu_pd(bi_ptr);
 25
 26    rr = _mm256_fmsub_pd(ai, bi, rr);
 27    rr = _mm256_fmsub_pd(ar, br, rr);
 28    ri = _mm256_fmadd_pd(ar, bi, ri);
 29    ri = _mm256_fmadd_pd(ai, br, ri);
 30
 31    _mm256_storeu_pd(rr_ptr, rr);
 32    _mm256_storeu_pd(ri_ptr, ri);
 33
 34    rr_ptr += 4;
 35    ri_ptr += 4;
 36    ar_ptr += 4;
 37    ai_ptr += 4;
 38    br_ptr += 4;
 39    bi_ptr += 4;
 40  }
 41}
 42
 43EXPORT void reim_fftvec_mul_fma(const REIM_FFTVEC_MUL_PRECOMP* precomp, double* r, const double* a, const double* b) {
 44  const uint64_t m = precomp->m;
 45  double* rr_ptr = r;
 46  double* ri_ptr = r + m;
 47  const double* ar_ptr = a;
 48  const double* ai_ptr = a + m;
 49  const double* br_ptr = b;
 50  const double* bi_ptr = b + m;
 51
 52  const double* const rend_ptr = ri_ptr;
 53  while (rr_ptr != rend_ptr) {
 54    const __m256d ar = _mm256_loadu_pd(ar_ptr);
 55    const __m256d ai = _mm256_loadu_pd(ai_ptr);
 56    const __m256d br = _mm256_loadu_pd(br_ptr);
 57    const __m256d bi = _mm256_loadu_pd(bi_ptr);
 58
 59    const __m256d t1 = _mm256_mul_pd(ai, bi);
 60    const __m256d t2 = _mm256_mul_pd(ar, bi);
 61
 62    __m256d rr = _mm256_fmsub_pd(ar, br, t1);
 63    __m256d ri = _mm256_fmadd_pd(ai, br, t2);
 64
 65    _mm256_storeu_pd(rr_ptr, rr);
 66    _mm256_storeu_pd(ri_ptr, ri);
 67
 68    rr_ptr += 4;
 69    ri_ptr += 4;
 70    ar_ptr += 4;
 71    ai_ptr += 4;
 72    br_ptr += 4;
 73    bi_ptr += 4;
 74  }
 75}
 76
 77EXPORT void reim_fftvec_add_fma(const REIM_FFTVEC_ADD_PRECOMP* precomp, double* r, const double* a, const double* b) {
 78  const uint64_t m = precomp->m;
 79  double* rr_ptr = r;
 80  double* ri_ptr = r + m;
 81  const double* ar_ptr = a;
 82  const double* ai_ptr = a + m;
 83  const double* br_ptr = b;
 84  const double* bi_ptr = b + m;
 85
 86  const double* const rend_ptr = ri_ptr;
 87  while (rr_ptr != rend_ptr) {
 88    const __m256d ar = _mm256_loadu_pd(ar_ptr);
 89    const __m256d ai = _mm256_loadu_pd(ai_ptr);
 90    const __m256d br = _mm256_loadu_pd(br_ptr);
 91    const __m256d bi = _mm256_loadu_pd(bi_ptr);
 92
 93    __m256d rr = _mm256_add_pd(ar, br);
 94    __m256d ri = _mm256_add_pd(ai, bi);
 95
 96    _mm256_storeu_pd(rr_ptr, rr);
 97    _mm256_storeu_pd(ri_ptr, ri);
 98
 99    rr_ptr += 4;
100    ri_ptr += 4;
101    ar_ptr += 4;
102    ai_ptr += 4;
103    br_ptr += 4;
104    bi_ptr += 4;
105  }
106}
107
108EXPORT void reim_fftvec_sub_fma(const REIM_FFTVEC_ADD_PRECOMP* precomp, double* r, const double* a, const double* b) {
109  const uint64_t m = precomp->m;
110  double* rr_ptr = r;
111  double* ri_ptr = r + m;
112  const double* ar_ptr = a;
113  const double* ai_ptr = a + m;
114  const double* br_ptr = b;
115  const double* bi_ptr = b + m;
116
117  const double* const rend_ptr = ri_ptr;
118  while (rr_ptr != rend_ptr) {
119    const __m256d ar = _mm256_loadu_pd(ar_ptr);
120    const __m256d ai = _mm256_loadu_pd(ai_ptr);
121    const __m256d br = _mm256_loadu_pd(br_ptr);
122    const __m256d bi = _mm256_loadu_pd(bi_ptr);
123
124    __m256d rr = _mm256_sub_pd(ar, br);
125    __m256d ri = _mm256_sub_pd(ai, bi);
126
127    _mm256_storeu_pd(rr_ptr, rr);
128    _mm256_storeu_pd(ri_ptr, ri);
129
130    rr_ptr += 4;
131    ri_ptr += 4;
132    ar_ptr += 4;
133    ai_ptr += 4;
134    br_ptr += 4;
135    bi_ptr += 4;
136  }
137}