//+------------------------------------------------------------------+ //| ScalerBaseCLCL.mqh | //| Copyright 2025, Leo. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, Leo." #property link "https://www.mql5.com" #property strict #ifndef SCALER_CL_BY_LEO_GEN_MQH #define SCALER_CL_BY_LEO_GEN_MQH #include "..\\MQLArticles\\Utils\\File.mqh" #ifdef SCALER_BASE_CL_DEBUG #include "..\\CLByLeo\\CL.mqh" #else #include "..\\CLByLeo\\CLFast.mqh" #endif //+------------------------------------------------------------------+ //| Scaler Base | //+------------------------------------------------------------------+ #resource "Scaler.cl" as const string cl_scaler_program //--- Generales #define SCALER_MIN_VAL 1e-9 //--- Principal - Global #define cl_scaler_kernels_total 10 #define cl_scaler_buffers_total 8 //--- Kernels globales #define kernel_matrix_extraer 0 #define kernel_matrix_reconstruir 1 #define kernel_vector_extraer 2 #define kernel_vector_reconstruir 3 //--- Argumentos recons/extraer matrix #define kernel_matrix_extraer_recons_arg_buff_data 0 #define kernel_matrix_extraer_recons_arg_buff_res 1 #define kernel_matrix_extraer_recons_arg_rows_data 2 #define kernel_matrix_extraer_recons_arg_cols_data 3 #define kernel_matrix_extraer_recons_arg_rows_res 4 #define kernel_matrix_extraer_recons_arg_cols_res 5 #define kernel_matrix_extraer_recons_arg_extraer_cols 6 #define kernel_matrix_extraer_recons_arg_start_col 7 //--- Kernel global [2] - Kernel[3] Vectores argumentos #define kernel_vector_extraer_recons_arg_buff_data 0 #define kernel_vector_extraer_recons_arg_buff_res 1 #define kernel_vector_extraer_recons_arg_start_col 2 #define kernel_vector_extraer_recons_arg_count_col 3 //--- Buffers globales // argumentos/buffer - no solo de esta funcion GLOBALES #define global_buffer_data_1 0 //mean/min/iqrs - buffer #define global_buffer_data_2 1 // std/max/medians - buffer #define global_matrix_to_escale 2 //Matriz a escalar (transform, fit_tranform, inverse_tranform) - buffer #define global_vector_to_escale 3 //Vector a escalar (fit_tranform, inverse_tranform) - buffer // Para extracion de matrizes si es necesario #define global_extraer_recos_mtx_matrix_data 4 #define global_extraer_recos_mtx_matrix_res 5 // Para extracion de vecores si es necesario #define global_extraer_recos_vec_vector_data 6 #define global_extraer_recos_vec_vector_res 7 //--- Indice general para el vector data // Indice general del vector /TRANSFORM - FITTRANSFORM #define kernel_arg_index_all_vector_to_escale 2 //En caso que se escale un vector - indice de argunmento //--- Kernels globales //--- Kernel[0] para la funcion de inicilizacino fit #define kernel_fit_transform_init 4 // argumentos #define kernel_fit_transform_init_arg_cols 3 #define kernel_fit_transform_init_arg_rows 4 //--- Kernel[1] para la transformacion (2) usso, ademas esta funcion recibe los mismo argumento que fit, solo qeu no incluye rows #define kernel_matrix_transform 5 //--- Kenel[2] para tranforma vector #define kernel_vector_transform 6 //se usan los mimos argunmenso global_.... //--- kernel[3] para desescalar data matrix, recibe los mismo parametros que el kernel 1 #define kernel_inverse_tranform_matrix 7 //--- kernel[4] para desescalar data vector recibe los mismo parametros que el kernel 2 #define kernel_inverse_transform_vector 8 //--- Kernel para el fit transform de vector #define kernel_fit_transform_vector 9 #define kernel_fit_transform_vector_arg_data1 0 #define kernel_fit_transform_vector_arg_data2 1 //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool ScalerCheckSizeCustomM(const matrix &mtx, ulong start_col, ulong count_cols, ulong excluyed_cols) { if(start_col >= mtx.Cols()) { FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("Columna de inicio %I64u >= total columnas %I64u", start_col, mtx.Cols())); return false; } if(start_col + count_cols > mtx.Cols()) { FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("Rango [%I64u:%I64u] excede columnas disponibles %I64u", start_col, start_col + count_cols - 1, mtx.Cols())); return false; } return true; } //+------------------------------------------------------------------+ bool ScalerCheckSizeExcludedM(const matrix &mtx, ulong start_col, ulong count_cols, ulong excluyed_cols) { if(mtx.Cols() < excluyed_cols) { FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("Columnas a excluir %I64u >= total columnas %I64u", excluyed_cols, mtx.Cols())); return false; } return true; } //+------------------------------------------------------------------+ bool ScalerCheckSizeCustomV(const vector &v, ulong start_col, ulong count_cols, ulong excluyed_cols) { if(start_col >= v.Size()) { FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("Columna de inicio %I64u >= tamaño total del vector%I64u", start_col, v.Size())); return false; } if(start_col + count_cols > v.Size()) { FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("Rango [%I64u:%I64u] excede el tamaño del vector %I64u", start_col, start_col + count_cols - 1, v.Size())); return false; } return true; } //+------------------------------------------------------------------+ bool ScalerCheckSizeExcludedV(const vector &v, ulong start_col, ulong count_cols, ulong excluyed_cols) { if(v.Size() < excluyed_cols) { FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("Columnas a excluir %I64u >= tamaño del vector: %I64u", excluyed_cols, v.Size())); return false; } return true; } //+------------------------------------------------------------------+ typedef bool(*ScalerFuncionCheckV)(const vector &v, ulong start_col, ulong count_cols, ulong excluyed_cols); typedef bool(*ScalerFuncionCheckM)(const matrix &mtx, ulong start_col, ulong count_cols, ulong excluyed_cols); //--- template //T es uint o ulong class ScalerBaseCL : public CLoggerBase { private: //--- static void CleanBufferVector(); static void CleanBufferMatrix(); protected: static COpenCL cl; static string type_suported; static bool open_cl_is_create; string file_name_out; string prefix_file; bool loaded_scaler; bool use_custom; //Bandera para saber si se usa custom (true) o excluyed (false) T start_col; T count_cols; T excluyed_cols; virtual bool Save() = 0; virtual bool Load(string prefix_name) = 0; //--- Chekear el tamaño ScalerFuncionCheckM CheckSizeMatrix; ScalerFuncionCheckV CheckSizeVector; //--- void CleanBuffersOnlyData(); void CleanExtraData(); public: ScalerBaseCL(); static inline COpenCL* GetCLPointer() { return GetPointer(cl); } //--- Seteo de rangos void SetRangeEscaler(T start_col_, T count_col_); //Custom void SetRangeEscaler(T excluyed_cols_ = 1); //Mas simple, el usuario decide cuantas columnas empezando por atras se excluyen //--- Metodos para guardar o cargar inline bool save(string prefix_name); inline bool load(string prefix_name); //--- Tranformar \ Inverse Transform \ Fit Transform virtual matrix fit_transform(matrix &X, bool save_data) = 0; virtual vector fit_transform(vector &X) = 0; //Para vectores no se guarda data virtual matrix transform(matrix &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false) = 0; virtual vector transform(vector &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false) = 0; virtual matrix inverse_transform(matrix &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false) = 0; virtual vector inverse_transform(vector &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false) = 0; //--- Extracion matrix ExtractMatrixToScale(matrix &X) const; vector ExtractVectorToScale(vector &X) const; //--- Reconstruccion matrix ReconstructMatrix(matrix &X_original, matrix &X_scaled) const; vector ReconstructVector(vector &X_original, vector &X_scaled) const; //--- Archivos virtual inline string GetOutputFile() const final { return this.file_name_out; } }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template static COpenCL ScalerBaseCL::cl; template static bool ScalerBaseCL::open_cl_is_create = false; template static string ScalerBaseCL::type_suported = ""; //+------------------------------------------------------------------+ template ScalerBaseCL::ScalerBaseCL() : start_col(0), count_cols(0), use_custom(false), excluyed_cols(1), file_name_out(NULL), loaded_scaler(false) { CheckSizeMatrix = ScalerCheckSizeExcludedM; CheckSizeVector = ScalerCheckSizeExcludedV; if(open_cl_is_create == false) { const int divice = CL_USE_ANY; cl.ContextCreate(divice); cl.ProgramCreate(cl_scaler_program); if(cl.SupportDouble() == false) { LogFatalError("Es necesario que el divice soporte double para calculos precisos", FUNCION_ACTUAL); Remover(); return; } type_suported = cl.SupportInt64() ? "ulong" : "uint"; cl.SetKernelsCount(cl_scaler_kernels_total); cl.SetBuffersCount(cl_scaler_buffers_total); if(cl.KernelCreate(kernel_matrix_extraer, "ExtractMatrixToScaler") == false) { Remover(); return; } if(cl.KernelCreate(kernel_vector_extraer, "ExtractVectorToScale") == false) { Remover(); return; } if(cl.KernelCreate(kernel_vector_reconstruir, "ReconstructVector") == false) { Remover(); return; } if(cl.KernelCreate(kernel_matrix_reconstruir, "ReconstructMatrix") == false) { Remover(); return; } open_cl_is_create = true; } if(typename(T) != type_suported) { LogError(StringFormat("El device solo soporta %s, clase creada con %s", type_suported, typename(T)), FUNCION_ACTUAL); Remover(); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template void ScalerBaseCL::CleanBufferMatrix(void) { cl.BufferFree(global_extraer_recos_mtx_matrix_data); cl.BufferFree(global_extraer_recos_mtx_matrix_res); } //+------------------------------------------------------------------+ template void ScalerBaseCL::CleanBufferVector(void) { cl.BufferFree(global_extraer_recos_vec_vector_data); cl.BufferFree(global_extraer_recos_vec_vector_res); } //+------------------------------------------------------------------+ template void ScalerBaseCL::SetRangeEscaler(T start_col_, T count_col_) { this.use_custom = true; this.count_cols = count_col_; this.start_col = start_col_; LogInfo(StringFormat("Configurado escalado CUSTOM: columnas %I64u a %I64u (%I64u columnas)", start_col_, start_col_ + count_col_ - 1, count_col_), FUNCION_ACTUAL); CheckSizeMatrix = ScalerCheckSizeCustomM; CheckSizeVector = ScalerCheckSizeCustomV; } //+------------------------------------------------------------------+ template void ScalerBaseCL::SetRangeEscaler(T excluyed_cols_ = 1) { this.excluyed_cols = excluyed_cols_; this.use_custom = false; LogInfo(StringFormat("Configurado escalado EXCLUDED: excluir últimas %I64u columnas", excluyed_cols_), FUNCION_ACTUAL); CheckSizeMatrix = ScalerCheckSizeExcludedM; CheckSizeVector = ScalerCheckSizeExcludedV; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template matrix ScalerBaseCL::ExtractMatrixToScale(matrix &X) const { /* Recordemos que previamenet se compmprueba el tamaño asi que no hace falta hacerlo */ if(use_custom) { if(X.Cols() == count_cols) //Se extrae todo, asi que no hacemo snada return X; matrix result(X.Rows(), count_cols); cl.BufferFromMatrix(global_extraer_recos_mtx_matrix_data, X, CL_MEM_READ_ONLY); //no lo modifica solo lectura cl.BufferFromMatrix(global_extraer_recos_mtx_matrix_res, result, CL_MEM_WRITE_ONLY); cl.SetArgumentBuffer(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_buff_data, global_extraer_recos_mtx_matrix_data); cl.SetArgumentBuffer(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_buff_res, global_extraer_recos_mtx_matrix_res); cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_rows_data, (T)X.Rows()); //cast a t dado que cl es stricto cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_cols_data, (T)X.Cols()); cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_rows_res, (T)result.Rows()); cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_cols_res, (T)result.Cols()); cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_extraer_cols, count_cols); cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_start_col, start_col); uint work_off[2] = {0, 0}; uint work_size[2] = {(uint)result.Rows(), (uint)result.Cols()}; cl.Execute(kernel_matrix_extraer, 2, work_off, work_size); /* CPU for(ulong row = 0; row < X.Rows(); row++) for(ulong col = 0; col < count_cols; col++) result[row][col] = X[row][start_col + col]; */ cl.BufferToMatrix(global_extraer_recos_mtx_matrix_res, result, result.Rows(), result.Cols()); //--- CleanBufferMatrix(); return result; } else { if(excluyed_cols == 0) //No hay columnas a exlcuir escalar todo return X; ulong cols_to_scale = X.Cols() - excluyed_cols; matrix result(X.Rows(), cols_to_scale); //Tinee que tener el mismo tamaño cl.BufferFromMatrix(global_extraer_recos_mtx_matrix_data, X, CL_MEM_READ_ONLY); cl.BufferFromMatrix(global_extraer_recos_mtx_matrix_res, result, CL_MEM_WRITE_ONLY); cl.SetArgumentBuffer(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_buff_data, global_extraer_recos_mtx_matrix_data); cl.SetArgumentBuffer(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_buff_res, global_extraer_recos_mtx_matrix_res); cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_rows_data, (T)X.Rows()); cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_cols_data, (T)X.Cols()); cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_rows_res, (T)result.Rows()); cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_cols_res, (T)result.Cols()); cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_extraer_cols, cols_to_scale); cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_start_col, (T)0); uint work_off[2] = {0, 0}; uint work_size[2] = {(uint)result.Rows(), (uint)result.Cols()}; cl.Execute(kernel_matrix_extraer, 2, work_off, work_size); /* for(ulong row = 0; row < X.Rows(); row++) for(ulong col = 0; col < cols_to_scale; col++) result[row][col] = X[row][col]; */ cl.BufferToMatrix(global_extraer_recos_mtx_matrix_res, result, result.Rows(), result.Cols()); //queremos modfiicar result //--- CleanBufferMatrix(); return result; } } //+------------------------------------------------------------------+ template matrix ScalerBaseCL::ReconstructMatrix(matrix &X_original, matrix &X_scaled) const //X_Scaled solo lectura.. { if(X_original.Rows() == X_scaled.Rows() && X_original.Cols() == X_scaled.Cols()) return X_scaled; matrix result = X_original; // Copia completa if(use_custom) { cl.BufferFromMatrix(global_extraer_recos_mtx_matrix_data, X_scaled, CL_MEM_READ_ONLY); cl.BufferFromMatrix(global_extraer_recos_mtx_matrix_res, result, CL_MEM_READ_WRITE); cl.SetArgumentBuffer(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_buff_data, global_extraer_recos_mtx_matrix_data); cl.SetArgumentBuffer(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_buff_res, global_extraer_recos_mtx_matrix_res); cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_rows_data, (T)X_scaled.Rows()); cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_cols_data, (T)X_scaled.Cols()); cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_rows_res, (T)result.Rows()); cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_cols_res, (T)result.Cols()); cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_extraer_cols, count_cols); cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_start_col, start_col); uint work_off[2] = {0, 0}; uint work_size[2] = {(uint)X_scaled.Rows(), (uint)X_scaled.Cols()}; cl.Execute(kernel_matrix_reconstruir, 2, work_off, work_size); cl.BufferToMatrix(global_extraer_recos_mtx_matrix_res, result, result.Rows(), result.Cols()); /* for(ulong row = 0; row < X_original.Rows(); row++) for(ulong col = 0; col < count_cols; col++) result[row][start_col + col] = X_scaled[row][col];*/ //--- CleanBufferMatrix(); } else { cl.BufferFromMatrix(global_extraer_recos_mtx_matrix_data, X_scaled, CL_MEM_READ_ONLY); cl.BufferFromMatrix(global_extraer_recos_mtx_matrix_res, result, CL_MEM_READ_WRITE); cl.SetArgumentBuffer(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_buff_data, global_extraer_recos_mtx_matrix_data); cl.SetArgumentBuffer(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_buff_res, global_extraer_recos_mtx_matrix_res); cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_rows_data, (T)X_scaled.Rows()); cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_cols_data, (T)X_scaled.Cols()); cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_rows_res, (T)result.Rows()); cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_cols_res, (T)result.Cols()); cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_extraer_cols, (T)X_scaled.Cols()); //aqui del original... cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_start_col, (T)0); uint work_off[2] = {0, 0}; uint work_size[2] = {(uint)X_scaled.Rows(), (uint)X_scaled.Cols()}; cl.Execute(kernel_matrix_reconstruir, 2, work_off, work_size); cl.BufferToMatrix(global_extraer_recos_mtx_matrix_res, result, result.Rows(), result.Cols()); /* for(ulong row = 0; row < X_original.Rows(); row++) for(ulong col = 0; col < X_scaled.Cols(); col++) result[row][col] = X_scaled[row][col];*/ //--- CleanBufferMatrix(); } return result; } //+------------------------------------------------------------------+ template vector ScalerBaseCL::ExtractVectorToScale(vector &X) const { if(use_custom) { if(X.Size() == count_cols) return X; vector result(count_cols); cl.BufferFromVector(global_extraer_recos_vec_vector_data, X, CL_MEM_READ_ONLY); //No se modifica X solo lectura cl.BufferFromVector(global_extraer_recos_vec_vector_res, result, CL_MEM_WRITE_ONLY); cl.SetArgumentBuffer(kernel_vector_extraer, kernel_vector_extraer_recons_arg_buff_data, global_extraer_recos_vec_vector_data); cl.SetArgumentBuffer(kernel_vector_extraer, kernel_vector_extraer_recons_arg_buff_res, global_extraer_recos_vec_vector_res); cl.SetArgument(kernel_vector_extraer, kernel_vector_extraer_recons_arg_start_col, start_col); cl.SetArgument(kernel_vector_extraer, kernel_vector_extraer_recons_arg_count_col, count_cols); // Extraer rango específico /* result.Resize(count_cols); for(ulong i = 0; i < count_cols; i++) result[i] = X[start_col + i];*/ uint work_off[1] = {0}; uint work_size[1] = {(uint)result.Size()}; cl.Execute(kernel_vector_extraer, 1, work_off, work_size); cl.BufferToVector(global_extraer_recos_vec_vector_res, result, result.Size()); //--- CleanBufferVector(); return result; } else { if(excluyed_cols == 0) return X; ulong size_to_scale = X.Size() - excluyed_cols; vector result(size_to_scale); cl.BufferFromVector(global_extraer_recos_vec_vector_data, X, CL_MEM_READ_ONLY); //No se modifica X solo lectura cl.BufferFromVector(global_extraer_recos_vec_vector_res, result, CL_MEM_WRITE_ONLY); cl.SetArgumentBuffer(kernel_vector_extraer, kernel_vector_extraer_recons_arg_buff_data, global_extraer_recos_vec_vector_data); cl.SetArgumentBuffer(kernel_vector_extraer, kernel_vector_extraer_recons_arg_buff_res, global_extraer_recos_vec_vector_res); cl.SetArgument(kernel_vector_extraer, kernel_vector_extraer_recons_arg_start_col, (T)0); cl.SetArgument(kernel_vector_extraer, kernel_vector_extraer_recons_arg_count_col, (T)size_to_scale); // Extraer todas excepto las últimas N uint work_off[1] = {0}; uint work_size[1] = {(uint)result.Size()}; cl.Execute(kernel_vector_extraer, 1, work_off, work_size); cl.BufferToVector(global_extraer_recos_vec_vector_res, result, result.Size()); //--- CleanBufferVector(); return result; } } //+------------------------------------------------------------------+ template vector ScalerBaseCL::ReconstructVector(vector &X_original, vector &X_scaled) const { if(X_original.Size() == X_scaled.Size()) return X_scaled; vector result = X_original; if(use_custom) { // Reemplazar rango específico cl.BufferFromVector(global_extraer_recos_vec_vector_data, X_scaled, CL_MEM_READ_ONLY); cl.BufferFromVector(global_extraer_recos_vec_vector_res, result, CL_MEM_READ_WRITE); cl.SetArgumentBuffer(kernel_vector_reconstruir, kernel_vector_extraer_recons_arg_buff_data, global_extraer_recos_vec_vector_data); cl.SetArgumentBuffer(kernel_vector_reconstruir, kernel_vector_extraer_recons_arg_buff_res, global_extraer_recos_vec_vector_res); cl.SetArgument(kernel_vector_reconstruir, kernel_vector_extraer_recons_arg_start_col, start_col); cl.SetArgument(kernel_vector_reconstruir, kernel_vector_extraer_recons_arg_count_col, count_cols); uint work_off[1] = {0}; uint work_size[1] = {(uint) X_scaled.Size()}; cl.Execute(kernel_vector_reconstruir, 1, work_off, work_size); cl.BufferToVector(global_extraer_recos_vec_vector_res, result, result.Size()); //escribimos en el result vector final /* for(ulong i = 0; i < count_cols; i++) result[start_col + i] = X_scaled[i]; */ //--- CleanBufferVector(); } else { // Reemplazar todas excepto las últimas N cl.BufferFromVector(global_extraer_recos_vec_vector_data, X_scaled, CL_MEM_READ_ONLY); cl.BufferFromVector(global_extraer_recos_vec_vector_res, result, CL_MEM_READ_WRITE); cl.SetArgumentBuffer(kernel_vector_reconstruir, kernel_vector_extraer_recons_arg_buff_data, global_extraer_recos_vec_vector_data); cl.SetArgumentBuffer(kernel_vector_reconstruir, kernel_vector_extraer_recons_arg_buff_res, global_extraer_recos_vec_vector_res); cl.SetArgument(kernel_vector_reconstruir, kernel_vector_extraer_recons_arg_start_col, (T)0); cl.SetArgument(kernel_vector_reconstruir, kernel_vector_extraer_recons_arg_count_col, (T)X_scaled.Size()); //aqui del original... no del "no_const" uint work_off[1] = {0}; uint work_size[1] = {(uint) X_scaled.Size()}; cl.Execute(kernel_vector_reconstruir, 1, work_off, work_size); cl.BufferToVector(global_extraer_recos_vec_vector_res, result, result.Size()); //escribimos en el result vector final /* for(ulong i = 0; i < X_scaled.Size(); i++) result[i] = X_scaled[i];*/ //--- CleanBufferVector(); } return result; } //+------------------------------------------------------------------+ template inline bool ScalerBaseCL::load(string prefix_name) { loaded_scaler = true; return this.Load(prefix_name); } //+------------------------------------------------------------------+ template inline bool ScalerBaseCL::save(string prefix_name) { this.file_name_out = prefix_name + this.prefix_file; return this.Save(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template void ScalerBaseCL::CleanBuffersOnlyData(void) { cl.BufferFree(global_matrix_to_escale); cl.BufferFree(global_vector_to_escale); } //+------------------------------------------------------------------+ template void ScalerBaseCL::CleanExtraData(void) { cl.BufferFree(global_buffer_data_1); cl.BufferFree(global_buffer_data_2); } //+------------------------------------------------------------------+ //| Standardization Scaler | //+------------------------------------------------------------------+ template //T = (uint o ulong) S = (float o double) class StandardizationScalerCL : public ScalerBaseCL { protected: vector mean, std; bool Save() override; bool Load(string prefix_name) override; public: StandardizationScalerCL(); vector fit_transform(vector &X) override; //Para vectores no se guarda data matrix fit_transform(matrix &X, bool save_data) override; matrix transform(matrix &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false) override; vector transform(vector &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false) override; matrix inverse_transform(matrix &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false) override; vector inverse_transform(vector &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false) override; }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template StandardizationScalerCL::StandardizationScalerCL() { this.prefix_file = "_mean_std.csv"; //--- Seteamos los kernels restantes if(!cl.KernelCreate(kernel_fit_transform_init, "fit_standard_scaler_init")) { Remover(); return; } if(!cl.KernelCreate(kernel_matrix_transform, "standard_scaler_tranform_matrix")) { Remover(); return; } if(!cl.KernelCreate(kernel_vector_transform, "standard_scaler_tranform_vector")) { Remover(); return; } if(!cl.KernelCreate(kernel_inverse_tranform_matrix, "standard_scaler_inverse_tranform_matrix")) { Remover(); return; } if(!cl.KernelCreate(kernel_inverse_transform_vector, "standard_scaler_inverse_tranform_vector")) { Remover(); return; } if(!cl.KernelCreate(kernel_fit_transform_vector, "standar_scaler_fit_transform_vector")) { Remover(); return; } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template bool StandardizationScalerCL::Save() { FileDelete(this.file_name_out); ResetLastError(); int handle = FileOpen(this.file_name_out, FILE_WRITE | FILE_CSV | FILE_COMMON); if(handle == INVALID_HANDLE) { LogFatalError(StringFormat("Invalid handle Err= %d >> Filename= %s", GetLastError(), this.file_name_out), FUNCION_ACTUAL); return false; } FileWrite(handle, vector_to_string(this.mean)); FileWrite(handle, vector_to_string(this.std)); FileWrite(handle, count_cols); FileWrite(handle, start_col); FileWrite(handle, excluyed_cols); FileWrite(handle, (int)use_custom); FileClose(handle); return true; } //+------------------------------------------------------------------+ template bool StandardizationScalerCL::Load(string prefix_name) { this.file_name_out = prefix_name + this.prefix_file; ResetLastError(); int handle = FileOpen(file_name_out, FILE_READ | FILE_CSV | FILE_COMMON, "\n"); if(handle == INVALID_HANDLE) { LogFatalError(StringFormat("Invalid handle Err= %d >> Filename= %s", GetLastError(), this.file_name_out), FUNCION_ACTUAL); return false; } this.mean = string_to_vector(FileReadString(handle)); this.std = string_to_vector(FileReadString(handle)); this.count_cols = (T)StringToInteger(FileReadString(handle)); this.start_col = (T)StringToInteger(FileReadString(handle)); this.excluyed_cols = (T)StringToInteger(FileReadString(handle)); this.use_custom = (bool)StringToInteger(FileReadString(handle)); //--- Establecemos una unica vez FileClose(handle); return true; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template vector StandardizationScalerCL::fit_transform(vector &X) { if(loaded_scaler) { LogWarning("Este es un escalador cargado >> no es necesario ajustarlo a los nuevos datos, llame a otra instancia de una clase", FUNCION_ACTUAL); return transform(X); } //--- if(!CheckSizeVector(X, start_col, count_cols, excluyed_cols)) return X; //--- vector X_to_scaled = ExtractVectorToScale(X); //--- double mean_val = X_to_scaled.Mean(); double std_val = X_to_scaled.Std(); if(std_val < SCALER_MIN_VAL) std_val = 1.0; //--- cl.BufferFromVector(global_vector_to_escale, X_to_scaled, CL_MEM_READ_WRITE); cl.SetArgument(kernel_fit_transform_vector, kernel_fit_transform_vector_arg_data1, mean_val); cl.SetArgument(kernel_fit_transform_vector, kernel_fit_transform_vector_arg_data2, std_val); cl.SetArgumentBuffer(kernel_fit_transform_vector, kernel_arg_index_all_vector_to_escale, global_vector_to_escale); uint work_size[1] = { (uint)X_to_scaled.Size() }; uint offset[1] = {0}; if(!cl.Execute(kernel_fit_transform_vector, 1, offset, work_size)) return X; cl.BufferToVector(global_vector_to_escale, X_to_scaled, X_to_scaled.Size()); return ReconstructVector(X, X_to_scaled); } //+------------------------------------------------------------------+ template matrix StandardizationScalerCL::fit_transform(matrix &X, bool save_data) { if(loaded_scaler) { LogWarning("Este es un escalador cargado >> no es necesario ajustarlo a los nuevos datos, llame a otra instancia de una clase", FUNCION_ACTUAL); return transform(X); } LogInfo(StringFormat("Numero de columnas de entrada: %I64u", X.Cols()), FUNCION_ACTUAL); //--- if(!CheckSizeMatrix(X, start_col, count_cols, excluyed_cols)) return X; //--- matrix X_to_scale = ExtractMatrixToScale(X); LogInfo(StringFormat("Columnas a escalar: %I64u", X_to_scale.Cols()), FUNCION_ACTUAL); vector mean_cts(X_to_scale.Cols()); vector std_cts(X_to_scale.Cols()); //--- cl.BufferFromVector(global_buffer_data_1, mean_cts, CL_MEM_READ_WRITE); cl.BufferFromVector(global_buffer_data_2, std_cts, CL_MEM_READ_WRITE); cl.BufferFromMatrix(global_matrix_to_escale, X_to_scale, CL_MEM_READ_WRITE); //lectura y escritura en los 3 buffers //--- Argumentos 1 cl.SetArgumentBuffer(kernel_fit_transform_init, global_buffer_data_1, global_buffer_data_1); cl.SetArgumentBuffer(kernel_fit_transform_init, global_buffer_data_2, global_buffer_data_2); cl.SetArgumentBuffer(kernel_fit_transform_init, global_matrix_to_escale, global_matrix_to_escale); cl.SetArgument(kernel_fit_transform_init, kernel_fit_transform_init_arg_cols, (T)X_to_scale.Cols()); cl.SetArgument(kernel_fit_transform_init, kernel_fit_transform_init_arg_rows, (T)X_to_scale.Rows()); const static uint work_off_set[1] = {0}; //no offset uint work_size[1] = { (uint)X_to_scale.Cols() }; cl.Execute(kernel_fit_transform_init, 1, work_off_set, work_size); //--- Argumentos 2 cl.SetArgumentBuffer(kernel_matrix_transform, global_buffer_data_1, global_buffer_data_1); cl.SetArgumentBuffer(kernel_matrix_transform, global_buffer_data_2, global_buffer_data_2); cl.SetArgumentBuffer(kernel_matrix_transform, global_matrix_to_escale, global_matrix_to_escale); cl.SetArgument(kernel_matrix_transform, kernel_fit_transform_init_arg_cols, (T)X_to_scale.Cols()); const static uint work_off_tranforst[2] = {0, 0}; //no offset uint work_size_tranfors[2] = { (uint)X_to_scale.Rows(), (uint)X_to_scale.Cols() }; cl.Execute(kernel_matrix_transform, 2, work_off_tranforst, work_size_tranfors); matrix X_scaled(X_to_scale.Rows(), X_to_scale.Cols()); cl.BufferToMatrix(global_matrix_to_escale, X_scaled, X_scaled.Rows(), X_scaled.Cols()); //--- if(save_data) { this.mean = mean_cts; this.std = std_cts; } //--- Limpiar los buffers CleanBuffersOnlyData(); //Buffers de data CleanExtraData(); //Data extra, dado que fit transforn se pude usar con difernetes mean/st //--- Aqui siempre se reconstruye return ReconstructMatrix(X, X_scaled); } //+------------------------------------------------------------------+ template matrix StandardizationScalerCL::transform(matrix &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false) { if(!loaded_scaler) { LogError("Primero llame a fit_transform o load() antes de transform", FUNCION_ACTUAL); return X; } //--- if(!CheckSizeMatrix(X, start_col, count_cols, excluyed_cols)) return X; //--- matrix X_to_scale = solo_escalar_lo_previsto ? ExtractMatrixToScale(X) : X; if(X_to_scale.Cols() != this.mean.Size()) { LogError(StringFormat("Columnas a escalar %I64u != columnas entrenadas %u", X_to_scale.Cols(), this.mean.Size()), FUNCION_ACTUAL); return X; } //--- cl.BufferFromMatrix(global_matrix_to_escale, X_to_scale, CL_MEM_READ_WRITE); //lectura y escritura en los 3 buffers cl.BufferFromVector(global_buffer_data_1, mean, CL_MEM_READ_ONLY); //mean lecutra cl.BufferFromVector(global_buffer_data_2, std, CL_MEM_READ_ONLY); //std lecutra //--- Argumentos cl.SetArgumentBuffer(kernel_matrix_transform, global_buffer_data_1, global_buffer_data_1); // mean cl.SetArgumentBuffer(kernel_matrix_transform, global_buffer_data_2, global_buffer_data_2); // std cl.SetArgumentBuffer(kernel_matrix_transform, global_matrix_to_escale, global_matrix_to_escale); // matrix a escalar cl.SetArgument(kernel_matrix_transform, kernel_fit_transform_init_arg_cols, (T)X_to_scale.Cols()); //columnas const static uint work_off_set[2] = {0, 0}; //no offset uint work_size_tranfors[2] = { (uint)X_to_scale.Rows(), (uint)X_to_scale.Cols() }; cl.Execute(kernel_matrix_transform, 2, work_off_set, work_size_tranfors); matrix X_scaled(X_to_scale.Rows(), X_to_scale.Cols()); cl.BufferToMatrix(global_matrix_to_escale, X_scaled, X_scaled.Rows(), X_scaled.Cols()); //--- Limpiar los buffers CleanBuffersOnlyData(); //--- if(reconstruir) return ReconstructMatrix(X, X_scaled); else return X_scaled; } //+------------------------------------------------------------------+ template vector StandardizationScalerCL::transform(vector &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false) { if(!loaded_scaler) { LogError("Primero llame a fit_transform o load() antes de transform", FUNCION_ACTUAL); return X; } //--- vector X_to_scale = solo_escalar_lo_previsto ? ExtractVectorToScale(X) : X; if(X_to_scale.Size() != this.mean.Size()) { LogError(StringFormat("Elementos a escalar %I64u != elementos entrenados %u", X_to_scale.Size(), this.mean.Size()), FUNCION_ACTUAL); return X; } //--- cl.BufferFromVector(global_vector_to_escale, X_to_scale, CL_MEM_READ_WRITE); //lectura y escritura en los 3 buffers cl.BufferFromVector(global_buffer_data_1, mean, CL_MEM_READ_ONLY); //mean lecutra cl.BufferFromVector(global_buffer_data_2, std, CL_MEM_READ_ONLY); //std lecutra //--- Argumentos cl.SetArgumentBuffer(kernel_vector_transform, global_buffer_data_1, global_buffer_data_1); // mean cl.SetArgumentBuffer(kernel_vector_transform, global_buffer_data_2, global_buffer_data_2); // std cl.SetArgumentBuffer(kernel_vector_transform, kernel_arg_index_all_vector_to_escale, global_vector_to_escale); // vector a escalar //--- const static uint work_off_set[1] = {0}; //no offset uint work_size_tranfors[1] = { (uint)X_to_scale.Size()}; //solo 1 dimension por lo tanto seran Size trabajadores cl.Execute(kernel_vector_transform, 1, work_off_set, work_size_tranfors); //Ejeuctamos el kernel //--- vector X_scaled(X_to_scale.Size()); cl.BufferToVector(global_vector_to_escale, X_scaled, X_scaled.Size()); //--- Limpiar los buffers CleanBuffersOnlyData(); //--- if(reconstruir) return ReconstructVector(X, X_scaled); else return X_scaled; } //+------------------------------------------------------------------+ template //Oye aqyu solo escalar lo provisto se vbuelve solo_desescalar_lo_previsto, no puedo cambiar nombre... pero ya ssabes no te confundas matrix StandardizationScalerCL::inverse_transform(matrix &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false) { if(!loaded_scaler) { LogError("Escalador no entrenado. Llame primero a fit_transform", FUNCION_ACTUAL); return X_scaled; } matrix X_to_unscale = (solo_escalar_lo_previsto) ? ExtractMatrixToScale(X_scaled) : X_scaled; //--- if(X_to_unscale.Cols() != this.mean.Size()) { LogError(StringFormat("Columnas escaladas %I64u != columnas entrenadas %u", X_to_unscale.Cols(), this.mean.Size()), FUNCION_ACTUAL); return X_scaled; } //--- Nuevo buffer cl.BufferFromMatrix(global_matrix_to_escale, X_to_unscale, CL_MEM_READ_WRITE); //lectura y escritura en los 3 buffers cl.BufferFromVector(global_buffer_data_1, mean, CL_MEM_READ_ONLY); //mean lecutra cl.BufferFromVector(global_buffer_data_2, std, CL_MEM_READ_ONLY); //std lecutra //--- Argumentos cl.SetArgumentBuffer(kernel_inverse_tranform_matrix, global_buffer_data_1, global_buffer_data_1); // mean cl.SetArgumentBuffer(kernel_inverse_tranform_matrix, global_buffer_data_2, global_buffer_data_2); // std cl.SetArgumentBuffer(kernel_inverse_tranform_matrix, global_matrix_to_escale, global_matrix_to_escale); // matrix a escalar cl.SetArgument(kernel_inverse_tranform_matrix, kernel_fit_transform_init_arg_cols, (T)X_to_unscale.Cols()); //columnas const static uint work_off_set[2] = {0, 0}; //no offset uint work_size_tranfors[2] = { (uint)X_to_unscale.Rows(), (uint)X_to_unscale.Cols() }; //2 dimensiones matriz cl.Execute(kernel_inverse_tranform_matrix, 2, work_off_set, work_size_tranfors); matrix X_unscaled(X_to_unscale.Rows(), X_to_unscale.Cols()); cl.BufferToMatrix(global_matrix_to_escale, X_unscaled, X_to_unscale.Rows(), X_to_unscale.Cols()); //Leeemos para nueva matriz //--- Limpiar los buffers CleanBuffersOnlyData(); //--- if(reconstruir) return ReconstructMatrix(X_scaled, X_unscaled); else return X_unscaled; } //+------------------------------------------------------------------+ template vector StandardizationScalerCL::inverse_transform(vector &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false) { if(!loaded_scaler) { LogError("Escalador no entrenado. Llame primero a fit_transform", FUNCION_ACTUAL); return X_scaled; } //--- vector X_to_unscale = (solo_escalar_lo_previsto) ? ExtractVectorToScale(X_scaled) : X_scaled; //--- if(X_to_unscale.Size() != this.mean.Size()) { LogError(StringFormat("Elementos escalados %I64u != elementos entrenados %u", X_to_unscale.Size(), this.mean.Size()), FUNCION_ACTUAL); return X_scaled; } //--- cl.BufferFromVector(global_vector_to_escale, X_to_unscale, CL_MEM_READ_WRITE); //lectura y escritura en los 3 buffers cl.BufferFromVector(global_buffer_data_1, mean, CL_MEM_READ_ONLY); //mean lecutra cl.BufferFromVector(global_buffer_data_2, std, CL_MEM_READ_ONLY); //std lecutra //--- Argumentos cl.SetArgumentBuffer(kernel_inverse_transform_vector, global_buffer_data_1, global_buffer_data_1); // mean cl.SetArgumentBuffer(kernel_inverse_transform_vector, global_buffer_data_2, global_buffer_data_2); // std cl.SetArgumentBuffer(kernel_inverse_transform_vector, kernel_arg_index_all_vector_to_escale, global_vector_to_escale); // vector a escalar //--- const static uint work_off_set[1] = {0}; //no offset uint work_size_tranfors[1] = { (uint)X_to_unscale.Size()}; //solo 1 dimension por lo tanto seran Size trabajadores cl.Execute(kernel_inverse_transform_vector, 1, work_off_set, work_size_tranfors); //Ejeuctamos el kernel vector X_unscaled(X_to_unscale.Size()); cl.BufferToVector(global_vector_to_escale, X_unscaled, X_unscaled.Size()); //--- Limpiar los buffers CleanBuffersOnlyData(); //--- if(reconstruir) return ReconstructVector(X_scaled, X_unscaled); else return X_unscaled; } //+------------------------------------------------------------------+ //| MaxMin Scaler | //+------------------------------------------------------------------+ //--- template class MaxMinScalerCL : public ScalerBaseCL { protected: vector min_vals, max_vals; bool Save() override; bool Load(string prefix_name) override; public: MaxMinScalerCL(); //--- vector fit_transform(vector &X) override; //Para vectores no se guarda data matrix fit_transform(matrix &X, bool save_data) override; matrix transform(matrix &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false) override; vector transform(vector &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false) override; matrix inverse_transform(matrix &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false) override; vector inverse_transform(vector &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false) override; }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template MaxMinScalerCL::MaxMinScalerCL(void) { this.prefix_file = "_min_max.csv"; //--- Seteamos los kernels restantes if(!cl.KernelCreate(kernel_fit_transform_init, "fit_scaler_max_min_init")) { Remover(); return; } if(!cl.KernelCreate(kernel_matrix_transform, "max_min_scaler_tranform_matrix")) { Remover(); return; } if(!cl.KernelCreate(kernel_vector_transform, "max_min_scaler_tranform_vector")) { Remover(); return; } if(!cl.KernelCreate(kernel_inverse_tranform_matrix, "min_max_inverse_tranform_matrix")) { Remover(); return; } if(!cl.KernelCreate(kernel_inverse_transform_vector, "max_min_scaler_inverse_tranform_vector")) { Remover(); return; } if(!cl.KernelCreate(kernel_fit_transform_vector, "max_min_scaler_fit_transform_vector")) { Remover(); return; } } //+------------------------------------------------------------------+ template bool MaxMinScalerCL::Save() { FileDelete(this.file_name_out); ResetLastError(); int handle = FileOpen(this.file_name_out, FILE_WRITE | FILE_CSV | FILE_COMMON); if(handle == INVALID_HANDLE) { LogFatalError(StringFormat("Invalid handle Err= %d - Filename= %s", GetLastError(), this.file_name_out), FUNCION_ACTUAL); return false; } FileWrite(handle, vector_to_string(this.min_vals)); FileWrite(handle, vector_to_string(this.max_vals)); FileWrite(handle, count_cols); FileWrite(handle, start_col); FileWrite(handle, excluyed_cols); FileWrite(handle, (int)use_custom); FileClose(handle); return true; } //+------------------------------------------------------------------+ template bool MaxMinScalerCL::Load(string prefix_name) { this.file_name_out = prefix_name + this.prefix_file; ResetLastError(); int handle = FileOpen(file_name_out, FILE_READ | FILE_CSV | FILE_COMMON, "\n"); if(handle == INVALID_HANDLE) { LogFatalError(StringFormat("Invalid handle Err= %d - Filename= %s", GetLastError(), this.file_name_out), FUNCION_ACTUAL); return false; } this.min_vals = string_to_vector(FileReadString(handle)); this.max_vals = string_to_vector(FileReadString(handle)); this.count_cols = (T)StringToInteger(FileReadString(handle)); this.start_col = (T)StringToInteger(FileReadString(handle)); this.excluyed_cols = (T)StringToInteger(FileReadString(handle)); this.use_custom = (bool)StringToInteger(FileReadString(handle)); FileClose(handle); return true; } //+------------------------------------------------------------------+ template vector MaxMinScalerCL::fit_transform(vector &X) { if(loaded_scaler) { LogWarning("Este es un escalador cargado >> no es necesario ajustarlo a los nuevos datos, llame a otra instancia de una clase", FUNCION_ACTUAL); return transform(X); } //--- if(!CheckSizeVector(X, start_col, count_cols, excluyed_cols)) return X; //--- vector X_to_scaled = ExtractVectorToScale(X); //--- Obtenemos el maximo y miunimo cpu double min = X_to_scaled.Min(); double max = X_to_scaled.Max(); //--- Modifcamos el max si el valor rango es pequeño if((max - min) < SCALER_MIN_VAL) max = min + 1.0; //--- Establecemos argumentos y creamos y escribimos en el buffer cl.BufferFromVector(global_vector_to_escale, X_to_scaled, CL_MEM_READ_WRITE); // Bufer vector cl.SetArgument(kernel_fit_transform_vector, kernel_fit_transform_vector_arg_data1, min); cl.SetArgument(kernel_fit_transform_vector, kernel_fit_transform_vector_arg_data2, max); cl.SetArgumentBuffer(kernel_fit_transform_vector, kernel_arg_index_all_vector_to_escale, global_vector_to_escale); uint work_size[1] = { (uint)X_to_scaled.Size() }; uint offset[1] = {0}; if(!cl.Execute(kernel_fit_transform_vector, 1, offset, work_size)) return X; cl.BufferToVector(global_vector_to_escale, X_to_scaled, X_to_scaled.Size()); return ReconstructVector(X, X_to_scaled); } //+------------------------------------------------------------------+ template matrix MaxMinScalerCL::fit_transform(matrix &X, bool save_data) { if(loaded_scaler) { LogWarning("Este es un escalador cargado >> no es necesario ajustarlo a los nuevos datos, llame a otra instancia de una clase", FUNCION_ACTUAL); return transform(X); } LogInfo(StringFormat("Numero de columnas de entrada: %I64u", X.Cols()), FUNCION_ACTUAL); //--- if(!CheckSizeMatrix(X, start_col, count_cols, excluyed_cols)) return X; //--- matrix X_to_scale = ExtractMatrixToScale(X); LogInfo(StringFormat("Columnas a escalar: %I64u", X_to_scale.Cols()), FUNCION_ACTUAL); vector min_cts(X_to_scale.Cols()); vector max_cts(X_to_scale.Cols()); //--- Creacion de los buffers cl.BufferFromVector(global_buffer_data_1, min_cts, CL_MEM_READ_WRITE); cl.BufferFromVector(global_buffer_data_2, max_cts, CL_MEM_READ_WRITE); cl.BufferFromMatrix(global_matrix_to_escale, X_to_scale, CL_MEM_READ_WRITE); //lectura y escritura en los 3 buffers //--- Argumentos 1 cl.SetArgumentBuffer(kernel_fit_transform_init, global_buffer_data_1, global_buffer_data_1); cl.SetArgumentBuffer(kernel_fit_transform_init, global_buffer_data_2, global_buffer_data_2); cl.SetArgumentBuffer(kernel_fit_transform_init, global_matrix_to_escale, global_matrix_to_escale); cl.SetArgument(kernel_fit_transform_init, kernel_fit_transform_init_arg_cols, (T)X_to_scale.Cols()); cl.SetArgument(kernel_fit_transform_init, kernel_fit_transform_init_arg_rows, (T)X_to_scale.Rows()); const static uint work_off_set[1] = {0}; //no offset uint work_size[1] = { (uint)X_to_scale.Cols() }; cl.Execute(kernel_fit_transform_init, 1, work_off_set, work_size); //--- Argumentos 2 cl.SetArgumentBuffer(kernel_matrix_transform, global_buffer_data_1, global_buffer_data_1); cl.SetArgumentBuffer(kernel_matrix_transform, global_buffer_data_2, global_buffer_data_2); cl.SetArgumentBuffer(kernel_matrix_transform, global_matrix_to_escale, global_matrix_to_escale); cl.SetArgument(kernel_matrix_transform, kernel_fit_transform_init_arg_cols, (T)X_to_scale.Cols()); const static uint work_off_tranforst[2] = {0, 0}; //no offset uint work_size_tranfors[2] = { (uint)X_to_scale.Rows(), (uint)X_to_scale.Cols() }; cl.Execute(kernel_matrix_transform, 2, work_off_tranforst, work_size_tranfors); matrix X_scaled(X_to_scale.Rows(), X_to_scale.Cols()); cl.BufferToMatrix(global_matrix_to_escale, X_scaled, X_scaled.Rows(), X_scaled.Cols()); //--- if(save_data) { this.min_vals = min_cts; this.max_vals = max_cts; } //--- Limpiar los buffers CleanBuffersOnlyData(); //Buffers de data CleanExtraData(); //Data extra, dado que fit transforn se pude usar con difernetes mean/st //--- Aqui siempre se reconstruye return ReconstructMatrix(X, X_scaled); } //+------------------------------------------------------------------+ template matrix MaxMinScalerCL::transform(matrix &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false) { if(!loaded_scaler) { LogError("Primero llame a fit_transform o load() antes de transform", FUNCION_ACTUAL); return X; } //--- if(!CheckSizeMatrix(X, start_col, count_cols, excluyed_cols)) return X; //--- matrix X_to_scale = solo_escalar_lo_previsto ? ExtractMatrixToScale(X) : X; if(X_to_scale.Cols() != this.min_vals.Size()) { LogError(StringFormat("Columnas a escalar %I64u != columnas entrenadas %u", X_to_scale.Cols(), this.min_vals.Size()), FUNCION_ACTUAL); return X; } //--- Creacion y escribtura de los buffers cl.BufferFromMatrix(global_matrix_to_escale, X_to_scale, CL_MEM_READ_WRITE); //lectura y escritura en los 3 buffers cl.BufferFromVector(global_buffer_data_1, min_vals, CL_MEM_READ_ONLY); cl.BufferFromVector(global_buffer_data_2, max_vals, CL_MEM_READ_ONLY); //--- Argumentos cl.SetArgumentBuffer(kernel_matrix_transform, global_buffer_data_1, global_buffer_data_1); // min cl.SetArgumentBuffer(kernel_matrix_transform, global_buffer_data_2, global_buffer_data_2); // max cl.SetArgumentBuffer(kernel_matrix_transform, global_matrix_to_escale, global_matrix_to_escale); // matrix a escalar cl.SetArgument(kernel_matrix_transform, kernel_fit_transform_init_arg_cols, (T)X_to_scale.Cols()); //columnas const static uint work_off_set[2] = {0, 0}; //no offset uint work_size_tranfors[2] = { (uint)X_to_scale.Rows(), (uint)X_to_scale.Cols() }; cl.Execute(kernel_matrix_transform, 2, work_off_set, work_size_tranfors); matrix X_scaled(X_to_scale.Rows(), X_to_scale.Cols()); cl.BufferToMatrix(global_matrix_to_escale, X_scaled, X_scaled.Rows(), X_scaled.Cols()); //--- Limpiar los buffers CleanBuffersOnlyData(); //--- if(reconstruir) return ReconstructMatrix(X, X_scaled); else return X_scaled; } //+------------------------------------------------------------------+ template vector MaxMinScalerCL::transform(vector &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false) { if(!loaded_scaler) { LogError("Primero llame a fit_transform o load() antes de transform", FUNCION_ACTUAL); return X; } //--- vector X_to_scale = solo_escalar_lo_previsto ? ExtractVectorToScale(X) : X; if(X_to_scale.Size() != this.min_vals.Size()) { LogError(StringFormat("Elementos a escalar %I64u != elementos entrenados %u", X_to_scale.Size(), this.min_vals.Size()), FUNCION_ACTUAL); return X; } //--- cl.BufferFromVector(global_vector_to_escale, X_to_scale, CL_MEM_WRITE_ONLY); //lectura y escritura en los 3 buffers cl.BufferFromVector(global_buffer_data_1, min_vals, CL_MEM_READ_ONLY); //min lecutra cl.BufferFromVector(global_buffer_data_2, max_vals, CL_MEM_READ_ONLY); //max lecutra //--- Argumentos cl.SetArgumentBuffer(kernel_vector_transform, global_buffer_data_1, global_buffer_data_1); // min cl.SetArgumentBuffer(kernel_vector_transform, global_buffer_data_2, global_buffer_data_2); // max cl.SetArgumentBuffer(kernel_vector_transform, kernel_arg_index_all_vector_to_escale, global_vector_to_escale); // vector a escalar //--- const static uint work_off_set[1] = {0}; //no offset uint work_size_tranfors[1] = { (uint)X_to_scale.Size()}; //solo 1 dimension por lo tanto seran Size trabajadores cl.Execute(kernel_vector_transform, 1, work_off_set, work_size_tranfors); //Ejeuctamos el kernel //--- vector X_scaled(X_to_scale.Size()); cl.BufferToVector(global_vector_to_escale, X_scaled, X_scaled.Size()); //--- Limpiar los buffers CleanBuffersOnlyData(); //--- if(reconstruir) return ReconstructVector(X, X_scaled); else return X_scaled; } //+------------------------------------------------------------------+ template matrix MaxMinScalerCL::inverse_transform(matrix &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false) { if(!loaded_scaler) { LogError("Escalador no entrenado. Llame primero a fit_transform", FUNCION_ACTUAL); return X_scaled; } matrix X_to_unscale = (solo_escalar_lo_previsto) ? ExtractMatrixToScale(X_scaled) : X_scaled; //--- if(X_to_unscale.Cols() != this.min_vals.Size()) { LogError(StringFormat("Columnas escaladas %I64u != columnas entrenadas %u", X_to_unscale.Cols(), this.min_vals.Size()), FUNCION_ACTUAL); return X_scaled; } //--- Nuevo buffer cl.BufferFromMatrix(global_matrix_to_escale, X_to_unscale, CL_MEM_READ_WRITE); //lectura y escritura en los 3 buffers cl.BufferFromVector(global_buffer_data_1, min_vals, CL_MEM_READ_ONLY); //min lecutra cl.BufferFromVector(global_buffer_data_2, max_vals, CL_MEM_READ_ONLY); //max lecutra //--- Argumentos cl.SetArgumentBuffer(kernel_inverse_tranform_matrix, global_buffer_data_1, global_buffer_data_1); // min cl.SetArgumentBuffer(kernel_inverse_tranform_matrix, global_buffer_data_2, global_buffer_data_2); // max cl.SetArgumentBuffer(kernel_inverse_tranform_matrix, global_matrix_to_escale, global_matrix_to_escale); // matrix a escalar cl.SetArgument(kernel_inverse_tranform_matrix, kernel_fit_transform_init_arg_cols, (T)X_to_unscale.Cols()); //columnas const static uint work_off_set[2] = {0, 0}; //no offset uint work_size_tranfors[2] = { (uint)X_to_unscale.Rows(), (uint)X_to_unscale.Cols() }; //2 dimensiones matriz cl.Execute(kernel_inverse_tranform_matrix, 2, work_off_set, work_size_tranfors); matrix X_unscaled(X_to_unscale.Rows(), X_to_unscale.Cols()); cl.BufferToMatrix(global_matrix_to_escale, X_unscaled, X_to_unscale.Rows(), X_to_unscale.Cols()); //Leeemos para nueva matriz //--- Limpiar los buffers CleanBuffersOnlyData(); //--- if(reconstruir) return ReconstructMatrix(X_scaled, X_unscaled); else return X_unscaled; } // X_unscaled[row][col] = X_to_unscale[row][col] * (this.max_vals[col] - this.min_vals[col]) + this.min_vals[col]; //+------------------------------------------------------------------+ template vector MaxMinScalerCL::inverse_transform(vector &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false) { if(!loaded_scaler) { LogError("Escalador no entrenado. Llame primero a fit_transform", FUNCION_ACTUAL); return X_scaled; } //--- vector X_to_unscale = (solo_escalar_lo_previsto) ? ExtractVectorToScale(X_scaled) : X_scaled; //--- if(X_to_unscale.Size() != this.min_vals.Size()) { LogError(StringFormat("Elementos escalados %I64u != elementos entrenados %u", X_to_unscale.Size(), this.min_vals.Size()), FUNCION_ACTUAL); return X_scaled; } //--- cl.BufferFromVector(global_vector_to_escale, X_to_unscale, CL_MEM_READ_WRITE); //lectura y escritura en los 3 buffers cl.BufferFromVector(global_buffer_data_1, min_vals, CL_MEM_READ_ONLY); //min lecutra cl.BufferFromVector(global_buffer_data_2, max_vals, CL_MEM_READ_ONLY); //max lecutra //--- Argumentos cl.SetArgumentBuffer(kernel_inverse_transform_vector, global_buffer_data_1, global_buffer_data_1); // min cl.SetArgumentBuffer(kernel_inverse_transform_vector, global_buffer_data_2, global_buffer_data_2); // max cl.SetArgumentBuffer(kernel_inverse_transform_vector, kernel_arg_index_all_vector_to_escale, global_vector_to_escale); // vector a escalar //--- const static uint work_off_set[1] = {0}; //no offset uint work_size_tranfors[1] = { (uint)X_to_unscale.Size()}; //solo 1 dimension por lo tanto seran Size trabajadores cl.Execute(kernel_inverse_transform_vector, 1, work_off_set, work_size_tranfors); //Ejeuctamos el kernel vector X_unscaled(X_to_unscale.Size()); cl.BufferToVector(global_vector_to_escale, X_unscaled, X_unscaled.Size()); //--- Limpiar los buffers CleanBuffersOnlyData(); //--- if(reconstruir) return ReconstructVector(X_scaled, X_unscaled); else return X_unscaled; } //+------------------------------------------------------------------+ #endif //+------------------------------------------------------------------+