Generated reference › Embedding Lookup — Machine Learning/Neural Networks
kind: generated#block#machine-learning-neural-networks

Embedding Lookup — Machine Learning/Neural Networks

Machine_Learning/Neural_Networks/Embedding_Lookup · 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.

Embedding Lookup

Machine Learning / Neural Networks

Selects one row of a trained embedding table by index: y = table[k, :], delivered as a column [d,1].

This is what turns a token, a category or a mode number into the dense vector a network was trained on – the front end of any model whose input is not a measurement. The index arrives as an ordinary signal and is rounded to the nearest whole number, so 2.0 and 1.9997 select the same row.

Ports

  • k – the index, a scalar [1,1]. Interpreted relative to Index Base.
  • Outputy, a column [d,1], where d is the NUMBER OF COLUMNS of Embedding Table. The selected row transposed into a column; all zeros when the index is out of range and Out Of Range is All Zeros.

Parameters

  • Embedding Table – the trained table, [V,d]: one row per index, which is the orientation torch.nn.Embedding.weight and a Keras Embedding layer both store, so weights paste in without transposing. Its shape is the only size source – V is the number of indices the block knows and d is the width of the output, and there is no second config that could disagree with it.
  • Index Base – what the first row is called:
    • Zero-based (PyTorch, numpy) – index 0 selects the first row. The default.
    • One-based (MATLAB) – index 1 selects the first row.
  • Out Of Range – what an index outside the V rows does:
    • All Zeros – the output is entirely zero. The default, and the one that lets a downstream block notice that nothing was selected. It is also what a padding or unknown token usually means.
    • Clamp To Range – below the first row selects the first, above the last selects the last.
    An index outside the table is not exotic: an unmapped token or a glitched mode number produces one on a live system, and the two settings send it to opposite places.
  • 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. The table, the base and the out-of-range rule are structural and baked in; there is no tunable parameter.

No backend converts the index to an integer, and no backend indexes the table with a signal. The lookup is emitted as one half-open comparison per row – (k − base) − v in −0.5, +0.5) – guarding a copy of that row's d constants. That is the same rule One Hot Encoder uses, it needs no integer type, and it leaves nothing in the emitted code that could read outside the table.

The three HDL targets are ordinary Q16.16 fixed point and are offered for synthesis: one subtraction, V comparisons and d assignments, with no multiplier and no transcendental. The cost is V×d constants in the emitted body rather than one indexed read – the honest price of a lookup that carries no address arithmetic, at the table sizes a deployed model uses.

Simulink bridge

None. Simulink's Deep Learning blocks take a trained network object, which no parameter mapping can carry, and Direct Lookup Table (n-D) is not this block: it takes an index per dimension and returns the single element they address, not a whole row. 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.

Notes

  • Algebraic and stateless: the output depends only on the current index, so the block cannot break an algebraic loop.
  • Nonlinear and discontinuous, and deliberately carries no state space.
  • The rounding boundary is a discontinuity, and the HDL targets sit one quantum away from the reference. They compare Q16.16 values (one quantum ≈ 1.5e-5) where the in-app run compares doubles, so an index within that distance of a ±0.5 boundary can round the other way and select a different row – and a different row is a whole different vector, not a rounding error. Feed this block a genuinely integral index – which is what a token is – and the question never arises. The same caveat governs One Hot Encoder and Argmax Decision.
  • Ordinary numbers, not a fitted object: the table is config, so nothing is loaded at run time and every target exports without a framework.

Code facts#

FactValue
registered typeMachine_Learning/Neural_Networks/Embedding_Lookup
familyMachine_Learning/Neural_Networks
solver environment classICoreBlock_0_Machine_Learning_1_Neural_Networks_2_Embedding_Lookup
source[src/ICoreSDK/ICoreBlockLibrary/Blocks/Machine_Learning/Neural_Networks/Embedding_Lookup/ICoreBlock_0_Machine_Learning_1_Neural_Networks_2_Embedding_Lookup.cpp
headersrc/ICoreSDK/ICoreBlockLibrary/Blocks/Machine_Learning/Neural_Networks/Embedding_Lookup/ICoreBlock_0_Machine_Learning_1_Neural_Networks_2_Embedding_Lookup.h
default size on canvas126 × 84 px
ports at insert1 in, 1 out
code generators implementedPython, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Ports#

#DirectionSignal typeDescription label
1inICoreDoublek
2outICoreDoubley

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 variableDefaultSimulink parameter
Embedding Table0.45 -1.2 0.75; -0.85 0.3 1.4; 1.15 0.95 -0.35; -0.25 -0…
Index BaseZero-based (PyTorch, numpy)%~%One-based (MATLAB)~~Zero-ba…
Out Of RangeAll Zeros%~%Clamp To Range~~All Zeros

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.

supportSupport::None
Simulink path
port-count rulePortsParam::None
SampleTime parameteryes

Caveat (shown to the user): no Simulink equivalent: the Deep Learning blocks take a trained network OBJECT, which no parameter mapping can carry, and Direct Lookup Table (n-D) returns the single element its indices address rather than a whole row of a table

Catalog contract: [src/ICoreSDK/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h

Description vs code#

The lists agree. check_block_descriptions.py finds no disagreement between the description's Ports, Parameters, Code export and Simulink bridge lists and the code's.

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).

Embedding Lookup — a token index in, the matching row of a [V,d] table out as [d,1] y = table[v, :]' where (k - base) - v lies in [-0.5, +0.5) else 0

The selection rule is One_Hot_Encoder's, shared deliberately rather than re-derived: the two blocks sit at the same seam of the same model, and an index the encoder calls class 3 must be the index this block calls row 3. See the header for why no backend converts the index to an integer, and why the selected row is ASSIGNED rather than accumulated through an indicator.

The three HDL targets are genuine Q16.16 -- one subtraction, V comparisons and d copies, with no multiplication anywhere and nothing transcendental.

Sample results#

Embedding Lookup — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sampleEmbedding Lookup — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample-1-0.500.51-2-10123inputoutput
tin ICoreDouble-Out-0out ICoreDouble-Out-0 [3x1] entry 0
0-2[0, 0, 0]
0.40.5[-0.85, 0.3, 1.4]
0.8-2[0, 0, 0]
1.20.5[-0.85, 0.3, 1.4]
1.6-2[0, 0, 0]
20.5[-0.85, 0.3, 1.4]
2.4-2[0, 0, 0]
2.80.5[-0.85, 0.3, 1.4]
3.2-2[0, 0, 0]
3.60.5[-0.85, 0.3, 1.4]
4-2[0, 0, 0]
4.40.5[-0.85, 0.3, 1.4]
4.8-2[0, 0, 0]
5.20.5[-0.85, 0.3, 1.4]

Every 4th of 60 samples, from the table stimulus.

The same rig also ran:

StimulusWhat it isOutput range
impulseImpulse: one sample of 1 at k = 5, 0 elsewhere (Repeating Sequence Stair)-0.85 … 0.45
rampRamp: slope 1 from t = 0-0.85 … 1.15
sineSine Wave: amplitude 1, 2 rad/s, no phase, no bias-0.85 … 0.45
stepStep: 0 -> 1 at t = 1 s-0.85 … 0.45

Plotted: table — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample

Category static · sample time 0.1 · 60 steps · commit ccf005c8 · produced by docsSample --out <folder> --steps 60 · data docs/generated/samples/Machine_Learning__Neural_Networks__Embedding_Lookup.json · the SVG is generated from those numbers by tools/docs/plot_svg.py, so it is a run and not a drawing (R-D10).