예제 #1
0
파일: wee-eval.c 프로젝트: Evalle/weechat
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;
}
예제 #2
0
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;
}