gs_smart_task_graph.c

Go to the documentation of this file.
00001 
00008 #include "config.h"
00009 #ifdef GS_SMART_GRIDSOLVE
00010 #include "gs_smart_task_graph.h"
00011 #include "gs_smart_mapping_graph.h"
00012 #include "gs_smart_app_pm.h"
00013 #include "comm_data.h"
00014 #include "comm_encode.h"
00015 
00016 #include "time.h"
00017 
00018 #define DEPENDENCY_FOUND 0
00019 #define DEPENDENCY_NOT_FOUND 1
00020 #define DEP_FOUND_ARG_UPDATED 2
00021 #define DEP_FOUND_ARG_NOT_UPDATED 3
00022 #define DEP_NOT_FOUND_ARG_UPDATED 4
00023 #define DEP_NOT_FOUND_ARG_NOT_UPDATED 5
00024 #define ERROR -1
00025 
00026 
00027 
00028 
00029 
00030 
00048 int gs_smart_generate_netpm_and_task_graph( gs_smart_app_pm * app_pm, gs_smart_tg * tg,
00049                           gs_smart_netpm * netpm, char *comm_type){
00050 
00051   gs_server_t ** server_list;
00052   int nb_servers;
00053   char *msg=NULL;
00054   int agentport, tag;
00055   char *agent = NULL;    
00056   SOCKET sock;
00057 
00058  if(!netpm) return -1;
00059   
00060   if((agent = getenv("GRIDSOLVE_AGENT")) == NULL){
00061     ERRPRINTF("SMART: Error getting agent env variable\n");
00062     return -1;
00063   }
00064   agentport = getenv_int("GRIDSOLVE_AGENT_PORT", GRIDSOLVE_AGENT_PORT_DEFAULT);
00065 
00066   if((sock = gs_connect_direct(agent, agentport)) == INVALID_SOCKET){
00067     ERRPRINTF("SMART: error connecting to agent port\n");
00068     if(agent) free(agent);
00069     if(app_pm) gs_smart_app_pm_free(app_pm);
00070     return -1;
00071   }
00072 
00073   if((gs_send_tag(sock, GS_PROT_APP_PM_MODEL) < 0) ||
00074       (gs_send_string(sock, VERSION) < 0) ||
00075       (gs_recv_tag(sock, &tag) < 0)){
00076      ERRPRINTF("SMART : Send recv tag error\n");
00077      return -1;
00078    }
00079 
00080    if(tag != GS_PROT_OK) {
00081       if(tag == GS_PROT_VERSION_MISMATCH) {
00082         ERRPRINTF("SMART: Error version mismatch\n");
00083         if(app_pm) gs_smart_app_pm_free(app_pm);
00084         return -1;
00085       } 
00086       else {
00087         ERRPRINTF("SMART: Tag error\n");
00088         if(app_pm) gs_smart_app_pm_free(app_pm);
00089         return -1;
00090       }
00091     }
00092     /*
00093      * Sending the communication scheme to implement
00094      * in task graph
00095      */ 
00096     if(gs_send_string(sock, comm_type) < 0){
00097       ERRPRINTF("SMART: Error sending application perforance model failed\n");
00098       if(app_pm) gs_smart_app_pm_free(app_pm);
00099       return -1;
00100     }
00101     
00102     /*
00103      * Encoding application performance model
00104      * to send to the agent
00105      */ 
00106     if(gs_smart_encode_app_pm(&msg, app_pm)  < 0) {
00107       ERRPRINTF("SMART: encode app_pm failed\n");
00108       if(msg) free(msg);
00109       if(app_pm) gs_smart_app_pm_free(app_pm);
00110       return -1;
00111     }
00112 
00113     /*
00114      * Sending encoded app pm to agent
00115      */ 
00116     if(gs_send_string(sock, msg) < 0){
00117       ERRPRINTF("SMART: Error sending application perforance model failed\n");
00118       if(msg) free(msg);
00119       if(app_pm) gs_smart_app_pm_free(app_pm);
00120       return -1;
00121     }
00122    if(msg) free(msg);
00123     if(gs_recv_tag(sock, &tag)<0){
00124       ERRPRINTF("SMART: Error receiving tag\n");
00125       if(app_pm) gs_smart_app_pm_free(app_pm);
00126       return -1;
00127     }
00128     if(tag==GS_SMART_GRAPH_FAIL){
00129       ERRPRINTF("SMART: Task graph could not be created, this may be due to no servers being registered\n");
00130       return -1;
00131     }
00132     if(tag==GS_SMART_GRAPH_OK){
00133       DBGPRINTF("SMART: Task graph created successfully\n");
00134     }
00135     else{
00136       ERRPRINTF("SMART: Invalid tag received from agent\n");
00137       return -1;
00138     }
00139     /*
00140      * Receiving the task graph from agent
00141      */ 
00142 
00143     if(gs_smart_recv_tg(sock, tg)<0){
00144       DBGPRINTF("SMART: Recv task graph failed\n");
00145       if(tg)  gs_smart_tg_free(tg);
00146       if(app_pm) gs_smart_app_pm_free(app_pm);
00147       return -1;
00148     }
00149 
00150    /* 
00151     *  Client receives all servers that can execute tasks in task 
00152     *  graph and their corresponding bandwidth ping info
00153     */
00154     
00155     if(gs_smart_recv_all_servers(sock, &server_list, &nb_servers)){
00156       int i;
00157       ERRPRINTF("SMART: Error receive all servers failed\n");
00158       if(tg)  gs_smart_tg_free(tg);
00159       if(app_pm) gs_smart_app_pm_free(app_pm);
00160       for(i=0;i<nb_servers;i++){ 
00161         if(server_list[i]) gs_server_free(server_list[i]);
00162       }
00163       return -1;
00164     }
00165 
00166    /*
00167     * Construct network performance model from list of servers
00168     */ 
00169    if(gs_smart_netpm_construct_netpm(netpm, server_list, nb_servers)<0){
00170      ERRPRINTF("SMART : Error constructing network performance model\n");
00171      return -1;
00172    }
00173 
00174    if(gs_recv_tag(sock, &tag) < 0) {
00175       proxy_close(sock);
00176       if(tg)  gs_smart_tg_free(tg);
00177       return -1;
00178     }
00179 
00180   if(tag==GS_PROT_OK){
00181     DBGPRINTF("SMART: Mapping comleted successfully\n");
00182     if(sock != INVALID_SOCKET)  proxy_close(sock);
00183     return 0;
00184   }
00185   else{
00186     ERRPRINTF("SMART: Mapping tag error\n");
00187     return -1;
00188   }
00189 
00190   return 0;
00191 }
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00227 int 
00228 gs_smart_tg_construct_tg(gs_smart_app_pm * apm,  gs_smart_tg * tg, int graph_type){
00229  
00230   gs_smart_graph_indexes * gi;   
00231   gs_smart_app_pm_task * this_apm_task;
00232 
00233 
00234   
00235   if((!apm) || (!tg)) return -1;
00236 
00237   
00238   if(gs_smart_init_graph_indexes(&gi)<0){
00239     ERRPRINTF("Smart : Error initialising graph indexes\n");
00240     return -1;
00241   }
00242  
00243   if(!gi) return -1;
00244 
00245   if(gs_smart_tg_analyse_dependencies(apm, tg, graph_type)<0){
00246     ERRPRINTF("Smart : Error analysing dependencies of apm\n");
00247     return -1;
00248   }
00249 
00250 
00251   /*
00252    * Initialises array of task nodes
00253    */
00254    
00255   if(gs_smart_tg_construct_frame(apm, tg)<0){
00256     ERRPRINTF("Smart : Error constructing frame of task graph\n");
00257     return -1;
00258   }
00259 
00260 
00261   if(!apm->tasks) return -1;
00262 
00263   for(gi->ap_ti=0;gi->ap_ti<apm->nb_tasks;gi->ap_ti++){
00264 
00265     if(!apm->tasks[gi->ap_ti]) return -1;
00266 
00267     this_apm_task=apm->tasks[gi->ap_ti];
00268     if(gi->ap_ti==0){
00269       if(gs_smart_tg_construct_start_node(tg, gi)<0){
00270         ERRPRINTF("Smart : Error constructing start node of task graph\n");
00271         return -1;
00272       } 
00273       gi->tg_ti++;
00274       if(gs_smart_tg_construct_client_node(apm, tg, gi)<0){
00275         ERRPRINTF("Smart : Error constructing client node of task graph\n");
00276         return -1;
00277       } 
00278       if(gs_smart_tg_construct_forward_links(apm, tg, gi)<0){
00279         ERRPRINTF("Smart : Error constructing forward links of task graph\n");
00280         return -1;
00281       } 
00282       gi->tg_ti++;
00283 
00284     }
00285     else if(gi->ap_ti>0){
00286       if(gs_smart_tg_construct_client_node(apm, tg, gi)<0){
00287         ERRPRINTF("Smart : Error constructing client node of task graph\n");
00288         return -1;
00289       } 
00290       if(gs_smart_tg_construct_forward_links(apm, tg, gi)<0){
00291         ERRPRINTF("Smart : Error constructing forward links of task graph\n");
00292         return -1;
00293       } 
00294       if(gs_smart_tg_construct_backward_links(apm, tg, gi)<0){
00295         ERRPRINTF("Smart : Error constructing backward links of task graph\n");
00296         return -1;
00297       } 
00298       if(gs_smart_tg_join_for_back_links(apm, tg,gi)<0){
00299         ERRPRINTF("SMART: Error joining dependencies links\n");
00300         return -1;
00301       }
00302       gi->tg_ti++;
00303     }
00304 
00305     if(gs_smart_tg_construct_remote_task_node(apm, tg, gi)<0){
00306       ERRPRINTF("Smart : Error constructing remote task node of task graph\n");  
00307       return -1;
00308     }
00309     if(gs_smart_tg_construct_forward_links(apm,tg, gi)<0){
00310       ERRPRINTF("Smart : Error constructing forward links of task graph\n");
00311       return -1;
00312     }
00313     if(gs_smart_tg_construct_backward_links(apm, tg, gi)<0){                      
00314       ERRPRINTF("Smart : Error constructing backward links of task graph\n");
00315       return -1;
00316     } 
00317     if(gs_smart_tg_join_for_back_links(apm, tg,gi)<0){
00318       ERRPRINTF("SMART: Error joining dependencies links\n");
00319       return -1;
00320     }
00321     gi->tg_ti++;
00322 
00323     if(gi->tg_ti==tg->nb_nodes-2){
00324      if(gs_smart_tg_construct_client_node(apm, tg, gi)<0){
00325         ERRPRINTF("Smart : Error constructing client node of task graph\n");
00326         return -1;
00327       }
00328 
00329       if(gs_smart_tg_construct_backward_links(apm, tg, gi)<0){
00330         ERRPRINTF("Smart : Error constructing backward links of task graph\n");
00331         return -1;
00332       } 
00333       if(gs_smart_tg_join_for_back_links(apm, tg,gi)<0){
00334         ERRPRINTF("SMART: Error joining dependencies links\n");
00335         return -1;
00336       }
00337       gi->tg_ti++;
00338      
00339       if(gs_smart_tg_construct_end_node(tg, gi)<0){
00340         ERRPRINTF("Smart : Error constructing end node\n");
00341         return -1;
00342       } 
00343     }
00344   }
00345   return 0;
00346   
00347 }
00348 
00349 
00350 
00351 
00352 
00353 /*
00354  * This function contructs and initialises the structure
00355  * which keeps track of the current position when traversing
00356  * both the task graph and application pm graph.
00357  * 
00358  * @param gi -- (inout )graph index structure
00359  */
00360 
00361 
00362 int gs_smart_init_graph_indexes(gs_smart_graph_indexes ** _gi){
00363   gs_smart_graph_indexes * gi;
00364   gi=(gs_smart_graph_indexes *)calloc(1, sizeof(gs_smart_graph_indexes));
00365   if(!gi){
00366     ERRPRINTF("Smart : Error allocating graph indexes\n");
00367     return -1;
00368   }
00369   gi->rem_dep_id=0; 
00370  gi->cur_arg_id=0;
00371   gi->tg_ti=0;
00372   gi->tg_sti=0; /* task node index */
00373   gi->tg_dti=0;
00374   gi->tg_lnai=0; /* task graph local node arg index */
00375   gi->tg_rnai=0;
00376   gi->tg_drnai=0; /* destination task node arg index */
00377 
00378   gi->ap_ti=0;
00379   gi->ap_sti=0;  /* src handle index */
00380   gi->ap_dti=0;  /* dest handle index */
00381   gi->ap_sai=0;  /* src handle arg index */
00382   gi->ap_dai=0;  /* dest handle arg index */
00383 
00384  
00385   *_gi=gi; 
00386 
00387   return 0;
00388 }
00389 
00390 
00391 /*
00392  *   This function analyzes the dependencies between tasks in the 
00393  *   application performance model.  It stores the results of this analysis 
00394  *   in the gs_smart_t_dep_anayl and the gs_smart_a_dep_anayl structures of 
00395  *   each app_pm nodes.  This information is subsequently used to construct 
00396  *   the links in the task graph.
00397  *   
00398  *   @param apm -- application performance model
00399  *   @param tg -- task graph 
00400  *   @param graph_type -- the type of graph to generate 
00401  *   'GS_SMART_NO_DEP_GRAPH' - Generate a task graph with no dependencies
00402  *   'GS_SMART_P2P_GRAPH' - Generate a task graph with peer to peer dependencies
00403  *   'GS_SMART_SRV_BRDCST_GRAPH' - Generate a task graph with server broadcast 
00404  *   dependencies
00405  *   'GS_SMART_CL_SRV_BRDCST_GRAPH' - Generate a task graph with both client and
00406  *   server broadcast dependencies
00407  *   
00408  *   @returns 0 on success, -1 on failure.
00409  */
00410 
00411 int 
00412 gs_smart_tg_analyse_dependencies(gs_smart_app_pm * apm,  
00413      gs_smart_tg * tg, int graph_type){
00414 
00415   if((!apm) || (!tg)) return -1;
00416 
00417   if(graph_type==GS_SMART_NO_DEP_GRAPH){
00418     if(gs_smart_tg_analyse_no_dependencies(apm, tg)<0){
00419       ERRPRINTF("Smart : Error analysing p2p dependencies of apm\n");
00420       return -1;
00421     }
00422   }
00423   else if(graph_type==GS_SMART_P2P_GRAPH){
00424     if(gs_smart_tg_analyse_p2p_dependencies(apm, tg)<0){
00425       ERRPRINTF("Smart : Error analysing p2p dependencies of apm\n");
00426       return -1;
00427     }
00428   }
00429   else if(graph_type==GS_SMART_SRV_BRDCST_GRAPH){
00430     if(gs_smart_tg_analyse_srvr_brdcst_dependencies(apm, tg)<0){
00431       ERRPRINTF("Smart : Error analysing brdcst dependencies of apm\n");
00432       return -1;
00433     }
00434   }
00435   else if(graph_type==GS_SMART_CLNT_BRDCAST_COMM){
00436     if(gs_smart_tg_analyse_clnt_brdcst_dependencies(apm, tg)<0){
00437       ERRPRINTF("Smart : Error analysing brdcst dependencies of apm\n");
00438       return -1;
00439     }
00440   }
00441   else if(graph_type==GS_SMART_CL_SRV_BRDCST_GRAPH){
00442     if(gs_smart_tg_analyse_clnt_srvr_brdcst_dependencies(apm, tg)<0){
00443       ERRPRINTF("Smart : Error analysing brdcst dependencies of apm\n");
00444       return -1;
00445     }
00446   }
00447   else{
00448     ERRPRINTF("Smart : Error invalid graph type\n");
00449     return -1;
00450   }
00451   return 0;
00452 }
00453 
00454 /*
00455  * This function is called when it is requested that no remote communication
00456  * should be implemented.
00457  *
00458  *
00459  *   @param apm -- application performance model
00460  *   @param tg -- task graph 
00461  *   @returns 0 on success, -1 on failure.
00462  */
00463 
00464 
00465 
00466 int
00467 gs_smart_tg_analyse_no_dependencies(gs_smart_app_pm * apm,
00468     gs_smart_tg * task_graph){
00469 
00470 
00471   gs_argument_t *argptr=NULL;
00472   gs_smart_graph_indexes * gi;   
00473   gs_smart_app_pm_args * src_arg;
00474   gs_smart_app_pm_task * apm_src_task;
00475   gs_smart_t_dep_anayl * src_t_anayl;
00476   gs_smart_a_dep_anayl * src_a_anayl;
00477 
00478   if((!apm) || (!task_graph)) return -1;
00479 
00480   if(gs_smart_init_graph_indexes(&gi)<0){
00481     ERRPRINTF("Smart : Error initialising graph indexes\n");
00482     return -1;
00483   }
00484  
00485   if(!apm->tasks) return -1;
00486   
00487   for(gi->ap_ti=0;gi->ap_ti<apm->nb_tasks;gi->ap_ti++){   
00488     if(!apm->tasks[gi->ap_ti]) return -1;
00489     apm_src_task= apm->tasks[gi->ap_ti];
00490 
00491     if(!apm_src_task->t_anayl) return -1;
00492     src_t_anayl=apm_src_task->t_anayl;
00493 
00494     gi->ap_ai=0; 
00495 
00496     if(!apm_src_task->problem) return -1;
00497 
00498     if(!apm_src_task->args) return -1;
00499 
00500     for(argptr=apm_src_task->problem->arglist;argptr!=NULL;argptr=argptr->next){
00501       
00502       if(argptr->objecttype!=GS_SCALAR){
00503      
00504         if(!apm_src_task->args[gi->ap_ai]) return -1;
00505         src_arg=apm_src_task->args[gi->ap_ai]; 
00506 
00507         if(!src_arg->a_anayl) return -1;
00508         src_a_anayl=src_arg->a_anayl;
00509 
00510        /*
00511         * if the arg is an output then add a forward task link to this task node
00512         * and a backward link to the next client node. 
00513         */  
00514         if(( (argptr->inout==GS_OUT) || (argptr->inout==GS_INOUT))){
00515           src_t_anayl->nb_next_client_back_links++;
00516           src_t_anayl->nb_task_for_links++;
00517         }
00518        
00519        /*
00520         * if the arg is an input then add a backward link to this task node
00521         * and a forward link to the previous client node. 
00522         */  
00523 
00524          if((argptr->inout==GS_INOUT) || (argptr->inout==GS_IN)){
00525            src_t_anayl->nb_prev_client_for_links++;
00526            src_t_anayl->nb_task_back_links++;
00527         }
00528       }
00529       gi->ap_ai++;
00530     }
00531  
00532   }
00533   return 0;
00534 }
00535 
00536 
00537 
00538 
00539 
00540 
00541 int 
00542 gs_smart_tg_analyse_p2p_dependencies(gs_smart_app_pm * apm,  
00543     gs_smart_tg * task_graph){
00544 
00545   gs_argument_t *argptr=NULL, *src_argptr=NULL, *dest_argptr=NULL;
00546 
00547   gs_smart_graph_indexes * gi;   
00548   gs_smart_app_pm_args * src_arg, * dest_arg;
00549   gs_smart_app_pm_task * apm_src_task, * apm_dest_task;
00550   gs_smart_t_dep_anayl * src_t_anayl, * dest_t_anayl;
00551   gs_smart_a_dep_anayl * src_a_anayl, * dest_a_anayl;
00552 
00553   int status, result;
00554   int ap_dai, ap_dti;
00555   int tg_bli, tg_dti;
00556   if((!apm) || (!task_graph)) return -1;
00557 
00558   if(gs_smart_init_graph_indexes(&gi)<0){
00559     ERRPRINTF("Smart : Error initialising graph indexes\n");
00560     return -1;
00561   }
00562  
00563   gi->tg_ti=2; 
00564   
00565   if(!apm->tasks) return -1;
00566   
00567   for(gi->ap_ti=0;gi->ap_ti<apm->nb_tasks;gi->ap_ti++){   
00568     if(!apm->tasks[gi->ap_ti]) return -1;
00569     apm_src_task= apm->tasks[gi->ap_ti];
00570 
00571     if(!apm_src_task->t_anayl) return -1;
00572     src_t_anayl=apm_src_task->t_anayl;
00573 
00574     gi->ap_ai=0; 
00575     gi->tg_fli=0;
00576 
00577     if(!apm_src_task->problem) return -1;
00578 
00579     if(!apm_src_task->args) return -1;
00580 
00581     for(argptr=apm_src_task->problem->arglist;argptr!=NULL;argptr=argptr->next){
00582       
00583       if(argptr->objecttype!=GS_SCALAR){
00584      
00585         if(!apm_src_task->args[gi->ap_ai]) return -1;
00586         src_arg=apm_src_task->args[gi->ap_ai]; 
00587 
00588         if(!src_arg->a_anayl) return -1;
00589         src_a_anayl=src_arg->a_anayl;
00590 
00591     /*
00592      * If this argument (argptr/src_argptr) is an output add a forward link to
00593      * this task node and add a back link to the next client node.
00594      * Then a dependency search is performed to determine if there is any input
00595      * arguments (dest_argptr) of subsequent tasks which have a dependency
00596      * on src_argptr.
00597      * If there is a dependency and dest_argptr is a either a GS_INOUT or GS_OUT
00598      * then the dependency is set.
00599      * If there is a dependency and dest_argptr is GS_IN only and is not the last
00600      * task (gi->ap_dti==apm->nb_tasks-1), then a subsequent
00601      * dependency search must be done. This depenency search evaluates whether 
00602      * any subsequent tasks have a dependency on the 
00603      * dependent argument (dest_argptr from the previous search). 
00604      * If this is the case, then a broadcast is required. 
00605      * Since this is p2p analysis, no dependency will be set as the output argument
00606      * is required by both tasks.
00607      * However if no broadcast is found then the dependency is set.
00608      */
00609         if(( (argptr->inout==GS_OUT) || (argptr->inout==GS_INOUT))){
00610           src_t_anayl->nb_next_client_back_links++;
00611           src_t_anayl->nb_task_for_links++;
00612           status=DEPENDENCY_NOT_FOUND;
00613           gi->ap_sti=gi->ap_ti;
00614           gi->ap_dti=gi->ap_sti+1;
00615           gi->tg_sti=gi->tg_ti; 
00616           gi->ap_sai=gi->ap_ai;
00617           gi->tg_dti= gi->tg_sti+2;
00618           src_argptr=argptr;
00619           if(gs_smart_tg_dependency_search(apm,  src_argptr,   
00620                                                        &dest_argptr, gi, &result)<0){
00621             ERRPRINTF("SMART: Error performing dependency search\n");
00622             return -1;
00623           }
00624 
00625           if(!dest_argptr) return -1;
00626           ap_dti=gi->ap_dti;
00627           ap_dai=gi->ap_dai;
00628           tg_bli=gi->tg_bli;
00629           tg_dti=gi->tg_dti;
00630           
00631           if((result==DEP_FOUND_ARG_UPDATED) || (result==DEP_FOUND_ARG_NOT_UPDATED)){
00632 
00633             if(!apm->tasks[ap_dti]) return -1;
00634             apm_dest_task=apm->tasks[ap_dti];
00635          
00636             if(!apm_dest_task->t_anayl) return -1;
00637             dest_t_anayl=apm_dest_task->t_anayl;
00638 
00639             if(!apm_dest_task->args) return -1;
00640             if(!apm_dest_task->args[ap_dai]) return -1;
00641 
00642             dest_arg=apm_dest_task->args[ap_dai];
00643 
00644             if(!dest_arg->a_anayl) return -1;
00645             dest_a_anayl=dest_arg->a_anayl;
00646 
00647             if(gi->ap_dti==apm->nb_tasks-1){
00648               if(gs_smart_tg_dep_anayl_set_remote_dep(src_t_anayl, 
00649                    dest_t_anayl,src_a_anayl, dest_a_anayl,gi, argptr->inout)<0){
00650                 ERRPRINTF("SMART: Error setting dependency anaylsis structures\n");
00651                 return -1;
00652               }
00653             }
00654             else if(dest_argptr->inout==GS_IN){
00655               gi->ap_sti=gi->ap_dti;
00656               gi->ap_dti=gi->ap_sti+1;
00657               gi->ap_sai=gi->ap_dai;
00658 
00659               if(!dest_argptr) return -1;
00660               src_argptr=dest_argptr;
00661               int result;
00662               if(gs_smart_tg_dependency_search(apm, src_argptr,  
00663                                                      &dest_argptr, gi, &result)<0){
00664                 ERRPRINTF("SMART: Error performing dependency search\n");
00665                 return -1;
00666               }  
00667               gi->ap_dti=ap_dti;
00668               gi->ap_dai=ap_dai;
00669               gi->tg_bli=tg_bli;
00670               gi->tg_dti=tg_dti;
00671 
00672               if(result==DEP_NOT_FOUND_ARG_NOT_UPDATED){
00673                 if(gs_smart_tg_dep_anayl_set_remote_dep(src_t_anayl,  dest_t_anayl,
00674                         src_a_anayl, dest_a_anayl,gi, argptr->inout)<0){
00675                   ERRPRINTF("SMART: Error setting dependency anaylsis structures\n");
00676                   return -1;
00677                 }
00678               }
00679             }
00680             else if((dest_argptr->inout==GS_INOUT) || (dest_argptr->inout==GS_OUT)){
00681               if(gs_smart_tg_dep_anayl_set_remote_dep(src_t_anayl,  dest_t_anayl,
00682                       src_a_anayl, dest_a_anayl,gi, argptr->inout)<0){
00683                 ERRPRINTF("SMART: Error setting dependency anaylsis structures\n");
00684                 return -1;
00685               }
00686             }
00687           }
00688           gi->tg_fli++;
00689         }
00690        
00691        /*
00692         * if the arg is an input then add a backward link to this task node
00693         * and a forward link to the previous client node. 
00694         */  
00695         if((argptr->inout==GS_INOUT) || (argptr->inout==GS_IN)){
00696            src_t_anayl->nb_prev_client_for_links++;
00697            src_t_anayl->nb_task_back_links++;
00698         }
00699       }
00700       gi->ap_ai++;
00701     }
00702  
00703     gi->tg_ti=gi->tg_ti+2;
00704   }
00705   return 0;
00706 }
00707 
00708 
00709 
00710 int 
00711 gs_smart_tg_analyse_srvr_brdcst_dependencies(gs_smart_app_pm * apm,  
00712     gs_smart_tg * tg){
00713 
00714   gs_argument_t *argptr=NULL, *src_argptr=NULL, *dest_argptr=NULL;
00715 
00716   gs_smart_graph_indexes * gi=NULL;  //graph indexes 
00717   gs_smart_app_pm_args * src_arg=NULL, * dest_arg=NULL;
00718   gs_smart_app_pm_task * apm_src_task=NULL, * apm_dest_task=NULL;
00719   gs_smart_t_dep_anayl * src_t_anayl=NULL, * dest_t_anayl=NULL;
00720   gs_smart_a_dep_anayl * src_a_anayl=NULL, * dest_a_anayl=NULL;
00721   int status;
00722   int arg_obj_updated=0;
00723   int result;
00724 
00725   if((!apm) || (!tg)) return -1;
00726    
00727   if(gs_smart_init_graph_indexes(&gi)<0){
00728     ERRPRINTF("Smart : Error initialising graph indexes\n");
00729     return -1;
00730   }
00731  
00732   gi->tg_ti=2; 
00733   
00734   if(!apm->tasks) return -1;
00735   
00736 
00737   for(gi->ap_ti=0;gi->ap_ti<apm->nb_tasks;gi->ap_ti++){   
00738 
00739 
00740     if(!apm->tasks[gi->ap_ti]) return -1;
00741     apm_src_task= apm->tasks[gi->ap_ti];
00742 
00743 
00744     if(!apm_src_task->t_anayl) return -1;
00745     src_t_anayl=apm_src_task->t_anayl;
00746 
00747 
00748     gi->ap_ai=0; 
00749     gi->tg_fli=0;
00750     gi->tg_clnt_fli=0;
00751 
00752     if(!apm_src_task->problem) return -1;
00753 
00754     if(!apm_src_task->args) return -1;
00755 
00756     for(argptr=apm_src_task->problem->arglist;argptr!=NULL;argptr=argptr->next){
00757       if(argptr->objecttype!=GS_SCALAR){
00758 
00759         if(!apm_src_task->args[gi->ap_ai]) return -1;
00760         src_arg=apm_src_task->args[gi->ap_ai]; 
00761 
00762         if(!src_arg->a_anayl) return -1;
00763         src_a_anayl=src_arg->a_anayl;
00764 
00765         /*
00766      * If this argument (argptr/src_argptr) is an output add a forward link to
00767      * this task node and add a back link to the next client node.
00768      * Then a dependency search is performed to determine if there are input
00769      * arguments (dest_argptr) of subsequent tasks which have a dependency
00770      * on src_argptr.
00771      * This dependency search is repeated even if a dependency is found to determine
00772      * if server broadcast is required.
00773      * The search is finished if the arg is updated (i.e. the arg now has new data) 
00774      * or all tasks have been checked (gi->ap_dti<(apm->nb_tasks-1)). 
00775      *
00776          */  
00777         if(( (argptr->inout==GS_OUT) || (argptr->inout==GS_INOUT))){
00778 
00779           src_t_anayl->nb_next_client_back_links++;
00780           src_t_anayl->nb_task_for_links++;
00781 
00782           status=DEPENDENCY_NOT_FOUND;
00783           gi->ap_sti=gi->ap_ti;
00784           gi->tg_sti=gi->tg_ti; 
00785           gi->ap_sai=gi->ap_ai;
00786           gi->ap_dti=gi->ap_sti+1;
00787           gi->tg_dti=gi->tg_sti+2;
00788           src_argptr=argptr;
00789           arg_obj_updated=0;
00790           while((!arg_obj_updated) && (gi->ap_dti<(apm->nb_tasks))){
00791             if( gs_smart_tg_dependency_search(apm,  src_argptr,
00792                                                &dest_argptr, gi, &result)<0 ){
00793                  ERRPRINTF("Smart: Error doing dependency search\n");
00794                  return -1;
00795             }
00796 
00797             if((result==DEP_FOUND_ARG_NOT_UPDATED) || (result==DEP_FOUND_ARG_UPDATED)){
00798               if(!apm->tasks[gi->ap_dti]) return -1;
00799               apm_dest_task=apm->tasks[gi->ap_dti];
00800          
00801               if(!apm_dest_task->t_anayl) return -1;
00802               dest_t_anayl=apm_dest_task->t_anayl;
00803 
00804               if(!apm_dest_task->args) return -1;
00805               if(!apm_dest_task->args[gi->ap_dai]) return -1;
00806 
00807               dest_arg=apm_dest_task->args[gi->ap_dai];
00808 
00809               if(!dest_arg->a_anayl) return -1;
00810               dest_a_anayl=dest_arg->a_anayl;
00811             } 
00812 
00813             /*
00814              * If a dependency is found and if a dependency has not been set 
00815              * for this arg from a previous task dependency search 
00816              * (!dest_arg->a_anayl->is_received_remotely) then set the 
00817              * dependency.
00818              */
00819  
00820             if(((result==DEP_FOUND_ARG_NOT_UPDATED) || 
00821                  (result==DEP_FOUND_ARG_UPDATED) ) && 
00822                  (!dest_arg->a_anayl->is_received_remotely)){
00823               
00824                if(gs_smart_tg_dep_anayl_set_remote_dep(src_t_anayl,  dest_t_anayl,
00825                                    src_a_anayl, dest_a_anayl,gi, argptr->inout)<0){
00826                 ERRPRINTF("SMART: Error setting dependency anaylsis structures\n");
00827                 return -1;
00828               }
00829               if(result==DEP_FOUND_ARG_UPDATED){
00830                 arg_obj_updated=1;
00831               }
00832             }
00833               
00834             gi->ap_dti++;
00835             gi->tg_dti=gi->tg_dti+2; 
00836             if(gi->ap_dti==(apm->nb_tasks-1)) break;
00837             if(result==DEP_NOT_FOUND_ARG_UPDATED){
00838               arg_obj_updated=1;
00839             }
00840           }
00841           gi->tg_fli++;
00842         }
00843 
00844         
00845         if(((argptr->inout==GS_IN) || (argptr->inout==GS_INOUT)) 
00846             && (!src_arg->a_anayl->is_received_remotely)){
00847           gi->tg_clnt_fli++;
00848         }
00849 
00850        /*
00851         * if the arg is an input then add a backward link to this task node
00852         * and a forward link to the previous client node. 
00853         */  
00854 
00855          if((argptr->inout==GS_INOUT) || (argptr->inout==GS_IN)){
00856            src_t_anayl->nb_prev_client_for_links++;
00857            src_t_anayl->nb_task_back_links++;
00858         }
00859       }
00860       gi->ap_ai++;
00861     }
00862  
00863     gi->tg_ti=gi->tg_ti+2;
00864   }
00865   return 0;
00866 }
00867 
00868 
00869 
00870 
00871 
00872 
00873 
00874 int 
00875 gs_smart_tg_analyse_clnt_brdcst_dependencies(gs_smart_app_pm * apm,  
00876     gs_smart_tg * tg){
00877   gs_argument_t *argptr=NULL, *src_argptr=NULL, *dest_argptr=NULL;
00878 
00879   gs_smart_graph_indexes * gi=NULL;  
00880   gs_smart_app_pm_args * src_arg=NULL, * dest_arg=NULL;
00881   gs_smart_app_pm_task * apm_src_task=NULL, * apm_dest_task=NULL;
00882   gs_smart_t_dep_anayl * src_t_anayl=NULL, * dest_t_anayl=NULL;
00883   gs_smart_a_dep_anayl * src_a_anayl=NULL, * dest_a_anayl=NULL;
00884   int status;
00885   int arg_obj_updated=0;
00886   int result;
00887 
00888   if((!apm) || (!tg)) return -1;
00889    
00890   if(gs_smart_init_graph_indexes(&gi)<0){
00891     ERRPRINTF("Smart : Error initialising graph indexes\n");
00892     return -1;
00893   }
00894  
00895   gi->tg_ti=2; 
00896   
00897   if(!apm->tasks) return -1;
00898   
00899 
00900   for(gi->ap_ti=0;gi->ap_ti<apm->nb_tasks;gi->ap_ti++){   
00901 
00902 
00903     if(!apm->tasks[gi->ap_ti]) return -1;
00904     apm_src_task= apm->tasks[gi->ap_ti];
00905 
00906 
00907     if(!apm_src_task->t_anayl) return -1;
00908     src_t_anayl=apm_src_task->t_anayl;
00909 
00910 
00911     gi->ap_ai=0; 
00912     gi->tg_fli=0;
00913     gi->tg_clnt_fli=0;
00914 
00915     if(!apm_src_task->problem) return -1;
00916 
00917     if(!apm_src_task->args) return -1;
00918 
00919     for(argptr=apm_src_task->problem->arglist;argptr!=NULL;argptr=argptr->next){
00920       if(argptr->objecttype!=GS_SCALAR){
00921 
00922         if(!apm_src_task->args[gi->ap_ai]) return -1;
00923         src_arg=apm_src_task->args[gi->ap_ai]; 
00924 
00925         if(!src_arg->a_anayl) return -1;
00926         src_a_anayl=src_arg->a_anayl;
00927 
00928 
00929         /*
00930      * If this argument (argptr/src_argptr) is an input only, then dependency search 
00931      * is performed to determine if there are any oppurtunities to client broadcast.
00932      * This dependency search is repeated even if a dependency found until either 
00933      * the arg is updated (i.e. the arg now has new data) or all tasks have been checked 
00934      * (gi->ap_dti<(apm->nb_tasks-1)). 
00935      *
00936          */  
00937         if((argptr->inout==GS_IN) && (!src_arg->a_anayl->is_received_remotely)){
00938           status=DEPENDENCY_NOT_FOUND;
00939           gi->ap_sti=gi->ap_ti;
00940           gi->tg_sti=gi->tg_ti; 
00941           gi->ap_sai=gi->ap_ai;
00942           gi->ap_dti=gi->ap_sti+1;
00943           gi->tg_dti=gi->tg_sti+2;
00944           src_argptr=argptr;
00945           arg_obj_updated=0;
00946           int fin_search=0;
00947           while((!arg_obj_updated) && (gi->ap_dti<(apm->nb_tasks-1))){
00948              if( gs_smart_tg_dependency_search(apm,  src_argptr,   
00949                                                &dest_argptr, gi, &result)<0 ){
00950                ERRPRINTF("Smart: Error doing dependency search\n");
00951                return -1;
00952              }
00953 
00954              if((result==DEP_FOUND_ARG_UPDATED) || (result==DEP_FOUND_ARG_NOT_UPDATED)){ 
00955               if(!apm->tasks[gi->ap_dti]) return -1;
00956               apm_dest_task=apm->tasks[gi->ap_dti];
00957          
00958               if(!apm_dest_task->t_anayl) return -1;
00959               dest_t_anayl=apm_dest_task->t_anayl;
00960 
00961               if(!apm_dest_task->args) return -1;
00962               if(!apm_dest_task->args[gi->ap_dai]) return -1;
00963 
00964               dest_arg=apm_dest_task->args[gi->ap_dai];
00965             }
00966   
00967             if(((result==DEP_FOUND_ARG_UPDATED) || 
00968                 (result==DEP_FOUND_ARG_NOT_UPDATED)) 
00969                 && (!dest_arg->a_anayl->is_received_remotely)){
00970 
00971               if(!dest_arg->a_anayl) return -1;
00972               dest_a_anayl=dest_arg->a_anayl;
00973 
00974               if(gs_smart_tg_dep_anayl_set_remote_dep(src_t_anayl,  dest_t_anayl,
00975                         src_a_anayl, dest_a_anayl,gi, argptr->inout)<0){
00976                 ERRPRINTF("SMART: Error setting dependency anaylsis structures\n");
00977                 return -1;
00978               }
00979               if(result==DEP_FOUND_ARG_UPDATED){
00980                 arg_obj_updated=1;
00981 
00982               }
00983               gi->ap_dti++;
00984               gi->tg_dti=gi->tg_dti+2; 
00985               if(gi->ap_dti>(apm->nb_tasks-1)){
00986                 fin_search=1;
00987               } 
00988             }
00989            
00990             if(result==DEP_NOT_FOUND_ARG_UPDATED){
00991               arg_obj_updated=1;
00992             }
00993           }
00994         }
00995 
00996         if(( (argptr->inout==GS_OUT) || (argptr->inout==GS_INOUT))){
00997 
00998           src_t_anayl->nb_next_client_back_links++;
00999           src_t_anayl->nb_task_for_links++;
01000         }
01001         if(((argptr->inout==GS_IN) || (argptr->inout==GS_INOUT)) 
01002             && (!src_arg->a_anayl->is_received_remotely)){
01003           gi->tg_clnt_fli++;
01004         }
01005 
01006        /*
01007         * if the arg is an input then add a backward link to this task node
01008         * and a forward link to the previous client node. 
01009         */  
01010 
01011          if((argptr->inout==GS_INOUT) || (argptr->inout==GS_IN)){
01012            src_t_anayl->nb_prev_client_for_links++;
01013            src_t_anayl->nb_task_back_links++;
01014         }
01015       }
01016       gi->ap_ai++;
01017     }
01018  
01019     gi->tg_ti=gi->tg_ti+2;
01020   }
01021   return 0;
01022 }
01023 
01024 
01025 
01026 
01027 
01028 
01029 
01030 
01031 
01032 
01033 
01034 
01035 
01036 int 
01037 gs_smart_tg_analyse_clnt_srvr_brdcst_dependencies(gs_smart_app_pm * apm,  
01038     gs_smart_tg * tg){
01039   gs_argument_t *argptr=NULL, *src_argptr=NULL, *dest_argptr=NULL;
01040 
01041   gs_smart_graph_indexes * gi=NULL;  
01042   gs_smart_app_pm_args * src_arg=NULL, * dest_arg=NULL;
01043   gs_smart_app_pm_task * apm_src_task=NULL, * apm_dest_task=NULL;
01044   gs_smart_t_dep_anayl * src_t_anayl=NULL, * dest_t_anayl=NULL;
01045   gs_smart_a_dep_anayl * src_a_anayl=NULL, * dest_a_anayl=NULL;
01046   int status;
01047   int arg_obj_updated=0;
01048   int result;
01049 
01050   if((!apm) || (!tg)) return -1;
01051    
01052   if(gs_smart_init_graph_indexes(&gi)<0){
01053     ERRPRINTF("Smart : Error initialising graph indexes\n");
01054     return -1;
01055   }
01056  
01057   gi->tg_ti=2; 
01058   
01059   if(!apm->tasks) return -1;
01060   
01061 
01062   for(gi->ap_ti=0;gi->ap_ti<apm->nb_tasks;gi->ap_ti++){   
01063 
01064 
01065     if(!apm->tasks[gi->ap_ti]) return -1;
01066     apm_src_task= apm->tasks[gi->ap_ti];
01067 
01068 
01069     if(!apm_src_task->t_anayl) return -1;
01070     src_t_anayl=apm_src_task->t_anayl;
01071 
01072 
01073     gi->ap_ai=0; 
01074     gi->tg_fli=0;
01075     gi->tg_clnt_fli=0;
01076 
01077     if(!apm_src_task->problem) return -1;
01078 
01079     if(!apm_src_task->args) return -1;
01080 
01081     for(argptr=apm_src_task->problem->arglist;argptr!=NULL;argptr=argptr->next){
01082       if(argptr->objecttype!=GS_SCALAR){
01083 
01084         if(!apm_src_task->args[gi->ap_ai]) return -1;
01085         src_arg=apm_src_task->args[gi->ap_ai]; 
01086 
01087         if(!src_arg->a_anayl) return -1;
01088         src_a_anayl=src_arg->a_anayl;
01089 
01090 
01091         /*
01092      * If this argument (argptr/src_argptr) is an input only, then dependency search 
01093      * is performed to determine if there are any oppurtunities to client broadcast.
01094      * This dependency search is repeated even if a dependency found until either 
01095      * the arg is updated (i.e. the arg now has new data) or all tasks have been checked 
01096      * (gi->ap_dti<(apm->nb_tasks-1)). 
01097      *
01098          */  
01099         if((argptr->inout==GS_IN) && (!src_arg->a_anayl->is_received_remotely)){
01100           status=DEPENDENCY_NOT_FOUND;
01101           gi->ap_sti=gi->ap_ti;
01102           gi->tg_sti=gi->tg_ti; 
01103           gi->ap_sai=gi->ap_ai;
01104           gi->ap_dti=gi->ap_sti+1;
01105           gi->tg_dti=gi->tg_sti+2;
01106           src_argptr=argptr;
01107           arg_obj_updated=0;
01108           int fin_search=0;
01109           while((!arg_obj_updated) && (gi->ap_dti<(apm->nb_tasks))){
01110              if( gs_smart_tg_dependency_search(apm,  src_argptr,   
01111                                                &dest_argptr, gi, &result)<0 ){
01112                ERRPRINTF("Smart: Error doing dependency search\n");
01113                return -1;
01114              }
01115 
01116              if((result==DEP_FOUND_ARG_UPDATED) || (result==DEP_FOUND_ARG_NOT_UPDATED)){ 
01117               if(!apm->tasks[gi->ap_dti]) return -1;
01118               apm_dest_task=apm->tasks[gi->ap_dti];
01119          
01120               if(!apm_dest_task->t_anayl) return -1;
01121               dest_t_anayl=apm_dest_task->t_anayl;
01122 
01123               if(!apm_dest_task->args) return -1;
01124               if(!apm_dest_task->args[gi->ap_dai]) return -1;
01125 
01126               dest_arg=apm_dest_task->args[gi->ap_dai];
01127             }
01128   
01129             if(((result==DEP_FOUND_ARG_UPDATED) || 
01130                 (result==DEP_FOUND_ARG_NOT_UPDATED)) 
01131                 && (!dest_arg->a_anayl->is_received_remotely)){
01132 
01133               if(!dest_arg->a_anayl) return -1;
01134               dest_a_anayl=dest_arg->a_anayl;
01135 
01136               if(gs_smart_tg_dep_anayl_set_remote_dep(src_t_anayl,  dest_t_anayl,
01137                         src_a_anayl, dest_a_anayl,gi, argptr->inout)<0){
01138                 ERRPRINTF("SMART: Error setting dependency anaylsis structures\n");
01139                 return -1;
01140               }
01141               if(result==DEP_FOUND_ARG_UPDATED){
01142                 arg_obj_updated=1;
01143 
01144               }
01145               gi->ap_dti++;
01146               gi->tg_dti=gi->tg_dti+2; 
01147               if(gi->ap_dti>(apm->nb_tasks-1)){
01148                 fin_search=1;
01149               } 
01150             }
01151            
01152             if(result==DEP_NOT_FOUND_ARG_UPDATED){
01153               arg_obj_updated=1;
01154             }
01155           }
01156         }
01157 
01158         /*
01159      * If this argument (argptr/src_argptr) is an output add a forward link to
01160      * this task node and add a back link to the next client node.
01161      * Then a dependency search is performed to determine if there are input
01162      * arguments (dest_argptr) of subsequent tasks which have a dependency
01163      * on src_argptr.
01164      * This dependency search is repeated even if a dependency is found to determine
01165      * if server broadcast is required.
01166      * The search is finished if the arg is updated (i.e. the arg now has new data) 
01167      * or all tasks have been checked (gi->ap_dti<(apm->nb_tasks-1)). 
01168      *
01169          */  
01170         
01171         if(( (argptr->inout==GS_OUT) || (argptr->inout==GS_INOUT))){
01172 
01173           src_t_anayl->nb_next_client_back_links++;
01174           src_t_anayl->nb_task_for_links++;
01175 
01176 
01177           status=DEPENDENCY_NOT_FOUND;
01178           gi->ap_sti=gi->ap_ti;
01179           gi->tg_sti=gi->tg_ti; 
01180           gi->ap_sai=gi->ap_ai;
01181           gi->ap_dti=gi->ap_sti+1;
01182           gi->tg_dti=gi->tg_sti+2;
01183           src_argptr=argptr;
01184           arg_obj_updated=0;
01185           while((!arg_obj_updated) && (gi->ap_dti<(apm->nb_tasks))){
01186             if( gs_smart_tg_dependency_search(apm,  src_argptr,
01187                                                &dest_argptr, gi, &result)<0 ){
01188                  ERRPRINTF("Smart: Error doing dependency search\n");
01189                  return -1;
01190             }
01191 
01192             if((result==DEP_FOUND_ARG_NOT_UPDATED) || (result==DEP_FOUND_ARG_UPDATED)){
01193               if(!apm->tasks[gi->ap_dti]) return -1;
01194               apm_dest_task=apm->tasks[gi->ap_dti];
01195          
01196               if(!apm_dest_task->t_anayl) return -1;
01197               dest_t_anayl=apm_dest_task->t_anayl;
01198 
01199               if(!apm_dest_task->args) return -1;
01200               if(!apm_dest_task->args[gi->ap_dai]) return -1;
01201 
01202               dest_arg=apm_dest_task->args[gi->ap_dai];
01203 
01204               if(!dest_arg->a_anayl) return -1;
01205               dest_a_anayl=dest_arg->a_anayl;
01206             } 
01207  
01208             /*
01209              * If a dependency is found and if a dependency has not been set 
01210              * for this arg from a previous task dependency search 
01211              * (!dest_arg->a_anayl->is_received_remotely) then set the 
01212              * dependency.
01213              */
01214 
01215             if(((result==DEP_FOUND_ARG_NOT_UPDATED) || 
01216                  (result==DEP_FOUND_ARG_UPDATED) ) && 
01217                  (!dest_arg->a_anayl->is_received_remotely)){
01218               
01219                if(gs_smart_tg_dep_anayl_set_remote_dep(src_t_anayl,  dest_t_anayl,
01220                                    src_a_anayl, dest_a_anayl,gi, argptr->inout)<0){
01221                 ERRPRINTF("SMART: Error setting dependency anaylsis structures\n");
01222                 return -1;
01223               }
01224               if(result==DEP_FOUND_ARG_UPDATED){
01225                 arg_obj_updated=1;
01226               }
01227             }
01228               
01229             gi->ap_dti++;
01230             gi->tg_dti=gi->tg_dti+2; 
01231             if(gi->ap_dti==(apm->nb_tasks-1)) break;
01232             if(result==DEP_NOT_FOUND_ARG_UPDATED){
01233               arg_obj_updated=1;
01234             }
01235           }
01236           gi->tg_fli++;
01237         }
01238 
01239         if(((argptr->inout==GS_IN) || (argptr->inout==GS_INOUT)) 
01240             && (!src_arg->a_anayl->is_received_remotely)){
01241           gi->tg_clnt_fli++;
01242         }
01243 
01244        /*
01245         * if the arg is an input then add a backward link to this task node
01246         * and a forward link to the previous client node. 
01247         */  
01248 
01249          if((argptr->inout==GS_INOUT) || (argptr->inout==GS_IN)){
01250            src_t_anayl->nb_prev_client_for_links++;
01251            src_t_anayl->nb_task_back_links++;
01252         }
01253       }
01254       gi->ap_ai++;
01255     }
01256  
01257     gi->tg_ti=gi->tg_ti+2;
01258   }
01259   return 0;
01260 }
01261 
01262 
01263 
01264 
01265 
01266 
01267 
01268 
01269 
01270 
01271 int 
01272 gs_smart_tg_construct_frame(gs_smart_app_pm * apm,  
01273     gs_smart_tg * task_graph){
01274   
01275 
01276   gs_smart_tg_task_node ** task_nodes;
01277 
01278   if((!apm) || (!task_graph)) return -1;
01279   int nb_tg_nodes, i;
01280   nb_tg_nodes=0;   
01281   nb_tg_nodes=apm->nb_tasks*2+3;
01282   task_graph->nb_nodes=nb_tg_nodes; 
01283   task_graph->nb_rem_nodes=apm->nb_tasks;
01284   task_graph->task_nodes = (gs_smart_tg_task_node **)
01285                             calloc(nb_tg_nodes, sizeof(gs_smart_tg_task_node *));
01286  
01287   if(!task_graph->task_nodes) return -1;
01288   task_nodes=task_graph->task_nodes;
01289   
01290   for(i=0; i<task_graph->nb_nodes;i++){
01291     task_nodes[i]= (gs_smart_tg_task_node *)
01292                     calloc(1, sizeof(gs_smart_tg_task_node ));
01293 
01294     if(!task_nodes[i]) return -1;
01295     task_nodes[i]->id=i;
01296   }
01297   return 0;
01298 }
01299 
01300 
01301 
01302 int 
01303 gs_smart_tg_construct_start_node(gs_smart_tg * task_graph, 
01304     gs_smart_graph_indexes * gi){
01305   gs_smart_tg_task_node * tg_task_node; 
01306 
01307   if((!task_graph) || (!gi)) return -1;
01308  
01309   if(!task_graph->task_nodes) return -1;
01310   if(!task_graph->task_nodes[0]) return -1; 
01311   tg_task_node=task_graph->task_nodes[0];
01312 
01313   tg_task_node->node_type= GS_SMART_TG_START_NODE;
01314 
01315   return 0;
01316 }
01317 
01318 
01319 int 
01320 gs_smart_tg_construct_client_node(gs_smart_app_pm * app_pm,  
01321     gs_smart_tg * task_graph, gs_smart_graph_indexes * gi){
01322   
01323   gs_smart_tg_task_node * tg_task_node; 
01324 
01325   if((!task_graph) || (!gi)) return -1;
01326 
01327   if(!task_graph->task_nodes) return -1;
01328   if(!task_graph->task_nodes[gi->tg_ti]) return -1;
01329 
01330   tg_task_node=task_graph->task_nodes[gi->tg_ti];
01331  
01332   tg_task_node->node_type=GS_SMART_TG_CLIENT_NODE;
01333  
01334   tg_task_node->tg_client_node=(gs_smart_tg_client_node *)
01335                                 calloc(1, sizeof(gs_smart_tg_client_node));
01336   if(!tg_task_node->tg_client_node){
01337     ERRPRINTF("SMART: Error allocating to local task node\n");
01338     return -1;
01339   }
01340 
01341   return 0;
01342 }
01343 
01344 int 
01345 gs_smart_tg_construct_remote_task_node(gs_smart_app_pm * apm, 
01346     gs_smart_tg * task_graph, gs_smart_graph_indexes * gi){
01347 
01348   gs_smart_tg_task_node * tg_task_node; 
01349   gs_smart_tg_remote_task_node * tg_rem_task_node;
01350   gs_smart_app_pm_task * apm_task;
01351   double nb_flops;
01352 
01353   if( (!apm) || (!task_graph) || (!gi)) return -1;
01354   
01355   if((!task_graph->task_nodes) || (!apm->tasks)) return -1;
01356   if((!task_graph->task_nodes[gi->tg_ti]) || (!apm->tasks[gi->ap_ti])) return -1;
01357   
01358 
01359   tg_task_node=task_graph->task_nodes[gi->tg_ti];
01360   apm_task=apm->tasks[gi->ap_ti];
01361 
01362   tg_task_node->node_type=GS_SMART_TG_REM_TASK_NODE;
01363   
01364 
01365   tg_task_node->tg_rem_task_node=(gs_smart_tg_remote_task_node *)
01366                                   calloc(1, sizeof(gs_smart_tg_remote_task_node));
01367 
01368   if(!tg_task_node->tg_rem_task_node){
01369     ERRPRINTF("SMART: Error allocating to local task node\n");
01370     return -1;
01371   }
01372   
01373   tg_rem_task_node=tg_task_node->tg_rem_task_node;
01374 
01375   if(!apm_task->problem) return -1;
01376 
01377   tg_rem_task_node->problem=apm_task->problem; 
01378 
01379   icl_hash_t *symtab;
01380   symtab = icl_hash_create(11, NULL);
01381 
01382   if(!symtab) return -1;
01383 
01384   /*
01385    * Setting up scalar arg values in task handle list (task_list)
01386    */
01387   if(gs_smart_tg_set_scalar_arg_values(apm,  symtab, gi)<0){
01388     ERRPRINTF("Smart: Error gs_smart_set_non_scalar_arg_values\n");
01389     return -1;
01390   }
01391 
01392   /*
01393    * Setting up non-scalar args in task handle list (task_list)
01394    */ 
01395 
01396   if(gs_setup_workspace(tg_rem_task_node->problem, symtab) < 0) {
01397     ERRPRINTF("Smart : Error setting up workspace.\n");
01398     return -1;
01399   }
01400  
01401   if(gs_smart_tg_get_problem_size(tg_rem_task_node->problem, &nb_flops)<0){
01402     ERRPRINTF("Smart : Error getting problem size\n");
01403     return -1;
01404   }
01405    
01406   if(nb_flops<0){
01407     ERRPRINTF("SMART: Error getting nb flops\n");
01408     return -1;
01409   }
01410 
01411   tg_rem_task_node->nb_flops=nb_flops;
01412   tg_rem_task_node->blocking=apm_task->blocking;
01413 
01414   return 0;
01415 }
01416 
01417 
01418 
01419 
01420 int
01421 gs_smart_tg_construct_forward_links(gs_smart_app_pm * app_pm, 
01422   gs_smart_tg * task_graph, gs_smart_graph_indexes * gi){
01423   
01424   gs_smart_tg_task_node * tg_task_node; 
01425   gs_smart_app_pm_task * apm_this_node, * apm_next_node; 
01426   gs_smart_tg_remote_task_node * tg_rem_task_node=NULL;
01427   gs_smart_tg_client_node * tg_client_node=NULL;
01428   int  nb_forward_links , nb_obj_for_links , i;
01429   gs_smart_tg_dep_link ** forward_links;
01430   gs_smart_tg_obj_node ** obj_nodes=NULL;
01431   gs_argument_t *argptr; 
01432   gs_smart_app_pm_args * this_arg;
01433 
01434   if((!app_pm) || (!task_graph) || (!gi)) return -1;
01435   
01436   if((!task_graph->task_nodes) || (!app_pm->tasks)) return -1;
01437   if((!task_graph->task_nodes[gi->tg_ti]) || (!app_pm->tasks[gi->ap_ti])) return -1;
01438 
01439   tg_task_node=task_graph->task_nodes[gi->tg_ti];
01440   apm_this_node= app_pm->tasks[gi->ap_ti];  
01441 
01442   if(tg_task_node->node_type==GS_SMART_TG_REM_TASK_NODE){
01443      
01444     if((!apm_this_node->t_anayl) || (!tg_task_node->tg_rem_task_node)) return -1;
01445  
01446     nb_forward_links=apm_this_node->t_anayl->nb_task_for_links;  
01447     tg_rem_task_node=tg_task_node->tg_rem_task_node;
01448     tg_rem_task_node->nb_node_frwd_links=nb_forward_links;  
01449     tg_rem_task_node->tg_node_frwrd_link=(gs_smart_tg_dep_link **)
01450          calloc(nb_forward_links, sizeof(gs_smart_tg_dep_link *));
01451     
01452     if(!tg_rem_task_node->tg_node_frwrd_link) return -1;
01453 
01454     obj_nodes=(gs_smart_tg_obj_node **)
01455                calloc(nb_forward_links, sizeof (gs_smart_tg_obj_node *));
01456 
01457     if(!obj_nodes) return -1;
01458 
01459     forward_links=tg_rem_task_node->tg_node_frwrd_link;
01460 
01461     /*
01462      * Alloc'ing for links and obj nodes for remote task node
01463      */ 
01464 
01465     gi->tg_fli=0;
01466     gi->ap_ai=0;
01467     for(argptr=apm_this_node->problem->arglist;argptr!=NULL;argptr=argptr->next){
01468       if(!apm_this_node->args[gi->ap_ai]) return -1;
01469       this_arg=apm_this_node->args[gi->ap_ai];
01470    
01471       if( ((argptr->inout==GS_OUT) || (argptr->inout==GS_INOUT)) &&  
01472                              (argptr->objecttype!=GS_SCALAR)){
01473       
01474         forward_links[gi->tg_fli] = (gs_smart_tg_dep_link *)
01475                             calloc(1, sizeof(gs_smart_tg_dep_link));
01476 
01477 
01478         forward_links[gi->tg_fli]->for_link_pos=gi->tg_fli;
01479 
01480          obj_nodes[gi->tg_fli] = (gs_smart_tg_obj_node *)
01481                         calloc(1, sizeof(gs_smart_tg_obj_node));
01482 
01483         if((!forward_links[gi->tg_fli]) || (!obj_nodes[gi->tg_fli])){
01484           return -1;
01485         }
01486 
01487         /*
01488          * Point remote task two-way forward link to empty object node 
01489          * and back to itself
01490          */
01491         forward_links[gi->tg_fli]->task_node_ptr=tg_task_node;
01492         forward_links[gi->tg_fli]->obj_node_ptr=obj_nodes[gi->tg_fli];
01493 
01494         forward_links[gi->tg_fli]->obj_node_ptr->out_call_seq_pos=gi->ap_ai;      
01495         forward_links[gi->tg_fli]->obj_node_ptr->data_ptr=this_arg->id;
01496 
01497         /*
01498          * Object node back link is the reverse of remote task node forward link.
01499          * Therefore the pointers of both links are the same.
01500          */
01501         obj_nodes[gi->tg_fli]->tg_obj_bkwrd_link=forward_links[gi->tg_fli];
01502 
01503 
01504        if(!this_arg->a_anayl) return -1;       
01505        /*
01506         * Allocating obj_node forward links
01507         */
01508         nb_obj_for_links=this_arg->a_anayl->nb_obj_for_links;
01509         if(nb_obj_for_links==0){
01510           nb_obj_for_links++; 
01511         }
01512         obj_nodes[gi->tg_fli]->nb_obj_frwd_links=nb_obj_for_links;
01513         obj_nodes[gi->tg_fli]->tg_obj_frwrd_link=( gs_smart_tg_dep_link **)
01514                                           calloc(nb_obj_for_links, sizeof(gs_smart_tg_dep_link *));
01515 
01516 
01517 
01518         if(!obj_nodes[gi->tg_fli]->tg_obj_frwrd_link) return -1;
01519 
01520         for(i=0; i<nb_obj_for_links;i++){  
01521           obj_nodes[gi->tg_fli]->tg_obj_frwrd_link[i]=(gs_smart_tg_dep_link *)
01522                                           calloc(1, sizeof(gs_smart_tg_dep_link));
01523          
01524           if(!obj_nodes[gi->tg_fli]->tg_obj_frwrd_link[i]) return -1;
01525           obj_nodes[gi->tg_fli]->tg_obj_frwrd_link[i]->for_link_pos=i;
01526         }
01527       
01528        // i++;
01529         gi->tg_fli++;
01530       }
01531       gi->ap_ai++;
01532       
01533     }
01534   }
01535 
01536 
01537 
01538     gi->tg_fli=0;
01539     gi->ap_ai=0;
01540 
01541   if(tg_task_node->node_type==GS_SMART_TG_CLIENT_NODE){
01542     if(!app_pm->tasks[gi->ap_ti]) return -1;
01543     apm_next_node= app_pm->tasks[gi->ap_ti]; 
01544     if(!apm_this_node->t_anayl) return -1; 
01545     nb_forward_links=apm_this_node->t_anayl->nb_prev_client_for_links;
01546 
01547     if(!tg_task_node->tg_client_node) return -1;
01548     tg_client_node=tg_task_node->tg_client_node;
01549     
01550     tg_client_node->nb_node_frwd_links=nb_forward_links;   
01551 
01552 
01553     tg_client_node->tg_node_frwrd_link=(gs_smart_tg_dep_link **)
01554          calloc(nb_forward_links, sizeof(gs_smart_tg_dep_link *));
01555 
01556     obj_nodes=(gs_smart_tg_obj_node **)
01557                calloc(nb_forward_links, sizeof (gs_smart_tg_obj_node *));
01558 
01559 
01560     if((!tg_client_node->tg_node_frwrd_link) && (!obj_nodes)){
01561       ERRPRINTF("SMART: Error allocating to object nodes\n");
01562       return -1;
01563     }
01564       
01565     forward_links=tg_client_node->tg_node_frwrd_link;
01566 
01567     /*
01568      * Alloc'ing for links and obj nodes for client node
01569      */ 
01570 
01571     nb_forward_links=0;
01572     gi->ap_ai=0;
01573     gi->tg_fli=0; 
01574     for(argptr=apm_this_node->problem->arglist;argptr!=NULL;argptr=argptr->next){
01575       this_arg=apm_this_node->args[gi->ap_ai];
01576       if( ((argptr->inout==GS_IN) || (argptr->inout==GS_INOUT)) &&  
01577                              (argptr->objecttype!=GS_SCALAR) && 
01578                              (!this_arg->a_anayl->is_received_remotely)){
01579 
01580       forward_links[gi->tg_fli] = (gs_smart_tg_dep_link *)calloc(1, sizeof(gs_smart_tg_dep_link));
01581       obj_nodes[gi->tg_fli] = (gs_smart_tg_obj_node *)calloc(1, sizeof(gs_smart_tg_obj_node));
01582       if((!forward_links[gi->tg_fli]) || (!obj_nodes[gi->tg_fli])){
01583         return -1;
01584       }
01585  
01586       forward_links[gi->tg_fli]->for_link_pos=gi->tg_fli;
01587 
01588       /*
01589        * Point client node forward link to empty object node and back to itself
01590        */
01591       forward_links[gi->tg_fli]->task_node_ptr=tg_task_node;
01592       forward_links[gi->tg_fli]->obj_node_ptr=obj_nodes[gi->tg_fli];
01593       forward_links[gi->tg_fli]->obj_node_ptr->data_ptr=this_arg->id;
01594       
01595       /*
01596        * Object node back link is the reverse of client node forward link.
01597        * Therefore the pointers of both links are the same.
01598        */
01599       obj_nodes[gi->tg_fli]->tg_obj_bkwrd_link=forward_links[gi->tg_fli];
01600 
01601 
01602      /*
01603       * Allocating obj_node forward links
01604       */
01605          
01606       nb_obj_for_links=this_arg->a_anayl->nb_clnt_obj_for_links;     
01607     
01608 
01609       if(nb_obj_for_links==0){
01610         nb_obj_for_links++; 
01611       }
01612 
01613       obj_nodes[gi->tg_fli]->nb_obj_frwd_links=nb_obj_for_links;
01614       obj_nodes[gi->tg_fli]->tg_obj_frwrd_link=( gs_smart_tg_dep_link **)
01615                                         calloc(nb_obj_for_links, sizeof(gs_smart_tg_dep_link *));
01616 
01617       if(!obj_nodes[gi->tg_fli]->tg_obj_frwrd_link) return -1;
01618          
01619       
01620       for(i=0; i<nb_obj_for_links;i++){
01621         obj_nodes[gi->tg_fli]->tg_obj_frwrd_link[i]=(gs_smart_tg_dep_link *)
01622                                         calloc(1, sizeof(gs_smart_tg_dep_link));
01623          
01624         if(!obj_nodes[gi->tg_fli]->tg_obj_frwrd_link[i]) return -1;
01625         obj_nodes[gi->tg_fli]->tg_obj_frwrd_link[i]->for_link_pos=i;
01626      }
01627 
01628      gi->tg_fli++;  
01629     }
01630     gi->ap_ai++;  
01631     }
01632   }
01633     
01634     gi->ap_ai=0;
01635     gi->tg_fli=0;  
01636 
01637   return 0;
01638 }
01639 
01640 
01641 
01642 
01643 
01644 
01645 int 
01646 gs_smart_tg_construct_backward_links(gs_smart_app_pm * app_pm,  
01647     gs_smart_tg * task_graph, gs_smart_graph_indexes * gi){
01648 
01649   gs_smart_app_pm_task   * apm_this_node=NULL, * apm_prev_node=NULL;
01650   gs_smart_tg_remote_task_node * tg_rem_task_node=NULL;
01651   gs_smart_tg_client_node * tg_client_node=NULL;
01652   gs_smart_tg_dep_link ** backward_links=NULL;
01653   int i, nb_backward_links=0;
01654   gs_smart_tg_task_node * tg_task_node;
01655 
01656 
01657   if((!app_pm) || (!task_graph) || (!gi)) return -1;
01658   if((!app_pm->tasks[gi->ap_ti])) return -1;
01659   if(!task_graph->task_nodes[gi->tg_ti]) return -1;
01660   if(gi->ap_ti>0){
01661     apm_prev_node= app_pm->tasks[gi->ap_ti-1];  
01662   }
01663 
01664   apm_this_node= app_pm->tasks[gi->ap_ti];  
01665   tg_task_node=task_graph->task_nodes[gi->tg_ti];
01666   if(tg_task_node->node_type==GS_SMART_TG_CLIENT_NODE){
01667     tg_client_node=tg_task_node->tg_client_node;
01668     if(!tg_client_node) return -1;
01669 
01670     if((gi->tg_ti)==(task_graph->nb_nodes-2)){
01671       nb_backward_links= apm_this_node->t_anayl->nb_next_client_back_links;
01672     }
01673     else if(gi->ap_ti==0){
01674       nb_backward_links=0;
01675     }
01676     else{
01677       nb_backward_links= apm_prev_node->t_anayl->nb_next_client_back_links;
01678     }
01679     tg_client_node->nb_node_bkwd_links=nb_backward_links;   
01680     
01681  
01682     /*
01683      * Allocating backward links of the client node
01684      */
01685     tg_client_node->tg_node_bkwrd_link=(gs_smart_tg_dep_link **)calloc(nb_backward_links, sizeof (gs_smart_tg_dep_link *));
01686   
01687     backward_links=tg_client_node->tg_node_bkwrd_link;
01688     for(i=0; i<nb_backward_links;i++){
01689       backward_links[i] = (gs_smart_tg_dep_link *)calloc(1, sizeof(gs_smart_tg_dep_link));
01690       if(!backward_links[i]){
01691         return -1;
01692       }
01693       backward_links[i]->back_link_pos=i;
01694     }
01695   }
01696   else if(tg_task_node->node_type==GS_SMART_TG_REM_TASK_NODE){
01697     tg_rem_task_node=tg_task_node->tg_rem_task_node;
01698     nb_backward_links=apm_this_node->t_anayl->nb_task_back_links;
01699 
01700     tg_rem_task_node=tg_task_node->tg_rem_task_node;
01701 
01702     if(!tg_rem_task_node) return -1;
01703     
01704     tg_rem_task_node->nb_node_bkwd_links=nb_backward_links;  
01705  
01706     /*
01707      * Allocating backward links of the remote task node 
01708      */
01709     tg_rem_task_node->tg_node_bkwrd_link=(gs_smart_tg_dep_link **)
01710                     calloc(nb_backward_links, sizeof (gs_smart_tg_dep_link *));
01711  
01712     backward_links=tg_rem_task_node->tg_node_bkwrd_link;
01713   
01714     for(i=0; i<nb_backward_links;i++){
01715       backward_links[i] = (gs_smart_tg_dep_link *)calloc(1, sizeof(gs_smart_tg_dep_link));
01716       if(!backward_links[i]){
01717         return -1;
01718       }
01719       backward_links[i]->back_link_pos=i;
01720     }
01721   }
01722   return 0;
01723 }
01724 
01725 
01726 
01727 int
01728 gs_smart_tg_join_for_back_links(gs_smart_app_pm * app_pm,
01729     gs_smart_tg * task_graph, gs_smart_graph_indexes * gi){
01730 
01731 
01732   gs_smart_tg_task_node * tg_task_node;
01733   if((!app_pm) || (!task_graph) || (!gi) ) return -1;
01734 
01735   tg_task_node=task_graph->task_nodes[gi->tg_ti];
01736 
01737   if(!tg_task_node) return -1;
01738 
01739   if(tg_task_node->node_type==GS_SMART_TG_CLIENT_NODE){
01740     if(gs_smart_tg_client_node_join_for_back_links(app_pm,task_graph,gi)<0){
01741       ERRPRINTF("SMART: Error joining client node dependencies links\n");
01742       return -1;
01743     }
01744   }
01745  
01746   if(tg_task_node->node_type==GS_SMART_TG_REM_TASK_NODE){
01747     if(gs_smart_tg_rem_task_join_for_back_links(app_pm,task_graph,gi)<0){
01748       ERRPRINTF("SMART: Error joining remote  task node dependencies links\n");
01749       return -1;
01750     } 
01751  
01752   }
01753   return 0;
01754 }
01755 
01756 
01757 
01758 
01759 
01760 
01761 
01762 
01763 int 
01764 gs_smart_tg_construct_end_node(gs_smart_tg * task_graph, 
01765     gs_smart_graph_indexes * gi){
01766 
01767   gs_smart_tg_task_node * tg_task_node; 
01768   if((!task_graph) || (!gi)) return -1;
01769  
01770   if(!task_graph->task_nodes) return -1;
01771   if(!task_graph->task_nodes[gi->tg_ti]) return -1; 
01772  
01773   tg_task_node=task_graph->task_nodes[gi->tg_ti];
01774 
01775   if(!tg_task_node) return -1;
01776 
01777   tg_task_node->node_type=GS_SMART_TG_END_NODE;
01778   return 0;
01779 }
01780 
01781 
01782 
01783 
01784 
01785 
01786 
01787 int gs_smart_tg_dependency_search(gs_smart_app_pm * apm,  
01788      gs_argument_t *src_argptr,  gs_argument_t **_dest_argptr,    
01789                                   gs_smart_graph_indexes * gi, int * result){
01790   
01791 
01792   if((!apm || (!src_argptr) || (!gi))) return ERROR;
01793   gs_smart_app_pm_task * apm_src_task, * apm_dest_task;
01794   gs_smart_app_pm_args * apm_src_arg, * apm_dest_arg;
01795  
01796   gi->ap_dai=0; 
01797   gs_argument_t * dest_argptr=NULL;
01798 
01799   *result=ERROR;
01800   if(!apm->tasks) return -1;
01801   if((!apm->tasks[gi->ap_sti])) return -1;
01802   apm_src_task=apm->tasks[gi->ap_sti];
01803 
01804   if(!apm_src_task->args) return -1;
01805   if(!apm_src_task->args[gi->ap_sai]) return -1;
01806   apm_src_arg=apm_src_task->args[gi->ap_sai];
01807   for( gi->ap_dti=gi->ap_dti; gi->ap_dti<apm->nb_tasks; gi->ap_dti++){   
01808      if(!apm->tasks[gi->ap_dti]) return -1;
01809      apm_dest_task=apm->tasks[gi->ap_dti];    
01810     
01811      if(!apm_dest_task->problem) return -1;
01812      if(!apm_dest_task->problem->arglist) return -1; 
01813      dest_argptr= apm->tasks[gi->ap_dti]->problem->arglist;
01814       gi->ap_dai=0;
01815       gi->tg_bli=0;
01816  
01817      if(!apm->tasks[gi->ap_dti]->args) return -1;
01818 
01819      while( dest_argptr!=NULL ){
01820 
01821        if(dest_argptr->objecttype!=GS_SCALAR){
01822          if(!apm_dest_task->args[gi->ap_dai]) return -1;
01823          apm_dest_arg=apm_dest_task->args[gi->ap_dai];
01824          if((dest_argptr->inout==GS_IN) || (dest_argptr->inout==GS_INOUT)) gi->tg_bli++;
01825 
01826          if(apm_src_arg->id==apm_dest_arg->id){
01827            if(dest_argptr->inout==GS_IN){
01828              *_dest_argptr= dest_argptr;
01829              *result=DEP_FOUND_ARG_NOT_UPDATED;
01830              return 0;
01831            }
01832            if(dest_argptr->inout==GS_INOUT){
01833              *_dest_argptr= dest_argptr;
01834              *result=DEP_FOUND_ARG_UPDATED;
01835              return 0;
01836            }
01837           if(dest_argptr->inout==GS_OUT){
01838              *result=DEP_NOT_FOUND_ARG_UPDATED;
01839              return 0;
01840           }
01841          }
01842        }
01843        gi->ap_dai++;
01844        dest_argptr=dest_argptr->next;
01845      }
01846      gi->tg_dti=gi->tg_dti+2;
01847   }
01848   *result=DEP_NOT_FOUND_ARG_NOT_UPDATED;
01849   return 0;
01850 }
01851 
01852 
01853 
01854 
01855 
01856 
01857 
01858 
01859 
01860 int 
01861 gs_smart_tg_dep_anayl_set_remote_dep(gs_smart_t_dep_anayl * src_t_anayl, 
01862           gs_smart_t_dep_anayl * dest_t_anayl, gs_smart_a_dep_anayl * src_a_anayl, 
01863           gs_smart_a_dep_anayl * dest_a_anayl, gs_smart_graph_indexes * gi, int inout){
01864 
01865   int obj_for_link;
01866   if((!src_a_anayl) || (!dest_a_anayl) || (!src_t_anayl) || (!dest_t_anayl)) return -1;
01867   if(!gi) return -1;
01868 
01869   src_a_anayl->is_sent_remotely=1;
01870   dest_a_anayl->is_received_remotely=1;
01871   
01872   src_a_anayl->out_task_dep=gi->tg_dti;
01873   src_a_anayl->out_task_dep_link=gi->tg_bli;
01874   src_a_anayl->out_obj_dep_link=1;
01875 
01876   obj_for_link=src_a_anayl->nb_obj_for_links;   
01877   dest_a_anayl->in_task_dep=gi->tg_ti;
01878   dest_a_anayl->in_task_dep_link=gi->tg_fli;
01879   dest_a_anayl->in_obj_dep_link=obj_for_link;   
01880 
01881 
01882   if(inout==GS_IN){
01883    if(src_a_anayl->nb_clnt_obj_for_links==0){
01884     src_a_anayl->nb_clnt_obj_for_links++;
01885  
01886    }
01887  
01888     obj_for_link=src_a_anayl->nb_clnt_obj_for_links;   
01889     dest_t_anayl->nb_prev_client_for_links--;
01890     dest_a_anayl->in_task_dep--;
01891     dest_a_anayl->in_task_dep_link=gi->tg_clnt_fli;
01892     dest_a_anayl->in_obj_dep_link=obj_for_link;        
01893     src_a_anayl->nb_clnt_obj_for_links++;
01894   }
01895   else{
01896     src_a_anayl->nb_obj_for_links++;
01897   }
01898 
01899   if((inout==GS_INOUT) || (inout==GS_OUT) ){
01900     dest_t_anayl->nb_prev_client_for_links--;
01901     if((src_a_anayl->nb_obj_for_links==1)){
01902       src_t_anayl->nb_next_client_back_links--;
01903     }
01904   }
01905   return 0;
01906 }
01907 
01908 
01909 
01910 
01911 
01912 
01913 
01914 
01915 int
01916 gs_smart_tg_rem_task_join_for_back_links(gs_smart_app_pm * app_pm,
01917     gs_smart_tg * task_graph, gs_smart_graph_indexes * gi){
01918   
01919   gs_argument_t *argptr; 
01920   gs_smart_app_pm_task  * apm_this_node;
01921   gs_smart_tg_task_node * tg_task_node;
01922   gs_smart_tg_remote_task_node * tg_rem_task_node=NULL, * tg_src_rem_task_node=NULL;
01923    gs_smart_tg_dep_link * for_link, * back_link;
01924   gs_smart_app_pm_args * apm_this_arg=NULL;
01925   gs_smart_tg_obj_node * obj_node;
01926   gs_smart_tg_client_node * tg_src_client_task_node=NULL, * tg_src_clnt_task_node=NULL;
01927 
01928   int src_task;
01929   int tg_fli;
01930   int src_clnt_node=0;
01931 
01932  
01933   if((!app_pm) || (!task_graph) || (!gi) ) return -1;
01934   if(!task_graph->task_nodes) return -1;
01935 
01936   if(!task_graph->task_nodes[gi->tg_ti]) return -1;
01937 
01938   tg_task_node=task_graph->task_nodes[gi->tg_ti];
01939   
01940   if(!tg_task_node->tg_rem_task_node) return -1;
01941 
01942   tg_rem_task_node=tg_task_node->tg_rem_task_node;
01943 
01944  if(!app_pm->tasks) return -1;
01945 
01946  if(!app_pm->tasks[gi->ap_ti]) return -1;
01947   apm_this_node=app_pm->tasks[gi->ap_ti];
01948 
01949   if(!apm_this_node->problem) return -1;
01950 
01951   if(!tg_rem_task_node->tg_node_bkwrd_link) return -1;
01952   if(!apm_this_node->args) return -1;
01953 
01954   gi->tg_bli=0;  
01955   gi->ap_ai=0;
01956   gi->tg_fli=0;  //previous client node forward link index
01957 
01958   for(argptr=apm_this_node->problem->arglist;argptr!=NULL;argptr=argptr->next){
01959     if( ((argptr->inout==GS_IN) || (argptr->inout==GS_INOUT)) &&  
01960                             (argptr->objecttype!=GS_SCALAR)){
01961       
01962       if(!tg_rem_task_node->tg_node_bkwrd_link[gi->tg_bli]) return -1;
01963       
01964    
01965       if(!apm_this_node->args[gi->ap_ai]) return -1;      
01966 
01967       apm_this_arg=apm_this_node->args[gi->ap_ai];
01968  
01969       
01970       if(!apm_this_arg->a_anayl) return -1;
01971 
01972       if(apm_this_arg->a_anayl->is_received_remotely){
01973          src_task=apm_this_arg->a_anayl->in_task_dep;
01974          tg_fli=apm_this_arg->a_anayl->in_task_dep_link;
01975 
01976          src_clnt_node=0;
01977          if(task_graph->task_nodes[src_task]->node_type==GS_SMART_TG_CLIENT_NODE) src_clnt_node=1;
01978 
01979          if(src_clnt_node==1){
01980            if(!task_graph->task_nodes[src_task]->tg_client_node) return -1;
01981            tg_src_clnt_task_node=task_graph->task_nodes[src_task]->tg_client_node;
01982            if(!tg_src_clnt_task_node->tg_node_frwrd_link[tg_fli]) return -1;
01983          
01984            /*
01985             * The back link (gi->tg_bli) of this remote task (tg_rem_task_node) 
01986             * points to object node (obj_node).
01987             * This object node orignates from source remote task node (tg_src_rem_task_node)
01988             * forward link (tg_fli) 
01989             */
01990             for_link=tg_src_clnt_task_node->tg_node_frwrd_link[tg_fli];
01991          } 
01992          else{
01993            if(!task_graph->task_nodes[src_task]->tg_rem_task_node) return -1;
01994 
01995             tg_src_rem_task_node=task_graph->task_nodes[src_task]->tg_rem_task_node;
01996          
01997             if(!tg_src_rem_task_node->tg_node_frwrd_link[tg_fli]) return -1;
01998            /*
01999             * The back link (gi->tg_bli) of this remote task (tg_rem_task_node) 
02000             * points to object node (obj_node).
02001             * This object node orignates from source remote task node (tg_src_rem_task_node)
02002             * forward link (tg_fli) 
02003             */
02004             for_link=tg_src_rem_task_node->tg_node_frwrd_link[tg_fli];
02005         }
02006 
02007 
02008          if(!for_link->obj_node_ptr) return -1;         
02009 
02010          obj_node=for_link->obj_node_ptr;
02011                 
02012          
02013          /*
02014           * The back link (gi->tg_bli) of this remote task (tg_rem_task_node) 
02015           * points to object node (obj_node).
02016           * This object node orignates from source remote task node (tg_src_rem_task_node)
02017           * forward link (tg_fli) 
02018           */
02019                 
02020          /*
02021           * Initalising parameters of obj_node that the forward link 
02022           * and backward link point to.
02023           */
02024          obj_node->byte_size=gs_smart_get_argument_size(argptr);
02025          obj_node->argptr=argptr;
02026          obj_node->name=strdup(obj_node->argptr->name);
02027          obj_node->in_call_seq_pos=gi->ap_ai; 
02028          obj_node->rem_dep_id=gi->rem_dep_id;
02029          gi->rem_dep_id++;          
02030 
02031          /*
02032           * Initialising the pointer of the two-way forward link of the object node 
02033           * Pointing it forward to this remote task node (tg_rem_task_node) 
02034           * and back to itself.
02035           */ 
02036 
02037          int obj_for_link= apm_this_arg->a_anayl->in_obj_dep_link;
02038          obj_node->tg_obj_frwrd_link[obj_for_link]->task_node_ptr=tg_task_node;
02039          obj_node->tg_obj_frwrd_link[obj_for_link]->obj_node_ptr=obj_node;
02040 
02041       
02042         /*
02043          * The backlink (tg_bli) of this remote task node (tg_rem_task_node)
02044          * points back to the object node (obj_node).
02045          * Therefore it is the reverse of object node forward link (0).
02046          * As a result the pointers of the two-way backlink (tg_bli) of
02047          * tg_rem_task_node are the exact same as the two-way foward link (0) of
02048          * obj_node.
02049          */
02050 
02051          back_link=obj_node->tg_obj_frwrd_link[obj_for_link];
02052          tg_rem_task_node->tg_node_bkwrd_link[gi->tg_bli]=back_link;
02053       }
02054       else{
02055          if(!task_graph->task_nodes[gi->tg_ti-1]->tg_client_node) return -1;
02056          tg_src_client_task_node=task_graph->task_nodes[gi->tg_ti-1]->tg_client_node;
02057          if(!tg_src_client_task_node->tg_node_frwrd_link[gi->tg_fli]) return -1;
02058 
02059          for_link=tg_src_client_task_node->tg_node_frwrd_link[gi->tg_fli];
02060          if(!for_link->obj_node_ptr) return -1;         
02061 
02062 
02063 
02064          /*
02065           * The back link (gi->tg_bli) of this remote task (tg_rem_task_node) 
02066           * points to object node (obj_node).
02067           * This object node originates from source client task node (tg_src_client_node)
02068           * forward link (tg_fli). 
02069           */
02070          obj_node=for_link->obj_node_ptr;
02071        
02072          /*
02073           * Initalising parameters of obj_node that the forward link 
02074           * and backward link point to.
02075           */
02076          obj_node->byte_size=gs_smart_get_argument_size(argptr);
02077          obj_node->argptr=argptr;
02078          obj_node->name=strdup(obj_node->argptr->name);
02079          obj_node->in_call_seq_pos=gi->ap_ai; 
02080          obj_node->rem_dep_id=-1;
02081          
02082 
02083          /*
02084           * Initialising the pointer of the two-way forward link of the object node. 
02085           * Pointing it forward to this remote task node (tg_rem_task_node) 
02086           * and back to itself.
02087           */ 
02088          int obj_for_link= apm_this_arg->a_anayl->in_obj_dep_link;
02089          obj_node->tg_obj_frwrd_link[obj_for_link]->task_node_ptr=tg_task_node;
02090          obj_node->tg_obj_frwrd_link[obj_for_link]->obj_node_ptr=obj_node;
02091          
02092         /*
02093          * The backlink (tg_bli) of this remote task node (tg_rem_task_node)
02094          * points back to the object node (obj_node).
02095          * Therefore it is the reverse of object node forward link (0).
02096          * As a result the pointers of the two-way backlink (tg_bli) of
02097          * tg_rem_task_node are the exact same as the two-way foward link (0) of
02098          * obj_node.
02099          */
02100          back_link=obj_node->tg_obj_frwrd_link[obj_for_link];
02101 
02102          tg_rem_task_node->tg_node_bkwrd_link[gi->tg_bli]=back_link;
02103         
02104         gi->tg_fli++;
02105       }
02106           
02107       gi->tg_bli++; 
02108         
02109     }
02110     gi->ap_ai++;
02111   } 
02112   return 0;
02113 }
02114 
02115 
02116 
02117 
02118 int
02119 gs_smart_tg_client_node_join_for_back_links(gs_smart_app_pm * app_pm,
02120     gs_smart_tg * task_graph, gs_smart_graph_indexes * gi){
02121  
02122   gs_argument_t *argptr; 
02123   gs_smart_app_pm_task  * apm_this_node;
02124   gs_smart_tg_task_node * tg_task_node;
02125   gs_smart_tg_remote_task_node  * tg_src_rem_task_node=NULL;
02126   gs_smart_tg_client_node * tg_client_node=NULL;
02127   gs_smart_tg_dep_link * for_link, * back_link;
02128   gs_smart_tg_obj_node * obj_node;
02129   gs_smart_app_pm_args * apm_this_arg=NULL;
02130   int node_id;
02131   if((!app_pm) || (!task_graph) || (!gi) ) return -1;
02132 
02133   /*
02134    * There are no back links if there is only one remote node.
02135    */
02136 /*
02137   if(task_graph->nb_nodes==5){
02138     return 0;
02139   }
02140 */
02141 
02142   if(gi->tg_ti==task_graph->nb_nodes-2){ 
02143     node_id=gi->ap_ti;
02144   }
02145   else{
02146     node_id=gi->ap_ti-1;
02147   }
02148 
02149   if((!app_pm->tasks) || (!task_graph->task_nodes)) return -1;
02150   if(!app_pm->tasks[node_id]) return -1;
02151 
02152   apm_this_node=app_pm->tasks[node_id];
02153  
02154   if(!task_graph->task_nodes[gi->tg_ti]) return -1;
02155   tg_task_node=task_graph->task_nodes[gi->tg_ti];
02156 
02157   if(!tg_task_node->tg_client_node) return -1;
02158 
02159   tg_client_node=tg_task_node->tg_client_node;
02160  
02161   if((!apm_this_node->args) || (!tg_client_node->tg_node_bkwrd_link)) return -1;
02162 
02163   gi->tg_bli=0;  
02164   gi->ap_ai=0;
02165   gi->tg_fli=0;  //previous client node forward link index
02166   for(argptr=apm_this_node->problem->arglist;argptr!=NULL;argptr=argptr->next){
02167     if( ((argptr->inout==GS_OUT) || (argptr->inout==GS_INOUT)) &&  (argptr->objecttype!=GS_SCALAR)){   
02168 
02169 
02170       if(apm_this_node->args[gi->ap_ai]->a_anayl->is_sent_remotely==0){
02171       
02172         
02173         if(!task_graph->task_nodes[gi->tg_ti-1]->tg_rem_task_node) return -1;
02174 
02175         tg_src_rem_task_node=task_graph->task_nodes[gi->tg_ti-1]->tg_rem_task_node;
02176        
02177 
02178         if(!tg_src_rem_task_node->tg_node_frwrd_link) return -1; 
02179         if(!tg_src_rem_task_node->tg_node_frwrd_link[gi->tg_fli]) return -1;
02180 
02181         for_link=tg_src_rem_task_node->tg_node_frwrd_link[gi->tg_fli];
02182 
02183         if(!for_link->obj_node_ptr) return -1;         
02184          
02185           /*
02186           * The back link (gi->tg_bli) of this client node task (tg_client_node) 
02187           * points to object node (obj_node).
02188           * This object node originates from source task node (tg_src_rem_task_node)
02189           * forward link (tg_fli).
02190           */
02191 
02192          obj_node=for_link->obj_node_ptr;
02193 
02194 
02195 
02196          /*
02197           * Initalising parameters of obj_node that the forward link 
02198           * and backward link point to.
02199           */
02200        
02201          obj_node->byte_size=gs_smart_get_argument_size(argptr);
02202          obj_node->argptr=argptr;
02203          obj_node->name=strdup(obj_node->argptr->name);
02204          //obj_node->call_seq_pos=gi->ap_ai; 
02205          
02206          obj_node->rem_dep_id=-1;
02207 
02208          if(!obj_node->tg_obj_frwrd_link[0]) return -1;
02209          /*
02210           * Initialising the pointer of the two-way forward link of the object node. 
02211           * Pointing it forward to this remote task node (tg_rem_task_node) 
02212           * and back to itself.
02213           */ 
02214          apm_this_arg=apm_this_node->args[gi->ap_ai];
02215          int obj_for_link=0;
02216          obj_node->tg_obj_frwrd_link[obj_for_link]->task_node_ptr=tg_task_node;
02217          obj_node->tg_obj_frwrd_link[obj_for_link]->obj_node_ptr=obj_node;
02218 
02219         /*
02220          * The backlink (tg_bli) of this client node (tg_client_node)
02221          * points back to the object node (obj_node).
02222          * Therefore it is the reverse of object node forward link (0).
02223          * As a result the pointers of the two-way backlink (tg_bli) of
02224          * tg_client_node are the exact same as the two-way foward link (0) of
02225          * obj_node.
02226          */
02227   
02228         if(!tg_client_node->tg_node_bkwrd_link[gi->tg_bli]) return -1;
02229          back_link=obj_node->tg_obj_frwrd_link[obj_for_link];  
02230          tg_client_node->tg_node_bkwrd_link[gi->tg_bli]=back_link; 
02231  
02232         gi->tg_bli++; 
02233       }
02234       gi->tg_fli++;
02235     }
02236     gi->ap_ai++;
02237   }
02238   return 0;
02239 }
02240 
02241 
02242 
02243 
02244 
02245 
02246 int
02247 gs_smart_tg_client_for_links_to_dotgraph(gs_smart_tg_client_node * tg_client_node,int rem_node, FILE * fp){
02248   gs_smart_tg_dep_link * for_link;
02249   int j, i;
02250   for(j=0; j<tg_client_node->nb_node_frwd_links; j++){
02251     for_link=tg_client_node->tg_node_frwrd_link[j];
02252     fprintf(fp, "%s_%d_%d [label=\"%s\\nbytes=%d\" ];\n", for_link->obj_node_ptr->name, rem_node, j, for_link->obj_node_ptr->name, for_link->obj_node_ptr->byte_size);
02253     fprintf(fp, "client_%d -> %s_%d_%d;\n", rem_node, for_link->obj_node_ptr->name, rem_node, j);
02254     for(i=0;i<for_link->obj_node_ptr->nb_obj_frwd_links;i++){
02255       fprintf(fp, "%s_%d_%d -> %s_%d;\n",  for_link->obj_node_ptr->name, rem_node, j, for_link->obj_node_ptr->tg_obj_frwrd_link[i]->task_node_ptr->tg_rem_task_node->problem->name, for_link->obj_node_ptr->tg_obj_frwrd_link[i]->task_node_ptr->id);
02256     }
02257   }
02258 
02259   return 0;
02260 }
02261 
02262 
02263 
02264 
02265 
02266 
02267 
02268 
02269 
02270 
02271 int
02272 gs_smart_tg_rem_for_links_to_dotgraph(gs_smart_tg_remote_task_node * tg_rem_task_node,int rem_node, FILE * fp, int * client_comm_exists){
02273 
02274   gs_smart_tg_task_node * tg_dest_task_node;
02275   gs_smart_tg_dep_link * for_link;
02276   gs_smart_tg_client_node * tg_dest_client_node; 
02277   gs_smart_tg_remote_task_node * tg_dest_rem_task_node;
02278   int node_type, j, i;
02279   *client_comm_exists=0;
02280   
02281   for(j=0; j<tg_rem_task_node->nb_node_frwd_links; j++){
02282     for_link=tg_rem_task_node->tg_node_frwrd_link[j];
02283      tg_dest_task_node=for_link->obj_node_ptr->tg_obj_frwrd_link[0]->task_node_ptr;
02284      fprintf(fp, " %s_%d_%d [label=\"%s\\nbytes=%d\" ];\n", for_link->obj_node_ptr->name, rem_node, j,  for_link->obj_node_ptr->name, for_link->obj_node_ptr->byte_size);
02285      fprintf(fp, "%s_%d -> %s_%d_%d;\n", tg_rem_task_node->problem->name, rem_node, for_link->obj_node_ptr->name, rem_node,  j);
02286 
02287      node_type=tg_dest_task_node->node_type;
02288 
02289      if(node_type==GS_SMART_TG_CLIENT_NODE){
02290        tg_dest_client_node=tg_dest_task_node->tg_client_node;
02291        for(i=0;i<for_link->obj_node_ptr->nb_obj_frwd_links;i++){
02292          fprintf(fp, "%s_%d_%d -> client_%d;\n",  for_link->obj_node_ptr->name, rem_node, j, for_link->obj_node_ptr->tg_obj_frwrd_link[i]->task_node_ptr->id);
02293          *client_comm_exists=1;
02294        }
02295      }
02296      else if(node_type==GS_SMART_TG_REM_TASK_NODE){
02297        tg_dest_rem_task_node=tg_dest_task_node->tg_rem_task_node;
02298        for(i=0;i<for_link->obj_node_ptr->nb_obj_frwd_links;i++){
02299          fprintf(fp, "%s_%d_%d -> %s_%d;\n",  for_link->obj_node_ptr->name, rem_node, j, for_link->obj_node_ptr->tg_obj_frwrd_link[i]->task_node_ptr->tg_rem_task_node->problem->name, for_link->obj_node_ptr->tg_obj_frwrd_link[i]->task_node_ptr->id);
02300        }
02301      } 
02302    }
02303   return 0;
02304 }
02305 
02306 
02307 
02308 
02309 
02310 
02311 
02312 int gs_smart_reset_graph_indexes(gs_smart_graph_indexes * gi){
02313   if(!gi){
02314     ERRPRINTF("Smart : Error allocating graph indexes\n");
02315     return -1;
02316   }
02317   gi->cur_arg_id=0;
02318   gi->tg_ti=0;
02319   gi->tg_sti=0; 
02320   gi->tg_dti=0;
02321   gi->tg_lnai=0; 
02322   gi->tg_rnai=0;
02323   gi->tg_drnai=0; 
02324 
02325   gi->ap_ti=0;
02326   gi->ap_sti=0;  
02327   gi->ap_dti=0;  
02328   gi->ap_sai=0; 
02329   gi->ap_dai=0; 
02330 
02331 
02332   return 0;
02333 }
02334 
02335 
02336 
02337 
02338 
02339 
02340 
02341 
02342 int gs_smart_tg_set_scalar_arg_values(gs_smart_app_pm * apm, icl_hash_t *symtab, gs_smart_graph_indexes * gi){
02343   gs_smart_app_pm_task * apm_task; 
02344   gs_smart_app_pm_args * apm_arg;
02345   gs_argument_t *argptr;
02346   int ai=0;
02347 
02348 
02349   if((!apm) || (!symtab) || (!gi)) return -1;
02350  
02351   apm_task=apm->tasks[gi->ap_ti];
02352 
02353   if(!apm_task){
02354     ERRPRINTF("Smart : Error finding apm task node %d\n", gi->ap_ti);
02355     return -1;
02356   }
02357 
02358   if(!apm_task->problem->arglist){
02359     ERRPRINTF("Smart : Error, arglist for apm task node %d is NULL\n",  gi->ap_ti);
02360     return -1;
02361   }
02362 
02363 
02364   for(argptr= apm_task->problem->arglist;argptr!=NULL;argptr=argptr->next){
02365     if((argptr->objecttype==GS_SCALAR) && ((argptr->inout == GS_IN) || 
02366         (argptr->inout == GS_INOUT)) ){
02367 
02368       apm_arg= apm_task->args[ai];
02369       if(apm_arg->scalar){
02370         switch(argptr->datatype) {
02371           case GS_INT:
02372             argptr->expr_val = (int) apm_arg->uvalue.i;; 
02373           break;
02374           case GS_CHAR:
02375             argptr->expr_val = (char) apm_arg->uvalue.c;
02376           break;
02377           case GS_FLOAT:
02378             argptr->expr_val = (double) *((float *)(argptr->data));
02379           break;
02380           case GS_DOUBLE:
02381             argptr->expr_val = (double) apm_arg->uvalue.d;
02382           break;
02383           case GS_SCOMPLEX:
02384             argptr->expr_val = (double) ((gs_scomplex *)(argptr->data))->r;
02385           break;
02386           case GS_DCOMPLEX:
02387             argptr->expr_val = (double) ((gs_dcomplex *)(argptr->data))->r;
02388           break;
02389           default:
02390             ERRPRINTF("Bad data type\n");
02391           return -1;
02392         }
02393         icl_hash_insert(symtab,argptr->name, &(argptr->expr_val));
02394       }
02395       else if ((argptr->objecttype==GS_SCALAR) && (argptr->inout == GS_OUT ) ){
02396         argptr->expr_val = 0.0;
02397         icl_hash_insert(symtab, argptr->name, &(argptr->expr_val)); 
02398         return -1;
02399       }
02400     }
02401     ai++;
02402   }
02403   return 0;
02404 }
02405 
02406    
02407 
02408 
02409 
02410 
02411 
02412 
02413 
02414 
02415 
02416 
02417 
02418 
02419 
02420 
02421 
02422 
02423 
02424 
02425 int gs_smart_tg_get_problem_size(gs_problem_t * problem, double * nb_flops){
02426   char *complexitystr = NULL;
02427   double complexity = -1.0;
02428   gs_argument_t *argptr;
02429   icl_hash_t *symtab;
02430   
02431  if(!problem){
02432     ERRPRINTF("SMART: Problem is NULL\n");
02433     return -1;
02434   }
02435 
02436   symtab = icl_hash_create(11, NULL);
02437 
02438   if(!symtab) {
02439     LOGPRINTF("SMART: could not create hash table; ");
02440     LOGPRINTF("assuming complexity=1000000 (1 gflop of work)\n");
02441     *nb_flops = 1000.0;
02442   }
02443   else {
02444     if(!problem->arglist){
02445       ERRPRINTF("Smart : Error, the arglist for problem is NULL\n");
02446       return -1;
02447     }
02448 
02449     for(argptr = problem->arglist; argptr != NULL; argptr = argptr->next){
02450       if((argptr->objecttype == GS_SCALAR) && (argptr->inout != GS_OUT)){
02451       icl_hash_insert(symtab, argptr->name, &(argptr->expr_val));
02452       }
02453     }
02454     // Evaluate complexity expression 
02455     complexitystr = gs_problem_getinfo(problem, "COMPLEXITY", "1000000");
02456     if(gs_expr_d(complexitystr, &complexity, symtab) < 0) {
02457       LOGPRINTF("Complexity string %s could not be evaluated; ", complexitystr);
02458       LOGPRINTF("assuming complexity=1000000 (1 gflop of work)\n");
02459     complexity = 1000000.00;    // a gigaflop of work 
02460     }
02461     *nb_flops= complexity / 1000.0;
02462   }
02463   return 0;
02464 }
02465 
02466 
02467 
02468 
02469 
02470 
02471 
02472 
02473 
02474 /*
02475 Given an argument structure this function returns argument size
02476 */
02477 
02478 int gs_smart_get_argument_size(gs_argument_t * arg){
02479   int my_dsig;
02480   if(!arg){
02481     ERRPRINTF("SMART: Argument pointer is NULL\n");
02482     return -1;
02483   }
02484   my_dsig = pvmgetdsig();
02485   return (arg->rows * arg->cols * gs_get_element_size(arg->datatype, my_dsig));
02486 }
02487 
02488 
02489 
02490 
02491 
02492 
02493 int gs_smart_tg_free(gs_smart_tg * task_graph){
02494 
02495   gs_smart_tg_remote_task_node * tg_rem_task_node;
02496   gs_smart_tg_client_node * tg_client_node;
02497   gs_smart_tg_dep_link * for_task_link, * back_task_link;
02498   gs_smart_tg_dep_link * for_obj_link, * back_obj_link;
02499   gs_smart_tg_obj_node * obj_node;
02500   int i, j, k, nb_node_for_links,nb_node_back_links;
02501   int nb_obj_for_links;
02502   if(!task_graph) return -1;
02503   for(i=0; i<task_graph->nb_nodes; i++){
02504     if(!task_graph->task_nodes[i]) return -1;
02505 
02506     if(task_graph->task_nodes[i]->id==GS_SMART_TG_REM_TASK_NODE){
02507 
02508 
02509       if(!task_graph->task_nodes[i]->tg_rem_task_node) return -1;
02510 
02511       tg_rem_task_node=task_graph->task_nodes[i]->tg_rem_task_node;
02512       nb_node_for_links=tg_rem_task_node->nb_node_frwd_links;
02513 
02514       for(j=0; j<nb_node_for_links; j++){
02515 
02516         if(!tg_rem_task_node->tg_node_frwrd_link[j]) return -1;
02517 
02518         for_task_link=tg_rem_task_node->tg_node_frwrd_link[j];
02519 
02520         if(!for_task_link->obj_node_ptr) return -1;
02521         obj_node=for_task_link->obj_node_ptr;
02522 
02523         nb_obj_for_links=obj_node->nb_obj_frwd_links;
02524         for(k=0;k<nb_obj_for_links;k++){
02525           if(!obj_node->tg_obj_frwrd_link[k]) return -1;
02526           for_obj_link=obj_node->tg_obj_frwrd_link[k];
02527           if(for_obj_link) free(for_obj_link);
02528 
02529         }
02530        
02531         if(!obj_node->tg_obj_bkwrd_link) return -1;
02532 
02533         back_obj_link=obj_node->tg_obj_bkwrd_link;
02534         if(back_obj_link) free(back_obj_link);
02535 
02536         if(obj_node->name) free(obj_node->name);
02537 
02538         if(obj_node) free(obj_node);
02539         
02540       }
02541 
02542       nb_node_back_links=tg_rem_task_node->nb_node_bkwd_links;
02543       if(tg_rem_task_node) free(tg_rem_task_node);  
02544 
02545     }
02546 
02547     else if(task_graph->task_nodes[i]->id==GS_SMART_TG_CLIENT_NODE){
02548       if(!task_graph->task_nodes[i]->tg_client_node) return -1;
02549       tg_client_node=task_graph->task_nodes[i]->tg_client_node;
02550       nb_node_for_links=tg_client_node->nb_node_frwd_links;
02551       
02552       for(j=0; j<nb_node_for_links; j++){
02553         if(!tg_client_node->tg_node_frwrd_link[j]) return -1;
02554 
02555         for_task_link=tg_client_node->tg_node_frwrd_link[j];
02556         if(!for_task_link->obj_node_ptr) return -1;
02557         obj_node=for_task_link->obj_node_ptr;
02558 
02559         nb_obj_for_links=obj_node->nb_obj_frwd_links;
02560         
02561         for(k=0;k<nb_obj_for_links;k++){
02562           if(!obj_node->tg_obj_frwrd_link[k]) return -1;
02563           for_obj_link=obj_node->tg_obj_frwrd_link[k];
02564           if(for_obj_link) free(for_obj_link);
02565         }
02566 
02567         if(!obj_node->tg_obj_bkwrd_link) return -1;
02568         back_obj_link=obj_node->tg_obj_bkwrd_link;
02569         if(back_obj_link) free(back_obj_link);
02570 
02571         if(obj_node->name) free(obj_node->name);
02572 
02573         if(obj_node) free(obj_node);
02574       }
02575       nb_node_back_links=tg_client_node->nb_node_bkwd_links;
02576 
02577       for(j=0; j<nb_node_back_links; j++){
02578         if(!tg_client_node->tg_node_bkwrd_link[j]) return -1;
02579         back_task_link=tg_client_node->tg_node_bkwrd_link[j];
02580         if(back_task_link) free(back_task_link);
02581       }
02582       if(tg_client_node) free(tg_client_node);  
02583       
02584     }
02585     if(task_graph->task_nodes[i]) free(task_graph->task_nodes[i]);
02586   }
02587   if(task_graph->task_nodes) free(task_graph->task_nodes);
02588   if(task_graph) free(task_graph);
02589   return 0;
02590 }
02591 
02592 
02593 
02594 
02595 
02596 
02597 
02598 
02599 int 
02600 gs_smart_tg_print_to_dotgraph(gs_smart_tg * task_graph, char * filename){
02601   gs_smart_tg_task_node * tg_task_node, * tg_next_task_node; 
02602   gs_smart_tg_remote_task_node * tg_rem_task_node, * tg_next_rem_task_node;
02603   gs_smart_tg_client_node * tg_client_node, * tg_next_client_node;
02604   FILE *fp;
02605   int i, node_type, client_comm_exists;
02606 
02607   fp = fopen(filename, "w");
02608   if(fp<0){
02609     ERRPRINTF("SMART: Error opening file\n");
02610     return -1;
02611   } 
02612 
02613   fprintf(fp, "digraph Task_Graph {\n");
02614   for(i=0; i<task_graph->nb_nodes;i++){
02615     tg_task_node=task_graph->task_nodes[i];
02616     node_type=tg_task_node->node_type;
02617     if(node_type==GS_SMART_TG_START_NODE){
02618       fprintf(fp, " start_node_0 [shape=polygon, label=\"start_node_0\",sides=5, peripheries=2, style=\"filled\", fillcolor=\"#FFA500\" fontsize=\"15.0\"];\n");
02619     }
02620     if(node_type==GS_SMART_TG_END_NODE){
02621       fprintf(fp, " end_node_%d [shape=polygon, label=\"end_node_%d\",sides=5, peripheries=2, style=\"filled\", fillcolor=\"#FFA500\" fontsize=\"15.0\"];\n", i, i);
02622       fprintf(fp, " client_%d -> end_node_%d [color=red];\n", i-1, i);
02623       break;
02624     }
02625     else if(node_type==GS_SMART_TG_CLIENT_NODE){
02626       tg_client_node=tg_task_node->tg_client_node;
02627       fprintf(fp, " client_%d [shape=\"diamond\", style=\"filled\", fillcolor=\"#ADD8E6\" fontsize=\"15.0\"];\n", i);
02628     }
02629     else if(node_type==GS_SMART_TG_REM_TASK_NODE){
02630       tg_rem_task_node=tg_task_node->tg_rem_task_node;
02631       if(tg_rem_task_node->blocking==0){
02632         fprintf(fp, " %s_%d [shape=box,label=\"%s_%d\\nblocking=%d\\nflops=%f\",  style=filled,fillcolor=\"gray80\",fontsize=15.0];\n", tg_rem_task_node->problem->name, i, tg_rem_task_node->problem->name, i, tg_rem_task_node->blocking, tg_rem_task_node->nb_flops);
02633 
02634       }
02635       else
02636       {
02637         fprintf(fp, " %s_%d [shape=box,label=\"%s_%d\\nblocking=%d\\nflops=%f\",  style=filled,fillcolor=\"gray60\",fontsize=15.0];\n", tg_rem_task_node->problem->name, i, tg_rem_task_node->problem->name, i, tg_rem_task_node->blocking, tg_rem_task_node->nb_flops);
02638       }
02639     }
02640   }
02641 
02642   for(i=0; i<task_graph->nb_nodes;i++){
02643     tg_task_node=task_graph->task_nodes[i];
02644     node_type=tg_task_node->node_type;
02645     if(node_type==GS_SMART_TG_END_NODE){
02646 
02647       fprintf(fp, " start_node_0 -> client_1 [color=red];\n");
02648       break;
02649     }
02650     else if(node_type==GS_SMART_TG_CLIENT_NODE){
02651       tg_client_node=tg_task_node->tg_client_node;
02652 
02653       if(tg_client_node->nb_node_frwd_links==0){
02654         tg_next_task_node=task_graph->task_nodes[i+1]; 
02655         node_type=tg_next_task_node->node_type;
02656         if(node_type==GS_SMART_TG_REM_TASK_NODE){
02657           tg_next_rem_task_node=task_graph->task_nodes[i+1]->tg_rem_task_node;
02658           fprintf(fp, " client_%d -> %s_%d [style=dotted color=red];\n", i, tg_next_rem_task_node->problem->name, i+1);
02659         
02660         }
02661       }
02662       if(gs_smart_tg_client_for_links_to_dotgraph(tg_client_node, i, fp)<0){
02663         ERRPRINTF("SMART: Error printing client node\n");
02664         return -1;
02665       }
02666     }
02667     else if(node_type==GS_SMART_TG_REM_TASK_NODE){
02668       tg_rem_task_node=tg_task_node->tg_rem_task_node;
02669       
02670       if(gs_smart_tg_rem_for_links_to_dotgraph(tg_rem_task_node, i, fp, &client_comm_exists)<0){
02671         ERRPRINTF("SMART: Error printing remote task node\n");
02672         return -1;
02673       }
02674       if(!client_comm_exists){
02675         tg_next_task_node=task_graph->task_nodes[i+1];
02676         node_type=tg_next_task_node->node_type;
02677         if(node_type==GS_SMART_TG_CLIENT_NODE){
02678           tg_next_client_node=task_graph->task_nodes[i+1]->tg_client_node;
02679           fprintf(fp, " %s_%d -> client_%d [style=dotted color=red];\n",  tg_rem_task_node->problem->name, i, i+1);
02680         }
02681       }
02682     }
02683   }
02684   fprintf(fp, "\n}\n");
02685 
02686   fclose(fp);
02687   return 0;
02688 }
02689 
02690 
02691 
02692 #endif
02693