33 #define CROSS_TOLERANCE 0.1
39 typedef struct propmap_s {
79 pmptr->candtab[rootnum].fcandnum = fcandnum;
80 pmptr->candtab[rootnum].lcandnum = lcandnum;
81 pmptr->candtab[rootnum].cluster = cluster;
84 sonsnbr = pmptr->etree->nodetab[rootnum].sonsnbr;
85 for(i=0;i<sonsnbr;i++) {
87 fcandnum, lcandnum, cluster );
127 double *cost_remain )
139 double *sub_cost_remain = NULL;
142 candnbr = lcandnum - fcandnum + 1;
152 pmptr->candtab[rootnum].fcandnum = fcandnum;
153 pmptr->candtab[rootnum].lcandnum = lcandnum;
154 pmptr->candtab[rootnum].cluster = cluster;
157 if(pmptr->etree->nodetab[rootnum].sonsnbr == 0)
162 assert( pmptr->etree->nodetab[rootnum].ndecost <= pmptr->etree->nodetab[rootnum].subcost );
165 isocost = pmptr->etree->nodetab[rootnum].ndecost / candnbr;
166 for(p=0;p<candnbr;p++)
167 cost_remain[p] -= isocost;
170 aspt_cost = pmptr->etree->nodetab[rootnum].subcost - pmptr->etree->nodetab[rootnum].ndecost;
176 if(cost_remain[0] <= 0)
180 if (cost_remain[candnbr-1] <= 0)
183 assert(fcand < candnbr);
184 assert(candnbr >= 1);
188 for(i=fcand; i<candnbr; i++)
189 cumul_cost += cost_remain[i];
191 if (cumul_cost < aspt_cost) {
192 double ratio = aspt_cost / cumul_cost;
193 for(i=fcand; i<candnbr; i++)
194 cost_remain[i] *= ratio;
203 sonsnbr = pmptr->etree->nodetab[rootnum].sonsnbr;
209 for(i=0; i<sonsnbr; i++)
212 cumul_cost = -pmptr->etree->nodetab[
eTreeSonI(pmptr->etree, rootnum, i)].subcost;
215 soncost = -pmptr->etree->nodetab[
eTreeSonI(pmptr->etree, rootnum, i)].ndecost;
224 i =
pqueuePop2( queue_tree, &cumul_cost, NULL );
225 cumul_cost = -cumul_cost;
233 if (cumul_cost <= cost_remain[fcand]) {
234 cost_remain[fcand] -= cumul_cost;
236 fcandnum+fcand, fcandnum+fcand, cluster);
244 if ( pmptr->nocrossproc &&
245 (cumul_cost <= (cost_remain[fcand]+epsilon)) )
247 cost_remain[fcand] -= cumul_cost;
249 fcandnum+fcand, fcandnum+fcand, cluster );
254 if( (fcand < candnbr-1) && (cost_remain[fcand] <= epsilon) )
266 cumul_cost -= cost_remain[fcand];
267 while ((( pmptr->nocrossproc && (cumul_cost > ((
double)scandnbr)*epsilon)) ||
268 (!pmptr->nocrossproc && (cumul_cost > epsilon))) &&
269 (lcand < candnbr - 1))
272 assert( cost_remain[lcand] > 0 );
273 cumul_cost -= cost_remain[lcand];
282 MALLOC_INTERN(sub_cost_remain, lcand-fcand+1,
double);
285 isocost = cumul_cost / scandnbr;
286 for(p=0; p<scandnbr; p++)
288 sub_cost_remain[p] = cost_remain[fcand+p] + isocost;
289 cost_remain[fcand+p] = - isocost;
294 for(p=0; p<scandnbr-1; p++)
296 sub_cost_remain[p] = cost_remain[fcand+p];
297 cost_remain[fcand+p] = 0.0;
299 sub_cost_remain[scandnbr-1] = cost_remain[lcand] + cumul_cost;
300 cost_remain[fcand+scandnbr-1] = -cumul_cost;
304 fcandnum+fcand, fcandnum+lcand, cluster, sub_cost_remain);
305 memFree_null(sub_cost_remain);
307 if ( (lcand < candnbr - 1) &&
308 ( pmptr->nocrossproc ||
309 (cost_remain[lcand] < epsilon) ) )
315 if ( pmptr->nocrossproc )
335 for (i=0; i<candnbr; i++) {
342 i =
pqueuePop2( queue_tree, &cumul_cost, NULL );
343 cumul_cost = -cumul_cost;
350 fcandnum+fcand, fcandnum+fcand, cluster);
353 cost_remain[fcand] -= cumul_cost;
354 pqueuePush1(queue_proc, fcand, -cost_remain[fcand]);
418 int nocrossproc,
int allcand )
424 pmdata.candtab = candtab;
425 pmdata.etree = etree;
426 pmdata.candnbr = candnbr;
427 pmdata.nocrossproc = nocrossproc;
434 double *cost_remain = NULL;
438 MALLOC_INTERN(cost_remain, candnbr,
double);
441 for(p=0; p<candnbr; p++) {
442 cost_remain[p] = isocost;
449 memFree_null(cost_remain);
BEGIN_C_DECLS typedef int pastix_int_t
Processor candidate group to own a column blok.
static pastix_int_t eTreeRoot(const EliminTree *etree)
Return the root of the elimination tree.
static pastix_int_t eTreeSonI(const EliminTree *etree, pastix_int_t node, pastix_int_t i)
Return the i^{th} son of a given node.
static void propMappSubtreeOn1P(const propmap_t *pmptr, pastix_int_t rootnum, pastix_int_t fcandnum, pastix_int_t lcandnum, pastix_int_t cluster)
Set the given candidates to all the subtree w/o conditions.
#define CROSS_TOLERANCE
Minimal work ratio to accept the contribution from one additional candidate.
static void propMappSubtree(const propmap_t *pmptr, pastix_int_t rootnum, pastix_int_t fcandnum, pastix_int_t lcandnum, pastix_int_t cluster, double *cost_remain)
Apply the proportional mapping algorithm to a subtree.
struct propmap_s propmap_t
Proportional mapping structure to forward the arguments throught the recursive calls.
void pqueuePush2(pastix_queue_t *, pastix_int_t, double, double)
Insert an element into the sorted queue.
static void pqueuePush1(pastix_queue_t *q, pastix_int_t elt, double key1)
Push an element with a single key.
void pqueueExit(pastix_queue_t *)
Free the structure associated to the queue.
pastix_int_t pqueuePop2(pastix_queue_t *, double *, double *)
Remove the first element of the queue and return its keys if needed.
pastix_int_t pqueueSize(const pastix_queue_t *)
Return the size of the queue.
static pastix_int_t pqueuePop(pastix_queue_t *q)
Pop the head of the queue whithout returning the keys.
int pqueueInit(pastix_queue_t *, pastix_int_t)
Initialize the queue structure with an initial space to store the elements.
void propMappTree(Cand *candtab, const EliminTree *etree, pastix_int_t candnbr, int nocrossproc, int allcand)
Apply the proportional mapping algorithm.