build: fix travis MPI/SMP build
[charm.git] / src / ck-ldb / LButil.C
1
2 #include "elements.h"
3 #include "ckheap.h"
4
5 #include "BaseLB.h"
6
7 LBVectorMigrateMsg * VectorStrategy(BaseLB::LDStats *stats)
8 {
9    int i;
10    int n_pes = stats->nprocs();
11
12    processorInfo *processors = new processorInfo[n_pes];
13
14    for(i=0; i < n_pes; i++) {
15     processors[i].Id = i;
16     processors[i].backgroundLoad = stats->procs[i].bg_walltime;
17     processors[i].computeLoad = stats->procs[i].total_walltime;
18     processors[i].load = processors[i].computeLoad + processors[i].backgroundLoad;
19     processors[i].pe_speed = stats->procs[i].pe_speed;
20     processors[i].available = stats->procs[i].available;
21   }
22
23   // compute average
24   double total = 0.0;
25   for (i=0; i<n_pes; i++)
26     total += processors[i].load;
27                                                                                 
28   double averageLoad = total/n_pes;
29
30   if (_lb_args.debug()>1) CkPrintf("Average load: %f (total: %f, n_pes: %d)\n", averageLoad, total, n_pes);
31
32   maxHeap *heavyProcessors = new maxHeap(n_pes);
33   Set *lightProcessors = new Set();
34
35   double overload_factor = 1.01;
36   for (i=0; i<n_pes; i++) {
37     if (processors[i].load > averageLoad*overload_factor) {
38       //      CkPrintf("Processor %d is HEAVY: load:%f averageLoad:%f!\n",
39       //               i, processors[i].load, averageLoad);
40       heavyProcessors->insert((InfoRecord *) &(processors[i]));
41     } else if (processors[i].load < averageLoad) {
42       //      CkPrintf("Processor %d is LIGHT: load:%f averageLoad:%f!\n",
43       //               i, processors[i].load, averageLoad);
44       lightProcessors->insert((InfoRecord *) &(processors[i]));
45     }
46   }
47
48   if (_lb_args.debug()>1) {
49     CkPrintf("Before migration: (%d) ", n_pes);
50     for (i=0; i<n_pes; i++) CkPrintf("%f (%f %f) ", processors[i].load, processors[i].computeLoad, processors[i].backgroundLoad);
51     CkPrintf("\n");
52   }
53
54   int done = 0;
55   CkVec<VectorMigrateInfo *> miginfo;
56   while (!done) {
57     processorInfo *donor = (processorInfo *) heavyProcessors->deleteMax();
58     if (!donor) break;
59     if (donor->computeLoad == 0.0) continue;    // nothing to move
60     Iterator nextProcessor;
61     processorInfo *p = (processorInfo *)
62       lightProcessors->iterator((Iterator *) &nextProcessor);
63     double load = donor->load - averageLoad;
64     while (load > 0.0 && p) {
65       double needed = averageLoad - p->load;
66       double give;
67       if (load > needed) give = needed;
68       else give = load;
69       if (give > donor->computeLoad) give = donor->computeLoad;
70       donor->load -= give;
71       donor->computeLoad -= give;
72       p->load += give;
73       p->computeLoad += give;
74       VectorMigrateInfo *move = new VectorMigrateInfo;
75       move->from_pe = donor->Id;
76       move->to_pe = p->Id;
77       move->load = give;
78       miginfo.push_back(move);
79       if (give < needed) 
80         break;
81       else
82         lightProcessors->remove(p);
83       p = (processorInfo *)lightProcessors->next((Iterator *) &nextProcessor);
84       load -= give;
85     }
86   }
87
88   int migrate_count = miginfo.length();
89   LBVectorMigrateMsg* msg = new(migrate_count,0) LBVectorMigrateMsg;
90   msg->n_moves = migrate_count;
91   for(i=0; i < migrate_count; i++) {
92     VectorMigrateInfo* item = (VectorMigrateInfo*) miginfo[i];
93     msg->moves[i] = *item;
94     if (_lb_args.debug()>1)
95       CkPrintf("Processor %d => %d load: %f.\n", item->from_pe, item->to_pe, item->load);
96     delete item;
97     miginfo[i] = 0;
98   }
99
100   if (_lb_args.debug()>1) {
101     CkPrintf("After migration: (%d) ", n_pes);
102     for (i=0; i<n_pes; i++) CkPrintf("%f (%f %f) ", processors[i].load, processors[i].computeLoad, processors[i].backgroundLoad);
103     CkPrintf("\n");
104   }
105
106   if (_lb_args.debug())
107     CkPrintf("VectorStrategy: %d processor vector migrating.\n", migrate_count);
108
109   delete heavyProcessors;
110   delete lightProcessors;
111
112   delete [] processors;
113
114   return msg;
115 }
116
117