nk 1.0.0
C++ Numerical Computing Runtime
Loading...
Searching...
No Matches
binary_ops.hpp
1// toolboxes/builtin/src/lang/operators/backends/binary_ops_loops.hpp
2//
3// Private declarations for the backend-split binary-op inner loops.
4// Implemented by exactly one of backends/MStdBinaryOps_{portable,simd}.cpp
5// depending on NK_WITH_SIMD. Callers (binary_ops.cpp) use these
6// only for the 2D same-shape DOUBLE fast path — every other shape
7// (broadcasting, 3D, type mismatch) goes through the general
8// elementwiseDouble() helper in helpers.hpp unchanged.
9
10#pragma once
11
12#include <cstddef>
13
14namespace nk::ops::detail {
15
16void plusLoop (const double *a, const double *b, double *out, std::size_t n);
17void minusLoop (const double *a, const double *b, double *out, std::size_t n);
18void timesLoop (const double *a, const double *b, double *out, std::size_t n);
19void rdivideLoop(const double *a, const double *b, double *out, std::size_t n);
20
21// Shared scalar bodies for the small-N gate ↔ portable fallback. The *Loop
22// entry points above forward here (portable) or call it from their small-N gate
23// (Highway), so the gate and the fallback are one definition and the loop lives
24// in a lambda-free TU (binary_scalar.cpp) that auto-vectorizes regardless of the
25// dispatcher's parallel_for capture. See bugs/ops/cheap-elementwise-simd-small-n.
26void plusScalar (const double *a, const double *b, double *out, std::size_t n);
27void minusScalar (const double *a, const double *b, double *out, std::size_t n);
28void timesScalar (const double *a, const double *b, double *out, std::size_t n);
29void rdivideScalar(const double *a, const double *b, double *out, std::size_t n);
30
31// Matrix multiply over column-major real doubles.
32// A: M×K at memory layout a[k*M + i]
33// B: K×N at memory layout b[j*K + k]
34// C: M×N written as c[j*M + i]; caller allocates, this function zeros
35// and then accumulates. Loop order is (j, k, i) — SAXPY down columns of
36// A with the (k,j) element of B as the scalar — cache-friendly and
37// directly vectorisable with MulAdd.
38void matmulDoubleLoop(const double *a, const double *b, double *c,
39 std::size_t M, std::size_t N, std::size_t K);
40
41} // namespace nk::ops::detail