Pooling 1D — Machine Learning/Neural Networks
Machine_Learning/Neural_Networks/Pooling_1D · 1 input / 1 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text
Description#
The block's own DESCRIPTION_HTML, rendered verbatim — the same text the config dialog's info panel and the library navigator show. Fix a wrong sentence in the block's .cpp (R-D9), never here.
Pooling 1D
Machine Learning / Neural Networks
Downsamples a column by reducing each sliding window to one value:
yi = max(uiS … uiS+K−1) or mean(…), with Lout = ⌊(L − K) ÷ S⌋ + 1
This is the downsampler that follows a Conv 1D in any 1-D CNN: it shortens the sequence and, in Max mode, keeps the strongest response in each window rather than averaging it away.
Ports
- u – the sequence, a column [L,1]. L must be at least Pool Size, or there is no complete window and the block is reported.
- Output – y, a column [Lout,1] with Lout as above. The block resizes its output when L, the window or the stride changes, so a downstream block sees the new length.
Parameters
- Pooling – which reduction:
- Max – the largest entry in the window. The default.
- Average – the mean of the window.
- Pool Size – K, the window length in samples; a whole number ≥ 1. Rounded to the nearest whole number if you give it a fraction.
- Stride – S, how far the window advances each step; a whole number ≥ 1. S = K is non-overlapping pooling, the usual choice.
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text. Every window is unrolled at export time – L, K and S are all known once the model is built – so no backend emits a loop bound or an index type. The mode and the window geometry are structural and baked in; there is no tunable parameter.
The three HDL targets are ordinary Q16.16 fixed point and are offered for synthesis: a max is a comparison, and an average is a sum times a constant reciprocal formed at export time, so no divider and no transcendental appears in the datapath.
Simulink bridge
None. Simulink's pooling lives inside its Deep Learning layer blocks,
which take a trained network object rather than a signal, and no config
value can carry an object across the bridge. The bridge reports the block rather
than dropping it silently, and it has no parity testbench, which is the
documented consequence of Support::None rather than a gap. Code
export verification still covers it across all ten languages.
Notes
- Algebraic and stateless: the whole window comes from the current input column, not from past samples. This block pools across the vector, not across time – for a window over TIME, put a delay line in front of it.
- Nonlinear in Max mode, so it deliberately carries no state space. Average mode is linear, but a state space that were valid in only one of two configurations would be worse than none, so neither declares one.
- The tail is dropped, exactly as in every framework: if (L − K) is not a multiple of S, the samples past the last complete window are not read. Nothing is padded – that is Conv 1D's job.
- Max mode breaks ties toward the earlier sample, which matters only for which index the value came from, not for the value itself – the output is the value, so ties cannot change it.
Code facts#
| Fact | Value |
|---|---|
| registered type | Machine_Learning/Neural_Networks/Pooling_1D |
| family | Machine_Learning/Neural_Networks |
| solver environment class | ICoreBlock_0_Machine_Learning_1_Neural_Networks_2_Pooling_1D |
| source | src/ICoreSDK/ICoreBlockLibrary/Blocks/Machine_Learning/Neural_Networks/Pooling_1D/ICoreBlock_0_Machine_Learning_1_Neural_Networks_2_Pooling_1D.cpp |
| header | src/ICoreSDK/ICoreBlockLibrary/Blocks/Machine_Learning/Neural_Networks/Pooling_1D/ICoreBlock_0_Machine_Learning_1_Neural_Networks_2_Pooling_1D.h |
| default size on canvas | 110 × 80 px |
| ports at insert | 1 in, 1 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | in | ICoreDouble | u |
| 2 | out | ICoreDouble | y |
Ports the constructor creates. A block whose port list changes with its configuration adds or removes ports at load time; the count above is the one a freshly inserted block has.
Configuration variables#
| Config variable | Default | Simulink parameter |
|---|---|---|
Pooling | Max%~%Average~~Max | — |
Pool Size | 3 | — |
Stride | 2 | — |
Every block also carries Sampling Time (s) from ICoreBlockSolverEnvironment: zero or less inherits the solver's rate, a positive value runs the block at that period.
Simulink bridge#
| support | Support::None |
| Simulink path | — |
| port-count rule | PortsParam::None |
SampleTime parameter | yes |
Caveat (shown to the user): no Simulink equivalent as a signal block: its pooling exists only inside the Deep Learning layer blocks, which take a trained network OBJECT rather than a signal, and no config value crosses the bridge as an object
Catalog contract: src/ICoreSDK/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h
Description vs code#
The checker has a blind spot here — it could not resolve something (a grouped port bullet, a computed config name), which is reported and never counted as a pass. A reader has to settle it:
B0every stimulus in the sample errored — cross-checks skipped
The verdict above is
tools/docs/check_block_descriptions.py(P7.1), which compares LISTS. It cannot read a sentence: "stateless" on a block with a state, an initial-value semantic the recursion does not implement, a "not synthesizable" caveat the HDL banner contradicts. That is the agent audit (P7.3) on BLOCK_DESCRIPTION_AUDIT.md, and this tool's green is not a substitute for one.
File banner (developer view)#
The top comment of the block's .cpp — the maths, the realization and the export strategy, addressed to whoever changes it. It must not contradict the description above (P7.5).
Pooling 1D — max or average over a sliding window y[i] = max(u[i*S .. i*S+K-1]) or mean(...), Lout = floor((L - K)/S) + 1
Window arithmetic identical to Conv_1D's, with no weights. Both windows are UNROLLED at export time -- L, K and S are all known once the model is built -- so no backend emits a loop bound or an index type, and PLC and the HDLs get the same straight-line code as C.
The three HDL targets are genuine Q16.16: max is a comparison and average is a sum times a constant reciprocal, neither of which is transcendental. That reciprocal is formed ONCE at export time (1/K is a config-derived constant), which is what keeps a divider out of the datapath -- the same move Standard_Scaler makes with its scale.
Sample results#
No stimulus produced a sampled output in this rig — Window longer than the signal at: ICore Blocks/Home/Pooling 1D. That is a fact about the single-block rig, not a verdict on the block: an offline batch fit, a block whose output only appears at onSolverFinish, or one that needs a driven environment cannot be exercised alone.
Category unsampled · sample time 0.1 · 60 steps · commit ccf005c8 · produced by docsSample --out <folder> --steps 60
Sample data: docs/generated/samples/Machine_Learning__Neural_Networks__Pooling_1D.json