Example #1
0
/*
 * Converts a PIP quast to a union of polyhedra
 */
osl_relation_p pip_quast_to_polyhedra(PipQuast *quast, int nvar, int npar) {
  // originaly used for lastwriter
  // july 5th 2012 : extracted from dependence.c

  osl_relation_p ep;
  osl_relation_p tp;
  osl_relation_p qp;
  osl_relation_p iter;
  int precision;
  int j;
  if (quast == NULL)
    return NULL;

  #if defined(CANDL_LINEAR_VALUE_IS_INT)
    precision = OSL_PRECISION_SP;
  #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
    precision = OSL_PRECISION_DP;
  #elif defined(CANDL_LINEAR_VALUE_IS_MP)
    precision = OSL_PRECISION_MP;
  #endif

  if (quast->condition != NULL) {
    tp = pip_quast_to_polyhedra(quast->next_then, nvar, npar);
    ep = pip_quast_to_polyhedra(quast->next_else, nvar, npar);
      
    /* Each of the matrices in the then tree needs to be augmented with
     * the condition */
    for (iter = tp ; iter != NULL ; iter = iter->next) {
      int nrows = iter->nb_rows;
      osl_int_set_si(precision, &iter->m[nrows][0], 1);
      for (j = 1; j < 1 + nvar; j++)
        osl_int_set_si(precision, &iter->m[nrows][j], 0);
      for (j = 0; j < npar + 1; j++)
        osl_int_set_si(precision, &iter->m[nrows][1 + nvar + j],
                        CANDL_get_si(quast->condition->the_vector[j]));
      (iter->nb_rows)++;
    }

    /* JP : july 5th 2012:
     * Fix negation of a constraint in adding -1 to the constant
     */

    for (iter = ep; iter != NULL ; iter = iter->next) {
      int nrows = iter->nb_rows;
      /* Inequality */
      osl_int_set_si(precision, &iter->m[nrows][0], 5);
      for (j = 1; j < 1 + nvar; j++)
        osl_int_set_si(precision, &iter->m[nrows][j], 0);
      for (j = 0; j < npar + 1; j++)
        osl_int_set_si(precision, &iter->m[nrows][1 + nvar + j],
                     -CANDL_get_si(quast->condition->the_vector[j]));
      osl_int_decrement(precision, 
                        &iter->m[nrows][iter->nb_columns - 1],
                        iter->m[nrows][iter->nb_columns - 1]);
      (iter->nb_rows)++;
    }

    /* union of tp and ep */
    if (tp) {
      qp = tp;
      for (iter = tp ; iter->next != NULL ; iter = iter->next)
        ;
      iter->next = ep;
    } else {
      qp = ep;
    }

    return qp;

  } else {
    /* quast condition is NULL */
    osl_relation_p lwmatrix = osl_relation_pmalloc(precision, nvar+npar+1,
                                                  nvar+npar+2);
    PipList *vecList = quast->list;

    int count=0;
    while (vecList != NULL) {
      /* Equality */
      osl_int_set_si(precision, &lwmatrix->m[count][0], 0);
      for (j=0; j < nvar; j++)
        if (j == count)
          osl_int_set_si(precision, &lwmatrix->m[count][j + 1], 1);
        else
          osl_int_set_si(precision, &lwmatrix->m[count][j + 1], 0);

      for (j=0; j < npar; j++)
        osl_int_set_si(precision, &lwmatrix->m[count][j + 1 + nvar],
                       -CANDL_get_si(vecList->vector->the_vector[j]));
      /* Constant portion */
      if (quast->newparm != NULL)
        /* Don't handle newparm for now */
        osl_int_set_si(precision, &lwmatrix->m[count][npar + 1 + nvar],
                       -CANDL_get_si(vecList->vector->the_vector[npar+1]));
      else
        osl_int_set_si(precision, &lwmatrix->m[count][npar + 1 + nvar],
                       -CANDL_get_si(vecList->vector->the_vector[npar]));

      count++;

      vecList = vecList->next;
    }
    lwmatrix->nb_rows = count;
    lwmatrix->nb_parameters = npar;

    return lwmatrix;
  }
}
Example #2
0
candl_program_p candl_program_convert_scop(scoplib_scop_p scop, int** indices)
{
  int i, j, k, l;
  candl_program_p res = candl_program_malloc();
  scoplib_statement_p s = scop->statement;

  /* Duplicate the context. */
  res->context = (CandlMatrix*) scoplib_matrix_copy(scop->context);
  if (res->context == NULL)
    res->context = candl_matrix_malloc(0, 2);

  /* Count the number of statements. */
  for (res->nb_statements = 0; s; s = s->next, res->nb_statements++)
    ;

  /* Allocate the statements array. */
  res->statement = (CandlStatement**) malloc(res->nb_statements *
					     sizeof(CandlStatement*));

  /* Initialize structures used in iterator indices computation. */
  int max = 0;
  int max_loop_depth = 128;
  int cur_index[max_loop_depth];
  int last[max_loop_depth];
  for (i = 0; i < max_loop_depth; ++i)
    {
      cur_index[i] = i;
      last[i] = 0;
    }
  /* Create the statements. */
  for (i = 0, s = scop->statement; s; s = s->next, ++i)
    {
      CandlStatement* statement = candl_statement_malloc();
      statement->label = i;
      statement->ref = s;
      if (s->domain->next != NULL)
	CANDL_FAIL("Error: union of domains not supported");

      statement->domain = (CandlMatrix*) scoplib_matrix_copy(s->domain->elt);
      /* For the moment, we do not parse the statement to extract its type. */
      statement->type = CANDL_ASSIGNMENT;
      statement->depth = statement->domain->NbColumns - 2 - scop->nb_parameters;
      statement->written = (CandlMatrix*) scoplib_matrix_copy(s->write);
      if (statement->written == NULL)
	statement->written =
	  candl_matrix_malloc(0, statement->domain->NbColumns);
      statement->read = (CandlMatrix*) scoplib_matrix_copy(s->read);
      if (statement->read == NULL)
	statement->read = candl_matrix_malloc(0, statement->domain->NbColumns);
      statement->index = (int*) malloc(statement->depth * sizeof(int));
      if (indices != NULL)
	/* Iterator indices are provided. */
	for (j = 0; j < statement->depth; ++j)
	  statement->index[j] = indices[i][j];
      else
	{
	  /* Iterator indices must be computed from the scattering matrix. */
	  scoplib_matrix_p m = s->schedule;
	  if (m == NULL)
	    CANDL_FAIL("Error: No scheduling matrix and no loop "
		       "indices specification");

	  /* FIXME: Sort the statements in their execution order. */
	  /* It must be a 2d+1 identity scheduling matrix, and
	     statements must be sorted in their execution order. */
	  /* Check that it is a identity matrix. */
	  int error = 0;
	  if (m->NbRows != 2 * statement->depth + 1)
	    error = 1;
	  /*else
	    for (l = 0; l < m->NbRows; ++l)
	      {

		for (k = 1; k < m->NbColumns - 1; ++k){
		  switch (CANDL_get_si(m->p[l][k]))
		    {
		    case 0:
		      if (l % 2 && k == (l / 2) + 1) error = 1;
		      break;
		    case 1:
		      if ((l % 2 && k != (l / 2) + 1) || (! l % 2)) error = 1;
		      break;
		    default:
		      error = 1;
		      break;
		    }
        }
		if (l % 2 && CANDL_get_si(m->p[l][k]))
		  error = 1;
	      }*/
	  if (error)
	    CANDL_FAIL("Error: schedule is not identity 2d+1 shaped.\n"
		       "Consider using the <indices> option tag to declare "
		       " iterator indices");

	  /* Compute the value of the iterator indices. */
	  for (j = 0; j < statement->depth; ++j)
	    {
	      int val = CANDL_get_si(m->p[2 * j][m->NbColumns - 1]);
	      if (last[j] < val)
		{
		  last[j] = val;
		  for (k = j + 1; k < max_loop_depth; ++k)
		    last[k] = 0;
		  for (k = j; k < max_loop_depth; ++k)
		    cur_index[k] = max + (k - j) + 1;
		  break;
		}
	    }
	  for (j = 0; j < statement->depth; ++j)
	    statement->index[j] = cur_index[j];
	  max = max < cur_index[j - 1] ? cur_index[j - 1] : max;
	}
      /* Store the statement. */
      res->statement[i] = statement;
    }

  return res;
}
Example #3
0
/*
 * Converts all conditions where the path does not lead to a solution
 * The return is a upip_quast_to_polyhedranion of polyhedra
 * extracted from pip_quast_to_polyhedra
 */
osl_relation_p pip_quast_no_solution_to_polyhedra(PipQuast *quast, int nvar, 
                                                  int npar) {
  osl_relation_p ep;
  osl_relation_p tp;
  osl_relation_p qp;
  osl_relation_p iter;
  int precision;
  int j;
  if (quast == NULL)
    return NULL;

  #if defined(CANDL_LINEAR_VALUE_IS_INT)
    precision = OSL_PRECISION_SP;
  #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
    precision = OSL_PRECISION_DP;
  #elif defined(CANDL_LINEAR_VALUE_IS_MP)
    precision = OSL_PRECISION_MP;
  #endif

  if (quast->condition != NULL) {
    tp = pip_quast_no_solution_to_polyhedra(quast->next_then, nvar, npar);
    ep = pip_quast_no_solution_to_polyhedra(quast->next_else, nvar, npar);
      
    /* Each of the matrices in the then tree needs to be augmented with
     * the condition */
    for (iter = tp ; iter != NULL ; iter = iter->next) {
      int nrows = iter->nb_rows;
      osl_int_set_si(precision, &iter->m[nrows][0], 1);
      for (j = 1; j < 1 + nvar; j++)
        osl_int_set_si(precision, &iter->m[nrows][j], 0);
      for (j = 0; j < npar + 1; j++)
        osl_int_set_si(precision, &iter->m[nrows][1 + nvar + j],
                        CANDL_get_si(quast->condition->the_vector[j]));
      (iter->nb_rows)++;
    }

    for (iter = ep; iter != NULL ; iter = iter->next) {
      int nrows = iter->nb_rows;
      /* Inequality */
      osl_int_set_si(precision, &iter->m[nrows][0], 1);
      for (j = 1; j < 1 + nvar; j++)
        osl_int_set_si(precision, &iter->m[nrows][j], 0);
      for (j = 0; j < npar + 1; j++)
        osl_int_set_si(precision, &iter->m[nrows][1 + nvar + j],
                     -CANDL_get_si(quast->condition->the_vector[j]));
      osl_int_decrement(precision, 
                        &iter->m[nrows][iter->nb_columns - 1],
                        iter->m[nrows][iter->nb_columns - 1]);
      (iter->nb_rows)++;
    }

    /* union of tp and ep */
    if (tp) {
      qp = tp;
      for (iter = tp ; iter->next != NULL ; iter = iter->next)
        ;
      iter->next = ep;
    } else {
      qp = ep;
    }

    return qp;

  }

  if (quast->list != NULL)
    return NULL;

  /* quast condition is NULL */
  osl_relation_p lwmatrix = osl_relation_pmalloc(precision, nvar+npar+1,
                                                nvar+npar+2);
  lwmatrix->nb_rows = 0;
  lwmatrix->nb_parameters = npar;

  return lwmatrix;
}
Example #4
0
File: ddv.c Project: Ced/candl
/**
 * candl_ddv_constant_val: returns true iff all possible values of the
 * minimization of the first variable of the system is a scalar constant
 * (not parametric), and has the same value for all conditions of the QUAST.
 * The scalar constant is put in the 'val' argument.
 *
 */
static
int
candl_ddv_constant_val(osl_relation_p system, int* val, int nb_par) {
  PipOptions * options;
  PipQuast * solution;
  osl_relation_p context;
  int is_constant_val = 1;
  int cst;
  int cst_base = 42;
  int first = 1;
  int i, j;
  int precision = system->precision;

  // 1- Comute the lexmin of the system, to get a QUAST.
  options = pip_options_init();
  options->Simplify = 1;
  options->Urs_parms = -1;
  options->Urs_unknowns = -1;
  options->Nq = 0;
  
  context = osl_relation_pmalloc(precision, 0, nb_par + 2);
  solution = pip_solve_osl(system, context, -1, options);

  if ((solution != NULL) &&
      ((solution->list != NULL) || (solution->condition != NULL))) {
    // 2- Traverse all leaves, ensure they have the same value.
    int nb_leaves = count_quast_leaves(solution);
    PipList* leaveslist[nb_leaves + 1];
    for (i = 0; i < nb_leaves + 1; ++i)
      leaveslist[i] = NULL;
    get_quast_leaves(solution, leaveslist);

    for (i = 0; i < nb_leaves; ++i) {
      PipList* list = leaveslist[i];
      if (list && list->vector) {
        PipVector* vect = list->vector;
        
        // FIXME : check if precision is correct to use piplib
        
        for (j = 0; j < nb_par; ++j)
          if (!CANDL_zero_p(vect->the_vector[j])) {
            is_constant_val = 0;
            break;
          }
        if (is_constant_val) {
          cst = CANDL_get_si(vect->the_vector[vect->nb_elements-1]);
          if (first) {
            first = 0;
            cst_base = cst;
          }
          else if (! first && cst != cst_base) {
            is_constant_val = 0;
            break;
          }
        }
        else
          break;
      }
    }
  }

  pip_quast_free(solution);
  pip_options_free(options);
  osl_relation_free(context);

  if (is_constant_val)
    *val = cst_base;

  return is_constant_val;
}