voidmutate_partition(structpartitions*partition,/* TODO restrict*/structvertex*graph,intN,intnr_nodes,structpartitions*new,idx_t*temp,double*temp_costs)
{
/* For now just find the max cost node*/
idx_t*parray=partition->partition;
double*costs=partition->costs;
for(inti=0;i<nr_nodes;i++)
{
temp_costs[i]=costs[i];
temp[i]=i;
}
/* Sort nodes by cost.*/
sort_costs(temp,temp_costs,nr_nodes);
idx_tmaxindex=0;
idx_tworstNode=-1;
/* Pick node psuedo randomly. First with chance 50%, second with chance 25%, so on....*/
doubler=(double)rand()/(double)RAND_MAX;
maxindex=(int)(-log2(r));
if(maxindex>=nr_nodes)maxindex=0;
worstNode=temp[maxindex];
idx_tguess=(2*N)/nr_nodes;
if(guess<27)
guess=27;
idx_tcells[guess*2];
intnr_on_node=0;
/* Find all of the cells allocated to the worst node.*/
for(inti=0;i<N&&nr_on_node<guess*2;i++)
{
if(parray[i]==worstNode)
{
cells[nr_on_node++]=i;
}
}
/* Pick one randomly.*/
idx_tchoice=-1;;
if(nr_on_node>1)
{
choice=rand()%nr_on_node;
choice=cells[choice];
/* Find the neighbouring cells that aren't on the same rank.*/
message("Step count = %i, since imrpove = %i",j,since_improve);
message("Best result = %f",initial_cost);
printf("final = [ ");
for(inti=0;i<s->nr_cells;i++)
{
printf("%lli ",initial.partition[i]);
}
printf("];\n");
sum=0.;
printf("costs per node = [ ");
for(inti=0;i<nr_nodes;i++)
{
sum+=initial.costs[i];
printf("%f ",initial.costs[i]);
}
printf("];\n");
message("Sum of costs = %f",sum);
toc=getticks();
message("Genetic algorithm took %.3f %s.",clocks_from_ticks(toc-tic),clocks_getunit());
for(inti=0;i<s->nr_cells;i++)
{
initial_partition[i]=initial.partition[i];
}
#ifdef OUTPUT
fclose(file);
#endif
#else
printf("Not compiled with MPI or METIS support\n");
#endif
}
/*
Graph partitioning for SWIFT
Init data
First we want to create a graph of the costs at the top-level cells.
struct {
int ci, cj;
Double cost;
} graph[N*27];
We fill this list by iterating over all the tasks:
for (int tid = 0; tid < nr_tasks; tid++) {
Struct task *t = …;
Int ci = highest-level parent of t->ci;
Int cj = highest-level parent of t->cj;
Int index = offset in graph[] for ci/cj.
Graph[index].cost += t->cost;
}
To evaluate the cost for each node in a partition, do the following: Can store max cost while doing this too!
Int part[N]
double cost_per_rank[nr_nodes];
For (int i = 0; i < N * 27; i++) {
Int pi = part[graph[i].ci];
Int pj = part[graph[i].cj];
If (pi == pj)
Cost_per_rank[pi] += graph[i].cost;
Else {
Cost_per_rank[pi] += graph[i].cost;
Cost_per_rank[pj] += graph[i].cost;
}
}
Fast lookup of neighbours of ci using graph. Large population - don’t be too strict on removing things. Pick solutions to keep probabilistically - don’t just prune “the worst”.
Mutation - probabilistically pick a node, 50% worst, 25% 2nd worst etc. move a cell from that to be adjacent to one of its non-local neighbours.
All nodes must have cells - can be enforced. They have INT_MAX solution value.
Run bigcosmovolume for 10 steps, output tasks as csv with higher level cells only. Partition it and check results - check max cost, load imbalance, reliability - modify costs see how badly it goes, lots of runs and check for divergence, feed in result and see if it diverges. How many iterations do we need to wait with no change before we stop etc.
TODO Try to convert the costs to integers? Might save slightly on recomputing various results.