Three backends left, as the operator specified: OpenCL, the CPU DLL,
and pure MQL5. CDirectMLMy was a two-tier wrapper (GPU via
WarriorDML.dll, CPU via WarriorCPU.dll) whose name only ever named the
tier being removed here; the CPU DLL tier - the one actually used on
the training machine (no OpenCL, no DirectML) - is untouched.
AI/NeuronDirectML.mqh -> AI/ComputeDll.mqh: dropped the DML_* #import
block and COMPUTE_TIER_GPU (checked first that nothing persists the
enum value and only one external site reads .Tier() - safe), collapsed
every tier==CPU?CPU_x():DML_x() ternary to a straight CPU_x() call.
Renamed CDirectMLMy->CComputeDll, InitDirectML()->InitComputeDll(),
member directml/DirectML->computeDll/ComputeDll across every AI/ file
that touched a neuron/net backend plus Topology.mqh/OnlineLearning.mqh.
NetBuild.mqh's InitComputeDll also lost the dead D3D12 error-code
switch and the now-impossible GPU-tier log branch.
Verified via per-file brace-balance diff against HEAD and a whole-repo
grep for every removed symbol (CDirectMLMy/InitDirectML/
COMPUTE_TIER_GPU/DML_*) - the only surviving hit is an intentional
historical-note comment in the new file's header.
DirectML\WarriorDML.cpp/.h and its build scripts are now orphaned C++
source, left in place pending an operator decision. Architecture docs
(AI_NETWORK.md, Warrior_EA_System_Overview.md, etc.) still describe the
4-backend/GPU-tier shape and are not updated in this pass.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
MQL5's MathRand() is the 15-bit MSVC LCG - 32768 distinct values and
the lattice structure that shape of generator has. Two places here
actually lean on randomness and both were hurt by it:
WEIGHT INIT. Six He/LeCun-uniform sites drew
((MathRand()+1)/32768.0 - 0.5) * 2 * scale, so a first dense layer of
~250k weights had only 32768 possible values and thousands of
connections started byte-identical. Breaking that symmetry is the whole
job of random init.
SHUFFLING. ShuffleRandomIndex() already had to splice TWO MathRand()
draws to reach 30 bits, and its own comment documented the residual
modulo bias it still carried. HQRndUniformI() is rejection-sampled and
exactly uniform, so the splice and the bias note both go.
CHighQualityRand is L'Ecuyer's combined multiplicative congruential
generator - two differenced streams, 31-bit output, period ~2.3e18 -
and it ships with the terminal.
AND A BUG THE MIGRATION EXPOSED. The three MathSrand(GetTickCount())
calls sit immediately before "build a fresh topology", once per model.
GetTickCount() steps in ~15.6 ms on Windows and an ensemble builds every
member inside one OnInit, so members could be handed the SAME seed and
draw the SAME weights wherever their shapes coincide - and members that
start identical are not an ensemble. WarriorRandSeed() takes a salt (the
model id) plus a never-reset call counter, so a collision is impossible
rather than merely unlikely, while the tick keeps the run itself
genuinely unrepeatable the way those call sites asked for.
Seeds are masked positive rather than trusted: HQRndSeed computes
s % (M-1) + 1 and MQL5's % keeps the sign, so a negative seed leaves the
generator in a state its own assertions reject. GetTickCount() is a uint
and goes negative as an int after ~24 days of uptime - a fault that
would surface as "training is broken" on a long-running terminal and
nowhere else.
The indicator tuner's 52 draws move across too: its random search is
where sample quality earns its keep.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Rename the original `CreateElement` with a defaulted `weighScale` parameter to `CreateElementScaled` and provide a proper virtual override that matches the base `CArrayObj::CreateElement` signature exactly. This ensures `CArrayObj::Load()` dispatches correctly, fixing a bug where every saved model load failed at the first layer. Update all call sites in `CNeuronBase::Init` and `CNeuronPool::Init`. Additionally, enhance error diagnostics in `CNet::Load` to distinguish between file truncation and code faults (such as the signature mismatch).
- Added optional `weighScale` parameter (default -1.0) to `CNeuronBase::Init` and `CLayer::CreateElement`.
- Updated `CNeuronPool::Init` to use LeCun-uniform scaling (1/sqrt(window+1)) for its base initialization.
- Updated `CNet::CNet` to use He-scaled initialization (sqrt(2/neurons)) for dense layers.
- These changes enable more flexible and statistically sound weight initialization, matching the rationale used in OCL-based implementations, leading to better training stability and convergence.
AI/Network.mqh was 5,805 lines / 18 classes in one file. Investigation
found method implementations for several classes (CNeuronBase/Pool/Conv,
CNeuronBaseOCL) hand-interleaved across thousands of lines - not safe to
split without risky manual reassembly. But 8 classes turned out to be
genuinely self-contained (declaration + every method body physically
contiguous, and only ever depended upon, never depending on anything
declared later): CConnection/CArrayCon, CNeuron, CDirectMLMy (+ its
WarriorDML.dll/WarriorCPU.dll #import blocks), CArrayLayer,
CLayerDescription, CBufferDouble, and CNeuronConvOCL/CNeuronPoolOCL.
Extracted each verbatim, via exact line-range extraction (not manual
retyping) to eliminate transcription risk, into its own AI/*.mqh file,
included from Network.mqh at the exact point each class used to sit -
preserving original declaration order exactly. Mathematically verified
byte-for-byte: reconstructing the original file from the 7 new files'
bodies + Network.mqh's remaining segments is line-for-line identical to
the pre-split git history. Compiled clean (MetaEditor, 0 errors/0
warnings) both before and after.
The remaining tangled classes (CNeuronBase, CNeuronPool, CNeuronConv,
CNet, CNeuronLSTM, CNeuronBaseOCL, CNeuronConvOCL/PoolOCL's shared base,
CNeuronLSTMOCL, COpenCLMy) stay in Network.mqh (now ~4,450 lines) -
splitting those safely needs deliberate per-method surgery, deferred to
a future dedicated pass rather than rushed into this one.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>