char * eval_expression_condition (const char *expr, struct t_hashtable *pointers, struct t_hashtable *extra_vars, int extra_vars_eval, const char *prefix, const char *suffix) { int logic, comp, length, level, rc; const char *pos, *pos_end; char *expr2, *sub_expr, *value, *tmp_value, *tmp_value2; value = NULL; if (!expr) return NULL; if (!expr[0]) return strdup (expr); /* skip spaces at beginning of string */ while (expr[0] == ' ') { expr++; } if (!expr[0]) return strdup (expr); /* skip spaces at end of string */ pos_end = expr + strlen (expr) - 1; while ((pos_end > expr) && (pos_end[0] == ' ')) { pos_end--; } expr2 = string_strndup (expr, pos_end + 1 - expr); if (!expr2) return NULL; /* * search for a logical operator, and if one is found: * - split expression into two sub-expressions * - evaluate first sub-expression * - if needed, evaluate second sub-expression * - return result */ for (logic = 0; logic < EVAL_NUM_LOGICAL_OPS; logic++) { pos = eval_strstr_level (expr2, logical_ops[logic]); if (pos > expr2) { pos_end = pos - 1; while ((pos_end > expr2) && (pos_end[0] == ' ')) { pos_end--; } sub_expr = string_strndup (expr2, pos_end + 1 - expr2); if (!sub_expr) goto end; tmp_value = eval_expression_condition (sub_expr, pointers, extra_vars, extra_vars_eval, prefix, suffix); free (sub_expr); rc = eval_is_true (tmp_value); if (tmp_value) free (tmp_value); /* * if rc == 0 with "&&" or rc == 1 with "||", no need to * evaluate second sub-expression, just return the rc */ if ((!rc && (logic == EVAL_LOGICAL_OP_AND)) || (rc && (logic == EVAL_LOGICAL_OP_OR))) { value = strdup ((rc) ? EVAL_STR_TRUE : EVAL_STR_FALSE); goto end; } pos += strlen (logical_ops[logic]); while (pos[0] == ' ') { pos++; } tmp_value = eval_expression_condition (pos, pointers, extra_vars, extra_vars_eval, prefix, suffix); rc = eval_is_true (tmp_value); if (tmp_value) free (tmp_value); value = strdup ((rc) ? EVAL_STR_TRUE : EVAL_STR_FALSE); goto end; } } /* * search for a comparison, and if one is found: * - split expression into two sub-expressions * - evaluate the two sub-expressions * - compare sub-expressions * - return result */ for (comp = 0; comp < EVAL_NUM_COMPARISONS; comp++) { pos = eval_strstr_level (expr2, comparisons[comp]); if (pos > expr2) { pos_end = pos - 1; while ((pos_end > expr2) && (pos_end[0] == ' ')) { pos_end--; } sub_expr = string_strndup (expr2, pos_end + 1 - expr2); if (!sub_expr) goto end; pos += strlen (comparisons[comp]); while (pos[0] == ' ') { pos++; } if ((comp == EVAL_COMPARE_REGEX_MATCHING) || (comp == EVAL_COMPARE_REGEX_NOT_MATCHING)) { /* for regex: just replace vars in both expressions */ tmp_value = eval_replace_vars (sub_expr, pointers, extra_vars, extra_vars_eval, prefix, suffix, NULL); tmp_value2 = eval_replace_vars (pos, pointers, extra_vars, extra_vars_eval, prefix, suffix, NULL); } else { /* other comparison: fully evaluate both expressions */ tmp_value = eval_expression_condition (sub_expr, pointers, extra_vars, extra_vars_eval, prefix, suffix); tmp_value2 = eval_expression_condition (pos, pointers, extra_vars, extra_vars_eval, prefix, suffix); } free (sub_expr); value = eval_compare (tmp_value, comp, tmp_value2); if (tmp_value) free (tmp_value); if (tmp_value2) free (tmp_value2); goto end; } } /* * evaluate sub-expressions between parentheses and replace them with their * value */ while (expr2[0] == '(') { level = 0; pos = expr2 + 1; while (pos[0]) { if (pos[0] == '(') level++; else if (pos[0] == ')') { if (level == 0) break; level--; } pos++; } /* closing parenthesis not found */ if (pos[0] != ')') goto end; sub_expr = string_strndup (expr2 + 1, pos - expr2 - 1); if (!sub_expr) goto end; tmp_value = eval_expression_condition (sub_expr, pointers, extra_vars, extra_vars_eval, prefix, suffix); free (sub_expr); if (!pos[1]) { /* * nothing around parentheses, then return value of * sub-expression as-is */ value = tmp_value; goto end; } length = ((tmp_value) ? strlen (tmp_value) : 0) + 1 + strlen (pos + 1) + 1; tmp_value2 = malloc (length); if (!tmp_value2) { if (tmp_value) free (tmp_value); goto end; } tmp_value2[0] = '\0'; if (tmp_value) strcat (tmp_value2, tmp_value); strcat (tmp_value2, " "); strcat (tmp_value2, pos + 1); free (expr2); expr2 = tmp_value2; if (tmp_value) free (tmp_value); } /* * at this point, there is no more logical operator neither comparison, * so we just replace variables in string and return the result */ value = eval_replace_vars (expr2, pointers, extra_vars, extra_vars_eval, prefix, suffix, NULL); end: if (expr2) free (expr2); return value; }
T1 eval_test_classic ( Workspace& workspace_cpu, CPUInstHom& cpu_inst_hom, CT* sol0, CT t, PolySys& Classic_Sys, int n_path ) { struct timeval start, end; long seconds, useconds; double timeMS_classic; double timeMS_cpu; double timeMS_gpu; int n_eq = cpu_inst_hom.n_eq; int dim = cpu_inst_hom.dim; if(n_path<=0) { std::cout << "Default number of path" << std::endl; n_path = 1000; } int n_predictor = workspace_cpu.n_predictor; std::cout << "n_path = " << n_path << std::endl; CT* sol = new CT[n_path*dim*(n_predictor+1)]; CT* sol_tmp = sol; for(int sol_idx=0; sol_idx<n_path; sol_idx++) { for(int pred_idx=0; pred_idx<n_predictor+1; pred_idx++) { for(int x_idx=0; x_idx<dim; x_idx++) { int r = rand(); T1 tmp = T1(r); // sol_tmp[x_idx] = CT(sin(tmp),cos(tmp)); sol_tmp[x_idx] = CT(x_idx+1,0.0); // sol_tmp[x_idx] = CT(1,0.0); } sol_tmp += dim; } } CT* t_mult = new CT[n_path*(n_predictor+1)]; for(int sol_idx=0; sol_idx<n_path*(n_predictor+1); sol_idx++) { double r = 1.0*rand()/RAND_MAX; // t_mult[sol_idx] = CT(r,0.0); t_mult[sol_idx] = CT(1,0.0); } int* x_t_idx = new int[n_path]; for(int sol_idx=0; sol_idx<n_path; sol_idx++) { x_t_idx[sol_idx] = rand()%(n_predictor+1); } std::cout << "----- CPU Evaluation ----" << std::endl; Workspace* workspace_cpu_all = new Workspace[n_path]; for(int sol_idx=0; sol_idx<n_path; sol_idx++) { cpu_inst_hom.init_workspace(workspace_cpu_all[sol_idx]); } gettimeofday(&start, NULL); for(int sol_idx=0; sol_idx<n_path; sol_idx++) { CT* tmp_sol = sol+sol_idx*dim*(n_predictor+1)+dim*x_t_idx[sol_idx]; CT* t_tmp = t_mult+sol_idx*(n_predictor+1)+x_t_idx[sol_idx]; cpu_inst_hom.eval(workspace_cpu_all[sol_idx], tmp_sol, *t_tmp); } gettimeofday(&end, NULL); seconds = end.tv_sec - start.tv_sec; useconds = end.tv_usec - start.tv_usec; timeMS_cpu = seconds*1000 + useconds/1000.0; bool classic_check = false; if(classic_check) { std::cout << "----- Class Evaluation ----" << std::endl; CT* workspace_classic = new CT[n_path*n_eq*(dim+1)]; CT** f_val = new CT*[n_path]; CT* tmp_workspace = workspace_classic; CT*** deri_val = new CT**[n_path]; CT** deri_space = new CT*[n_path*n_eq]; for(int sol_idx=0; sol_idx<n_path; sol_idx++) { f_val[sol_idx] = tmp_workspace; tmp_workspace += n_eq; deri_val[sol_idx] = deri_space + sol_idx*n_eq; for(int i=0; i<n_eq; i++) { deri_val[sol_idx][i] = tmp_workspace; tmp_workspace += dim; } } gettimeofday(&start, NULL); for(int sol_idx=0; sol_idx<n_path; sol_idx++) { CT* tmp_sol = sol+sol_idx*dim*(n_predictor+1)+dim*x_t_idx[sol_idx]; Classic_Sys.eval(tmp_sol, f_val[sol_idx], deri_val[sol_idx]); } gettimeofday(&end, NULL); seconds = end.tv_sec - start.tv_sec; useconds = end.tv_usec - start.tv_usec; timeMS_classic = seconds*1000 + useconds/1000.0; // Check two CPU method std::cout << "----- Classic Evaluation Check ----" << std::endl; for(int sol_idx=0; sol_idx<n_path; sol_idx++) { err_check_class_workspace(deri_val[sol_idx],f_val[sol_idx], workspace_cpu_all[sol_idx].matrix, n_eq, dim); } delete[] workspace_classic; delete[] f_val; delete[] deri_val; delete[] deri_space; } std::cout << "----- GPU Evaluation ----" << std::endl; CT** gpu_workspace_all; CT** gpu_matrix_all; gettimeofday(&start, NULL); GPU_Eval(cpu_inst_hom,sol,t_mult,gpu_workspace_all,gpu_matrix_all,n_path, x_t_idx, n_predictor); gettimeofday(&end, NULL); seconds = end.tv_sec - start.tv_sec; useconds = end.tv_usec - start.tv_usec; timeMS_gpu = seconds*1000 + useconds/1000.0; std::cout << "----- CPU vs GPU Evaluation Check----" << std::endl; T1 err = 0; for(int sol_idx=0; sol_idx<n_path; sol_idx++) { // std::cout << "sol_idx = " << sol_idx << std::endl; T1 err_tmp = eval_compare(cpu_inst_hom,gpu_workspace_all[sol_idx], gpu_matrix_all[sol_idx],workspace_cpu_all[sol_idx].all, workspace_cpu_all[sol_idx].matrix); if(err_tmp > err) { err = err_tmp; } // std::cout << "err = " << err_tmp << std::endl; } delete[] x_t_idx; delete[] t_mult; delete[] sol; for(int sol_idx=0; sol_idx<n_path; sol_idx++) { delete[] gpu_workspace_all[sol_idx]; delete[] gpu_matrix_all[sol_idx]; } delete[] gpu_workspace_all; delete[] gpu_matrix_all; std::cout << "err = " << err << std::endl; std::cout << "Classic Eval time " << timeMS_classic << std::endl; std::cout << "CPU Eval time " << timeMS_cpu << std::endl; std::cout << "GPU Eval time " << timeMS_gpu << std::endl; return err; }