//+------------------------------------------------------------------+ //| Warrior_EA | //| Multithreaded CPU compute fallback - used when neither | //| OpenCL nor the D3D12/DirectML tier are available (e.g. | //| a VM with no GPU passthrough). Same buffer-handle model | //| as WarriorDML.dll but full double precision throughout | //| (no GPU float roundtrip) and work is spread across a | //| configurable pool of worker threads instead of a device. | //+------------------------------------------------------------------+ // Flat C ABI so MQL5 can #import this DLL directly. Function names and // argument order/semantics mirror WarriorDML.h / AI\Network.cl 1:1 so the // two backends are interchangeable behind CDirectMLMy in AI\Network.mqh. #pragma once #define WARRIORCPU_API extern "C" __declspec(dllexport) // Every exported function (besides CPU_Init/CPU_GetHardwareConcurrency) takes a // CpuHandle as its first argument - an opaque pointer to a heap-allocated, // self-contained context (its own thread pool, buffer table and mutex) that // CPU_Init() allocates and the caller (CDirectMLMy on the MQL5 side) is // responsible for remembering and passing back on every subsequent call, then // releasing via CPU_Shutdown(). No state is shared between contexts and this // DLL keeps no global/static mutable state of its own, so it can be loaded any // number of times and driven by any number of instances/threads in parallel - // a fault or a wedged call against one context can never poison another // context's calls, unlike a process-wide singleton would. // A plain `long long` (not C++ `long`, which is only 32 bits on Windows) so it // round-trips exactly through MQL5's 64-bit `long` on the #import side. typedef long long CpuHandle; // Lifecycle. CPU_Init(threads) always succeeds (returns a non-zero handle) // since it needs no hardware - threads<=0 means "use // std::thread::hardware_concurrency()". Returns 0 on failure. WARRIORCPU_API CpuHandle __stdcall CPU_Init(int threads); WARRIORCPU_API void __stdcall CPU_Shutdown(CpuHandle ctx); WARRIORCPU_API int __stdcall CPU_GetLastError(CpuHandle ctx); WARRIORCPU_API int __stdcall CPU_GetThreadCount(CpuHandle ctx); // Stateless: true std::thread::hardware_concurrency(), independent of any // context's pool size. Use this (not a CPU_Init(0)/GetThreadCount()/Shutdown() // probe) to size a CPU_Init() request. WARRIORCPU_API int __stdcall CPU_GetHardwareConcurrency(); // Buffer management. Handles are small non-negative integers scoped to ctx; // -1 means failure. Buffers are plain double vectors owned by ctx; Write/Read // just memcpy in/out, there is no upload/download step on CPU. WARRIORCPU_API int __stdcall CPU_BufferCreate(CpuHandle ctx, int elementCount); WARRIORCPU_API int __stdcall CPU_BufferWrite(CpuHandle ctx, int handle, const double *data, int count); WARRIORCPU_API int __stdcall CPU_BufferRead(CpuHandle ctx, int handle, double *data, int count); WARRIORCPU_API void __stdcall CPU_BufferFree(CpuHandle ctx, int handle); // Compute kernels - argument order/semantics mirror AI\Network.cl and // WarriorDML.h 1:1. activation: 0 = TANH, 1 = SIGMOID, 2 = PReLU (conv only). WARRIORCPU_API int __stdcall CPU_FeedForward(CpuHandle ctx, int wHandle, int iHandle, int oHandle, int inputs, int activation); WARRIORCPU_API int __stdcall CPU_CalcOutputGradient(CpuHandle ctx, int tHandle, int oHandle, int igHandle, int activation, int count); WARRIORCPU_API int __stdcall CPU_CalcHiddenGradient(CpuHandle ctx, int wHandle, int gHandle, int oHandle, int igHandle, int outputs, int activation, int count); WARRIORCPU_API int __stdcall CPU_UpdateWeightsMomentum(CpuHandle ctx, int wHandle, int gHandle, int iHandle, int dwHandle, int inputs, double learningRate, double momentum, int neurons); WARRIORCPU_API int __stdcall CPU_UpdateWeightsAdam(CpuHandle ctx, int wHandle, int gHandle, int iHandle, int mHandle, int vHandle, int inputs, double lt, double b1, double b2, int neurons); WARRIORCPU_API int __stdcall CPU_FeedForwardConv(CpuHandle ctx, int wHandle, int iHandle, int oHandle, int inputs, int step, int windowIn, int windowOut, int activation, int positions); WARRIORCPU_API int __stdcall CPU_CalcHiddenGradientConv(CpuHandle ctx, int wHandle, int gHandle, int oHandle, int igHandle, int outputs, int step, int windowIn, int windowOut, int activation, int inputCount); WARRIORCPU_API int __stdcall CPU_UpdateWeightsConvMomentum(CpuHandle ctx, int wHandle, int gHandle, int iHandle, int dwHandle, int inputs, double learningRate, double momentum, int windowIn, int windowOut, int step); WARRIORCPU_API int __stdcall CPU_UpdateWeightsConvAdam(CpuHandle ctx, int wHandle, int gHandle, int iHandle, int mHandle, int vHandle, int inputs, double lt, double b1, double b2, int windowIn, int windowOut, int step); WARRIORCPU_API int __stdcall CPU_LSTMGates(CpuHandle ctx, int wHandle, int hiddenPrevHandle, int inputsHandle, int concatenatedHandle, int hiddenSize, int inputSize); WARRIORCPU_API int __stdcall CPU_LSTMState(CpuHandle ctx, int concatenatedHandle, int memoryHandle, int hiddenPrevHandle, int hiddenCacheHandle, int outputHandle, int hiddenSize); WARRIORCPU_API int __stdcall CPU_LSTMGateGradient(CpuHandle ctx, int gradientHandle, int memoryHandle, int concatenatedHandle, int concatenatedGradientHandle, int hiddenSize); WARRIORCPU_API int __stdcall CPU_LSTMWeightsGradient(CpuHandle ctx, int concatenatedGradientHandle, int hiddenCacheHandle, int inputsHandle, int weightsGradientHandle, int hiddenSize, int inputSize); WARRIORCPU_API int __stdcall CPU_LSTMInputsGradient(CpuHandle ctx, int concatenatedGradientHandle, int wHandle, int inputsGradientHandle, int hiddenSize, int inputSize); WARRIORCPU_API int __stdcall CPU_LSTMUpdateWeightsAdam(CpuHandle ctx, int wHandle, int weightsGradientHandle, int mHandle, int vHandle, double l, double b1, double b2, int total); WARRIORCPU_API int __stdcall CPU_LSTMUpdateWeightsMomentum(CpuHandle ctx, int wHandle, int weightsGradientHandle, int dwHandle, double learningRate, double momentum, int total); WARRIORCPU_API int __stdcall CPU_FeedForwardProof(CpuHandle ctx, int iHandle, int oHandle, int inputs, int window, int step, int outputs); WARRIORCPU_API int __stdcall CPU_CalcInputGradientProof(CpuHandle ctx, int iHandle, int gHandle, int oHandle, int igHandle, int outputs, int window, int step, int inputs);