ScalerByLeo/Src/CL/Main.mqh
nique_372 1496207a00 mejoras
2026-09-16 18:20:12 -05:00

309 lines
9.3 KiB
MQL5

//+------------------------------------------------------------------+
//| Main.mqh |
//| Copyright 2026, Niquel Mendoza. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Niquel Mendoza."
#property link "https://www.mql5.com"
#property strict
#ifndef SCALERBYLEO_SRC_CL_MAIN_MQH
#define SCALERBYLEO_SRC_CL_MAIN_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
//-- incluimos hashmap
#include <TSN\\GCol\\HashMap.mqh>
#include <TSN\\GCol\\GenericHashes.mqh>
//-- tambien los kerneles
#include "..\\Kernels\\Rsrc.mqh"
#include "..\\..\\..\\CLByLeo\\SharedCtx.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
//+------------------------------------------------------------------+
//| Defines |
//+------------------------------------------------------------------+
#ifndef SCALERBYLEO_CL_DEVICE
#define SCALERBYLEO_CL_DEVICE (CL_USE_ANY)
#endif // SCALERBYLEO_CL_DEVICE
//---
enum ENUM_CLCONTEXT_MANAGER_LAST_ERR
{
CLCONTEXT_MANAGER_LAST_ERR_NOT,
CLCONTEXT_MANAGER_LAST_ERR_INVALID_HANDLE,
CLCONTEXT_MANAGER_LAST_ERR_CL,
};
//---
#define SCALERBYLEO_CLCTX_IS_CREATE (CCLCtxShared::s_context != INVALID_HANDLE && s_program != INVALID_HANDLE)
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template<typename TFlt>
class COpenCLCtxManager
{
private:
static CHashMapFastP(int, uint, _fibbo) s_hash;
static CHashMapFast(string, int) s_hash_kernel;
//---
template<typename TValue>
static bool UpdateVectorDataInternal(int &handle, vector<TValue> &vec, uint flags);
public:
COpenCLCtxManager(void) {}
~COpenCLCtxManager(void) {}
//---
static string s_last_build_log;
static int s_program;
static ENUM_CLCONTEXT_MANAGER_LAST_ERR s_last_err;
//---
static bool ProgramInit(const string& src);
static bool KernelGet(const string& name, int& h);
//---
static bool UpdateVectorData(int& h, vector& vec, uint flags);
//---
static void Deinit(const int reason);
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template<typename TFlt>
int COpenCLCtxManager::s_program = INVALID_HANDLE;
template<typename TFlt>
string COpenCLCtxManager::s_last_build_log = "";
template<typename TFlt>
ENUM_CLCONTEXT_MANAGER_LAST_ERR COpenCLCtxManager::s_last_err = CLCONTEXT_MANAGER_LAST_ERR_NOT;
//---
template<typename TFlt>
CHashMapFastP(int, uint, _fibbo) COpenCLCtxManager::s_hash;
template<typename TFlt>
CHashMapFast(string, int) COpenCLCtxManager::s_hash_kernel;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template<typename TFlt>
static bool COpenCLCtxManager::ProgramInit(const string& src)
{
//---
if(SCALERBYLEO_CLCTX_IS_CREATE)
return true;
//---
::ResetLastError();
//---
if(!CCLCtxShared::ContextInit())
{
s_last_err = CLCONTEXT_MANAGER_LAST_ERR_CL;
return false;
}
//---
if((s_program = CLProgramCreate(CCLCtxShared::s_context, src, s_last_build_log)) == INVALID_HANDLE)
{
s_last_err = CLCONTEXT_MANAGER_LAST_ERR_CL;
// En caso hayamos fallado en su creacion igual lo liberamos (dado que si logramos iniciar)
CCLCtxShared::ContextFree();
return false;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template<typename TFlt>
static void COpenCLCtxManager::Deinit(const int reason)
{
//---
// Si en caso la razon de remove fue chart change o parameotrs
// Los objetod golbales como tal se conservan no se liberan.. por lo que ya no se volvera a llamar a esa funcion o limpiar lo que tiene
// asi que lo prevenimos.
//---
if(reason == REASON_CHARTCHANGE || reason == REASON_PARAMETERS)
{
//FastLog(FUNCION_ACTUAL, WARNING_TEXT, "No se limpara el factory de features dado que la razon de deinit es chart-change,params");
return;
}
//---
if(s_program != INVALID_HANDLE)
{
CLProgramFree(s_program);
s_program = INVALID_HANDLE;
CCLCtxShared::ContextFree();
}
//---
CHashMapFastIteratorP(int, uint, _fibbo) it = s_hash.BeginIteration();
while(it.IsValid())
{
CLBufferFree(it.Key());
it.Next();
}
s_hash.Clear();
//---
CHashMapFastIterator(string, int) it_kernels = s_hash_kernel.BeginIteration();
while(it_kernels.IsValid())
{
CLKernelFree(it_kernels.Val());
it_kernels.Next();
}
s_hash_kernel.Clear();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template<typename TFlt>
static bool COpenCLCtxManager::KernelGet(const string &name, int& h)
{
//---
if(!s_hash_kernel.ReserveSlot(name))
{
const uint p = s_hash_kernel.m_last_pos_tbl;
h = s_hash_kernel.m_table[p].value;
return true;
}
//---
if((h = CLKernelCreate(s_program, name)) == INVALID_HANDLE)
{
//---
const uint p = s_hash_kernel.m_last_pos_tbl;
s_hash_kernel.m_bit_pos = int(TSN_FASTHASHMAP_INDEX_GET_BITPOS_WCORR(p)); // truqueamos
s_hash_kernel.RemoveLastFindCall();
//---
s_last_err = CLCONTEXT_MANAGER_LAST_ERR_CL;
return false;
}
//---
const uint p = s_hash_kernel.m_last_pos_tbl;
s_hash_kernel.m_table[p].value = h; // ya poenmos
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
// La idea siempre revismos un vec
// dependie del TFlt tenemos que evitanso una copia o hacer la copia\conversion..
// Si en caso tflt es dbl entonces sin copias..
template<typename TFlt>
static bool COpenCLCtxManager::UpdateVectorData(int &h, vector &vec, uint flags)
{
//---
// 1. si es float enveonces el vector (De datos) hay que converitlo a float (dado qeu es dbl)
// 2. si en cambio la clase es dbl (Es pro que el usuario precisa tener soporte para dbl) lo mandamos tal cual
//---
if(sizeof(TFlt) == sizeof(float))
{
vectorf f;
f.Assign(vec);
return UpdateVectorDataInternal(h, f, flags);
}
else
return UpdateVectorDataInternal(h, vec, flags);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template<typename TFlt>
template<typename TValue>
static bool COpenCLCtxManager::UpdateVectorDataInternal(int &handle, vector<TValue> &vec, uint flags)
{
//---
const uint vec_size = uint(vec.Size());
const uint vec_bytes = uint(vec_size * sizeof(TValue));
//---
// en caso haya cambiado de tamaño entonces tambine cremos
::ResetLastError();
if(handle == INVALID_HANDLE)
{
if((handle = CLBufferCreate(CCLCtxShared::s_context, vec_bytes, flags)) == INVALID_HANDLE)
{
s_last_err = CLCONTEXT_MANAGER_LAST_ERR_CL;
return false;
}
s_hash.Add(handle, vec_bytes);
}
else
{
uint bytes;
if(!s_hash.TryGet(handle, bytes))
{
s_last_err = CLCONTEXT_MANAGER_LAST_ERR_INVALID_HANDLE;
return false;
}
if(bytes != vec_bytes)
{
//---
CLBufferFree(handle);
//---
if((handle = CLBufferCreate(CCLCtxShared::s_context, vec_bytes, flags)) == INVALID_HANDLE)
{
s_last_err = CLCONTEXT_MANAGER_LAST_ERR_CL;
return false;
}
//--- actulizamos el tamaño
const uint p = s_hash.m_last_pos_tbl;
s_hash.m_table[p].value = vec_bytes;
}
// iguales no actulizamos
}
//--- actulizamos
if(!CLBufferWrite(handle, 0, vec))
{
s_last_err = CLCONTEXT_MANAGER_LAST_ERR_CL;
return false;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| Macros de ayuda |
//+------------------------------------------------------------------+
#define OPENCLMANAGER_MAKE_VECTOR(h, vec, flags) if(!COpenCLCtxManager<TFlt>::UpdateVectorData(h, vec, flags)) { m_last_err=SCALERBYLEO_ERR_IN_CTX_MANAGER_CL; return false; }
//--- end namepsace
}
//+------------------------------------------------------------------+
#endif // SCALERBYLEO_SRC_CL_MAIN_MQH