00001
00005
00006 #include <math.h>
00007 #include <charm++.h>
00008 #include "CentralLB.h"
00009
00010 void CentralLB::staticPredictorOn(void* data, void *model)
00011 {
00012 CentralLB *me = (CentralLB*)(data);
00013 me->predictorOn((LBPredictorFunction*)model);
00014 }
00015
00016 void CentralLB::staticPredictorOnWin(void* data, void *model, int wind)
00017 {
00018 CentralLB *me = (CentralLB*)(data);
00019 me->predictorOn((LBPredictorFunction*)model, wind);
00020 }
00021
00022 void CentralLB::staticPredictorOff(void* data)
00023 {
00024 CentralLB *me = (CentralLB*)(data);
00025 me->predictorOff();
00026 }
00027
00028 void CentralLB::staticChangePredictor(void* data, void *model)
00029 {
00030 CentralLB *me = (CentralLB*)(data);
00031 me->changePredictor((LBPredictorFunction*)model);
00032 }
00033
00034 #define MAX_CHISQ_ITER 10000
00035 #define SMALL_NUMBER 0.00001 // to avoid singular matrix in gaussj
00036
00037 void gaussj(double **a, double *b, int n) {
00038 #if CMK_LBDB_ON
00039 int i,j,k;
00040 int irow, icol;
00041 double big, dum, pivinv;
00042
00043 int *indxc, *indxr, *ipiv;
00044
00045 indxc = new int[n];
00046 indxr = new int[n];
00047 ipiv = new int[n];
00048 for (j=0; j<n; ++j) ipiv[j]=0;
00049
00050 for (i=0; i<n; ++i) {
00051 big = 0;
00052
00053 for (j=0; j<n; ++j)
00054 if (ipiv[j] != 1)
00055 for (k=0; k<n; ++k) {
00056 if (ipiv[k] == 0 && fabs(a[j][k]) >= big) {
00057 big = fabs(a[j][k]);
00058 irow=j;
00059 icol=k;
00060 }
00061 }
00062 ++(ipiv[icol]);
00063
00064 if (irow != icol) {
00065 for (j=0; j<n; ++j) {dum=a[irow][j]; a[irow][j]=a[icol][j]; a[icol][j]=dum;}
00066 dum=b[irow]; b[irow]=b[icol]; b[icol]=dum;
00067 }
00068
00069 indxr[i]=irow;
00070 indxc[i]=icol;
00071 if (a[icol][icol] == 0) {
00072 a[icol][icol] = SMALL_NUMBER;
00073 CkPrintf("LB: Singular Matrix\n");
00074 }
00075 pivinv = 1.0/a[icol][icol];
00076 a[icol][icol] = 1;
00077 for (j=0; j<n; ++j) a[icol][j] *= pivinv;
00078 b[icol] *= pivinv;
00079 for (j=0; j<n; ++j)
00080 if (j != icol) {
00081 dum = a[j][icol];
00082 a[j][icol] = 0;
00083 for (k=0; k<n; ++k) a[j][k] -= a[icol][k]*dum;
00084 b[j] -= b[icol]*dum;
00085 }
00086 }
00087
00088 for (i=n-1; i>=0; --i) {
00089 if (indxr[i] != indxc[i])
00090 for (j=0; j<n; ++j) {dum=a[j][indxr[i]]; a[j][indxr[i]]=a[j][indxc[i]]; a[j][indxc[i]]=dum;}
00091 }
00092 delete[] indxr;
00093 delete[] indxc;
00094 delete[] ipiv;
00095
00096 #endif
00097 }
00098
00099 void Marquardt_coefficients(double *x, double *y, double *param, double **alpha, double *beta, double &chisq, LBPredictorFunction *predict) {
00100 #if CMK_LBDB_ON
00101 int i,j,k,l,m;
00102 double ymod, dy;
00103 double *dyda = new double[predict->num_params];
00104
00105 for (i=0; i<predict->num_params; ++i) {
00106 for (j=0; j<=i; ++j) alpha[i][j] = 0;
00107 beta[i]=0;
00108 }
00109 chisq = 0;
00110
00111
00112 for (i=0; i<predict->num_params; ++i) {
00113 predict->function(x[i], param, ymod, dyda);
00114 dy = y[i] - ymod;
00115 for (j=0, l=0; l<predict->num_params; ++l) {
00116 for (k=0, m=0; m<l+1; ++m) {
00117 alpha[j][k++] += dyda[l]*dyda[m];
00118 }
00119 beta[j++] += dy*dyda[l];
00120 }
00121 chisq += dy*dy;
00122 }
00123
00124
00125 for (j=1; j<predict->num_params; ++j) {
00126 for (k=0; k<j; ++k) alpha[k][j] = alpha[j][k];
00127 }
00128
00129 delete[] dyda;
00130 #endif
00131 }
00132
00133 bool Marquardt_solver(CentralLB::FutureModel *mod, int object) {
00134 #if CMK_LBDB_ON
00135 double chisq, ochisq;
00136 double lambda = 0.001;
00137 int i,j;
00138 int iterations=0;
00139 bool allow_stop = false;
00140
00141 double *oneda = new double[mod->predictor->num_params];
00142 double *atry = new double[mod->predictor->num_params];
00143 double *beta = new double[mod->predictor->num_params];
00144 double *da = new double[mod->predictor->num_params];
00145 double **covar = new double*[mod->predictor->num_params];
00146 double **alpha = new double*[mod->predictor->num_params];
00147 double *x = new double[mod->cur_stats-1];
00148 double *y = new double[mod->cur_stats-1];
00149 double **temp = new double*[mod->predictor->num_params];
00150
00151 for (i=0; i<mod->predictor->num_params; ++i) {
00152 alpha[i] = new double[mod->predictor->num_params];
00153 covar[i] = new double[mod->predictor->num_params];
00154 temp[i] = new double[mod->predictor->num_params];
00155 atry[i] = mod->parameters[object][i];
00156 }
00157 for (i=0; i<mod->cur_stats-2; ++i) {
00158 x[i] = mod->collection[i].objData[object].wallTime;
00159 y[i] = mod->collection[i+1].objData[object].wallTime;
00160 }
00161
00162 Marquardt_coefficients(x,y,mod->parameters[object],alpha,beta,chisq,mod->predictor);
00163 ochisq = chisq;
00164
00165 while (chisq > 0.01 || !allow_stop) {
00166 if (++iterations > MAX_CHISQ_ITER) {
00167
00168 return false;
00169 }
00170
00171 for (i=0; i<mod->predictor->num_params; ++i) {
00172 for (j=0; j<mod->predictor->num_params; ++j) covar[i][j] = alpha[i][j];
00173 covar[i][i] = alpha[i][i] * (1 + lambda);
00174 for (j=0; j<mod->predictor->num_params; ++j) temp[i][j] = covar[i][j];
00175 oneda[i] = beta[i];
00176 }
00177
00178
00179 gaussj(temp, oneda, mod->predictor->num_params);
00180 for (i=0; i<mod->predictor->num_params; ++i) {
00181 for (j=0; j<mod->predictor->num_params; ++j) covar[i][j] = temp[i][j];
00182 da[i] = oneda[i];
00183 }
00184
00185
00186 for (i=0, j=0; j<mod->predictor->num_params; ++j) atry[j] = mod->parameters[object][j] + da[i++];
00187 Marquardt_coefficients(x,y,atry,covar,da,chisq,mod->predictor);
00188 if (chisq < ochisq) {
00189 lambda *= 0.1;
00190 allow_stop = true;
00191 for (i=0; i<mod->predictor->num_params; ++i) {
00192 for (j=0; j<mod->predictor->num_params; ++j) alpha[i][j] = covar[i][j];
00193 beta[i] = da[i];
00194 mod->parameters[object][i] = atry[i];
00195 }
00196 } else {
00197 lambda *= 10;
00198 allow_stop = false;
00199 }
00200 ochisq = chisq;
00201 }
00202 for (i=0; i<mod->predictor->num_params; ++i) {
00203 delete[] alpha[i];
00204 delete[] covar[i];
00205 delete[] temp[i];
00206 }
00207 delete[] oneda;
00208 delete[] atry;
00209 delete[] beta;
00210 delete[] da;
00211 delete[] covar;
00212 delete[] alpha;
00213 delete[] x;
00214 delete[] y;
00215 delete[] temp;
00216
00217 #endif
00218 return true;
00219 }
00220
00221
00222 void CentralLB::FuturePredictor(BaseLB::LDStats* stats) {
00223 #if CMK_LBDB_ON
00224 bool model_done;
00225 int i;
00226
00227 if (predicted_model->cur_stats < _lb_predict_delay) {
00228
00229 predicted_model->collection[predicted_model->start_stats].objData.resize(stats->n_objs);
00230 predicted_model->collection[predicted_model->start_stats].commData.resize(stats->n_comm);
00231 predicted_model->collection[predicted_model->start_stats].n_objs = stats->n_objs;
00232 predicted_model->collection[predicted_model->start_stats].n_migrateobjs = stats->n_migrateobjs;
00233 predicted_model->collection[predicted_model->start_stats].n_comm = stats->n_comm;
00234 for (i=0; i<stats->n_objs; ++i)
00235 predicted_model->collection[predicted_model->start_stats].objData[i] = stats->objData[i];
00236 for (i=0; i<stats->n_comm; ++i)
00237 predicted_model->collection[predicted_model->start_stats].commData[i] = stats->commData[i];
00238 ++predicted_model->cur_stats;
00239 ++predicted_model->start_stats;
00240
00241 } else {
00242
00243 if (predicted_model->parameters == NULL) {
00244
00245 predicted_model->model_valid = new bool[stats->n_objs];
00246 predicted_model->parameters = new double*[stats->n_objs];
00247 for (i=0; i<stats->n_objs; ++i) predicted_model->parameters[i] = new double[predicted_model->predictor->num_params];
00248 for (i=0; i<stats->n_objs; ++i) {
00249
00250 predicted_model->predictor->initialize_params(predicted_model->parameters[i]);
00251 predicted_model->predictor->print(predicted_model->parameters[i]);
00252
00253 model_done = Marquardt_solver(predicted_model, i);
00254
00255 predicted_model->model_valid[i] = false;
00256 CkPrintf("LB: Model for object %d %s\n",i,model_done?"found":"not found");
00257 predicted_model->predictor->print(predicted_model->parameters[i]);
00258 }
00259
00260 if (predicted_model->model_valid) {
00261 CkPrintf("LB: New model completely constructed\n");
00262 } else {
00263 CkPrintf("LB: Construction of new model failed\n");
00264 }
00265
00266 } else {
00267
00268 double *error_model = new double[stats->n_objs];
00269 double *error_default = new double[stats->n_objs];
00270
00271 CkPrintf("Error in estimation:\n");
00272 for (i=0; i<stats->n_objs; ++i) {
00273 error_model[i] = stats->objData[i].wallTime-predicted_model->predictor->predict(predicted_model->collection[(predicted_model->start_stats-1)%predicted_model->n_stats].objData[i].wallTime,predicted_model->parameters[i]);
00274 error_default[i] = stats->objData[i].wallTime-predicted_model->collection[(predicted_model->start_stats-1)%predicted_model->n_stats].objData[i].wallTime;
00275 CkPrintf("object %d: real time=%f, model error=%f, default error=%f\n",i,stats->objData[i].wallTime,error_model[i],error_default[i]);
00276 }
00277
00278
00279 if (predicted_model->start_stats >= predicted_model->n_stats) predicted_model->start_stats -= predicted_model->n_stats;
00280 if (predicted_model->cur_stats < predicted_model->n_stats) ++predicted_model->cur_stats;
00281
00282 predicted_model->collection[predicted_model->start_stats].objData.resize(stats->n_objs);
00283 predicted_model->collection[predicted_model->start_stats].commData.resize(stats->n_comm);
00284
00285 predicted_model->collection[predicted_model->start_stats].n_objs = stats->n_objs;
00286 predicted_model->collection[predicted_model->start_stats].n_migrateobjs = stats->n_migrateobjs;
00287 predicted_model->collection[predicted_model->start_stats].n_comm = stats->n_comm;
00288 for (i=0; i<stats->n_objs; ++i)
00289 predicted_model->collection[predicted_model->start_stats].objData[i] = stats->objData[i];
00290 for (i=0; i<stats->n_comm; ++i)
00291 predicted_model->collection[predicted_model->start_stats].commData[i] = stats->commData[i];
00292 ++predicted_model->start_stats;
00293
00294
00295
00296
00297
00298
00299
00300
00301 for (i=0; i<stats->n_objs; ++i) {
00302
00303 if (fabs(error_model[i]) > fabs(error_default[i])) {
00304 predicted_model->model_valid[i] = false;
00305
00306 predicted_model->predictor->initialize_params(predicted_model->parameters[i]);
00307 model_done = Marquardt_solver(predicted_model, i);
00308 CkPrintf("LB: Updated model for object %d %s",i,model_done?"success":"failed. ");
00309 predicted_model->predictor->print(predicted_model->parameters[i]);
00310 }
00311 if (fabs(error_model[i]) < fabs(error_default[i])) predicted_model->model_valid[i] = true;
00312 }
00313
00314 }
00315
00316
00317 double *param;
00318 for (int i=0; i<stats->n_objs; ++i) {
00319 if (predicted_model->model_valid[i]) {
00320 param = predicted_model->parameters[i];
00321 stats->objData[i].wallTime = predicted_model->predictor->predict(stats->objData[i].wallTime, param);
00322 #if CMK_LB_CPUTIMER
00323 stats->objData[i].cpuTime = predicted_model->predictor->predict(stats->objData[i].cpuTime, param);
00324 #endif
00325 }
00326 }
00327
00328 }
00329
00330 #endif
00331 }
00332