Making the learner a dynamic switch rather than a compile time switch.
[charm.git] / src / ck-com / AAPLearner.C
1 #include "AAPLearner.h"
2 #include "ComlibManager.h"
3 #include "EachToManyMulticastStrategy.h"
4
5 #define max(a,b) ((a > b) ? a : b)
6
7 AAPLearner::AAPLearner() {
8     init();
9 }
10
11 void AAPLearner::init() {
12     alpha = ALPHA;
13     beta = BETA;
14 }
15
16 Strategy *AAPLearner::optimizePattern(Strategy *strat, 
17                                            ComlibGlobalStats &stats) {
18     CharmStrategy *in_strat = (CharmStrategy *)strat;
19     double npes;              //, *pelist;
20     CharmStrategy *ostrat = NULL;
21
22     /*
23       if(in_strat->getType() == ARRAY_STRATEGY) {
24       in_strat->ainfo.getCombinedPeList(pelist, npes);
25       }
26       
27       if(in_strat->getType() == GROUP_STRATEGY) {
28       CkGroupID gid;
29       //Convert to combined pelist
30       in_strat->ginfo.getSourceGroup(gid, pelist, npes);
31       }
32     */
33
34     double degree = 0, msgsize = 0, nmsgs = 0;
35     stats.getAverageStats(strat->getInstance(), msgsize, nmsgs, degree, npes);
36
37     double dcost = computeDirect(npes, msgsize, degree);
38     double mcost = computeMesh(npes, msgsize, degree);
39     double gcost = computeGrid(npes, msgsize, degree);
40     double hcost = computeHypercube(npes, msgsize, degree);
41     double mincost = min4(dcost, mcost, gcost, hcost);
42
43     int minstrat = USE_MESH;
44     if(dcost == mincost) 
45         minstrat = USE_DIRECT;
46     else if(mcost == mincost)                     
47         minstrat = USE_MESH;                
48     else if(gcost == mincost) 
49         minstrat = USE_GRID;
50     else if(hcost == mincost) 
51         minstrat = USE_HYPERCUBE;
52
53     //CkPrintf("Choosing router %d, %g, %g, %g, %g; %g : %g,%g,%g\n", minstrat, 
54     //       mcost, hcost, gcost, dcost, mincost, npes, msgsize, degree);
55     
56     if(in_strat->getType() == ARRAY_STRATEGY) {
57         CkArrayID said, daid;
58         CkArrayIndexMax *sidxlist, *didxlist;
59         int nsrc, ndest;
60         
61         in_strat->ainfo.getSourceArray(said, sidxlist, nsrc);
62         in_strat->ainfo.getDestinationArray(daid, didxlist, ndest);
63                 
64         ostrat = new EachToManyMulticastStrategy
65             (minstrat, said, daid,
66              nsrc, sidxlist, ndest,
67              didxlist);
68
69         ostrat->setInstance(in_strat->getInstance());
70         ((EachToManyMulticastStrategy *) ostrat)->enableLearning();
71     }
72     
73     //Group strategy implement later, foo bar !!
74     if(in_strat->getType() == GROUP_STRATEGY) {
75         CkGroupID gid;
76         int src_npes, *src_pelist;
77         int dest_npes, *dest_pelist;
78         in_strat->ginfo.getSourceGroup(gid, src_pelist, src_npes);
79         in_strat->ginfo.getDestinationGroup(gid, dest_pelist, dest_npes); 
80
81         ostrat = new EachToManyMulticastStrategy
82             (minstrat, src_npes, src_pelist, dest_npes, dest_pelist);
83         ((EachToManyMulticastStrategy *) ostrat)->enableLearning();
84         ostrat->setInstance(in_strat->getInstance());
85     }
86
87     return ostrat;
88 }
89
90 //P = number of processors, m = msgsize, d = degree
91 double AAPLearner::computeDirect(double P, double m, double d) {
92     double cost1, cost2;
93
94     /*  //Old equations do not model bursts 
95       cost = d * alpha;
96       cost += d * m * beta;
97     */
98
99     cost1 = (d-1) * ALPHA_NIC1 + alpha + m * beta + d * m * GAMMA_NIC; 
100     cost2 = alpha + d * ALPHA_NIC2 +  d * m * beta + m * GAMMA_NIC;
101     
102     return max(cost1, cost2); 
103 }
104
105 //P = number of processors, m = msgsize, d = degree
106 double AAPLearner::computeMesh(double P, double m, double d) {
107
108     double cost1, cost2;
109
110     /* old equation 
111     cost = 2 * sqrt((double) P) * alpha;
112     cost += 2 * d * m * beta;
113     */
114
115     double sqrt_p = ceil(sqrt((double) P));
116
117     cost1 = 2 * (sqrt_p - 2) * ALPHA_NIC1 + 2 * alpha + 2 * m * beta
118       + 2 * d * m * GAMMA_NIC; 
119     cost2 = 2 * alpha + 2 * (sqrt_p - 2) * ALPHA_NIC2 + 2 * d * m * beta + 2 * m *GAMMA_NIC;
120     
121     return max(cost1, cost2) + d * ALPHA_CHARM; 
122 }
123
124 //P = number of processors, m = msgsize, d = degree
125 double AAPLearner::computeHypercube(double P, double m, double d) {
126
127     //Temporarily disabling hypercube
128     return 100;
129
130     if(P == 0)
131         return 0;
132
133     double cost = 0.0;
134     double log_2_P = log(P)/log(2.0);
135     
136     if(d >= P/2) {
137       cost = log_2_P * alpha;
138       cost += (P/2) * log_2_P * m * (beta + GAMMA_NIC + GAMMA_MEM);
139     }
140     else {
141       cost = log_2_P * alpha;
142       cost += log_2_P * d * m * (beta + GAMMA_NIC + GAMMA_MEM);
143     }
144     
145     return cost + d * ALPHA_CHARM;
146 }
147
148 //P = number of processors, m = msgsize, d = degree
149 double AAPLearner::computeGrid(double P, double m, double d) {
150     double cost1, cost2 = 0.0;
151     /*
152       cost = 3 * cubeRoot((double) P) * alpha;
153       cost += 3 * d * m * beta;
154     */
155
156     double cbrt_p = ceil(cubeRoot((double) P));
157
158     cost1 = 3 * (cbrt_p - 2) * ALPHA_NIC1 + 3 * alpha + 3 * m * beta +
159       3 * d *m * GAMMA_NIC;  
160     cost2 = 3 * alpha + 3 * (cbrt_p - 2) * ALPHA_NIC2 + 3 * d * m * beta + 3 * m *GAMMA_NIC; 
161     
162     return max(cost1, cost2) + d * ALPHA_CHARM;
163 }
164