gs_smart_app_pm.c

Go to the documentation of this file.
00001 
00010 #include "config.h"
00011 #ifdef GS_SMART_GRIDSOLVE
00012 #include "grpc.h"
00013 #include "gs_smart_stored_group_handles.h"
00014 #include "gs_smart_app_pm_builder.h"
00015 
00016 
00017 /*
00018  * Function creates the application performance model of a group of tasks based 
00019  * on the stored group of handles. 
00020  */
00021 
00022 int gs_smart_generate_app_pm(grpc_function_handle_t ** handles_array, int ** blocking_array, int num_handles, gs_smart_app_pm * app_pm){
00023    int i;
00024   gs_argument_t *argptr;
00025   app_pm->nb_tasks=num_handles;
00026   if(app_pm->nb_tasks<0){
00027     ERRPRINTF("SMART: Error: incorrect value for nb_tasks or nb_rem_tasks\n");
00028     return -1;
00029   }
00030   app_pm->tasks= (gs_smart_app_pm_task **)calloc(app_pm->nb_tasks ,sizeof(gs_smart_app_pm_task *));
00031   if(!app_pm->tasks){
00032     ERRPRINTF("SMART: Failed to allocate memory for app_pm tasks\n");
00033     return -1;
00034   }
00035   for(i=0;i<app_pm->nb_tasks;i++){
00036     app_pm->tasks[i]=(gs_smart_app_pm_task *)calloc(1,sizeof(gs_smart_app_pm_task));
00037     if(!app_pm->tasks){
00038       ERRPRINTF("SMART: Failed to allocate memory for task %d of app_pm\n", i);
00039       return -1;
00040     }
00041     app_pm->tasks[i]->blocking=(int)blocking_array[i];
00042     app_pm->tasks[i]->local=0;
00043     app_pm->tasks[i]->nickname=handles_array[i]->problem_desc->name;  
00044 
00045     int nb_args=0;
00046     for(argptr= handles_array[i]->problem_desc->arglist;argptr!=NULL;argptr=argptr->next){
00047       nb_args++;
00048     }
00049     app_pm->tasks[i]->nb_args=nb_args;
00050     
00051     app_pm->tasks[i]->args= (gs_smart_app_pm_args **)calloc(app_pm->tasks[i]->nb_args ,sizeof(gs_smart_app_pm_args *));
00052     if(!app_pm->tasks[i]->args){
00053       ERRPRINTF("SMART: Failed to allocate memory for task arg\n");
00054       return -1;
00055     }
00056     int j;
00057     for(j=0;j<app_pm->tasks[i]->nb_args;j++){
00058       app_pm->tasks[i]->args[j]=(gs_smart_app_pm_args *)calloc(1,sizeof(gs_smart_app_pm_args));
00059       if(!app_pm->tasks[i]->args[j]){
00060         ERRPRINTF("SMART: Failed to allocate memory for task arg %d\n", j);
00061         return -1;
00062       }
00063     }
00064     j=0;
00065     for(argptr= handles_array[i]->problem_desc->arglist;argptr!=NULL;argptr=argptr->next){
00066       if(argptr->objecttype==0){
00067         app_pm->tasks[i]->args[j]->scalar=1;
00068       }
00069       else{
00070         app_pm->tasks[i]->args[j]->scalar=0;
00071       }
00072       if(argptr->objecttype==GS_SCALAR){
00073         if(argptr->datatype==GS_INT){
00074           app_pm->tasks[i]->args[j]->type=argptr->datatype;
00075           app_pm->tasks[i]->args[j]->uvalue.i=argptr->scalar_val.int_val;
00076 
00077         }
00078         else if(argptr->datatype==GS_DOUBLE){
00079           app_pm->tasks[i]->args[j]->type=argptr->datatype;
00080           app_pm->tasks[i]->args[j]->uvalue.d=argptr->scalar_val.double_val;
00081         }
00082         else if(argptr->datatype==GS_CHAR){
00083           app_pm->tasks[i]->args[j]->type=argptr->datatype;
00084           app_pm->tasks[i]->args[j]->uvalue.c=argptr->scalar_val.char_val;
00085         }
00086       }
00087       if(!app_pm->tasks[i]->args[j]->scalar){
00088         app_pm->tasks[i]->args[j]->id=(int)argptr->data;
00089       }
00090       else{
00091          app_pm->tasks[i]->args[j]->id=-1;
00092       }
00093       j++;
00094     }
00095 
00096   }
00097   return 0;
00098   
00099 }  
00100 
00101 
00102 /*
00103  * Function frees  the application performance model 
00104  */
00105 
00106 int
00107 gs_smart_app_pm_free(gs_smart_app_pm *app_pm)
00108 {
00109   gs_smart_app_pm_args * arg;
00110   int i, j;
00111  
00112   if(!app_pm){
00113     ERRPRINTF("SMART: Error freeing application performance model\n");
00114     return -1;
00115   }
00116   for(i=0;i<app_pm->nb_tasks;i++){
00117     for(j=0;j<app_pm->tasks[i]->nb_args;j++){
00118       arg=app_pm->tasks[i]->args[j];
00119       if(arg->a_anayl) free(arg->a_anayl);
00120       if(arg) free(arg);
00121     }
00122 
00123     if(app_pm->tasks[i]->args) free(app_pm->tasks[i]->args);
00124     if(app_pm->tasks[i]->t_anayl) free(app_pm->tasks[i]->t_anayl);
00125     if(app_pm->tasks[i]) free(app_pm->tasks[i]);
00126   }
00127 
00128   if(app_pm->tasks) free(app_pm->tasks);
00129     
00130   if(app_pm) free(app_pm);
00131   return 0;
00132 }
00133 
00134 
00135 
00136 /*
00137  * Function adds a handle to the stored group of handles
00138  */
00139 
00140 
00141 int gs_smart_store_handle(grpc_function_handle_t * handle,  grpc_sessionid_t * sessionId , gs_va_list * argptr, int blocking, int lang, char major, int map_group_type){
00142 
00143   /*
00144    * if the user  has not explicitly specified the number of tasks to map
00145    * the handle array size is unknown. Therefore the array storage size must 
00146    * be constantaly adjusted 
00147    * We are adjusting the array size every time a new task handle is called
00148    * 
00149    * when the user has explicitly specified the number of tasks to map, the storage for the handle arrays 
00150    * have already been alloc'd.
00151    * therefore the handle array storage does not need to be adjusted.
00152    */
00153   if(map_group_type==GS_SMART_IMPLICIT_GROUP){
00154     if(gs_smart_adjust_handle_array_sizes()<0){
00155       ERRPRINTF("SMART Error: Error adjusting handle array sizes\n");
00156       return -1;
00157     }
00158   }
00159   
00160   /*
00161    * storing this task handle,its session id and whether it's a blocking or non-blocking task
00162    */ 
00163   handles_array[handle_array_pos]=handle;
00164   blocking_array[handle_array_pos]=blocking;
00165   session_ids[handle_array_pos]=sessionId;
00166 
00167  
00168   /*
00169    * this function retrieves the IDL information for each handle
00170    * ToDo: Retrieve all the IDL information for all the handles at the same time
00171    * just before mapping
00172    */ 
00173   if(gs_sender_compute_arg_sizes(argptr, NULL,  handles_array[handle_array_pos]->problem_desc, lang, major) < 0){
00174     ERRPRINTF("SMART : Error computing arg sizes\n");
00175     return -1;
00176   }
00177 
00178   /*
00179    * the handle_array_pos variable keeps track of the position of the last handle
00180    * stored in the the handle array. therefore everytime a handle is added, this variable
00181    * needs to be incremented
00182    */ 
00183   handle_array_pos++;
00184   return 0;
00185 }
00186 
00187 
00188 
00189 /*
00190  * If the array storing the group of handles is not sufficient
00191  * size to store the next handle then this function increases 
00192  * its size by 1.
00193  */
00194 
00195 int gs_smart_adjust_handle_array_sizes(){
00196   
00197   /*
00198    * if the current build index, which keeps track of the position of the last handle
00199    * stored in the handle array is greater than or equal to the current handle array
00200    * size then we need to increase the size of the handle array.
00201    */
00202   if(handle_array_pos==0){
00203    handles_array=(grpc_function_handle_t  **)calloc(1, sizeof(grpc_function_handle_t  *));  
00204 
00205    session_ids = (grpc_sessionid_t **)calloc(1 , sizeof(grpc_sessionid_t *));
00206    blocking_array=(int *)calloc(1 , sizeof(int));
00207    handle_array_size++;
00208   }
00209   else if(handle_array_pos>=handle_array_size){
00210    handles_array=(grpc_function_handle_t  **)realloc(handles_array , sizeof(grpc_function_handle_t  *) *  (handle_array_size+1));  
00211    session_ids = (grpc_sessionid_t **)realloc(session_ids , sizeof(grpc_sessionid_t *) * (handle_array_size+1));
00212    blocking_array=(int *)realloc(blocking_array , sizeof(int)* (handle_array_size+1));
00213    handle_array_size++;
00214   } 
00215 
00216   return 0;
00217 }
00218 
00219 /*
00220  * Function return the stored group of handles, their session id, the array indicating 
00221  * whether they are blocking and the number of tasks stored.
00222  */
00223 
00224 int gs_smart_get_handle_list(grpc_function_handle_t ***handle,  grpc_sessionid_t *** sessionId, int *** _blocking_array, int * nb_tasks){
00225   *sessionId=session_ids;
00226   *_blocking_array= (int **)blocking_array;
00227   *handle=handles_array;
00228   *nb_tasks=handle_array_size;
00229   return 0;
00230 }
00231 
00232 
00233 
00234 /*
00235  * Function return the number of tasks left to store in
00236  * handle array. This is used when the number of tasks
00237  * to map has been explicitly specified by the application programmer.
00238  */
00239 
00240 int gs_smart_get_nb_auto_tasks_left_to_build(){
00241   return (handle_array_size-handle_array_pos);
00242 }
00243 
00244 int gs_smart_free_handle_list(){
00245 
00246  // int i;
00247   free(blocking_array);
00248   free(handles_array);
00249   free(session_ids);
00250   handle_array_size=0;
00251   handle_array_pos=0;
00252   return 0;
00253 }
00254 
00255 #endif