Deepity
Ultra-fast, SIMD-accelerated Predictive Coding
Loading...
Searching...
No Matches
Im2Col.h File Reference

Standalone im2col / col2im utilities: convolution expressed as matrix multiplication, so ConvPCLayer can reuse cblas_sgemm rather than needing hand-written conv kernels. More...

#include <cstddef>
#include <cstring>
#include <immintrin.h>

Go to the source code of this file.

Namespaces

namespace  Deep
 This file exists to provide both Tensor.h and IComputeBackend.h with device types without introducing circular dependencies.

Functions

int Deep::ConvOutDim (int inDim, int kernel, int stride, int pad) noexcept
 Computes a single convolution output dimension (height or width) from its corresponding input dimension and conv parameters.
void Deep::Im2Col (const float *input, int channels, int height, int width, int kH, int kW, int strideH, int strideW, int padH, int padW, float *columns) noexcept
 Rearranges a single (channels, height, width) input image into a (channels*kH*kW, outH*outW) column matrix, where each column holds one flattened receptive-field patch – the standard im2col transform that lets convolution be computed as a single GEMM against a (outChannels, channels*kH*kW) weight matrix.
void Deep::Col2Im (const float *columns, int channels, int height, int width, int kH, int kW, int strideH, int strideW, int padH, int padW, float *outputImage) noexcept
 The adjoint of Im2Col(): scatters a (channels*kH*kW, outH*outW) column-gradient buffer back into a (channels, height, width) image.

Detailed Description

Standalone im2col / col2im utilities: convolution expressed as matrix multiplication, so ConvPCLayer can reuse cblas_sgemm rather than needing hand-written conv kernels.

VERIFIED: passed tConvVerify.cpp – naive-reference comparison across three shape configurations (max error ~1e-6, float32 GEMM accumulation tolerance) AND an exact adjoint check (<Wx,y> == <x,W^Ty>, |diff|=0), confirming Col2Im is the TRUE adjoint of Im2Col, not just a plausible-looking inverse-shaped operation. This matters because ConvPCLayer's UpdateState() feedback term relies on that adjoint property the same way DiscriminativePCLayer's feedback term relies on W^T being the genuine transpose.

Layout convention: NCHW. A single batch item's input is (channels, height, width), row-major, contiguous per channel.

im2col output shape: (channels*kH*kW, outH*outW) – each column is one flattened receptive-field patch, ready to be GEMM'd against a (outChannels, channels*kH*kW) weight matrix to produce (outChannels, outH*outW) in one matrix multiply.

col2im is the adjoint operation: scatters a (channels*kH*kW, outH*outW) gradient buffer back into a (channels, height, width) image, ACCUMULATING (does not zero the destination first – caller must memset if needed).

Neither function knows anything about batching – call once per batch item, with pointers offset to that item's slice.

Note
Each SIMD width (AVX-512/AVX2+AVX/SSE) is handled as a separate preprocessor branch with its own scalar-tail fallback along the stride-1 fast path; the strided (strideW != 1) path is always scalar, since a fixed vector width can't align with an arbitrary stride.
Version
1.0
Date
2026-06-30
Author
Jack Rose