Exemple #1
0
static ppl_Pointset_Powerset_C_Polyhedron_t
build_pairwise_scheduling_inequality (graphite_dim_t dim,
				      graphite_dim_t pos,
				      graphite_dim_t offset,
				      bool direction)
{
  ppl_Pointset_Powerset_C_Polyhedron_t res;
  ppl_Polyhedron_t equalities;
  ppl_Constraint_t cstr;

  ppl_new_C_Polyhedron_from_space_dimension (&equalities, dim, 0);

  if (direction)
    cstr = build_pairwise_constraint (dim, pos, pos + offset, -1,
				      PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
  else
    cstr = build_pairwise_constraint (dim, pos, pos + offset, 1,
				      PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL);

  ppl_Polyhedron_add_constraint (equalities, cstr);
  ppl_delete_Constraint (cstr);

  ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&res, equalities);
  ppl_delete_Polyhedron (equalities);
  return res;
}
Exemple #2
0
static ppl_Pointset_Powerset_C_Polyhedron_t
dr_equality_constraints (graphite_dim_t dim,
		         graphite_dim_t pos, graphite_dim_t nb_subscripts)
{
  ppl_Polyhedron_t subscript_equalities;
  ppl_Pointset_Powerset_C_Polyhedron_t res;
  Value v, v_op;
  graphite_dim_t i;

  value_init (v);
  value_init (v_op);
  value_set_si (v, 1);
  value_set_si (v_op, -1);

  ppl_new_C_Polyhedron_from_space_dimension (&subscript_equalities, dim, 0);
  for (i = 0; i < nb_subscripts; i++)
    {
      ppl_Linear_Expression_t expr;
      ppl_Constraint_t cstr;
      ppl_Coefficient_t coef;

      ppl_new_Coefficient (&coef);
      ppl_new_Linear_Expression_with_dimension (&expr, dim);

      ppl_assign_Coefficient_from_mpz_t (coef, v);
      ppl_Linear_Expression_add_to_coefficient (expr, pos + i, coef);
      ppl_assign_Coefficient_from_mpz_t (coef, v_op);
      ppl_Linear_Expression_add_to_coefficient (expr, pos + i + nb_subscripts,
						coef);

      ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_EQUAL);
      ppl_Polyhedron_add_constraint (subscript_equalities, cstr);

      ppl_delete_Linear_Expression (expr);
      ppl_delete_Constraint (cstr);
      ppl_delete_Coefficient (coef);
    }

  ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
    (&res, subscript_equalities);
  value_clear (v);
  value_clear (v_op);
  ppl_delete_Polyhedron (subscript_equalities);

  return res;
}
Exemple #3
0
static ppl_Pointset_Powerset_C_Polyhedron_t
build_pairwise_scheduling_equality (graphite_dim_t dim,
		                    graphite_dim_t pos, graphite_dim_t offset)
{
  ppl_Pointset_Powerset_C_Polyhedron_t res;
  ppl_Polyhedron_t equalities;
  ppl_Constraint_t cstr;

  ppl_new_C_Polyhedron_from_space_dimension (&equalities, dim, 0);

  cstr = build_pairwise_constraint (dim, pos, pos + offset, 0,
				    PPL_CONSTRAINT_TYPE_EQUAL);
  ppl_Polyhedron_add_constraint (equalities, cstr);
  ppl_delete_Constraint (cstr);

  ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&res, equalities);
  ppl_delete_Polyhedron (equalities);
  return res;
}
void
timed_compute_open_hypercube_generators(int csecs, int max_dimension) {
  int i;
  int result;
  ppl_const_Generator_System_t gs;
  ppl_Polyhedron_t ph;

  for (i = 0; i <= max_dimension; ++i) {
    ppl_new_NNC_Polyhedron_from_space_dimension(&ph, i, 0);
    open_hypercube(i, ph);
    ppl_set_timeout(csecs);
    result = ppl_Polyhedron_get_generators(ph, &gs);
    ppl_reset_timeout();
    ppl_delete_Polyhedron(ph);
    if (result == PPL_TIMEOUT_EXCEPTION)
      /* Timeout expired */
      return;
    else if (result != 0)
      /* Unexpected error */
      exit(1);
  }
  /* Should not reach this point */
  exit(1);
}
Exemple #5
0
static int
solve_with_generators(ppl_Constraint_System_t ppl_cs,
                      ppl_const_Linear_Expression_t ppl_objective_le,
                      ppl_Coefficient_t optimum_n,
                      ppl_Coefficient_t optimum_d,
                      ppl_Generator_t point) {
  ppl_Polyhedron_t ppl_ph;
  int optimum_found = 0;
  int empty;
  int unbounded;
  int included;

  /* Create the polyhedron (recycling the data structures of ppl_cs). */
  ppl_new_C_Polyhedron_recycle_Constraint_System(&ppl_ph, ppl_cs);

#ifdef PPL_LPSOL_SUPPORTS_TIMINGS

  if (print_timings) {
    fprintf(stderr, "Time to create a PPL polyhedron: ");
    print_clock(stderr);
    fprintf(stderr, " s\n");
    start_clock();
  }

#endif /* defined(PPL_LPSOL_SUPPORTS_TIMINGS) */

  empty = ppl_Polyhedron_is_empty(ppl_ph);

#ifdef PPL_LPSOL_SUPPORTS_TIMINGS

  if (print_timings) {
    fprintf(stderr, "Time to check for emptiness: ");
    print_clock(stderr);
    fprintf(stderr, " s\n");
    start_clock();
  }

#endif /* defined(PPL_LPSOL_SUPPORTS_TIMINGS) */

  if (empty) {
    if (verbosity >= 1)
      fprintf(output_file, "Unfeasible problem.\n");
    maybe_check_results(PPL_MIP_PROBLEM_STATUS_UNFEASIBLE, 0.0);
    goto exit;
  }

  if (!empty && no_optimization) {
    if (verbosity >= 1)
      fprintf(output_file, "Feasible problem.\n");
    /* Kludge: let's pass PPL_MIP_PROBLEM_STATUS_OPTIMIZED,
       to let work `maybe_check_results'. */
    maybe_check_results(PPL_MIP_PROBLEM_STATUS_OPTIMIZED, 0.0);
    goto exit;
  }

  /* Check whether the problem is unbounded. */
  unbounded = maximize
    ? !ppl_Polyhedron_bounds_from_above(ppl_ph, ppl_objective_le)
    : !ppl_Polyhedron_bounds_from_below(ppl_ph, ppl_objective_le);

#ifdef PPL_LPSOL_SUPPORTS_TIMINGS

  if (print_timings) {
    fprintf(stderr, "Time to check for unboundedness: ");
    print_clock(stderr);
    fprintf(stderr, " s\n");
    start_clock();
  }

#endif /* defined(PPL_LPSOL_SUPPORTS_TIMINGS) */

  if (unbounded) {
    if (verbosity >= 1)
      fprintf(output_file, "Unbounded problem.\n");
    maybe_check_results(PPL_MIP_PROBLEM_STATUS_UNBOUNDED, 0.0);
    goto exit;
  }

  optimum_found = maximize
    ? ppl_Polyhedron_maximize_with_point(ppl_ph, ppl_objective_le,
                                         optimum_n, optimum_d, &included,
                                         point)
    : ppl_Polyhedron_minimize_with_point(ppl_ph, ppl_objective_le,
                                         optimum_n, optimum_d, &included,
                                         point);

#ifdef PPL_LPSOL_SUPPORTS_TIMINGS

  if (print_timings) {
    fprintf(stderr, "Time to find the optimum: ");
    print_clock(stderr);
    fprintf(stderr, " s\n");
    start_clock();
  }

#endif /* defined(PPL_LPSOL_SUPPORTS_TIMINGS) */

  if (!optimum_found)
    fatal("internal error");

  if (!included)
    fatal("internal error");

 exit:
  ppl_delete_Polyhedron(ppl_ph);
  return optimum_found;
}
Exemple #6
0
static void
solve(char* file_name) {
  ppl_Constraint_System_t ppl_cs;
#ifndef NDEBUG
  ppl_Constraint_System_t ppl_cs_copy;
#endif
  ppl_Generator_t optimum_location;
  ppl_Linear_Expression_t ppl_le;
  int dimension, row, num_rows, column, nz, i, j, type;
  int* coefficient_index;
  double lb, ub;
  double* coefficient_value;
  mpq_t rational_lb, rational_ub;
  mpq_t* rational_coefficient;
  mpq_t* objective;
  ppl_Linear_Expression_t ppl_objective_le;
  ppl_Coefficient_t optimum_n;
  ppl_Coefficient_t optimum_d;
  mpq_t optimum;
  mpz_t den_lcm;
  int optimum_found;
  glp_mpscp glpk_mpscp;

  glpk_lp = glp_create_prob();
  glp_init_mpscp(&glpk_mpscp);

  if (verbosity == 0) {
    /* FIXME: find a way to suppress output from glp_read_mps. */
  }

#ifdef PPL_LPSOL_SUPPORTS_TIMINGS

  if (print_timings)
    start_clock();

#endif /* defined(PPL_LPSOL_SUPPORTS_TIMINGS) */

  if (glp_read_mps(glpk_lp, GLP_MPS_FILE, &glpk_mpscp, file_name) != 0)
    fatal("cannot read MPS file `%s'", file_name);

#ifdef PPL_LPSOL_SUPPORTS_TIMINGS

  if (print_timings) {
    fprintf(stderr, "Time to read the input file: ");
    print_clock(stderr);
    fprintf(stderr, " s\n");
    start_clock();
  }

#endif /* defined(PPL_LPSOL_SUPPORTS_TIMINGS) */

  glpk_lp_num_int = glp_get_num_int(glpk_lp);

  if (glpk_lp_num_int > 0 && !no_mip && !use_simplex)
     fatal("the enumeration solving method can not handle MIP problems");

  dimension = glp_get_num_cols(glpk_lp);

  /* Read variables constrained to be integer. */
  if (glpk_lp_num_int > 0 && !no_mip && use_simplex) {
    if (verbosity >= 4)
      fprintf(output_file, "Integer variables:\n");
    integer_variables = (ppl_dimension_type*)
      malloc((glpk_lp_num_int + 1)*sizeof(ppl_dimension_type));
    for (i = 0, j = 0; i < dimension; ++i) {
      int col_kind = glp_get_col_kind(glpk_lp, i+1);
      if (col_kind == GLP_IV || col_kind == GLP_BV) {
        integer_variables[j] = i;
        if (verbosity >= 4) {
          ppl_io_fprint_variable(output_file, i);
          fprintf(output_file, " ");
        }
        ++j;
      }
    }
  }
  coefficient_index = (int*) malloc((dimension+1)*sizeof(int));
  coefficient_value = (double*) malloc((dimension+1)*sizeof(double));
  rational_coefficient = (mpq_t*) malloc((dimension+1)*sizeof(mpq_t));


  ppl_new_Constraint_System(&ppl_cs);

  mpq_init(rational_lb);
  mpq_init(rational_ub);
  for (i = 1; i <= dimension; ++i)
    mpq_init(rational_coefficient[i]);

  mpz_init(den_lcm);

  if (verbosity >= 4)
    fprintf(output_file, "\nConstraints:\n");

  /* Set up the row (ordinary) constraints. */
  num_rows = glp_get_num_rows(glpk_lp);
  for (row = 1; row <= num_rows; ++row) {
    /* Initialize the least common multiple computation. */
    mpz_set_si(den_lcm, 1);
    /* Set `nz' to the number of non-zero coefficients. */
    nz = glp_get_mat_row(glpk_lp, row, coefficient_index, coefficient_value);
    for (i = 1; i <= nz; ++i) {
      set_mpq_t_from_double(rational_coefficient[i], coefficient_value[i]);
      /* Update den_lcm. */
      mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_coefficient[i]));
    }

    lb = glp_get_row_lb(glpk_lp, row);
    ub = glp_get_row_ub(glpk_lp, row);

    set_mpq_t_from_double(rational_lb, lb);
    set_mpq_t_from_double(rational_ub, ub);

    mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_lb));
    mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_ub));

    ppl_new_Linear_Expression_with_dimension(&ppl_le, dimension);

    for (i = 1; i <= nz; ++i) {
      mpz_mul(tmp_z, den_lcm, mpq_numref(rational_coefficient[i]));
      mpz_divexact(tmp_z, tmp_z, mpq_denref(rational_coefficient[i]));
      ppl_assign_Coefficient_from_mpz_t(ppl_coeff, tmp_z);
      ppl_Linear_Expression_add_to_coefficient(ppl_le, coefficient_index[i]-1,
                                               ppl_coeff);
    }

    type = glp_get_row_type(glpk_lp, row);
    add_constraints(ppl_le, type, rational_lb, rational_ub, den_lcm, ppl_cs);

    ppl_delete_Linear_Expression(ppl_le);
  }

  free(coefficient_value);
  for (i = 1; i <= dimension; ++i)
    mpq_clear(rational_coefficient[i]);
  free(rational_coefficient);
  free(coefficient_index);

#ifndef NDEBUG
  ppl_new_Constraint_System_from_Constraint_System(&ppl_cs_copy, ppl_cs);
#endif

  /*
    FIXME: here we could build the polyhedron and minimize it before
    adding the variable bounds.
  */

  /* Set up the columns constraints, i.e., variable bounds. */
  for (column = 1; column <= dimension; ++column) {

    lb = glp_get_col_lb(glpk_lp, column);
    ub = glp_get_col_ub(glpk_lp, column);

    set_mpq_t_from_double(rational_lb, lb);
    set_mpq_t_from_double(rational_ub, ub);

    /* Initialize the least common multiple computation. */
    mpz_set_si(den_lcm, 1);
    mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_lb));
    mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_ub));

    ppl_new_Linear_Expression_with_dimension(&ppl_le, dimension);
    ppl_assign_Coefficient_from_mpz_t(ppl_coeff, den_lcm);
    ppl_Linear_Expression_add_to_coefficient(ppl_le, column-1, ppl_coeff);

    type = glp_get_col_type(glpk_lp, column);
    add_constraints(ppl_le, type, rational_lb, rational_ub, den_lcm, ppl_cs);

    ppl_delete_Linear_Expression(ppl_le);
  }

  mpq_clear(rational_ub);
  mpq_clear(rational_lb);

  /* Deal with the objective function. */
  objective = (mpq_t*) malloc((dimension+1)*sizeof(mpq_t));

  /* Initialize the least common multiple computation. */
  mpz_set_si(den_lcm, 1);

  mpq_init(objective[0]);
  set_mpq_t_from_double(objective[0], glp_get_obj_coef(glpk_lp, 0));
  for (i = 1; i <= dimension; ++i) {
    mpq_init(objective[i]);
    set_mpq_t_from_double(objective[i], glp_get_obj_coef(glpk_lp, i));
    /* Update den_lcm. */
    mpz_lcm(den_lcm, den_lcm, mpq_denref(objective[i]));
  }

  /* Set the ppl_objective_le to be the objective function. */
  ppl_new_Linear_Expression_with_dimension(&ppl_objective_le, dimension);
  /* Set value for objective function's inhomogeneous term. */
  mpz_mul(tmp_z, den_lcm, mpq_numref(objective[0]));
  mpz_divexact(tmp_z, tmp_z, mpq_denref(objective[0]));
  ppl_assign_Coefficient_from_mpz_t(ppl_coeff, tmp_z);
  ppl_Linear_Expression_add_to_inhomogeneous(ppl_objective_le, ppl_coeff);
  /* Set values for objective function's variable coefficients. */
  for (i = 1; i <= dimension; ++i) {
    mpz_mul(tmp_z, den_lcm, mpq_numref(objective[i]));
    mpz_divexact(tmp_z, tmp_z, mpq_denref(objective[i]));
    ppl_assign_Coefficient_from_mpz_t(ppl_coeff, tmp_z);
    ppl_Linear_Expression_add_to_coefficient(ppl_objective_le, i-1, ppl_coeff);
  }

  if (verbosity >= 4) {
    fprintf(output_file, "Objective function:\n");
    if (mpz_cmp_si(den_lcm, 1) != 0)
      fprintf(output_file, "(");
    ppl_io_fprint_Linear_Expression(output_file, ppl_objective_le);
  }

  for (i = 0; i <= dimension; ++i)
    mpq_clear(objective[i]);
  free(objective);

  if (verbosity >= 4) {
    if (mpz_cmp_si(den_lcm, 1) != 0) {
      fprintf(output_file, ")/");
      mpz_out_str(output_file, 10, den_lcm);
    }
    fprintf(output_file, "\n%s\n",
            (maximize ? "Maximizing." : "Minimizing."));
  }

  ppl_new_Coefficient(&optimum_n);
  ppl_new_Coefficient(&optimum_d);
  ppl_new_Generator_zero_dim_point(&optimum_location);

  optimum_found = use_simplex
    ? solve_with_simplex(ppl_cs,
                         ppl_objective_le,
                         optimum_n,
                         optimum_d,
                         optimum_location)
    : solve_with_generators(ppl_cs,
                            ppl_objective_le,
                            optimum_n,
                            optimum_d,
                            optimum_location);

  ppl_delete_Linear_Expression(ppl_objective_le);

  if (glpk_lp_num_int > 0)
      free(integer_variables);

  if (optimum_found) {
    mpq_init(optimum);
    ppl_Coefficient_to_mpz_t(optimum_n, tmp_z);
    mpq_set_num(optimum, tmp_z);
    ppl_Coefficient_to_mpz_t(optimum_d, tmp_z);
    mpz_mul(tmp_z, tmp_z, den_lcm);
    mpq_set_den(optimum, tmp_z);
    if (verbosity == 1)
      fprintf(output_file, "Optimized problem.\n");
    if (verbosity >= 2)
      fprintf(output_file, "Optimum value: %.10g\n", mpq_get_d(optimum));
    if (verbosity >= 3) {
      fprintf(output_file, "Optimum location:\n");
      ppl_Generator_divisor(optimum_location, ppl_coeff);
      ppl_Coefficient_to_mpz_t(ppl_coeff, tmp_z);
      for (i = 0; i < dimension; ++i) {
        mpz_set(mpq_denref(tmp1_q), tmp_z);
        ppl_Generator_coefficient(optimum_location, i, ppl_coeff);
        ppl_Coefficient_to_mpz_t(ppl_coeff, mpq_numref(tmp1_q));
        ppl_io_fprint_variable(output_file, i);
        fprintf(output_file, " = %.10g\n", mpq_get_d(tmp1_q));
      }
    }
#ifndef NDEBUG
    {
      ppl_Polyhedron_t ph;
      unsigned int relation;
      ppl_new_C_Polyhedron_recycle_Constraint_System(&ph, ppl_cs_copy);
      ppl_delete_Constraint_System(ppl_cs_copy);
      relation = ppl_Polyhedron_relation_with_Generator(ph, optimum_location);
      ppl_delete_Polyhedron(ph);
      assert(relation == PPL_POLY_GEN_RELATION_SUBSUMES);
    }
#endif
    maybe_check_results(PPL_MIP_PROBLEM_STATUS_OPTIMIZED,
                        mpq_get_d(optimum));
    mpq_clear(optimum);
  }

  ppl_delete_Constraint_System(ppl_cs);
  ppl_delete_Coefficient(optimum_d);
  ppl_delete_Coefficient(optimum_n);
  ppl_delete_Generator(optimum_location);

  glp_delete_prob(glpk_lp);
}
ppl_Polyhedron_t
ppl_strip_loop (ppl_Polyhedron_t ph, ppl_dimension_type loop, int stride)
{
  ppl_const_Constraint_System_t pcs;
  ppl_Constraint_System_const_iterator_t cit, end;
  ppl_const_Constraint_t cstr;
  ppl_Linear_Expression_t expr;
  int v;
  ppl_dimension_type dim;
  ppl_Polyhedron_t res;
  ppl_Coefficient_t c;
  Value val;

  value_init (val);
  ppl_new_Coefficient (&c);

  ppl_Polyhedron_space_dimension (ph, &dim);
  ppl_Polyhedron_get_constraints (ph, &pcs);

  /* Start from a copy of the constraints.  */
  ppl_new_C_Polyhedron_from_space_dimension (&res, dim + 1, 0);
  ppl_Polyhedron_add_constraints (res, pcs);

  /* Add an empty dimension for the strip loop.  */
  ppl_insert_dimensions (res, loop, 1);

  /* Identify the constraints that define the lower and upper bounds
     of the strip-mined loop, and add them to the strip loop.  */
  {
    ppl_Polyhedron_t tmp;

    ppl_new_C_Polyhedron_from_space_dimension (&tmp, dim + 1, 0);
    ppl_new_Constraint_System_const_iterator (&cit);
    ppl_new_Constraint_System_const_iterator (&end);

    for (ppl_Constraint_System_begin (pcs, cit),
	   ppl_Constraint_System_end (pcs, end);
	 !ppl_Constraint_System_const_iterator_equal_test (cit, end);
	 ppl_Constraint_System_const_iterator_increment (cit))
      {
	ppl_Constraint_System_const_iterator_dereference (cit, &cstr);
	ppl_new_Linear_Expression_from_Constraint (&expr, cstr);
	ppl_Linear_Expression_coefficient (expr, loop, c);
	ppl_delete_Linear_Expression (expr);
	ppl_Coefficient_to_mpz_t (c, val);
	v = value_get_si (val);

	if (0 < v || v < 0)
	  ppl_Polyhedron_add_constraint (tmp, cstr);
      }
    ppl_delete_Constraint_System_const_iterator (cit);
    ppl_delete_Constraint_System_const_iterator (end);

    ppl_insert_dimensions (tmp, loop + 1, 1);
    ppl_Polyhedron_get_constraints (tmp, &pcs);
    ppl_Polyhedron_add_constraints (res, pcs);
    ppl_delete_Polyhedron (tmp);
  }

  /* Lower bound of a tile starts at "stride * outer_iv".  */
  {
    ppl_Constraint_t new_cstr;
    ppl_new_Linear_Expression_with_dimension (&expr, dim + 1);

    ppl_set_coef (expr, loop + 1, 1);
    ppl_set_coef (expr, loop, -1 * stride);

    ppl_new_Constraint (&new_cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
    ppl_delete_Linear_Expression (expr);
    ppl_Polyhedron_add_constraint (res, new_cstr);
    ppl_delete_Constraint (new_cstr);
  }

  /* Upper bound of a tile stops at "stride * outer_iv + stride - 1",
     or at the old upper bound that is not modified.  */
  {
    ppl_Constraint_t new_cstr;
    ppl_new_Linear_Expression_with_dimension (&expr, dim + 1);

    ppl_set_coef (expr, loop + 1, -1);
    ppl_set_coef (expr, loop, stride);
    ppl_set_inhomogeneous (expr, stride - 1);

    ppl_new_Constraint (&new_cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
    ppl_delete_Linear_Expression (expr);
    ppl_Polyhedron_add_constraint (res, new_cstr);
    ppl_delete_Constraint (new_cstr);
  }

  value_clear (val);
  ppl_delete_Coefficient (c);
  return res;
}