agent_scheduler_eval.c

Go to the documentation of this file.
00001 
00009 /* $Id: agent_scheduler_eval.c,v 1.2 2006/09/28 20:39:03 seymour Exp $ */
00010 /* $UTK_Copyright: $ */
00011 
00012 
00013 #include <stdlib.h>
00014 #include <stdio.h>
00015 
00016 #include "utility.h"
00017 #include "server.h"
00018 #include "agent.h"
00019 #include "gs_storage.h"
00020 #include "problem.h"
00021 #include "comm_data.h"
00022 
00023 static double
00024 gs_agent_perf_model_score(gs_problem_t *problem, gs_server_t *server)
00025 {
00026   double enum_pos, est_time = -1.0;
00027   gs_argument_t *argptr = NULL;
00028   gs_arg_enum_t *arg_enum;
00029   icl_hash_t *symtab;
00030 
00031   if(!problem || !server) {
00032     ERRPRINTF("Bad args\n");
00033     return -1.0;
00034   }
00035 
00036   if(!strcmp(server->perf_expr, GS_NO_MODEL_UPDATE))
00037     return -1.0;
00038 
00039   if(gs_construct_scalar_hashtable(&symtab, problem, GS_IN) < 0) {
00040     /* skip scheduling since scalars aren't available */
00041     return -1.0;
00042   }
00043 
00044   for(argptr = problem->arglist; argptr != NULL; argptr = argptr->next) {
00045     enum_pos = 0.0;
00046 
00047     if(argptr->arg_enum) {
00048       int found_enum_match = 0;
00049 
00050       for(arg_enum=argptr->arg_enum; arg_enum != NULL; arg_enum=arg_enum->next) {
00051         if((strcmp(arg_enum->val, "other") == 0) ||
00052            ((argptr->datatype == GS_CHAR) && !strncmp(argptr->data, arg_enum->val, 1)) ||
00053            ((argptr->datatype != GS_CHAR) && (argptr->expr_val == atof(arg_enum->val))))
00054         {
00055           void *ht;
00056 
00057           /* replace actual value in hash table with enum position */
00058 
00059           ht = icl_hash_find(symtab, argptr->name);
00060 
00061           if(!ht)
00062             ERRPRINTF("Warning: expected to find '%s' in hash table\n",
00063               argptr->name);
00064           else
00065             *((double *)ht) = enum_pos;
00066  
00067           found_enum_match = 1;
00068           break;
00069         }
00070 
00071         enum_pos += 1.0;
00072       }
00073 
00074       if(!found_enum_match) {
00075         ERRPRINTF("No match in model for arg %s\n", argptr->name);
00076         return -1.0;
00077       }
00078     }
00079   }
00080 
00081   if(gs_expr_d(server->perf_expr, &est_time, symtab) < 0) {
00082     LOGPRINTF("Perf model expr '%s' could not be evaluated; ", 
00083        server->perf_expr);
00084     return -1.0;
00085   }
00086 
00087   if(symtab)
00088     icl_hash_destroy(symtab, NULL, NULL);
00089 
00090   return(est_time);
00091 }
00092 
00109 static double
00110 gs_agent_complexity_score(gs_problem_t *problem, gs_server_t *server)
00111 {
00112   icl_hash_t *symtab;
00113   gs_argument_t *argptr = NULL;
00114   char *complexitystr = NULL;
00115   double complexity = -1.0;
00116   double problem_kflop = -1.0;
00117   double effective_speed = -1.0;
00118   double computational_score = -1.0;
00119 
00120   if(!problem || !server) {
00121     ERRPRINTF("Bad args, returning score of 2000.0\n");
00122     return 2000.0;
00123   }
00124 
00125   symtab = icl_hash_create(11, NULL);
00126 
00127   if(!symtab) {
00128     LOGPRINTF("could not create hash table; ");
00129     LOGPRINTF("assuming complexity=1000000 (1 gflop of work)\n");
00130     complexity = 1000000.00;    /* a gigaflop of work */
00131   }
00132   else {
00133     /* Insert scalar input arguments into a hash table */
00134     for(argptr = problem->arglist; argptr != NULL; argptr = argptr->next)
00135       if((argptr->objecttype == GS_SCALAR) && (argptr->inout != GS_OUT))
00136         icl_hash_insert(symtab, argptr->name, &(argptr->expr_val));
00137 
00138     /* Evaluate complexity expression */
00139     complexitystr = gs_problem_getinfo(problem, "COMPLEXITY", "1000000");
00140 
00141     if(gs_expr_d(complexitystr, &complexity, symtab) < 0) {
00142       LOGPRINTF("Complexity string %s could not be evaluated; ", complexitystr);
00143       LOGPRINTF("assuming complexity=1000000 (1 gflop of work)\n");
00144       complexity = 1000000.00;    /* a gigaflop of work */
00145     }
00146   }
00147 
00148   problem_kflop = complexity / 1000.0;
00149 
00150   /* calculation per eijkhout */
00151   effective_speed = ((double) server->kflops * (double) server->ncpu) /
00152       (((double) server->workload / 100.0) + 1.0);
00153 
00154   /* The reflects the seconds required to solve the problem, so the smaller
00155    * the score, the better it is 
00156    */
00157   computational_score = (double) problem_kflop / (double) effective_speed;
00158 
00159   DBGPRINTF("Scheduling info:\n");
00160   DBGPRINTF("\tserver_kflops %d\n", server->kflops);
00161   DBGPRINTF("\tserver_ncpu %d\n", server->ncpu);
00162   DBGPRINTF("\tserver_workload %d\n", server->workload);
00163   DBGPRINTF("\tproblem_kflop %f\n", problem_kflop);
00164   DBGPRINTF("\teffective_speed %f\n", effective_speed);
00165   DBGPRINTF("\tcomputational_score %g\n", computational_score);
00166 
00167   if(symtab)
00168     icl_hash_destroy(symtab, NULL, NULL);
00169 
00170   return(computational_score);
00171 }
00172 
00177 double
00178 gs_agent_get_server_score(gs_problem_t *problem, gs_server_t *server)
00179 {
00180   double score;
00181 
00182   score = gs_agent_perf_model_score(problem, server);
00183 
00184   if(score < 0)
00185     score = gs_agent_complexity_score(problem, server);
00186 
00187   return score;
00188 }