/** * Eliminates all the equalities in a set of constraints and returns the set of * constraints defining a full-dimensional polyhedron, such that there is a * bijection between integer points of the original polyhedron and these of the * resulting (projected) polyhedron). * If VL is set to NULL, this funciton allocates it. Else, it assumes that * (*VL) points to a matrix of the right size. * <p> The following things are done: * <ol> * <li> remove equalities involving only parameters, and remove as many * parameters as there are such equalities. From that, the list of * eliminated parameters <i>elimParms</i> is built. * <li> remove equalities that involve variables. This requires a compression * of the parameters and of the other variables that are not eliminated. * The affine compresson is represented by matrix VL (for <i>validity * lattice</i>) and is such that (N I 1)^T = VL.(N' I' 1), where N', I' * are integer (they are the parameters and variables after compression). *</ol> *</p> */ void Constraints_fullDimensionize(Matrix ** M, Matrix ** C, Matrix ** VL, Matrix ** Eqs, Matrix ** ParmEqs, unsigned int ** elimVars, unsigned int ** elimParms, int maxRays) { unsigned int i, j; Matrix * A=NULL, *B=NULL; Matrix * Ineqs=NULL; unsigned int nbVars = (*M)->NbColumns - (*C)->NbColumns; unsigned int nbParms; int nbElimVars; Matrix * fullDim = NULL; /* variables for permutations */ unsigned int * permutation; Matrix * permutedEqs=NULL, * permutedIneqs=NULL; /* 1- Eliminate the equalities involving only parameters. */ (*ParmEqs) = Constraints_removeParmEqs(M, C, 0, elimParms); /* if the polyehdron is empty, return now. */ if ((*M)->NbColumns==0) return; /* eliminate the columns corresponding to the eliminated parameters */ if (elimParms[0]!=0) { Constraints_removeElimCols(*M, nbVars, (*elimParms), &A); Matrix_Free(*M); (*M) = A; Constraints_removeElimCols(*C, 0, (*elimParms), &B); Matrix_Free(*C); (*C) = B; if (dbgCompParm) { printf("After false parameter elimination: \n"); show_matrix(*M); show_matrix(*C); } } nbParms = (*C)->NbColumns-2; /* 2- Eliminate the equalities involving variables */ /* a- extract the (remaining) equalities from the poyhedron */ split_constraints((*M), Eqs, &Ineqs); nbElimVars = (*Eqs)->NbRows; /* if the polyhedron is already full-dimensional, return */ if ((*Eqs)->NbRows==0) { Matrix_identity(nbParms+1, VL); return; } /* b- choose variables to be eliminated */ permutation = find_a_permutation((*Eqs), nbParms); if (dbgCompParm) { printf("Permuting the vars/parms this way: [ "); for (i=0; i< (*Eqs)->NbColumns-2; i++) { printf("%d ", permutation[i]); } printf("]\n"); } Constraints_permute((*Eqs), permutation, &permutedEqs); Equalities_validityLattice(permutedEqs, (*Eqs)->NbRows, VL); if (dbgCompParm) { printf("Validity lattice: "); show_matrix(*VL); } Constraints_compressLastVars(permutedEqs, (*VL)); Constraints_permute(Ineqs, permutation, &permutedIneqs); if (dbgCompParmMore) { show_matrix(permutedIneqs); show_matrix(permutedEqs); } Matrix_Free(*Eqs); Matrix_Free(Ineqs); Constraints_compressLastVars(permutedIneqs, (*VL)); if (dbgCompParm) { printf("After compression: "); show_matrix(permutedIneqs); } /* c- eliminate the first variables */ assert(Constraints_eliminateFirstVars(permutedEqs, permutedIneqs)); if (dbgCompParmMore) { printf("After elimination of the variables: "); show_matrix(permutedIneqs); } /* d- get rid of the first (zero) columns, which are now useless, and put the parameters back at the end */ fullDim = Matrix_Alloc(permutedIneqs->NbRows, permutedIneqs->NbColumns-nbElimVars); for (i=0; i< permutedIneqs->NbRows; i++) { value_set_si(fullDim->p[i][0], 1); for (j=0; j< nbParms; j++) { value_assign(fullDim->p[i][j+fullDim->NbColumns-nbParms-1], permutedIneqs->p[i][j+nbElimVars+1]); } for (j=0; j< permutedIneqs->NbColumns-nbParms-2-nbElimVars; j++) { value_assign(fullDim->p[i][j+1], permutedIneqs->p[i][nbElimVars+nbParms+j+1]); } value_assign(fullDim->p[i][fullDim->NbColumns-1], permutedIneqs->p[i][permutedIneqs->NbColumns-1]); } Matrix_Free(permutedIneqs); } /* Constraints_fullDimensionize */
/** * Given a matrix with m parameterized equations, compress the nb_parms * parameters and n-m variables so that m variables are integer, and transform * the variable space into a n-m space by eliminating the m variables (using * the equalities) the variables to be eliminated are chosen automatically by * the function. * <b>Deprecated.</b> Try to use Constraints_fullDimensionize instead. * @param M the constraints * @param the number of parameters * @param validityLattice the the integer lattice underlying the integer * solutions. */ Matrix * full_dimensionize(Matrix const * M, int nbParms, Matrix ** validityLattice) { Matrix * Eqs, * Ineqs; Matrix * permutedEqs, * permutedIneqs; Matrix * Full_Dim; Matrix * WVL; /* The Whole Validity Lattice (vars+parms) */ unsigned int i,j; int nbElimVars; unsigned int * permutation, * permutationInv; /* 0- Split the equalities and inequalities from each other */ split_constraints(M, &Eqs, &Ineqs); /* 1- if the polyhedron is already full-dimensional, return it */ if (Eqs->NbRows==0) { Matrix_Free(Eqs); (*validityLattice) = Identity_Matrix(nbParms+1); return Ineqs; } nbElimVars = Eqs->NbRows; /* 2- put the vars to be eliminated at the first positions, and compress the other vars/parms -> [ variables to eliminate / parameters / variables to keep ] */ permutation = find_a_permutation(Eqs, nbParms); if (dbgCompParm) { printf("Permuting the vars/parms this way: [ "); for (i=0; i< Eqs->NbColumns; i++) { printf("%d ", permutation[i]); } printf("]\n"); } permutedEqs = mpolyhedron_permute(Eqs, permutation); WVL = compress_parms(permutedEqs, Eqs->NbColumns-2-Eqs->NbRows); if (dbgCompParm) { printf("Whole validity lattice: "); show_matrix(WVL); } mpolyhedron_compress_last_vars(permutedEqs, WVL); permutedIneqs = mpolyhedron_permute(Ineqs, permutation); if (dbgCompParm) { show_matrix(permutedEqs); } Matrix_Free(Eqs); Matrix_Free(Ineqs); mpolyhedron_compress_last_vars(permutedIneqs, WVL); if (dbgCompParm) { printf("After compression: "); show_matrix(permutedIneqs); } /* 3- eliminate the first variables */ if (!mpolyhedron_eliminate_first_variables(permutedEqs, permutedIneqs)) { fprintf(stderr,"full-dimensionize > variable elimination failed. \n"); return NULL; } if (dbgCompParm) { printf("After elimination of the variables: "); show_matrix(permutedIneqs); } /* 4- get rid of the first (zero) columns, which are now useless, and put the parameters back at the end */ Full_Dim = Matrix_Alloc(permutedIneqs->NbRows, permutedIneqs->NbColumns-nbElimVars); for (i=0; i< permutedIneqs->NbRows; i++) { value_set_si(Full_Dim->p[i][0], 1); for (j=0; j< nbParms; j++) value_assign(Full_Dim->p[i][j+Full_Dim->NbColumns-nbParms-1], permutedIneqs->p[i][j+nbElimVars+1]); for (j=0; j< permutedIneqs->NbColumns-nbParms-2-nbElimVars; j++) value_assign(Full_Dim->p[i][j+1], permutedIneqs->p[i][nbElimVars+nbParms+j+1]); value_assign(Full_Dim->p[i][Full_Dim->NbColumns-1], permutedIneqs->p[i][permutedIneqs->NbColumns-1]); } Matrix_Free(permutedIneqs); /* 5- Keep only the the validity lattice restricted to the parameters */ *validityLattice = Matrix_Alloc(nbParms+1, nbParms+1); for (i=0; i< nbParms; i++) { for (j=0; j< nbParms; j++) value_assign((*validityLattice)->p[i][j], WVL->p[i][j]); value_assign((*validityLattice)->p[i][nbParms], WVL->p[i][WVL->NbColumns-1]); } for (j=0; j< nbParms; j++) value_set_si((*validityLattice)->p[nbParms][j], 0); value_assign((*validityLattice)->p[nbParms][nbParms], WVL->p[WVL->NbColumns-1][WVL->NbColumns-1]); /* 6- Clean up */ Matrix_Free(WVL); return Full_Dim; } /* full_dimensionize */
void kpartition_build_level_topology(tree_t *cur_node, com_mat_t *com_mat, int N, int depth, tm_topology_t *topology, int *local_vertices, int *constraints, int nb_constraints, double *obj_weight, double *comm_speed) { com_mat_t **tab_com_mat = NULL; /* table of comunication matrix. We will have k of such comunication matrix, one for each subtree */ int k = topology->arity[depth]; tree_t **tab_child = NULL; int *partition = NULL; int **tab_local_vertices = NULL; constraint_t *const_tab = NULL; int i; verbose_level = get_verbose_level(); /* if we are at the bottom of the tree set cur_node and return*/ if ( depth == topology->nb_levels - 1 ){ if(verbose_level>=DEBUG) printf("id : %d, com_mat= %p\n",local_vertices[0], (void *)com_mat->comm); set_node(cur_node,NULL, 0, NULL, local_vertices[0], 0, NULL, depth); return; } /* partition the com_matrix in k partitions*/ partition = kpartition(topology->arity[depth], com_mat, N, constraints, nb_constraints); /* split the communication matrix in k parts according to the partition just found above */ tab_com_mat = split_com_mat( com_mat, N, k, partition); /* split the local vertices in k parts according to the partition just found above */ tab_local_vertices = split_vertices( local_vertices, N, k, partition); /* construct a tab of constraints of size k: one for each partitions*/ const_tab = split_constraints (constraints, nb_constraints, k, topology, depth); /* create the table of k nodes of the resulting sub-tree */ tab_child = (tree_t **) CALLOC (k,sizeof(tree_t*)); for( i = 0 ; i < k ; i++){ tab_child[i] = (tree_t *) MALLOC(sizeof(tree_t)); } /* for each child, proceeed recursively*/ for( i = 0 ; i < k ; i++){ tab_child[i]->id = i; kpartition_build_level_topology ( tab_child[i], tab_com_mat[i], N/k, depth + 1, topology, tab_local_vertices[i], const_tab[i].constraints, const_tab[i].length, obj_weight, comm_speed); tab_child[i]->parent = cur_node; } /* link the node with its child */ set_node( cur_node, tab_child, k, NULL, cur_node->id, 0, NULL, depth); /* FREE local data*/ FREE(partition); FREE_tab_com_mat(tab_com_mat,k); FREE_tab_local_vertices(tab_local_vertices,k); FREE_const_tab(const_tab,k); }