# AI/ — neural network subsystem The engine behind the four AI signal modules (`CSignalPAI`, `CSignalCONV`, `CSignalLSTM`, `CSignalHYBRID`). It is a from-scratch MQL5 network — no external ML runtime — with four interchangeable compute tiers behind one interface. ## File layout `AI\Network.mqh` is the entry point and the only file anything outside `AI\` includes. It holds **declarations only**: the nine core classes, the compile-time constants, and the nested include chain that orders them. Each nested `#include` sits exactly where its base class becomes visible, so that order is a dependency graph, not a preference — do not reorder it. | file | holds | |---|---| | `Network.mqh` | class declarations, tuning constants, include chain | | `Network.cl` | OpenCL kernels (see below) | | `NeuronPrimitives.mqh` | `CConnection` / `CArrayCon` — weight storage | | `NeuronCPU.mqh` | `CNeuron` — pure-MQL5 dense neuron | | `NeuronDirectML.mqh` | `CDirectMLMy` — DirectML + CPU-DLL bridge (`#import`ed DLLs) | | `ArrayLayer.mqh` | `CArrayLayer` — the layer collection | | `LayerDescription.mqh` | `CLayerDescription` — the topology descriptor | | `BufferDouble.mqh` | `CBufferDouble` — host/device buffer | | `NeuronOCLConvPool.mqh` | `CNeuronConvOCL`, `CNeuronPoolOCL` | | `NeuronBatchNorm.mqh` | `CNeuronBatchNormOCL` — host-side batch norm, all tiers | Method **bodies** live in `AI\Impl\`, included at the bottom of `Network.mqh` after every declaration. This is a pure relocation — a body cannot run during compilation, and every declaration it could reference is already visible above it. | `AI\Impl\` | holds | |---|---| | `NeuronBase.mqh` | `CNeuronBase` — init, forward, gradients, activation, persistence | | `NeuronConvPool.mqh` | `CNeuronConv`, `CNeuronPool` | | `NeuronLSTM.mqh` | `CNeuronLSTM` — gate layers, BPTT | | `Layer.mqh` | `CLayer` — element construction from a descriptor or a `.nnw` stream | | `NetBuild.mqh` | `CNet` lifecycle: topology construction, OpenCL/DirectML init | | `NetForward.mqh` | `feedForward`, `backProp`, `getResults`, logit adjustment | | `NetPersistence.mqh` | `CNet::Save` / `CNet::Load` — the `.nnw` format | | `NetWeights.mqh` | EMA blend, in-memory snapshot/restore, per-layer learning report | | `NeuronOCLBase.mqh` | `CNeuronBaseOCL` | | `NeuronOCLLSTM.mqh` | `CNeuronLSTMOCL` — sequence LSTM, fused kernels, BPTT caches | ## Compute tiers Selected once at construction and logged; each layer runs entirely on one tier. 1. **OpenCL** — `Network.cl`, compiled from the `#resource` at startup. 2. **DirectML** — `WarriorDML.dll` (D3D12 compute). 3. **CPU DLL** — `WarriorCPU.dll`, a threaded fallback. Thread count is fixed at `CPU_THREADS_PER_NETWORK` per net rather than a share of the machine; see the comment on that constant for why a machine-wide budget was wrong. 4. **Pure MQL5** — no DLL, no GPU. Single backtests run here so a Market build (which strips every `#import`) is still able to infer. A Market build (`WARRIOR_MARKET_BUILD`) compiles tiers 2 and 3 out entirely. ## Classes - **`CNet`** — owns the layer stack, the forward/backward passes and `.nnw` persistence. Note that a `.nnw` pins the **architecture**, not just the weights: `Save` writes each layer's activation and `Load` restores it, so a head activation changed in source only ever reaches a brand-new topology. `EnforceOutputActivation()` re-asserts it after every load. - **`CLayer` / `CArrayLayer`** — neuron containers; `CreateElementScaled()` is the single construction point for every neuron type, from a descriptor or from a file stream. - **`CNeuronBase` → `CNeuron` / `CNeuronPool` / `CNeuronConv` / `CNeuronLSTM`** — the pure-MQL5 family. - **`CNeuronBaseOCL` → `CNeuronLSTMOCL` / `CNeuronConvOCL` / `CNeuronPoolOCL` / `CNeuronBatchNormOCL`** — the accelerated family. Despite the `OCL` suffix these also drive the DirectML and CPU-DLL tiers. `ENUM_ACTIVATION` is `NONE, TANH, SIGMOID, PRELU`; `ENUM_OPTIMIZATION` is `SGD, ADAM`. `NativeActivationCode()` translates to the int code the backends share — and deliberately makes `NONE` fall through every backend switch. ## Network.cl 22 kernels in four groups: dense (`FeedForward`, `CaclOutputGradient`, `CaclHiddenGradient`, `UpdateWeightsMomentum/Adam`), conv/pool (`FeedForwardConv`, `FeedForwardProof`, `CalcHiddenGradientConv`, `CalcInputGradientProof`, `UpdateWeightsConv*`), single-step LSTM (`LSTM_Gates`, `LSTM_State`, `LSTM_*Gradient`) and sequence LSTM (`LSTM_SeqStep*`, `LSTM_UpdateWeights*`). Two invariants worth knowing before touching them: - `MIN_ACTIVATION_DERIVATIVE` (1.0e-3f) floors every LSTM gate derivative in both gradient kernels. It is already there — do not "add" it. - Kernel math is mirrored in `DirectML\WarriorCPU.cpp` and `WarriorDML.cpp`. A change to one is a change to all three, or the tiers silently diverge. ## Usage ``` CNet *net = new CNet(topology); // CArrayObj of CLayerDescription net.feedForward(inputs); // CArrayDouble net.backProp(targets, weight); net.getResults(out); net.Save(path, ...); net.Load(path, ...); ``` The 3-output classification case is special-cased in `backProp`/`backPropOCL`: it computes a joint softmax + cross-entropy gradient across all three neurons rather than three independent per-neuron deltas. ## Known gaps - No unit tests. Changes are validated by compile + a live era's `dW/W` line (`CNet::LayerLearningReport`), which is the only reliable check that a layer is actually receiving gradient in the assembled net. - No dedicated SoftMax layer; the head is `Dense(SIGMOID)` with the gradient short-circuited. See `REFACTOR_NOTES.md` §G for why, and for what would have to move together to change it.