4 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
807b9d5284 Fix dx4 calculation in scalar remainder code and add null checks
- Fix dx4 computation in scalar remainder loops (should be dx2*dx2)
- Add missing null pointer check in benchmark_sinf for consistency

Co-authored-by: wvbbreu <185333235+wvbbreu@users.noreply.github.com>
2025-10-29 16:26:27 +00:00
copilot-swe-agent[bot]
3addf2b05e Fix memory management bug and computational inefficiencies
- Fix mismatched new[]/free() to use proper delete[] in interface.hpp
- Fix incorrect dx4 calculation (should be dx2*dx2, not dx2*dx) in lookup_xsimd.cpp
- Fix redundant sinv calculation by using separate base variables in sin_cosf_dispatcher
- Remove unused variable declarations in lookup_avx.cpp
- Optimize reference backend to use sincosf() instead of separate sin/cos calls

Co-authored-by: wvbbreu <185333235+wvbbreu@users.noreply.github.com>
2025-10-29 16:23:35 +00:00
copilot-swe-agent[bot]
3eb537d586 Initial plan 2025-10-29 16:15:26 +00:00
Dantali0n
58bc640d6d 32: Set AVX and AVX2 flags using CMake checks (#34)
* 32: Set mavx and mavx2 based on CMake checks
* 32: Update flags for Intel compiler
* Fix: AVX2 instead of AVX__2

Co-authored-by: Bram Veenboer <bram.veenboer@gmail.com>
Co-authored-by: lukken <lukken@astron.nl>
2025-10-29 09:18:43 +01:00
5 changed files with 16 additions and 15 deletions

View File

@@ -26,6 +26,9 @@ static void benchmark_sinf(benchmark::State &state) {
reinterpret_cast<float *>(backend.allocate_memory(N * sizeof(float))); reinterpret_cast<float *>(backend.allocate_memory(N * sizeof(float)));
float *s = float *s =
reinterpret_cast<float *>(backend.allocate_memory(N * sizeof(float))); reinterpret_cast<float *>(backend.allocate_memory(N * sizeof(float)));
if (!x || !s) {
throw std::runtime_error("Buffer allocation failed");
}
auto end = std::chrono::high_resolution_clock::now(); auto end = std::chrono::high_resolution_clock::now();
state.counters["init_ms"] = state.counters["init_ms"] =
std::chrono::duration_cast<std::chrono::microseconds>(end - start) std::chrono::duration_cast<std::chrono::microseconds>(end - start)

View File

@@ -16,7 +16,7 @@ public:
return static_cast<void *>(new uint8_t[bytes]); return static_cast<void *>(new uint8_t[bytes]);
}; };
virtual void free_memory(void *ptr) const { std::free(ptr); }; virtual void free_memory(void *ptr) const { delete[] static_cast<uint8_t*>(ptr); };
// Compute sine for n elements // Compute sine for n elements
virtual void compute_sinf(size_t n, const float *x, float *s) const = 0; virtual void compute_sinf(size_t n, const float *x, float *s) const = 0;

View File

@@ -89,7 +89,6 @@ template <std::size_t NR_SAMPLES> struct LookupAVXBackend<NR_SAMPLES>::Impl {
constexpr std::size_t VL = 8; // AVX processes 8 floats constexpr std::size_t VL = 8; // AVX processes 8 floats
const __m256 scale = _mm256_set1_ps(SCALE); const __m256 scale = _mm256_set1_ps(SCALE);
const __m256i mask = _mm256_set1_epi32(MASK); const __m256i mask = _mm256_set1_epi32(MASK);
const __m256i quarter_pi = _mm256_set1_epi32(NR_SAMPLES / 4);
std::size_t i = 0; std::size_t i = 0;
for (; i + VL <= n; i += VL) { for (; i + VL <= n; i += VL) {
@@ -104,7 +103,7 @@ template <std::size_t NR_SAMPLES> struct LookupAVXBackend<NR_SAMPLES>::Impl {
#else #else
// fallback gather for AVX1 // fallback gather for AVX1
float sin_tmp[VL]; float sin_tmp[VL];
int idx_a[VL], idxc_a[VL]; int idx_a[VL];
_mm256_store_si256((__m256i *)idx_a, idx); _mm256_store_si256((__m256i *)idx_a, idx);
for (std::size_t k = 0; k < VL; ++k) { for (std::size_t k = 0; k < VL; ++k) {
sin_tmp[k] = lookup[idx_a[k]]; sin_tmp[k] = lookup[idx_a[k]];

View File

@@ -56,7 +56,7 @@ template <std::size_t NR_SAMPLES> struct cosf_dispatcher {
const b_type dx = xsimd::sub(vx, xsimd::mul(f_idx, pi_frac)); const b_type dx = xsimd::sub(vx, xsimd::mul(f_idx, pi_frac));
const b_type dx2 = xsimd::mul(dx, dx); const b_type dx2 = xsimd::mul(dx, dx);
const b_type dx3 = xsimd::mul(dx2, dx); const b_type dx3 = xsimd::mul(dx2, dx);
const b_type dx4 = xsimd::mul(dx2, dx); const b_type dx4 = xsimd::mul(dx2, dx2);
const b_type t2 = xsimd::mul(dx2, term2); const b_type t2 = xsimd::mul(dx2, term2);
const b_type t3 = xsimd::mul(dx3, term3); const b_type t3 = xsimd::mul(dx3, term3);
const b_type t4 = xsimd::mul(dx4, term4); const b_type t4 = xsimd::mul(dx4, term4);
@@ -78,7 +78,7 @@ template <std::size_t NR_SAMPLES> struct cosf_dispatcher {
const float dx = a[i] - idx * lookup_table_.PI_FRAC; const float dx = a[i] - idx * lookup_table_.PI_FRAC;
const float dx2 = dx * dx; const float dx2 = dx * dx;
const float dx3 = dx2 * dx; const float dx3 = dx2 * dx;
const float dx4 = dx3 * dx; const float dx4 = dx2 * dx2;
const float cosdx = const float cosdx =
1.0f - lookup_table_.TERM2 * dx2 + lookup_table_.TERM4 * dx4; 1.0f - lookup_table_.TERM2 * dx2 + lookup_table_.TERM4 * dx4;
const float sindx = dx - lookup_table_.TERM3 * dx3; const float sindx = dx - lookup_table_.TERM3 * dx3;
@@ -115,7 +115,7 @@ template <std::size_t NR_SAMPLES> struct sinf_dispatcher {
const b_type dx = xsimd::sub(vx, xsimd::mul(f_idx, pi_frac)); const b_type dx = xsimd::sub(vx, xsimd::mul(f_idx, pi_frac));
const b_type dx2 = xsimd::mul(dx, dx); const b_type dx2 = xsimd::mul(dx, dx);
const b_type dx3 = xsimd::mul(dx2, dx); const b_type dx3 = xsimd::mul(dx2, dx);
const b_type dx4 = xsimd::mul(dx2, dx); const b_type dx4 = xsimd::mul(dx2, dx2);
const b_type t2 = xsimd::mul(dx2, term2); const b_type t2 = xsimd::mul(dx2, term2);
const b_type t3 = xsimd::mul(dx3, term3); const b_type t3 = xsimd::mul(dx3, term3);
const b_type t4 = xsimd::mul(dx4, term4); const b_type t4 = xsimd::mul(dx4, term4);
@@ -138,7 +138,7 @@ template <std::size_t NR_SAMPLES> struct sinf_dispatcher {
const float dx = a[i] - idx * lookup_table_.PI_FRAC; const float dx = a[i] - idx * lookup_table_.PI_FRAC;
const float dx2 = dx * dx; const float dx2 = dx * dx;
const float dx3 = dx2 * dx; const float dx3 = dx2 * dx;
const float dx4 = dx3 * dx; const float dx4 = dx2 * dx2;
const float cosdx = const float cosdx =
1.0f - lookup_table_.TERM2 * dx2 + lookup_table_.TERM4 * dx4; 1.0f - lookup_table_.TERM2 * dx2 + lookup_table_.TERM4 * dx4;
const float sindx = dx - lookup_table_.TERM3 * dx3; const float sindx = dx - lookup_table_.TERM3 * dx3;
@@ -176,20 +176,20 @@ template <std::size_t NR_SAMPLES> struct sin_cosf_dispatcher {
const b_type dx = xsimd::sub(vx, xsimd::mul(f_idx, pi_frac)); const b_type dx = xsimd::sub(vx, xsimd::mul(f_idx, pi_frac));
const b_type dx2 = xsimd::mul(dx, dx); const b_type dx2 = xsimd::mul(dx, dx);
const b_type dx3 = xsimd::mul(dx2, dx); const b_type dx3 = xsimd::mul(dx2, dx);
const b_type dx4 = xsimd::mul(dx2, dx); const b_type dx4 = xsimd::mul(dx2, dx2);
const b_type t2 = xsimd::mul(dx2, term2); const b_type t2 = xsimd::mul(dx2, term2);
const b_type t3 = xsimd::mul(dx3, term3); const b_type t3 = xsimd::mul(dx3, term3);
const b_type t4 = xsimd::mul(dx4, term4); const b_type t4 = xsimd::mul(dx4, term4);
idx = xsimd::bitwise_and(idx, mask); idx = xsimd::bitwise_and(idx, mask);
b_type sinv = b_type::gather(lookup_table_.sin_values.data(), idx); const b_type sinv_base = b_type::gather(lookup_table_.sin_values.data(), idx);
b_type cosv = b_type::gather(lookup_table_.cos_values.data(), idx); const b_type cosv_base = b_type::gather(lookup_table_.cos_values.data(), idx);
const b_type cosdx = xsimd::add(xsimd::sub(term1, t2), t4); const b_type cosdx = xsimd::add(xsimd::sub(term1, t2), t4);
const b_type sindx = xsimd::sub(dx, t3); const b_type sindx = xsimd::sub(dx, t3);
sinv = xsimd::add(xsimd::mul(cosv, sindx), xsimd::mul(sinv, cosdx)); b_type sinv = xsimd::add(xsimd::mul(cosv_base, sindx), xsimd::mul(sinv_base, cosdx));
cosv = xsimd::sub(xsimd::mul(cosv, cosdx), xsimd::mul(sinv, sindx)); b_type cosv = xsimd::sub(xsimd::mul(cosv_base, cosdx), xsimd::mul(sinv_base, sindx));
sinv.store(s + i, Tag()); sinv.store(s + i, Tag());
cosv.store(c + i, Tag()); cosv.store(c + i, Tag());
@@ -202,7 +202,7 @@ template <std::size_t NR_SAMPLES> struct sin_cosf_dispatcher {
const float dx = a[i] - idx * lookup_table_.PI_FRAC; const float dx = a[i] - idx * lookup_table_.PI_FRAC;
const float dx2 = dx * dx; const float dx2 = dx * dx;
const float dx3 = dx2 * dx; const float dx3 = dx2 * dx;
const float dx4 = dx3 * dx; const float dx4 = dx2 * dx2;
const float cosdx = const float cosdx =
1.0f - lookup_table_.TERM2 * dx2 + lookup_table_.TERM4 * dx4; 1.0f - lookup_table_.TERM2 * dx2 + lookup_table_.TERM4 * dx4;
const float sindx = dx - lookup_table_.TERM3 * dx3; const float sindx = dx - lookup_table_.TERM3 * dx3;

View File

@@ -17,7 +17,6 @@ void ReferenceBackend::compute_cosf(size_t n, const float *x, float *c) const {
void ReferenceBackend::compute_sincosf(size_t n, const float *x, float *s, void ReferenceBackend::compute_sincosf(size_t n, const float *x, float *s,
float *c) const { float *c) const {
for (size_t i = 0; i < n; ++i) { for (size_t i = 0; i < n; ++i) {
s[i] = sinf(x[i]); sincosf(x[i], &s[i], &c[i]);
c[i] = cosf(x[i]);
} }
} }