forked from animatedread/Warrior_EA
THE OPTIMIZER ("0.1% an hour per agent", 0 of 39 passes in 78 min,
12 agents): the tester fires OnTimer on SIMULATED time, so the live
chart's 500ms EventSetMillisecondTimer over a 2016-2026 pass is ~600
MILLION OnTimer calls - each walking 4x PollTraining, the vote
readout's string build, the overlay advance and the deployed census.
None of it serves an inference-only pass: training never runs, per-bar
inference is driven by OnTickHandler off the tick stream, the risk
budget re-checks in OnTick, and there is no chart to keep fresh.
StepSetTimer now arms EventSetTimer(3600) in tester/optimizer/forward
(~2,600 calls per pass) and keeps the 500ms timer for live charts.
Plus a TESTER PASS SELF-PROFILE: per-tick buckets (pre / Expert.OnTick
/ journal) and the timer total, printed once at the pass's OnDeinit -
so if a pass is still slow it names its own consumer instead of being
diagnosed from outside.
OFFLOAD (operator: "as much calculation as possible to DLL/OpenCL"):
batch norm was the ONE stage still host-side on the DLL tier - the
device path was OpenCL-only, so every sample crossed the bus twice per
BN layer and normalized in interpreted MQL5 (and every model runs
batchnorm ON). Four new exports mirror AI\Network.cl's BatchNorm*
kernels 1:1 in DOUBLE precision (closer to the host reference than
the float OpenCL kernels): forward with running stats + frozen flag,
hidden gradient with the clamp derivative, gamma/beta accumulate, and
the batch-mean apply (no weight decay, moments-before-skip ordering,
sqrt-stored v). BnDeviceEligible/EnsureBnDeviceBuffers/all four
Dispatch* now route by backend; the EXISTING in-situ self-checks
(host-vs-device on the first real sample, latch-off + host fallback on
mismatch) verify the DLL kernels exactly as they verified OpenCL ones.
batch_accum_check regression: ALL CHECKS PASSED on the rebuilt DLL.
Same deployment coupling as bd46374: the .ex5 imports the new exports
- copy DirectML\WarriorCPU.dll into MQL5\Libraries (terminal closed)
together with the new .ex5, and re-copy it to the tester agents (or
just run DirectML\build_cpu.bat once with everything closed - it
deploys to every discovered Libraries folder).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
221 lines
20 KiB
MQL5
221 lines
20 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//+------------------------------------------------------------------+
|
|
//| ComputeDll.mqh |
|
|
//| AnimateDread |
|
|
//| https://www.mql5.com |
|
|
//| CComputeDll + the WarriorCPU.dll #import block it wraps - the |
|
|
//| multithreaded-CPU compute tier used when OpenCL is unavailable. |
|
|
//| Self-contained - nothing outside this class touches CPU_* import |
|
|
//| functions directly. |
|
|
//| Formerly NeuronDirectML.mqh / CDirectMLMy: the D3D12/DirectML GPU |
|
|
//| tier (WarriorDML.dll) it also used to front was removed entirely |
|
|
//| (operator directive 2026-08-23) - three backends left: OpenCL, |
|
|
//| this CPU DLL, pure MQL5. See project_solid_campaign_plan S1.5. |
|
|
//+------------------------------------------------------------------+
|
|
//| CPU thread-pool fallback tier - used when OpenCL is unavailable |
|
|
//| (e.g. a VM with no GPU passthrough). Full double precision, work |
|
|
//| spread across a configurable pool of worker threads instead of a |
|
|
//| device. Backed by DirectML\WarriorCPU.dll (build it with |
|
|
//| DirectML\build_cpu.bat). |
|
|
//+------------------------------------------------------------------+
|
|
// Every function below (besides CPU_Init/CPU_GetHardwareConcurrency) takes `ctx`, the opaque
|
|
// per-instance handle CPU_Init() returns - see DirectML\WarriorCPU.h's comment for why: the DLL
|
|
// keeps no global state of its own, so each CComputeDll instance owns an independent thread pool
|
|
// and the DLL can be loaded/used by any number of instances or threads in parallel with zero
|
|
// cross-talk between them.
|
|
#import "WarriorCPU.dll"
|
|
long CPU_Init(int threads);
|
|
int CPU_GetLastError(long ctx);
|
|
int CPU_GetThreadCount(long ctx);
|
|
int CPU_GetHardwareConcurrency();
|
|
void CPU_Shutdown(long ctx);
|
|
int CPU_BufferCreate(long ctx, int elementCount);
|
|
int CPU_BufferWrite(long ctx, int handle, const double &data[], int count);
|
|
int CPU_BufferRead(long ctx, int handle, double &data[], int count);
|
|
void CPU_BufferFree(long ctx, int handle);
|
|
int CPU_FeedForward(long ctx, int wHandle, int iHandle, int oHandle, int inputs, int activation);
|
|
int CPU_CalcOutputGradient(long ctx, int tHandle, int oHandle, int igHandle, int activation, int count);
|
|
int CPU_CalcHiddenGradient(long ctx, int wHandle, int gHandle, int oHandle, int igHandle, int outputs, int activation, int count);
|
|
int CPU_UpdateWeightsMomentum(long ctx, int wHandle, int gHandle, int iHandle, int dwHandle, int inputs, double learningRate, double momentumRate, int neurons, int optimizer);
|
|
int CPU_UpdateWeightsAdam(long ctx, int wHandle, int gHandle, int iHandle, int mHandle, int vHandle, int inputs, double lt, double b1v, double b2v, int neurons);
|
|
int CPU_FeedForwardConv(long ctx, int wHandle, int iHandle, int oHandle, int inputs, int step, int windowIn, int windowOut, int activation, int positions);
|
|
int CPU_CalcHiddenGradientConv(long ctx, int wHandle, int gHandle, int oHandle, int igHandle, int outputs, int step, int windowIn, int windowOut, int activation, int inputCount);
|
|
int CPU_UpdateWeightsConvMomentum(long ctx, int wHandle, int gHandle, int iHandle, int dwHandle, int inputs, double learningRate, double momentumRate, int windowIn, int windowOut, int step, int optimizer);
|
|
int CPU_UpdateWeightsConvAdam(long ctx, int wHandle, int gHandle, int iHandle, int mHandle, int vHandle, int inputs, double lt, double b1v, double b2v, int windowIn, int windowOut, int step);
|
|
int CPU_LSTMGates(long ctx, int wHandle, int hiddenPrevHandle, int inputsHandle, int concatenatedHandle, int hiddenSize, int inputSize);
|
|
int CPU_LSTMState(long ctx, int concatenatedHandle, int memoryHandle, int hiddenPrevHandle, int hiddenCacheHandle, int outputHandle, int hiddenSize);
|
|
int CPU_LSTMGateGradient(long ctx, int gradientHandle, int memoryHandle, int concatenatedHandle, int concatenatedGradientHandle, int hiddenSize);
|
|
int CPU_LSTMWeightsGradient(long ctx, int concatenatedGradientHandle, int hiddenCacheHandle, int inputsHandle, int weightsGradientHandle, int hiddenSize, int inputSize);
|
|
int CPU_LSTMInputsGradient(long ctx, int concatenatedGradientHandle, int wHandle, int inputsGradientHandle, int hiddenSize, int inputSize);
|
|
int CPU_LSTMSeqForward(long ctx, int wHandle, int inputsHandle, int cacheGatesHandle, int cacheCellHandle, int cacheHiddenHandle, int outputHandle, int hiddenSize, int stepInputs, int steps);
|
|
int CPU_LSTMSeqBackward(long ctx, int wHandle, int inputsHandle, int cacheGatesHandle, int cacheCellHandle, int cacheHiddenHandle, int outGradientHandle, int weightsGradientHandle, int inputsGradientHandle, int hiddenSize, int stepInputs, int steps);
|
|
int CPU_LSTMUpdateWeightsAdam(long ctx, int wHandle, int weightsGradientHandle, int mHandle, int vHandle, double l, double b1v, double b2v, int total);
|
|
int CPU_LSTMUpdateWeightsMomentum(long ctx, int wHandle, int weightsGradientHandle, int dwHandle, double learningRate, double momentumRate, int total, int optimizer);
|
|
int CPU_FeedForwardProof(long ctx, int iHandle, int oHandle, int inputs, int window, int step, int outputs);
|
|
int CPU_CalcInputGradientProof(long ctx, int iHandle, int gHandle, int oHandle, int igHandle, int outputs, int window, int step, int inputs);
|
|
int CPU_AccumulateWeightGrad(long ctx, int accHandle, int gHandle, int iHandle, int inputs, int neurons);
|
|
int CPU_AccumulateWeightGradConv(long ctx, int accHandle, int gHandle, int iHandle, int inputs, int windowIn, int windowOut, int step);
|
|
int CPU_AccumulateBufferInto(long ctx, int dstHandle, int srcHandle, int count);
|
|
int CPU_ApplyAccumAdam(long ctx, int wHandle, int accHandle, int mHandle, int vHandle, int total, double scale, double lt, double b1v, double b2v);
|
|
int CPU_ApplyAccumMomentum(long ctx, int wHandle, int accHandle, int dwHandle, int total, double scale, double learningRate, double momentumRate);
|
|
int CPU_BatchNormForward(long ctx, int iHandle, int oHandle, int optHandle, double w, int frozen, int count);
|
|
int CPU_BatchNormHiddenGrad(long ctx, int gHandle, int prevOHandle, int prevGHandle, int optHandle, int activation, int count);
|
|
int CPU_BatchNormAccumGammaBeta(long ctx, int gHandle, int optHandle, int accHandle, int count);
|
|
int CPU_BatchNormApplyGammaBeta(long ctx, int optHandle, int accHandle, double scale, double lt, double b1v, double b2v, double lr, double momentumRate, int optimizer, int count);
|
|
#import
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
enum ENUM_COMPUTE_TIER
|
|
{
|
|
COMPUTE_TIER_NONE = 0,
|
|
COMPUTE_TIER_CPU = 2 // multithreaded fallback - WarriorCPU.dll
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| CPU DLL fallback wrapper. Used when OpenCL is unavailable (no HW |
|
|
//| accel, e.g. a VM), so callers just get "multithreaded acceleration,|
|
|
//| or NULL" without caring about the backend's internals. |
|
|
//+------------------------------------------------------------------+
|
|
class CComputeDll
|
|
{
|
|
private:
|
|
ENUM_COMPUTE_TIER m_tier;
|
|
int m_cpuLoadPercent; // 100 = auto/all cores; 10-90 scales down from the detected count
|
|
//--- opaque per-instance context handle for the CPU DLL tier (0 when m_tier==NONE). WarriorCPU.dll
|
|
//--- keeps no global state of its own - each CPU_Init() call heap-allocates an independent context
|
|
//--- (own thread pool, own buffer table) and this handle is the caller's only reference to it,
|
|
//--- threaded through every single call below. This is what makes the DLL safe to load/reload and
|
|
//--- use from any number of CNet instances at once: a fault or a watchdog-killed call against one
|
|
//--- instance's context can never poison another chart's or another CNet's calls the way a
|
|
//--- shared/global singleton could.
|
|
long m_ctx;
|
|
//--- CPU_Init()'s failure reason, captured immediately since a failed Init() hands back no context
|
|
//--- to read it from afterward - LastError() falls back to this when m_tier is NONE.
|
|
int m_initError;
|
|
public:
|
|
CComputeDll(void) : m_tier(COMPUTE_TIER_NONE), m_cpuLoadPercent(100), m_ctx(0), m_initError(0) {};
|
|
~CComputeDll(void)
|
|
{
|
|
if(m_tier == COMPUTE_TIER_CPU)
|
|
CPU_Shutdown(m_ctx);
|
|
}
|
|
//--- pct <= 0 or >= 100 means "let WarriorCPU.dll pick hardware_concurrency() (all cores)";
|
|
//--- 10-90 targets that percentage of the auto-detected core count instead.
|
|
void SetCpuLoadPercent(int pct) { m_cpuLoadPercent = pct; }
|
|
ENUM_COMPUTE_TIER Tier(void) { return m_tier; }
|
|
//--- Which DLL is actually behind this object, for diagnostics.
|
|
string BackendName(void)
|
|
{
|
|
switch(m_tier)
|
|
{
|
|
case COMPUTE_TIER_CPU:
|
|
return "CPU-DLL";
|
|
default:
|
|
return "no-backend";
|
|
}
|
|
}
|
|
int CpuThreadsUsed(void) { return (m_tier == COMPUTE_TIER_CPU) ? CPU_GetThreadCount(m_ctx) : 0; }
|
|
bool Initialize(void)
|
|
{
|
|
int threads = 0; // 0 = auto (hardware_concurrency, i.e. all cores)
|
|
if(m_cpuLoadPercent > 0 && m_cpuLoadPercent < 100)
|
|
{
|
|
// CPU_GetHardwareConcurrency() is a stateless OS query, independent of any other
|
|
// instance's pool size - each CNet gets its own CPU_Init() context now, so there is no
|
|
// shared pool for this to be scaled down by the way there used to be.
|
|
int detected = CPU_GetHardwareConcurrency();
|
|
threads = (int)MathMax(1, MathRound(detected * m_cpuLoadPercent / 100.0));
|
|
}
|
|
long cpuCtx = CPU_Init(threads);
|
|
if(cpuCtx != 0)
|
|
{
|
|
m_ctx = cpuCtx;
|
|
m_tier = COMPUTE_TIER_CPU;
|
|
return true;
|
|
}
|
|
// CPU-DLL init failed - every layer now falls through to the slow plain-MQL5 CPU path with no
|
|
// diagnostic trail explaining the resulting behavior/performance change unless this is logged here.
|
|
m_initError = -1;
|
|
Print(__FUNCTION__ + ": CPU-DLL init failed (CPU_Init returned no context) - falling back to the plain-MQL5 CPU tier.");
|
|
m_tier = COMPUTE_TIER_NONE;
|
|
return false;
|
|
}
|
|
int LastError(void) { return (m_tier == COMPUTE_TIER_NONE) ? m_initError : CPU_GetLastError(m_ctx); }
|
|
int BufferCreate(int count)
|
|
{ return CPU_BufferCreate(m_ctx, count); }
|
|
bool BufferWrite(int handle, double &data[], int count)
|
|
{ return CPU_BufferWrite(m_ctx, handle, data, count) != 0; }
|
|
bool BufferRead(int handle, double &data[], int count)
|
|
{ return CPU_BufferRead(m_ctx, handle, data, count) != 0; }
|
|
void BufferFree(int handle)
|
|
{ CPU_BufferFree(m_ctx, handle); }
|
|
bool FeedForward(int wHandle, int iHandle, int oHandle, int inputs, int activation)
|
|
{ return CPU_FeedForward(m_ctx, wHandle, iHandle, oHandle, inputs, activation) != 0; }
|
|
bool CalcOutputGradient(int tHandle, int oHandle, int igHandle, int activation, int count)
|
|
{ return CPU_CalcOutputGradient(m_ctx, tHandle, oHandle, igHandle, activation, count) != 0; }
|
|
bool CalcHiddenGradient(int wHandle, int gHandle, int oHandle, int igHandle, int outputs, int activation, int count)
|
|
{ return CPU_CalcHiddenGradient(m_ctx, wHandle, gHandle, oHandle, igHandle, outputs, activation, count) != 0; }
|
|
bool UpdateWeightsMomentum(int wHandle, int gHandle, int iHandle, int dwHandle, int inputs, double learningRate, double momentumRate, int neurons, int optimizer)
|
|
{ return CPU_UpdateWeightsMomentum(m_ctx, wHandle, gHandle, iHandle, dwHandle, inputs, learningRate, momentumRate, neurons, optimizer) != 0; }
|
|
bool UpdateWeightsAdam(int wHandle, int gHandle, int iHandle, int mHandle, int vHandle, int inputs, double lt, double b1v, double b2v, int neurons)
|
|
{ return CPU_UpdateWeightsAdam(m_ctx, wHandle, gHandle, iHandle, mHandle, vHandle, inputs, lt, b1v, b2v, neurons) != 0; }
|
|
bool FeedForwardConv(int wHandle, int iHandle, int oHandle, int inputs, int step, int windowIn, int windowOut, int activation, int positions)
|
|
{ return CPU_FeedForwardConv(m_ctx, wHandle, iHandle, oHandle, inputs, step, windowIn, windowOut, activation, positions) != 0; }
|
|
bool CalcHiddenGradientConv(int wHandle, int gHandle, int oHandle, int igHandle, int outputs, int step, int windowIn, int windowOut, int activation, int inputCount)
|
|
{ return CPU_CalcHiddenGradientConv(m_ctx, wHandle, gHandle, oHandle, igHandle, outputs, step, windowIn, windowOut, activation, inputCount) != 0; }
|
|
bool UpdateWeightsConvMomentum(int wHandle, int gHandle, int iHandle, int dwHandle, int inputs, double learningRate, double momentumRate, int windowIn, int windowOut, int step, int optimizer)
|
|
{ return CPU_UpdateWeightsConvMomentum(m_ctx, wHandle, gHandle, iHandle, dwHandle, inputs, learningRate, momentumRate, windowIn, windowOut, step, optimizer) != 0; }
|
|
bool UpdateWeightsConvAdam(int wHandle, int gHandle, int iHandle, int mHandle, int vHandle, int inputs, double lt, double b1v, double b2v, int windowIn, int windowOut, int step)
|
|
{ return CPU_UpdateWeightsConvAdam(m_ctx, wHandle, gHandle, iHandle, mHandle, vHandle, inputs, lt, b1v, b2v, windowIn, windowOut, step) != 0; }
|
|
//--- Mini-batch gradient accumulation (2026-08-09 audit, F4). Accumulation only - the optimizer step
|
|
//--- is host-side MQL5, so there is no matching Apply* here; see CNeuronBaseOCL::ApplyAccumulatedGradients.
|
|
bool AccumulateWeightGrad(int accHandle, int gHandle, int iHandle, int inputs, int neurons)
|
|
{ return CPU_AccumulateWeightGrad(m_ctx, accHandle, gHandle, iHandle, inputs, neurons) != 0; }
|
|
bool AccumulateWeightGradConv(int accHandle, int gHandle, int iHandle, int inputs, int windowIn, int windowOut, int step)
|
|
{ return CPU_AccumulateWeightGradConv(m_ctx, accHandle, gHandle, iHandle, inputs, windowIn, windowOut, step) != 0; }
|
|
bool AccumulateBufferInto(int dstHandle, int srcHandle, int count)
|
|
{ return CPU_AccumulateBufferInto(m_ctx, dstHandle, srcHandle, count) != 0; }
|
|
//--- Mini-batch apply (2026-08-25): the optimizer step on the batch mean, device-side. See
|
|
//--- CPU_ApplyAccumAdam in WarriorCPU.h - without these the step ran as a per-weight MQL5 loop.
|
|
bool ApplyAccumAdam(int wHandle, int accHandle, int mHandle, int vHandle, int total, double scale, double lt, double b1v, double b2v)
|
|
{ return CPU_ApplyAccumAdam(m_ctx, wHandle, accHandle, mHandle, vHandle, total, scale, lt, b1v, b2v) != 0; }
|
|
bool ApplyAccumMomentum(int wHandle, int accHandle, int dwHandle, int total, double scale, double learningRate, double momentumRate)
|
|
{ return CPU_ApplyAccumMomentum(m_ctx, wHandle, accHandle, dwHandle, total, scale, learningRate, momentumRate) != 0; }
|
|
//--- Batch norm (2026-08-25) - see CPU_BatchNormForward in WarriorCPU.h. These are what let a BN
|
|
//--- layer run device-side on the DLL tier; the OpenCL kernels remain the device path there.
|
|
bool BatchNormForward(int iHandle, int oHandle, int optHandle, double w, int frozen, int count)
|
|
{ return CPU_BatchNormForward(m_ctx, iHandle, oHandle, optHandle, w, frozen, count) != 0; }
|
|
bool BatchNormHiddenGrad(int gHandle, int prevOHandle, int prevGHandle, int optHandle, int activation, int count)
|
|
{ return CPU_BatchNormHiddenGrad(m_ctx, gHandle, prevOHandle, prevGHandle, optHandle, activation, count) != 0; }
|
|
bool BatchNormAccumGammaBeta(int gHandle, int optHandle, int accHandle, int count)
|
|
{ return CPU_BatchNormAccumGammaBeta(m_ctx, gHandle, optHandle, accHandle, count) != 0; }
|
|
bool BatchNormApplyGammaBeta(int optHandle, int accHandle, double scale, double lt, double b1v, double b2v, double lr, double momentumRate, int optimizer, int count)
|
|
{ return CPU_BatchNormApplyGammaBeta(m_ctx, optHandle, accHandle, scale, lt, b1v, b2v, lr, momentumRate, optimizer, count) != 0; }
|
|
//--- Fused unrolled sequence LSTM. These are what a sequence model uses; the per-step LSTMGates/
|
|
//--- LSTMState/LSTM*Gradient below remain only for the legacy single-timestep layer.
|
|
bool LSTMSeqForward(int wHandle, int inputsHandle, int cacheGatesHandle, int cacheCellHandle, int cacheHiddenHandle, int outputHandle, int hiddenSize, int stepInputs, int steps)
|
|
{ return CPU_LSTMSeqForward(m_ctx, wHandle, inputsHandle, cacheGatesHandle, cacheCellHandle, cacheHiddenHandle, outputHandle, hiddenSize, stepInputs, steps) != 0; }
|
|
bool LSTMSeqBackward(int wHandle, int inputsHandle, int cacheGatesHandle, int cacheCellHandle, int cacheHiddenHandle, int outGradientHandle, int weightsGradientHandle, int inputsGradientHandle, int hiddenSize, int stepInputs, int steps)
|
|
{ return CPU_LSTMSeqBackward(m_ctx, wHandle, inputsHandle, cacheGatesHandle, cacheCellHandle, cacheHiddenHandle, outGradientHandle, weightsGradientHandle, inputsGradientHandle, hiddenSize, stepInputs, steps) != 0; }
|
|
bool LSTMGates(int wHandle, int hiddenPrevHandle, int inputsHandle, int concatenatedHandle, int hiddenSize, int inputSize)
|
|
{ return CPU_LSTMGates(m_ctx, wHandle, hiddenPrevHandle, inputsHandle, concatenatedHandle, hiddenSize, inputSize) != 0; }
|
|
bool LSTMState(int concatenatedHandle, int memoryHandle, int hiddenPrevHandle, int hiddenCacheHandle, int outputHandle, int hiddenSize)
|
|
{ return CPU_LSTMState(m_ctx, concatenatedHandle, memoryHandle, hiddenPrevHandle, hiddenCacheHandle, outputHandle, hiddenSize) != 0; }
|
|
bool LSTMGateGradient(int gradientHandle, int memoryHandle, int concatenatedHandle, int concatenatedGradientHandle, int hiddenSize)
|
|
{ return CPU_LSTMGateGradient(m_ctx, gradientHandle, memoryHandle, concatenatedHandle, concatenatedGradientHandle, hiddenSize) != 0; }
|
|
bool LSTMWeightsGradient(int concatenatedGradientHandle, int hiddenCacheHandle, int inputsHandle, int weightsGradientHandle, int hiddenSize, int inputSize)
|
|
{ return CPU_LSTMWeightsGradient(m_ctx, concatenatedGradientHandle, hiddenCacheHandle, inputsHandle, weightsGradientHandle, hiddenSize, inputSize) != 0; }
|
|
bool LSTMInputsGradient(int concatenatedGradientHandle, int wHandle, int inputsGradientHandle, int hiddenSize, int inputSize)
|
|
{ return CPU_LSTMInputsGradient(m_ctx, concatenatedGradientHandle, wHandle, inputsGradientHandle, hiddenSize, inputSize) != 0; }
|
|
bool LSTMUpdateWeightsAdam(int wHandle, int weightsGradientHandle, int mHandle, int vHandle, double l, double b1v, double b2v, int total)
|
|
{ return CPU_LSTMUpdateWeightsAdam(m_ctx, wHandle, weightsGradientHandle, mHandle, vHandle, l, b1v, b2v, total) != 0; }
|
|
bool LSTMUpdateWeightsMomentum(int wHandle, int weightsGradientHandle, int dwHandle, double learningRate, double momentumRate, int total, int optimizer)
|
|
{ return CPU_LSTMUpdateWeightsMomentum(m_ctx, wHandle, weightsGradientHandle, dwHandle, learningRate, momentumRate, total, optimizer) != 0; }
|
|
bool FeedForwardProof(int iHandle, int oHandle, int inputs, int window, int step, int outputs)
|
|
{ return CPU_FeedForwardProof(m_ctx, iHandle, oHandle, inputs, window, step, outputs) != 0; }
|
|
bool CalcInputGradientProof(int iHandle, int gHandle, int oHandle, int igHandle, int outputs, int window, int step, int inputs)
|
|
{ return CPU_CalcInputGradientProof(m_ctx, iHandle, gHandle, oHandle, igHandle, outputs, window, step, inputs) != 0; }
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|