gemm.c file
Classes
- struct vm_gemm_job
- One parallel-for chunk: invoke
fn(begin, end, ctx). - struct vm_gemm_ws
- Thread-local pack workspace for A/B panels (grows on demand).
- struct vm_gemm_batch_ctx
- Context for a batched GEMM parallel-for range.
Enums
- enum (anonymous) { VM_GEMM_MAX_THREADS = 16, VM_GEMM_THREAD_MIN_FLOPS = 131072, VM_GEMM_THREAD_MIN_PER_WORKER = 2, VM_GEMM_STRIDE_STACK = 32 }
Functions
- void vm_gemm_set_threads(const int n)
- Cap or force the GEMM worker-thread budget.
- static auto vm_gemm_hw_threads(void) -> int
- Online logical CPU count for GEMM threading defaults.
- auto vm_gemm_threads(void) -> int
- Resolve the GEMM worker-thread budget.
- static auto vm_gemm_pick_threads(const int batch, const int M, const int N, const int K) -> int
- Choose how many workers to use for a batched GEMM.
- static void vm_gemm_parallel_for(const int n, void(*)(int begin, int end, void*ctx) fn, void* ctx, const int threads)
- Run
fn(begin, end, ctx)over[0, n)using up tothreadsworkers. - static auto vm_gemm_min(const int a, const int b) -> int
- Return the smaller of two integers (panel edge clamp).
-
static auto vm_panel_at(const vm_
float_ t* M, const int ld, const int r, const int c, const bool trans, const vm_ layout_ t layout) -> vm_ float_ t - Read one entry from A or B with optional transpose and layout.
-
static auto vm_panel_get_c(const vm_
float_ t* C, const int ldc, const int r, const int c, const vm_ layout_ t layout) -> vm_ float_ t - Read C(r, c) according to layout (no transpose).
-
static void vm_panel_set_c(vm_
float_ t* C, const int ldc, const int r, const int c, const vm_ float_ t v, const vm_ layout_ t layout) - Write C(r, c) according to layout (no transpose).
-
void vm_gemm_ref(vm_
float_ t* C, const int ldc, const vm_ float_ t* A, const int lda, const vm_ float_ t* B, const int ldb, const int M, const int N, const int K, const vm_ float_ t alpha, const vm_ float_ t beta, const bool transA, const bool transB, const vm_ layout_ t layout) - Triple-loop reference GEMM.
-
auto vm_gemm_ukernel_scalar(vm_
float_ t* acc, const vm_ float_ t* Ap, const vm_ float_ t* Bp, const int K) -> VECMAT_ SCALAR_ API void - Scalar packed MR×NR micro-kernel.
- static void vm_gemm_ensure_dispatch(void)
- Ensure runtime CPU feature detection has run (no-op without dispatch).
-
static void vm_gemm_ukernel_call(vm_
float_ t* acc, const vm_ float_ t* Ap, const vm_ float_ t* Bp, const int K) - Invoke the GEMM micro-kernel for a packed MR×NR tile.
-
static void vm_gemm_pack_a(vm_
float_ t* Ap, const vm_ float_ t* A, const int lda, const int i0, const int k0, const int ib, const int kb, const bool transA, const vm_ layout_ t layout) - Pack an A panel into contiguous MR-wide micro-panels (zero-padded).
-
static void vm_gemm_pack_b(vm_
float_ t* Bp, const vm_ float_ t* B, const int ldb, const int k0, const int j0, const int kb, const int jb, const bool transB, const vm_ layout_ t layout) - Pack a B panel into contiguous NR-wide micro-panels (zero-padded).
-
static void vm_gemm_store_tile(vm_
float_ t* C, const int ldc, const vm_ float_ t* acc, const int i0, const int j0, const int mr, const int nr, const vm_ float_ t alpha, const vm_ float_ t beta, const vm_ layout_ t layout, const int op, const vm_ float_ t* bias) - Write a micro-kernel tile into C with alpha/beta and optional epilogue.
-
static void vm_gemm_scale_c(vm_
float_ t* C, const int ldc, const int M, const int N, const vm_ float_ t beta, const vm_ layout_ t layout) - Apply C = beta * C over an M×N panel (alpha==0 / empty product path).
-
static auto vm_gemm_alloc_pack(const size_t need) -> vm_
float_ t* - Allocate a 32-byte-aligned pack buffer for at least
needelements. -
static void vm_gemm_free_pack(vm_
float_ t* p) - Free a pack buffer from
vm_.gemm_ alloc_ pack -
static auto vm_gemm_ws_fit(vm_
float_ t** buf, size_t* cap, const size_t need) -> vm_ float_ t* - Grow a pack buffer so it holds at least
needelements. - static auto vm_gemm_pack_a_elems(const int ib, const int kb) -> size_t
- Element count for an A pack covering
ibrows andkbK-steps. - static auto vm_gemm_pack_b_elems(const int jb, const int kb) -> size_t
- Element count for a B pack covering
jbcolumns andkbK-steps. -
static void vm_gemm_apply_packed(vm_
float_ t* C, const int ldc, const vm_ float_ t* A, const int lda, const vm_ float_ t* Bp, const int M, const int jb, const int kb, const int ic0, const int jc, const int kc, const vm_ float_ t alpha, const vm_ float_ t beta_panel, const bool transA, const vm_ layout_ t layout, const int last_k, const int op, const vm_ float_ t* bias) - Multiply A panels against a pre-packed B panel and store into C.
-
static void vm_gemm_ex_body(vm_
float_ t* C, const int ldc, const vm_ float_ t* A, const int lda, const vm_ float_ t* B, const int ldb, const int M, const int N, const int K, const vm_ float_ t alpha, const vm_ float_ t beta, const bool transA, const bool transB, const vm_ layout_ t layout, const int op, const vm_ float_ t* bias) - Core blocked GEMM with optional bias/ReLU epilogue.
-
void vm_gemm_ex(vm_
float_ t* C, const int ldc, const vm_ float_ t* A, const int lda, const vm_ float_ t* B, const int ldb, const int M, const int N, const int K, const vm_ float_ t alpha, const vm_ float_ t beta, const bool transA, const bool transB, const vm_ layout_ t layout, const int op, const vm_ float_ t* bias) - C = alpha * op(A) * op(B) + beta * C with optional fused epilogue.
-
void vm_gemm(vm_
float_ t* C, const int ldc, const vm_ float_ t* A, const int lda, const vm_ float_ t* B, const int ldb, const int M, const int N, const int K, const vm_ float_ t alpha, const vm_ float_ t beta, const bool transA, const bool transB, const vm_ layout_ t layout) - C = alpha * op(A) * op(B) + beta * C for dense float panels.
-
static void vm_gemm_batch_shared_b(vm_
float_ t*const* C, const int ldc, const vm_ float_ t*const* A, const int lda, const vm_ float_ t* B, const int ldb, const int M, const int N, const int K, const vm_ float_ t alpha, const vm_ float_ t beta, const bool transA, const bool transB, const vm_ layout_ t layout, const int begin, const int end) - Batched GEMM with one shared B, packing B once per KC/NC panel.
- static void vm_gemm_batch_range(const int begin, const int end, void* arg)
- Runs GEMM for batch indices
[begin, end). -
void vm_gemm_batch(vm_
float_ t*const* C, const int ldc, const vm_ float_ t*const* A, const int lda, const vm_ float_ t*const* B, const int ldb, const int M, const int N, const int K, const vm_ float_ t alpha, const vm_ float_ t beta, const bool transA, const bool transB, const vm_ layout_ t layout, const int batch) - Batched GEMM:
batchindependent GEMMs with shared shape. -
void vm_gemm_strided_batch(vm_
float_ t* C, const int ldc, const int strideC, const vm_ float_ t* A, const int lda, const int strideA, const vm_ float_ t* B, const int ldb, const int strideB, const int M, const int N, const int K, const vm_ float_ t alpha, const vm_ float_ t beta, const bool transA, const bool transB, const vm_ layout_ t layout, const int batch) - Strided batched GEMM: problems live
strideXelements apart. -
void vm_im2col(vm_
float_ t* col, const int ld_col, const vm_ float_ t* img, const int n, const int c, const int h, const int w, const int kh, const int kw, const int pad_h, const int pad_w, const int stride_h, const int stride_w, const vm_ layout_ t layout) - NCHW im2col into a GEMM-ready panel.
Variables
- static int vm_gemm_thread_limit
- GEMM thread budget:
0= auto,1= serial,N= cap at N. - static int vm_gemm_env_threads
- Cached
VECMAT_GEMM_THREADS(0= unset / invalid). -
static VM_
TLS vm_ gemm_ ws vm_gemm_tls
Defines
- #define VM_TLS
Function documentation
void vm_gemm_set_threads(const int n)
Cap or force the GEMM worker-thread budget.
| Parameters | |
|---|---|
| n | Thread limit (0 = auto, 1 = serial, N = cap at N). |
n > 0 sets a fixed limit used by vm_; n == 0 (or negative, treated as 0) restores auto selection via env / hardware.
static int vm_gemm_hw_threads(void)
Online logical CPU count for GEMM threading defaults.
| Returns | Hardware thread count estimate (>= 1). |
|---|
Uses GetSystemInfo on Windows and sysconf(_SC_NPROCESSORS_ONLN) elsewhere. Falls back to 1 if the probe fails or returns a non-positive value.
int vm_gemm_threads(void)
Resolve the GEMM worker-thread budget.
| Returns | Requested thread count (>= 1 from hardware fallback when unset). |
|---|
Order: vm_ limit if > 0; else a positive integer from VECMAT_GEMM_THREADS (invalid values ignored); else online CPU count.
static int vm_gemm_pick_threads(const int batch, const int M, const int N, const int K)
Choose how many workers to use for a batched GEMM.
| Parameters | |
|---|---|
| batch | Number of independent GEMMs. |
| M | Rows of op(A)/C per problem. |
| N | Columns of op(B)/C per problem. |
| K | Inner-product length per problem. |
| Returns | Thread count to pass to vm_. |
Returns 1 for a single problem, insufficient items per worker, or tiny total FLOPs (spawn cost dominates). Otherwise takes vm_, clamped to [1, batch] and VM_.
static void vm_gemm_parallel_for(const int n, void(*)(int begin, int end, void*ctx) fn, void* ctx, const int threads)
Run fn(begin, end, ctx) over [0, n) using up to threads workers.
| Parameters | |
|---|---|
| n | Iteration count (no-op if <= 0). |
| fn | Callback for a half-open subrange [begin, end). |
| ctx | Opaque pointer passed through to fn. |
| threads | Requested worker count (clamped; <= 1 forces serial). |
Splits the range into roughly equal chunks (capped by n and VM_). Runs serial when threading is off, threads <= 1, or the range is tiny. Persistent pool workers handle extra chunks; the caller thread always runs the first chunk.
static int vm_gemm_min(const int a, const int b)
Return the smaller of two integers (panel edge clamp).
| Parameters | |
|---|---|
| a | First value. |
| b | Second value. |
| Returns | The minimum of a and b. |
static vm_ float_ t vm_panel_at(const vm_ float_ t* M,
const int ld,
const int r,
const int c,
const bool trans,
const vm_ layout_ t layout)
Read one entry from A or B with optional transpose and layout.
| Parameters | |
|---|---|
| M | Matrix base pointer. |
| ld | Leading dimension of M. |
| r | Logical row in op(M). |
| c | Logical column in op(M). |
| trans | If true, treat M as transposed. |
| layout | Row-major or column-major storage. |
| Returns | The value at the mapped location. |
Logical indices (r, c) are in op(M) space; trans swaps them before applying row- or column-major addressing.
static vm_ float_ t vm_panel_get_c(const vm_ float_ t* C,
const int ldc,
const int r,
const int c,
const vm_ layout_ t layout)
Read C(r, c) according to layout (no transpose).
| Parameters | |
|---|---|
| C | Output matrix base pointer. |
| ldc | Leading dimension of C. |
| r | Row index. |
| c | Column index. |
| layout | Row-major or column-major storage. |
| Returns | C at (r, c). |
static void vm_panel_set_c(vm_ float_ t* C,
const int ldc,
const int r,
const int c,
const vm_ float_ t v,
const vm_ layout_ t layout)
Write C(r, c) according to layout (no transpose).
| Parameters | |
|---|---|
| C | Output matrix base pointer. |
| ldc | Leading dimension of C. |
| r | Row index. |
| c | Column index. |
| v | Value to store. |
| layout | Row-major or column-major storage. |
void vm_gemm_ref(vm_ float_ t* C,
const int ldc,
const vm_ float_ t* A,
const int lda,
const vm_ float_ t* B,
const int ldb,
const int M,
const int N,
const int K,
const vm_ float_ t alpha,
const vm_ float_ t beta,
const bool transA,
const bool transB,
const vm_ layout_ t layout)
Triple-loop reference GEMM.
| Parameters | |
|---|---|
| C | Output matrix (M×N), updated in place. |
| ldc | Leading dimension of C. |
| A | Left input matrix; ignored when alpha == 0 or K <= 0. |
| lda | Leading dimension of A. |
| B | Right input matrix; ignored when alpha == 0 or K <= 0. |
| ldb | Leading dimension of B. |
| M | Number of rows of op(A) and C. |
| N | Number of columns of op(B) and C. |
| K | Inner product length (columns of op(A), rows of op(B)). |
| alpha | Scale factor for the A*B product. |
| beta | Scale factor for the existing C values (0 skips reading C). |
| transA | If true, use A^T; otherwise A. |
| transB | If true, use B^T; otherwise B. |
| layout | Memory layout for A, B, and C. |
Useful for tests and tiny/fallback paths.
Computes C = alpha * op(A) * op(B) + beta * C. op(X) = X or X^T according to the matching transpose flag. Layout selects row-major or column-major indexing for A, B and C together.
VECMAT_ SCALAR_ API void vm_gemm_ukernel_scalar(vm_ float_ t* acc,
const vm_ float_ t* Ap,
const vm_ float_ t* Bp,
const int K)
Scalar packed MR×NR micro-kernel.
| Parameters | |
|---|---|
| acc | Accumulator tile (MR×NR), updated in place. |
| Ap | Packed A panel columns (MR values per k). |
| Bp | Packed B panel rows (NR values per k). |
| K | Number of packed inner-dimension steps. |
Updates acc[i + j*MR] += Ap[k*MR+i] * Bp[k*NR+j] for k in [0, K). Ap / Bp must already be packed with MR/NR padding.
static void vm_gemm_ensure_dispatch(void)
Ensure runtime CPU feature detection has run (no-op without dispatch).
When built with VECMAT_RUNTIME_DISPATCH, calls vm_ so the selected GEMM micro-kernel is ready. Otherwise does nothing.
static void vm_gemm_ukernel_call(vm_ float_ t* acc,
const vm_ float_ t* Ap,
const vm_ float_ t* Bp,
const int K)
Invoke the GEMM micro-kernel for a packed MR×NR tile.
| Parameters | |
|---|---|
| acc | Accumulator tile (MR×NR), updated in place. |
| Ap | Packed A micro-panel (MR values per k, MR-padded). |
| Bp | Packed B micro-panel (NR values per k, NR-padded). |
| K | Inner-dimension length for this tile. |
With VECMAT_RUNTIME_DISPATCH, calls the CPU-selected kernel (vm_gemm_ukernel_); otherwise calls vm_.
static void vm_gemm_pack_a(vm_ float_ t* Ap,
const vm_ float_ t* A,
const int lda,
const int i0,
const int k0,
const int ib,
const int kb,
const bool transA,
const vm_ layout_ t layout)
Pack an A panel into contiguous MR-wide micro-panels (zero-padded).
| Parameters | |
|---|---|
| Ap | Destination pack buffer. |
| A | Source matrix A. |
| lda | Leading dimension of A. |
| i0 | Starting row of the panel in op(A). |
| k0 | Starting K index of the panel. |
| ib | Number of rows to pack. |
| kb | Number of K steps to pack. |
| transA | If true, read A as transposed. |
| layout | Row-major or column-major storage of A. |
Layout is k-major within each MR block so the micro-kernel streams linearly.
static void vm_gemm_pack_b(vm_ float_ t* Bp,
const vm_ float_ t* B,
const int ldb,
const int k0,
const int j0,
const int kb,
const int jb,
const bool transB,
const vm_ layout_ t layout)
Pack a B panel into contiguous NR-wide micro-panels (zero-padded).
| Parameters | |
|---|---|
| Bp | Destination pack buffer. |
| B | Source matrix B. |
| ldb | Leading dimension of B. |
| k0 | Starting K index of the panel. |
| j0 | Starting column of the panel in op(B). |
| kb | Number of K steps to pack. |
| jb | Number of columns to pack. |
| transB | If true, read B as transposed. |
| layout | Row-major or column-major storage of B. |
Layout is k-major within each NR block so the micro-kernel streams linearly.
static void vm_gemm_store_tile(vm_ float_ t* C,
const int ldc,
const vm_ float_ t* acc,
const int i0,
const int j0,
const int mr,
const int nr,
const vm_ float_ t alpha,
const vm_ float_ t beta,
const vm_ layout_ t layout,
const int op,
const vm_ float_ t* bias)
Write a micro-kernel tile into C with alpha/beta and optional epilogue.
| Parameters | |
|---|---|
| C | Output matrix. |
| ldc | Leading dimension of C. |
| acc | MR×NR accumulator from the micro-kernel. |
| i0 | Destination row origin in C. |
| j0 | Destination column origin in C. |
| mr | Active rows in this tile (<= MR). |
| nr | Active columns in this tile (<= NR). |
| alpha | Scale for the accumulator. |
| beta | Scale for existing C (0 skips the read). |
| layout | Row-major or column-major storage of C. |
| op | Epilogue flags (VM_GEMM_OP_*); VM_ skips bias/ReLU. |
| bias | Optional length-N bias vector (used with VM_). |
Computes C = alpha * acc + beta * C. When op != VM_, also adds per-column bias and/or applies ReLU as requested. Callers pass VM_ on non-final K panels so the epilogue runs only once.
static void vm_gemm_scale_c(vm_ float_ t* C,
const int ldc,
const int M,
const int N,
const vm_ float_ t beta,
const vm_ layout_ t layout)
Apply C = beta * C over an M×N panel (alpha==0 / empty product path).
| Parameters | |
|---|---|
| C | Output matrix to scale in place. |
| ldc | Leading dimension of C. |
| M | Number of rows. |
| N | Number of columns. |
| beta | Scale factor (0 zeros the panel). |
| layout | Row-major or column-major storage of C. |
static vm_ float_ t* vm_gemm_alloc_pack(const size_t need)
Allocate a 32-byte-aligned pack buffer for at least need elements.
| Parameters | |
|---|---|
| need | Required element count. |
| Returns | Aligned buffer pointer, or NULL on allocation failure. |
Rounds the byte size up to a multiple of 32 (minimum 32 bytes).
static void vm_gemm_free_pack(vm_ float_ t* p)
Free a pack buffer from vm_.
| Parameters | |
|---|---|
| p | Buffer pointer returned by vm_ (or NULL). |
static vm_ float_ t* vm_gemm_ws_fit(vm_ float_ t** buf,
size_t* cap,
const size_t need)
Grow a pack buffer so it holds at least need elements.
| Parameters | |
|---|---|
| buf | In/out pointer to the buffer (may be reallocated). |
| cap | In/out capacity in elements. |
| need | Required element count. |
| Returns | Pointer to a buffer with capacity >= need, or NULL on OOM. |
Reuses *buf when *cap >= need; otherwise allocates a new aligned buffer, frees the old one, and updates *buf / *cap.
static size_t vm_gemm_pack_a_elems(const int ib, const int kb)
Element count for an A pack covering ib rows and kb K-steps.
| Parameters | |
|---|---|
| ib | Rows in the A panel. |
| kb | K-panel width. |
| Returns | Number of vm_ elements required (MR-padded). |
static size_t vm_gemm_pack_b_elems(const int jb, const int kb)
Element count for a B pack covering jb columns and kb K-steps.
| Parameters | |
|---|---|
| jb | Columns in the B panel. |
| kb | K-panel width. |
| Returns | Number of vm_ elements required (NR-padded). |
static void vm_gemm_apply_packed(vm_ float_ t* C,
const int ldc,
const vm_ float_ t* A,
const int lda,
const vm_ float_ t* Bp,
const int M,
const int jb,
const int kb,
const int ic0,
const int jc,
const int kc,
const vm_ float_ t alpha,
const vm_ float_ t beta_panel,
const bool transA,
const vm_ layout_ t layout,
const int last_k,
const int op,
const vm_ float_ t* bias)
Multiply A panels against a pre-packed B panel and store into C.
| Parameters | |
|---|---|
| C | Output matrix. |
| ldc | Leading dimension of C. |
| A | Left matrix (or NULL to skip). |
| lda | Leading dimension of A. |
| Bp | Pre-packed B panel for this (jc, kc) block. |
| M | Rows of op(A)/C to process from ic0. |
| jb | Columns in the packed B panel. |
| kb | K width of the packed panel. |
| ic0 | Row origin of this A/C slab in the full problem. |
| jc | Column origin in C / op(B). |
| kc | K origin used when packing A. |
| alpha | Scale for the product tiles. |
| beta_panel | Beta for this K panel (beta on first panel, else 1). |
| transA | If true, read A as transposed. |
| layout | Storage layout for A and C. |
| last_k | Nonzero if this is the final K panel (enable epilogue). |
| op | Epilogue flags applied on last K (VM_GEMM_OP_*). |
| bias | Optional bias vector for VM_. |
Walks M in MC blocks, packs each A slab, runs the MR×NR micro-kernel, and writes tiles. Epilogue ops run only when last_k is set. On thread-local A-pack allocation failure, returns without updating C (no fallback).
static void vm_gemm_ex_body(vm_ float_ t* C,
const int ldc,
const vm_ float_ t* A,
const int lda,
const vm_ float_ t* B,
const int ldb,
const int M,
const int N,
const int K,
const vm_ float_ t alpha,
const vm_ float_ t beta,
const bool transA,
const bool transB,
const vm_ layout_ t layout,
const int op,
const vm_ float_ t* bias)
Core blocked GEMM with optional bias/ReLU epilogue.
| Parameters | |
|---|---|
| C | Output matrix (M×N), updated in place. |
| ldc | Leading dimension of C. |
| A | Left input matrix; ignored when alpha == 0 or K <= 0. |
| lda | Leading dimension of A. |
| B | Right input matrix; ignored when alpha == 0 or K <= 0. |
| ldb | Leading dimension of B. |
| M | Number of rows of op(A) and C. |
| N | Number of columns of op(B) and C. |
| K | Inner product length. |
| alpha | Scale factor for the A*B product. |
| beta | Scale factor for existing C on the first K panel. |
| transA | If true, use A^T; otherwise A. |
| transB | If true, use B^T; otherwise B. |
| layout | Memory layout for A, B, and C. |
| op | Epilogue flags (VM_, bias, ReLU, …). |
| bias | Optional length-N bias; used when op includes bias. |
Packs B by NC×KC panels, then applies packed A×B tiles. On allocation failure falls back to vm_ (without epilogue). When the product is empty (alpha==0 / missing inputs / K==0), scales C and still applies op.
void vm_gemm_ex(vm_ float_ t* C,
const int ldc,
const vm_ float_ t* A,
const int lda,
const vm_ float_ t* B,
const int ldb,
const int M,
const int N,
const int K,
const vm_ float_ t alpha,
const vm_ float_ t beta,
const bool transA,
const bool transB,
const vm_ layout_ t layout,
const int op,
const vm_ float_ t* bias)
C = alpha * op(A) * op(B) + beta * C with optional fused epilogue.
| Parameters | |
|---|---|
| C | Output matrix (M×N), updated in place. |
| ldc | Leading dimension of C. |
| A | Left input matrix; ignored when alpha == 0 or K <= 0. |
| lda | Leading dimension of A. |
| B | Right input matrix; ignored when alpha == 0 or K <= 0. |
| ldb | Leading dimension of B. |
| M | Number of rows of op(A) and C. |
| N | Number of columns of op(B) and C. |
| K | Inner product length. |
| alpha | Scale factor for the A*B product. |
| beta | Scale factor for the existing C values. |
| transA | If true, use A^T; otherwise A. |
| transB | If true, use B^T; otherwise B. |
| layout | Memory layout for A, B, and C. |
| op | Epilogue flags (VM_GEMM_OP_*). |
| bias | Optional length-N bias vector (may be NULL). |
Same blocked packed path as vm_, plus last-K bias add and/or ReLU when requested via op.
void vm_gemm(vm_ float_ t* C,
const int ldc,
const vm_ float_ t* A,
const int lda,
const vm_ float_ t* B,
const int ldb,
const int M,
const int N,
const int K,
const vm_ float_ t alpha,
const vm_ float_ t beta,
const bool transA,
const bool transB,
const vm_ layout_ t layout)
C = alpha * op(A) * op(B) + beta * C for dense float panels.
| Parameters | |
|---|---|
| C | Output matrix (M×N), updated in place. |
| ldc | Leading dimension of C. |
| A | Left input matrix; ignored when alpha == 0 or K <= 0. |
| lda | Leading dimension of A. |
| B | Right input matrix; ignored when alpha == 0 or K <= 0. |
| ldb | Leading dimension of B. |
| M | Number of rows of op(A) and C. |
| N | Number of columns of op(B) and C. |
| K | Inner product length. |
| alpha | Scale factor for the A*B product. |
| beta | Scale factor for the existing C values. |
| transA | If true, use A^T; otherwise A. |
| transB | If true, use B^T; otherwise B. |
| layout | Memory layout for A, B, and C. |
Blocked packed kernel with thread-local A/B workspaces. Equivalent to vm_ with op == VM_.
static void vm_gemm_batch_shared_b(vm_ float_ t*const* C,
const int ldc,
const vm_ float_ t*const* A,
const int lda,
const vm_ float_ t* B,
const int ldb,
const int M,
const int N,
const int K,
const vm_ float_ t alpha,
const vm_ float_ t beta,
const bool transA,
const bool transB,
const vm_ layout_ t layout,
const int begin,
const int end)
Batched GEMM with one shared B, packing B once per KC/NC panel.
| Parameters | |
|---|---|
| C | Array of batch output matrix pointers. |
| ldc | Leading dimension shared by every C[p]. |
| A | Array of batch left matrix pointers (per-item A). |
| lda | Leading dimension shared by every A[p]. |
| B | Shared right matrix for all batch items. |
| ldb | Leading dimension of B. |
| M | Rows of op(A) and C (same for all problems). |
| N | Columns of op(B) and C (same for all problems). |
| K | Inner product length (same for all problems). |
| alpha | Scale factor for each A*B product. |
| beta | Scale factor for each existing C[p]. |
| transA | If true, use A^T for every problem. |
| transB | If true, use B^T for the shared B. |
| layout | Memory layout for all panels. |
| begin | First batch index (inclusive). |
| end | Last batch index (exclusive). |
Heap-allocates a B pack for this batch index range. Each KC×NC panel of the shared B is packed once, then applied to every item in [begin, end). Each item still packs its own A via thread-local workspace. On pack allocation failure, falls back to per-item vm_.
static void vm_gemm_batch_range(const int begin, const int end, void* arg)
Runs GEMM for batch indices [begin, end).
| Parameters | |
|---|---|
| begin | First batch index (inclusive). |
| end | Last batch index (exclusive). |
| arg | Pointer to a vm_. |
void vm_gemm_batch(vm_ float_ t*const* C,
const int ldc,
const vm_ float_ t*const* A,
const int lda,
const vm_ float_ t*const* B,
const int ldb,
const int M,
const int N,
const int K,
const vm_ float_ t alpha,
const vm_ float_ t beta,
const bool transA,
const bool transB,
const vm_ layout_ t layout,
const int batch)
Batched GEMM: batch independent GEMMs with shared shape.
| Parameters | |
|---|---|
| C | Array of batch pointers to output matrices (each M×N). |
| ldc | Leading dimension shared by every C[p]. |
| A | Array of batch pointers to left matrices, or NULL. |
| lda | Leading dimension shared by every A[p]. |
| B | Array of batch pointers to right matrices, or NULL. |
| ldb | Leading dimension shared by every B[p]. |
| M | Number of rows of op(A) and C (same for all problems). |
| N | Number of columns of op(B) and C (same for all problems). |
| K | Inner product length (same for all problems). |
| alpha | Scale factor for each A*B product. |
| beta | Scale factor for each existing C[p]. |
| transA | If true, use A^T for every problem; otherwise A. |
| transB | If true, use B^T for every problem; otherwise B. |
| layout | Memory layout for all A, B, and C panels. |
| batch | Number of independent GEMM problems. |
A[p], B[p], C[p] are the p-th problem. If every B[p] aliases the same buffer, uses a shared-B pack path; otherwise runs per-item vm_. The batch range is split across worker threads when the work is large enough.
void vm_gemm_strided_batch(vm_ float_ t* C,
const int ldc,
const int strideC,
const vm_ float_ t* A,
const int lda,
const int strideA,
const vm_ float_ t* B,
const int ldb,
const int strideB,
const int M,
const int N,
const int K,
const vm_ float_ t alpha,
const vm_ float_ t beta,
const bool transA,
const bool transB,
const vm_ layout_ t layout,
const int batch)
Strided batched GEMM: problems live strideX elements apart.
| Parameters | |
|---|---|
| C | Base pointer for output matrices; problem p at C + p*strideC. |
| ldc | Leading dimension shared by every C panel. |
| strideC | Element stride between consecutive C problems. |
| A | Base pointer for left matrices, or NULL; problem p at A + p*strideA. |
| lda | Leading dimension shared by every A panel. |
| strideA | Element stride between consecutive A problems. |
| B | Base pointer for right matrices, or NULL; problem p at B + p*strideB. |
| ldb | Leading dimension shared by every B panel. |
| strideB | Element stride between B problems (0 means one shared B). |
| M | Number of rows of op(A) and C (same for all problems). |
| N | Number of columns of op(B) and C (same for all problems). |
| K | Inner product length (same for all problems). |
| alpha | Scale factor for each A*B product. |
| beta | Scale factor for each existing C panel. |
| transA | If true, use A^T for every problem; otherwise A. |
| transB | If true, use B^T for every problem; otherwise B. |
| layout | Memory layout for all A, B, and C panels. |
| batch | Number of independent GEMM problems. |
Problem p uses A + p * strideA, B + p * strideB, C + p * strideC. When strideB == 0 (shared B), reuses the shared-B batch path.
void vm_im2col(vm_ float_ t* col,
const int ld_col,
const vm_ float_ t* img,
const int n,
const int c,
const int h,
const int w,
const int kh,
const int kw,
const int pad_h,
const int pad_w,
const int stride_h,
const int stride_w,
const vm_ layout_ t layout)
NCHW im2col into a GEMM-ready panel.
| Parameters | |
|---|---|
| col | Destination matrix for unfolded patches. |
| ld_col | Leading dimension of col under layout. |
| img | Source image tensor in NCHW order. |
| n | Batch size (N). |
| c | Channel count (C). |
| h | Input height (H). |
| w | Input width (W). |
| kh | Kernel height. |
| kw | Kernel width. |
| pad_h | Top/bottom padding in pixels. |
| pad_w | Left/right padding in pixels. |
| stride_h | Vertical kernel stride (<= 0 treated as 1). |
| stride_w | Horizontal kernel stride (<= 0 treated as 1). |
| layout | Row-major or column-major storage for col. |
img is N×C×H×W packed as ((n*C+c)*H+y)*W+x. Output has C*kH*kW rows and N*outH*outW columns (zero-filled off-image taps). outH/outW use standard floor division with the given pads and strides; non-positive stride_h / stride_w are treated as 1.