nk
1.0.0
C++ Numerical Computing Runtime
Toggle main menu visibility
Loading...
Searching...
No Matches
dims.hpp
1
// include/dims.hpp
2
#pragma once
3
4
#include <cstddef>
5
#include <cstdint>
6
7
namespace
nk {
8
9
// ============================================================
10
// Dims — array dimensions, ND with SBO storage.
11
//
12
// Layout:
13
// * inline_ holds dims [0, kInlineCap). Slots beyond ndim() are
14
// always = 1 (so trailing-singleton equality semantics work
15
// without per-call branching).
16
// * For ndim() > kInlineCap, the extra dims live on heap_, indexed
17
// as heap_[i - kInlineCap]. heap_ == nullptr when ndim() <= kInlineCap.
18
//
19
// The SBO threshold of 4 covers MATLAB's typical use (scalar / vector /
20
// matrix / 3D-volume / 4D-batch tensor) without any allocation. Heap is
21
// reserved for the genuinely ND case (5D+). Same pattern as
22
// llvm::SmallVector / pytorch::DimVector.
23
//
24
// rows()/cols()/pages() are inline aliases on inline_[0/1/2] — no
25
// branch on the hot accessor path. dim(i) branches on i < kInlineCap;
26
// for compile-time-constant i (the common case in 2D/3D code) the
27
// optimiser folds the branch away.
28
// ============================================================
29
struct
Dims
30
{
31
static
constexpr
int
kInlineCap = 4;
32
// Maximum supported rank for any ND op. Used as a stack-buffer
33
// bound (e.g. `size_t coords[Dims::kMaxRank]`) and a sanity-check
34
// ceiling. 32 is well above any practical use.
35
static
constexpr
int
kMaxRank = 32;
36
37
Dims();
38
Dims(
size_t
r,
size_t
c);
39
Dims(
size_t
r,
size_t
c,
size_t
p);
40
Dims(
const
size_t
*dims,
int
nd);
41
42
Dims(
const
Dims &o);
43
Dims(Dims &&o)
noexcept
;
44
Dims &operator=(
const
Dims &o);
45
Dims &operator=(Dims &&o)
noexcept
;
46
~Dims();
47
48
int
ndims()
const
noexcept
{
return
nd_; }
49
int
ndim()
const
noexcept
{
return
nd_; }
50
size_t
rows()
const
noexcept
{
return
inline_[0]; }
51
size_t
cols()
const
noexcept
{
return
inline_[1]; }
52
size_t
pages()
const
noexcept
{
return
inline_[2]; }
53
54
size_t
dim(
int
i)
const
noexcept
55
{
56
if
(i < 0)
return
1;
57
if
(i < kInlineCap)
return
inline_[i];
58
if
(i < nd_)
return
heap_[i - kInlineCap];
59
return
1;
60
}
61
62
size_t
dimSize(
int
i)
const
noexcept
{
return
dim(i); }
63
64
size_t
numel()
const
noexcept
65
{
66
size_t
n = inline_[0] * inline_[1] * inline_[2] * inline_[3];
67
if
(heap_) {
68
const
int
extra = nd_ - kInlineCap;
69
for
(
int
i = 0; i < extra; ++i)
70
n *= heap_[i];
71
}
72
return
n;
73
}
74
75
bool
isScalar()
const
noexcept
{
return
numel() == 1; }
76
bool
isEmpty()
const
noexcept
{
return
numel() == 0; }
77
bool
isVector()
const
noexcept
78
{
79
return
nd_ == 2 && (inline_[0] == 1 || inline_[1] == 1);
80
}
81
bool
is3D()
const
noexcept
{
return
nd_ == 3 && inline_[2] > 1; }
82
83
size_t
sub2ind(
size_t
r,
size_t
c)
const
noexcept
84
{
85
return
c * inline_[0] + r;
86
}
87
size_t
sub2ind(
size_t
r,
size_t
c,
size_t
p)
const
noexcept
88
{
89
return
p * inline_[0] * inline_[1] + c * inline_[0] + r;
90
}
91
size_t
sub2indChecked(
size_t
r,
size_t
c)
const
;
92
size_t
sub2indChecked(
size_t
r,
size_t
c,
size_t
p)
const
;
93
94
bool
operator==(
const
Dims &o)
const
noexcept
;
95
bool
operator!=(
const
Dims &o)
const
noexcept
{
return
!(*
this
== o); }
96
97
private
:
98
void
setND(
const
size_t
*dims,
int
nd);
99
void
freeHeap()
noexcept
;
100
101
size_t
inline_[kInlineCap];
102
size_t
*heap_;
103
uint8_t nd_;
104
};
105
106
}
// namespace nk
src
value
include
nk
value
dims.hpp
Generated by
1.17.0