14#include <nk/value/dims.hpp>
32inline bool broadcastDimsND(
const Dims &a,
const Dims &b,
Dims &out)
34 const int na = a.ndim();
35 const int nb = b.ndim();
36 const int nOut = std::max(na, nb);
40 constexpr int kMaxStack = 32;
41 size_t buf[kMaxStack];
42 if (nOut > kMaxStack)
return false;
44 for (
int i = 0; i < nOut; ++i) {
45 const size_t da = (i < na) ? a.dim(i) : 1;
46 const size_t db = (i < nb) ? b.dim(i) : 1;
47 if (da != db && da != 1 && db != 1)
return false;
48 buf[i] = std::max(da, db);
50 out =
Dims(buf, nOut);
64inline size_t broadcastOffsetND(
const size_t *coords,
int outNdim,
67 const int nOp = operand.ndim();
70 for (
int i = 0; i < outNdim; ++i) {
71 const size_t opDim = (i < nOp) ? operand.dim(i) : 1;
72 const size_t c = (opDim == 1) ? 0 : coords[i];
85inline void computeStridesColMajor(
const Dims &d,
size_t *strides)
87 const int n = d.ndim();
90 for (
int i = 1; i < n; ++i)
91 strides[i] = strides[i - 1] * d.dim(i - 1);
101inline size_t linearizeFromCoords(
const size_t *coords,
const size_t *strides,
105 for (
int i = 0; i < nd; ++i)
106 off += coords[i] * strides[i];
124inline bool incrementCoords(
size_t *coords,
const Dims &d)
126 const int n = d.ndim();
127 for (
int i = 0; i < n; ++i) {
128 if (++coords[i] < d.dim(i))
return true;
149template <
typename Fn>
150inline void forEachNDPair(
const Dims &aDims,
const Dims &bDims,
151 const Dims &outDims, Fn &&fn)
153 if (aDims == bDims && aDims == outDims) {
154 const size_t n = outDims.numel();
155 for (
size_t i = 0; i < n; ++i) fn(i, i, i);
158 const int nd = outDims.ndim();
159 size_t coords[Dims::kMaxRank] = {0};
162 const size_t aOff = broadcastOffsetND(coords, nd, aDims);
163 const size_t bOff = broadcastOffsetND(coords, nd, bDims);
164 fn(outIdx++, aOff, bOff);
165 }
while (incrementCoords(coords, outDims));
180template <
typename Fn>
181inline void forEachOuterPage(
const Dims &d, Fn &&fn)
183 const int nd = d.ndim();
184 size_t outerCount = 1;
185 for (
int i = 2; i < nd; ++i) outerCount *= d.dim(i);
186 size_t outerCoords[Dims::kMaxRank] = {0};
187 for (
size_t plin = 0; plin < outerCount; ++plin) {
188 fn(plin, outerCoords);
190 for (
int i = 2; i < nd; ++i) {
191 if (++outerCoords[i - 2] < d.dim(i))
break;
192 outerCoords[i - 2] = 0;
Value db(const Value &x, const std::string &signalType="voltage", std::pmr::memory_resource *mr=nullptr)
Convert magnitude or power to decibels.