#pragma OPENCL EXTENSION cl_khr_fp64 : enable //Tiene que soportar double #ifdef cl_khr_int64 #define entero_signed long #define entero_unsigned ulong #pragma OPENCL EXTENSION cl_khr_int64 : enable #else #define entero_signed int #define entero_unsigned uint #endif #define min_value 1e-9 //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ __kernel void fit_standard_scaler_init( __global double* mean, // Output: [cols] __global double* std, // Output: [cols] __global const double* matrix, // Input: [rows * cols] const entero_unsigned cols, const entero_unsigned rows ) { uint col = get_global_id(0); // Solo una dimensión if(col >= cols) return; //--- media double total_sum = 0.0; for(entero_unsigned row = 0; row < rows; row++) { entero_unsigned idx = row * cols + col; total_sum += matrix[idx]; } double mean_col = total_sum / rows; //media mean[col] = mean_col; double variance_sum = 0.0; //valor inicial for(entero_unsigned row = 0; row < rows; row++) { entero_unsigned idx = row * cols + col; double diff = matrix[idx] - mean_col; variance_sum += diff * diff; //obtenemos la variacion Suma } double variance = variance_sum / (rows); // ddof=0 double std_val = sqrt(variance); //valor del std // Evitar división por cero std[col] = (std_val < min_value) ? 1.0 : std_val; } //+------------------------------------------------------------------+ __kernel void standar_scaler_fit_transform_vector( const double mean, const double std, __global double* X_to_scale ) { uint idx = get_global_id(0); X_to_scale[idx] = (X_to_scale[idx] - mean) / std; } //+------------------------------------------------------------------+ __kernel void standard_scaler_tranform_matrix( __global const double* mean, __global const double* std, __global double* matrix, const entero_unsigned cols ) { //2 dimensiones const uint row = get_global_id(0); const uint col = get_global_id(1); entero_unsigned idx = row * cols + col; // La compprobacion ya se hace en init matrix[idx] = (matrix[idx] - mean[col]) / std[col]; } //+------------------------------------------------------------------+ __kernel void standard_scaler_tranform_vector( __global const double* mean, __global const double* std, __global double* vector ) { const uint idx = get_global_id(0); // esta funcion ya esta cargada por lo que std ya esta corregido (si es que era muy pequeño) vector[idx] = (vector[idx] - mean[idx]) / std[idx]; } //+------------------------------------------------------------------+ __kernel void standard_scaler_inverse_tranform_matrix( __global const double* mean, __global const double* std, __global double* matrix, const entero_unsigned cols ) { //2 dimensiones uint row = get_global_id(0); uint col = get_global_id(1); entero_unsigned idx = row * cols + col; matrix[idx] = matrix[idx] * std[col] + mean[col]; } //X_unscaled[row][col] = X_to_unscale[row][col] * this.std[col] + this.mean[col]; //+------------------------------------------------------------------+ __kernel void standard_scaler_inverse_tranform_vector( __global const double* mean, __global const double* std, __global double* vector ) { uint idx = get_global_id(0); vector[idx] = vector[idx] * std[idx] + mean[idx] ; } //X_unscaled[i] = X_to_unscale[i] * this.std[i] + this.mean[i]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ __kernel void fit_scaler_max_min_init( __global double* min_values, // Output: [cols] __global double* max_values, // Output: [cols] __global const double* matrix, // Input: [rows * cols] const entero_unsigned cols, const entero_unsigned rows ) { const uint col = get_global_id(0); // Solo una dimensión // variables inicales double max_col = DBL_MIN; double min_col = DBL_MAX; // Macro incial #define value(prow , pcol) matrix[prow * cols + pcol] // Encontramos el miaxmo y minimo for(int i = 0; i < rows; i++) { const double val = value(i, col); if(val > max_col) max_col = val; if(val < min_col) min_col = val; } // Correcion de valores pequeños if(max_col - min_col < min_value) max_col = min_col + 1.0; // Escritura max_values[col] = max_col; min_values[col] = min_col; #undef value } //+------------------------------------------------------------------+ __kernel void max_min_scaler_fit_transform_vector( const double min_data, const double max_data, __global double* vector ) { const uint idx = get_global_id(0); // Indice en la primera dimension vector[idx] = (vector[idx] - min_data) / (max_data - min_data); // la comprobacion de division se hace en mql } //+------------------------------------------------------------------+ __kernel void max_min_scaler_tranform_matrix( __global const double* min_values, //vector __global const double* max_values, // vector __global double* matrix, // matriz const entero_unsigned cols ) { //2 dimensiones const uint row = get_global_id(0); const uint col = get_global_id(1); entero_unsigned idx = row * cols + col; // la comprobacion de rango se ha hecho en init (los valores ya estan corregidos) matrix[idx] = (matrix[idx] - min_values[col]) / (max_values[col] - min_values[col]); } //+------------------------------------------------------------------+ __kernel void max_min_scaler_tranform_vector( __global const double* min_values, __global const double* max_values, __global double* vector ) { const uint idx = get_global_id(0); // esta funcion ya esta cargada por lo que range ya esta corregido (si es que era muy pequeño) vector[idx] = (vector[idx] - min_values[idx]) / (max_values[idx] - min_values[idx]); } //+------------------------------------------------------------------+ __kernel void min_max_inverse_tranform_matrix( __global const double* min_values, __global const double* max_values, __global double* matrix, const entero_unsigned cols ) { //2 dimensiones const uint row = get_global_id(0); const uint col = get_global_id(1); entero_unsigned idx = row * cols + col; matrix[idx] = matrix[idx] * (max_values[col] - min_values[col]) + min_values[col]; } // X_unscaled[row][col] = X_to_unscale[row][col] * (this.max_vals[col] - this.min_vals[col]) + this.min_vals[col]; //+------------------------------------------------------------------+ __kernel void max_min_scaler_inverse_tranform_vector( __global const double* min_values, __global const double* max_values, __global double* vector ) { const uint idx = get_global_id(0); vector[idx] = vector[idx] * (max_values[idx] - min_values[idx]) + min_values[idx]; } // X_unscaled[i] = X_to_unscale[i] * (this.max_vals[i] - this.min_vals[i]) + this.min_vals[i]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ __kernel void ExtractMatrixToScaler( __global const double* data, //solo lectura __global double* result, //Escritura y lectura const entero_unsigned rows_data, const entero_unsigned cols_data, const entero_unsigned rows_res, const entero_unsigned cols_res, const entero_unsigned cols_to_escale, //numero de columnas a extraer desde el inicio const entero_unsigned start_col ) { uint row = get_global_id(0); uint col = get_global_id(1); entero_unsigned idx_data = row * cols_data + (col + start_col); entero_unsigned idx_res = row * cols_res + col; // Asumiendo mismas dimensiones result[idx_res] = data[idx_data]; } /* //+------------------------------------------------------------------+ matrix ScalerBase::ExtractMatrixToScale(const matrix &X) const { matrix result; if(use_custom) { result.Init(X.Rows(), count_cols); for(entero_unsigned row = 0; row < X.Rows(); row++) for(entero_unsigned col = 0; col < count_cols; col++) result[row][col] = X[row][start_col + col]; } else { entero_unsigned cols_to_scale = X.Cols() - excluyed_cols; result.Init(X.Rows(), cols_to_scale); for(entero_unsigned row = 0; row < X.Rows(); row++) for(entero_unsigned col = 0; col < cols_to_scale; col++) result[row][col] = X[row][col]; } return result; } */ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ __kernel void ExtractVectorToScale( __global const double* data, __global double* result, const entero_unsigned start_col, const entero_unsigned count_cols ) { uint idx = get_global_id(0); result[idx] = data[start_col + idx]; } /* //+------------------------------------------------------------------+ vector ScalerBaseCL::ExtractVectorToScale(const vector &X) const { vector result; if(use_custom) { // Extraer rango específico result.Resize(count_cols); for(entero_unsigned i = 0; i < count_cols; i++) result[i] = X[start_col + i]; } else { // Extraer todas excepto las últimas N entero_unsigned size_to_scale = X.Size() - excluyed_cols; result.Resize(size_to_scale); for(entero_unsigned i = 0; i < size_to_scale; i++) result[i] = X[i]; } return result; } */ //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ __kernel void ReconstructVector( __global const double* data, //data __global double* result, //resultado const entero_unsigned start_col, const entero_unsigned count_cols ) { uint idx = get_global_id(0); result[idx + start_col] = data[idx]; //No es necesario comprobar ya se da eltamaño } /* //+------------------------------------------------------------------+ vector ScalerBaseCL::ReconstructVector(const vector &X_original, const vector &X_scaled) const { vector result = X_original; if(use_custom) { // Reemplazar rango específico for(entero_unsigned i = 0; i < count_cols; i++) result[start_col + i] = X_scaled[i]; } else { // Reemplazar todas excepto las últimas N for(entero_unsigned i = 0; i < X_scaled.Size(); i++) result[i] = X_scaled[i]; } return result; } */ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ __kernel void ReconstructMatrix( __global const double* scaled_data, // X_scaled __global double* original_result, // X_original const entero_unsigned rows_data, const entero_unsigned cols_data, const entero_unsigned rows_res, const entero_unsigned cols_res, const entero_unsigned cols_to_insert, // Columnas a insertar const entero_unsigned start_col // Posición donde insertar ) { uint row = get_global_id(0); uint col = get_global_id(1); // Leer desde X_scaled entero_unsigned idx_scaled = row * cols_to_insert + col; // Escribir en X_original en posición específica entero_unsigned target_col = start_col + col; entero_unsigned idx_result = row * cols_res + target_col; original_result[idx_result] = scaled_data[idx_scaled]; } /* //+------------------------------------------------------------------+ matrix ScalerBaseCL::ReconstructMatrix(const matrix &X_original, const matrix &X_scaled) const { matrix result = X_original; // Copia completa if(use_custom) { for(entero_unsigned row = 0; row < X_original.Rows(); row++) for(entero_unsigned col = 0; col < count_cols; col++) result[row][start_col + col] = X_scaled[row][col]; } else { for(entero_unsigned row = 0; row < X_original.Rows(); row++) for(entero_unsigned col = 0; col < X_scaled.Cols(); col++) result[row][col] = X_scaled[row][col]; } return result; } */ //+------------------------------------------------------------------+